Version:  2.0.40 2.2.26 2.4.37 3.13 3.14 3.15 3.16 3.17 3.18 3.19 4.0 4.1 4.2 4.3 4.4 4.5 4.6 4.7 4.8 4.9 4.10

Linux/lib/decompress_inflate.c

  1 #ifdef STATIC
  2 #define PREBOOT
  3 /* Pre-boot environment: included */
  4 
  5 /* prevent inclusion of _LINUX_KERNEL_H in pre-boot environment: lots
  6  * errors about console_printk etc... on ARM */
  7 #define _LINUX_KERNEL_H
  8 
  9 #include "zlib_inflate/inftrees.c"
 10 #include "zlib_inflate/inffast.c"
 11 #include "zlib_inflate/inflate.c"
 12 
 13 #else /* STATIC */
 14 /* initramfs et al: linked */
 15 
 16 #include <linux/zutil.h>
 17 
 18 #include "zlib_inflate/inftrees.h"
 19 #include "zlib_inflate/inffast.h"
 20 #include "zlib_inflate/inflate.h"
 21 
 22 #include "zlib_inflate/infutil.h"
 23 #include <linux/decompress/inflate.h>
 24 
 25 #endif /* STATIC */
 26 
 27 #include <linux/decompress/mm.h>
 28 
 29 #define GZIP_IOBUF_SIZE (16*1024)
 30 
 31 static long INIT nofill(void *buffer, unsigned long len)
 32 {
 33         return -1;
 34 }
 35 
 36 /* Included from initramfs et al code */
 37 STATIC int INIT __gunzip(unsigned char *buf, long len,
 38                        long (*fill)(void*, unsigned long),
 39                        long (*flush)(void*, unsigned long),
 40                        unsigned char *out_buf, long out_len,
 41                        long *pos,
 42                        void(*error)(char *x)) {
 43         u8 *zbuf;
 44         struct z_stream_s *strm;
 45         int rc;
 46 
 47         rc = -1;
 48         if (flush) {
 49                 out_len = 0x8000; /* 32 K */
 50                 out_buf = malloc(out_len);
 51         } else {
 52                 if (!out_len)
 53                         out_len = ((size_t)~0) - (size_t)out_buf; /* no limit */
 54         }
 55         if (!out_buf) {
 56                 error("Out of memory while allocating output buffer");
 57                 goto gunzip_nomem1;
 58         }
 59 
 60         if (buf)
 61                 zbuf = buf;
 62         else {
 63                 zbuf = malloc(GZIP_IOBUF_SIZE);
 64                 len = 0;
 65         }
 66         if (!zbuf) {
 67                 error("Out of memory while allocating input buffer");
 68                 goto gunzip_nomem2;
 69         }
 70 
 71         strm = malloc(sizeof(*strm));
 72         if (strm == NULL) {
 73                 error("Out of memory while allocating z_stream");
 74                 goto gunzip_nomem3;
 75         }
 76 
 77         strm->workspace = malloc(flush ? zlib_inflate_workspacesize() :
 78                                  sizeof(struct inflate_state));
 79         if (strm->workspace == NULL) {
 80                 error("Out of memory while allocating workspace");
 81                 goto gunzip_nomem4;
 82         }
 83 
 84         if (!fill)
 85                 fill = nofill;
 86 
 87         if (len == 0)
 88                 len = fill(zbuf, GZIP_IOBUF_SIZE);
 89 
 90         /* verify the gzip header */
 91         if (len < 10 ||
 92            zbuf[0] != 0x1f || zbuf[1] != 0x8b || zbuf[2] != 0x08) {
 93                 if (pos)
 94                         *pos = 0;
 95                 error("Not a gzip file");
 96                 goto gunzip_5;
 97         }
 98 
 99         /* skip over gzip header (1f,8b,08... 10 bytes total +
100          * possible asciz filename)
101          */
102         strm->next_in = zbuf + 10;
103         strm->avail_in = len - 10;
104         /* skip over asciz filename */
105         if (zbuf[3] & 0x8) {
106                 do {
107                         /*
108                          * If the filename doesn't fit into the buffer,
109                          * the file is very probably corrupt. Don't try
110                          * to read more data.
111                          */
112                         if (strm->avail_in == 0) {
113                                 error("header error");
114                                 goto gunzip_5;
115                         }
116                         --strm->avail_in;
117                 } while (*strm->next_in++);
118         }
119 
120         strm->next_out = out_buf;
121         strm->avail_out = out_len;
122 
123         rc = zlib_inflateInit2(strm, -MAX_WBITS);
124 
125         if (!flush) {
126                 WS(strm)->inflate_state.wsize = 0;
127                 WS(strm)->inflate_state.window = NULL;
128         }
129 
130         while (rc == Z_OK) {
131                 if (strm->avail_in == 0) {
132                         /* TODO: handle case where both pos and fill are set */
133                         len = fill(zbuf, GZIP_IOBUF_SIZE);
134                         if (len < 0) {
135                                 rc = -1;
136                                 error("read error");
137                                 break;
138                         }
139                         strm->next_in = zbuf;
140                         strm->avail_in = len;
141                 }
142                 rc = zlib_inflate(strm, 0);
143 
144                 /* Write any data generated */
145                 if (flush && strm->next_out > out_buf) {
146                         long l = strm->next_out - out_buf;
147                         if (l != flush(out_buf, l)) {
148                                 rc = -1;
149                                 error("write error");
150                                 break;
151                         }
152                         strm->next_out = out_buf;
153                         strm->avail_out = out_len;
154                 }
155 
156                 /* after Z_FINISH, only Z_STREAM_END is "we unpacked it all" */
157                 if (rc == Z_STREAM_END) {
158                         rc = 0;
159                         break;
160                 } else if (rc != Z_OK) {
161                         error("uncompression error");
162                         rc = -1;
163                 }
164         }
165 
166         zlib_inflateEnd(strm);
167         if (pos)
168                 /* add + 8 to skip over trailer */
169                 *pos = strm->next_in - zbuf+8;
170 
171 gunzip_5:
172         free(strm->workspace);
173 gunzip_nomem4:
174         free(strm);
175 gunzip_nomem3:
176         if (!buf)
177                 free(zbuf);
178 gunzip_nomem2:
179         if (flush)
180                 free(out_buf);
181 gunzip_nomem1:
182         return rc; /* returns Z_OK (0) if successful */
183 }
184 
185 #ifndef PREBOOT
186 STATIC int INIT gunzip(unsigned char *buf, long len,
187                        long (*fill)(void*, unsigned long),
188                        long (*flush)(void*, unsigned long),
189                        unsigned char *out_buf,
190                        long *pos,
191                        void (*error)(char *x))
192 {
193         return __gunzip(buf, len, fill, flush, out_buf, 0, pos, error);
194 }
195 #else
196 STATIC int INIT __decompress(unsigned char *buf, long len,
197                            long (*fill)(void*, unsigned long),
198                            long (*flush)(void*, unsigned long),
199                            unsigned char *out_buf, long out_len,
200                            long *pos,
201                            void (*error)(char *x))
202 {
203         return __gunzip(buf, len, fill, flush, out_buf, out_len, pos, error);
204 }
205 #endif
206 

This page was automatically generated by LXR 0.3.1 (source).  •  Linux is a registered trademark of Linus Torvalds  •  Contact us