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