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