diff options
Diffstat (limited to 'minigzip.c')
-rw-r--r-- | minigzip.c | 193 |
1 files changed, 192 insertions, 1 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* minigzip.c -- simulate gzip using the zlib compression library | 1 | /* minigzip.c -- simulate gzip using the zlib compression library |
2 | * Copyright (C) 1995-2006, 2010 Jean-loup Gailly. | 2 | * Copyright (C) 1995-2006, 2010, 2011 Jean-loup Gailly. |
3 | * For conditions of distribution and use, see copyright notice in zlib.h | 3 | * For conditions of distribution and use, see copyright notice in zlib.h |
4 | */ | 4 | */ |
5 | 5 | ||
@@ -138,6 +138,197 @@ static void pwinerror (s) | |||
138 | # define local | 138 | # define local |
139 | #endif | 139 | #endif |
140 | 140 | ||
141 | #ifdef Z_SOLO | ||
142 | /* for Z_SOLO, create simplified gz* functions using deflate and inflate */ | ||
143 | |||
144 | #if defined(Z_HAVE_UNISTD_H) || defined(Z_LARGE) | ||
145 | # include <unistd.h> /* for unlink() */ | ||
146 | #endif | ||
147 | |||
148 | void *myalloc OF((void *, unsigned, unsigned)); | ||
149 | void myfree OF((void *, void *)); | ||
150 | |||
151 | void *myalloc(q, n, m) | ||
152 | void *q; | ||
153 | unsigned n, m; | ||
154 | { | ||
155 | q = Z_NULL; | ||
156 | return calloc(n, m); | ||
157 | } | ||
158 | |||
159 | void myfree(q, p) | ||
160 | void *q, *p; | ||
161 | { | ||
162 | q = Z_NULL; | ||
163 | free(p); | ||
164 | } | ||
165 | |||
166 | typedef struct gzFile_s { | ||
167 | FILE *file; | ||
168 | int write; | ||
169 | int err; | ||
170 | char *msg; | ||
171 | z_stream strm; | ||
172 | } *gzFile; | ||
173 | |||
174 | gzFile gzopen OF((const char *, const char *)); | ||
175 | gzFile gzdopen OF((int, const char *)); | ||
176 | gzFile gz_open OF((const char *, int, const char *)); | ||
177 | |||
178 | gzFile gzopen(path, mode) | ||
179 | const char *path; | ||
180 | const char *mode; | ||
181 | { | ||
182 | return gz_open(path, -1, mode); | ||
183 | } | ||
184 | |||
185 | gzFile gzdopen(fd, mode) | ||
186 | int fd; | ||
187 | const char *mode; | ||
188 | { | ||
189 | return gz_open(NULL, fd, mode); | ||
190 | } | ||
191 | |||
192 | gzFile gz_open(path, fd, mode) | ||
193 | const char *path; | ||
194 | int fd; | ||
195 | const char *mode; | ||
196 | { | ||
197 | gzFile gz; | ||
198 | int ret; | ||
199 | |||
200 | gz = malloc(sizeof(gzFile)); | ||
201 | if (gz == NULL) | ||
202 | return NULL; | ||
203 | gz->write = strchr(mode, 'w') != NULL; | ||
204 | gz->strm.zalloc = myalloc; | ||
205 | gz->strm.zfree = myfree; | ||
206 | gz->strm.opaque = Z_NULL; | ||
207 | if (gz->write) | ||
208 | ret = deflateInit2(&(gz->strm), -1, 8, 15 + 16, 8, 0); | ||
209 | else { | ||
210 | gz->strm.next_in = 0; | ||
211 | gz->strm.avail_in = Z_NULL; | ||
212 | ret = inflateInit2(&(gz->strm), 15 + 16); | ||
213 | } | ||
214 | if (ret != Z_OK) { | ||
215 | free(gz); | ||
216 | return NULL; | ||
217 | } | ||
218 | gz->file = path == NULL ? fdopen(fd, gz->write ? "wb" : "rb") : | ||
219 | fopen(path, gz->write ? "wb" : "rb"); | ||
220 | if (gz->file == NULL) { | ||
221 | gz->write ? deflateEnd(&(gz->strm)) : inflateEnd(&(gz->strm)); | ||
222 | free(gz); | ||
223 | return NULL; | ||
224 | } | ||
225 | gz->err = 0; | ||
226 | gz->msg = ""; | ||
227 | return gz; | ||
228 | } | ||
229 | |||
230 | int gzwrite OF((gzFile, const void *, unsigned)); | ||
231 | |||
232 | int gzwrite(gz, buf, len) | ||
233 | gzFile gz; | ||
234 | const void *buf; | ||
235 | unsigned len; | ||
236 | { | ||
237 | z_stream *strm; | ||
238 | unsigned char out[BUFLEN]; | ||
239 | |||
240 | if (gz == NULL || !gz->write) | ||
241 | return 0; | ||
242 | strm = &(gz->strm); | ||
243 | strm->next_in = (void *)buf; | ||
244 | strm->avail_in = len; | ||
245 | do { | ||
246 | strm->next_out = out; | ||
247 | strm->avail_out = BUFLEN; | ||
248 | (void)deflate(strm, Z_NO_FLUSH); | ||
249 | fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); | ||
250 | } while (strm->avail_out == 0); | ||
251 | return len; | ||
252 | } | ||
253 | |||
254 | int gzread OF((gzFile, void *, unsigned)); | ||
255 | |||
256 | int gzread(gz, buf, len) | ||
257 | gzFile gz; | ||
258 | void *buf; | ||
259 | unsigned len; | ||
260 | { | ||
261 | int ret; | ||
262 | unsigned got; | ||
263 | unsigned char in[1]; | ||
264 | z_stream *strm; | ||
265 | |||
266 | if (gz == NULL || gz->write) | ||
267 | return 0; | ||
268 | if (gz->err) | ||
269 | return 0; | ||
270 | strm = &(gz->strm); | ||
271 | strm->next_out = (void *)buf; | ||
272 | strm->avail_out = len; | ||
273 | do { | ||
274 | got = fread(in, 1, 1, gz->file); | ||
275 | if (got == 0) | ||
276 | break; | ||
277 | strm->next_in = in; | ||
278 | strm->avail_in = 1; | ||
279 | ret = inflate(strm, Z_NO_FLUSH); | ||
280 | if (ret == Z_DATA_ERROR) { | ||
281 | gz->err = Z_DATA_ERROR; | ||
282 | gz->msg = strm->msg; | ||
283 | return 0; | ||
284 | } | ||
285 | if (ret == Z_STREAM_END) | ||
286 | inflateReset(strm); | ||
287 | } while (strm->avail_out); | ||
288 | return len - strm->avail_out; | ||
289 | } | ||
290 | |||
291 | int gzclose OF((gzFile)); | ||
292 | |||
293 | int gzclose(gz) | ||
294 | gzFile gz; | ||
295 | { | ||
296 | z_stream *strm; | ||
297 | unsigned char out[BUFLEN]; | ||
298 | |||
299 | if (gz == NULL) | ||
300 | return Z_STREAM_ERROR; | ||
301 | strm = &(gz->strm); | ||
302 | if (gz->write) { | ||
303 | strm->next_in = Z_NULL; | ||
304 | strm->avail_in = 0; | ||
305 | do { | ||
306 | strm->next_out = out; | ||
307 | strm->avail_out = BUFLEN; | ||
308 | (void)deflate(strm, Z_FINISH); | ||
309 | fwrite(out, 1, BUFLEN - strm->avail_out, gz->file); | ||
310 | } while (strm->avail_out == 0); | ||
311 | deflateEnd(strm); | ||
312 | } | ||
313 | else | ||
314 | inflateEnd(strm); | ||
315 | fclose(gz->file); | ||
316 | free(gz); | ||
317 | return Z_OK; | ||
318 | } | ||
319 | |||
320 | const char *gzerror OF((gzFile, int *)); | ||
321 | |||
322 | const char *gzerror(gz, err) | ||
323 | gzFile gz; | ||
324 | int *err; | ||
325 | { | ||
326 | *err = gz->err; | ||
327 | return gz->msg; | ||
328 | } | ||
329 | |||
330 | #endif | ||
331 | |||
141 | char *prog; | 332 | char *prog; |
142 | 333 | ||
143 | void error OF((const char *msg)); | 334 | void error OF((const char *msg)); |