Line 15... |
Line 15... |
15 |
#include <unistd.h> /* unlink() */
|
15 |
#include <unistd.h> /* unlink() */
|
16 |
|
16 |
|
17 |
#include "crc32.h"
|
17 |
#include "crc32.h"
|
18 |
#include "kprintf.h"
|
18 |
#include "kprintf.h"
|
19 |
#include "parsecmd.h"
|
19 |
#include "parsecmd.h"
|
20 |
#ifndef NOLZMA
|
- |
|
21 |
#include "lzmadec.h" /* LZMA support */
|
- |
|
22 |
#endif
|
- |
|
23 |
#include "inf.h" /* DEFLATE support */
|
20 |
#include "inf.h" /* DEFLATE support */
|
24 |
#include "version.h"
|
21 |
#include "version.h"
|
25 |
|
22 |
|
26 |
#include "libunzip.h" /* include self for control */
|
23 |
#include "libunzip.h" /* include self for control */
|
27 |
|
24 |
|
Line 52... |
Line 49... |
52 |
if (result == (time_t)-1) return(0);
|
49 |
if (result == (time_t)-1) return(0);
|
53 |
return(result);
|
50 |
return(result);
|
54 |
}
|
51 |
}
|
55 |
|
52 |
|
56 |
|
53 |
|
57 |
#ifndef NOLZMA
|
- |
|
58 |
/* this is a wrapper on malloc(), used as a callback by lzmadec */
|
- |
|
59 |
static void *SzAlloc(void *p, size_t size) {
|
- |
|
60 |
p = p; /* for gcc to not complain */
|
- |
|
61 |
if (size == 0) return(0);
|
- |
|
62 |
return(malloc(size));
|
- |
|
63 |
}
|
- |
|
64 |
|
- |
|
65 |
/* this is a wrapper on free(), used as a callback by lzmadec */
|
- |
|
66 |
static void SzFree(void *p, void *address) {
|
- |
|
67 |
p = p; /* for gcc to not complain */
|
- |
|
68 |
free(address);
|
- |
|
69 |
}
|
- |
|
70 |
#endif
|
- |
|
71 |
|
- |
|
72 |
|
- |
|
73 |
|
- |
|
74 |
/* opens a zip file and provides the list of files in the archive.
|
54 |
/* opens a zip file and provides the list of files in the archive.
|
75 |
returns a pointer to a ziplist (linked list) with all records, or NULL on error.
|
55 |
returns a pointer to a ziplist (linked list) with all records, or NULL on error.
|
76 |
The ziplist is allocated automatically, and must be freed via zip_freelist. */
|
56 |
The ziplist is allocated automatically, and must be freed via zip_freelist. */
|
77 |
struct ziplist *zip_listfiles(FILE *fd) {
|
57 |
struct ziplist *zip_listfiles(FILE *fd) {
|
78 |
struct ziplist *reslist = NULL;
|
58 |
struct ziplist *reslist = NULL;
|
Line 196... |
Line 176... |
196 |
|
176 |
|
197 |
/* first of all, check we support the compression method */
|
177 |
/* first of all, check we support the compression method */
|
198 |
switch (curzipnode->compmethod) {
|
178 |
switch (curzipnode->compmethod) {
|
199 |
case 0: /* stored */
|
179 |
case 0: /* stored */
|
200 |
case 8: /* deflated */
|
180 |
case 8: /* deflated */
|
201 |
#ifndef NOLZMA
|
- |
|
202 |
case 14: /* lzma */
|
- |
|
203 |
#endif
|
- |
|
204 |
break;
|
181 |
break;
|
205 |
default: /* unsupported compression method, sorry */
|
182 |
default: /* unsupported compression method, sorry */
|
206 |
return(-1);
|
183 |
return(-1);
|
207 |
break;
|
184 |
break;
|
208 |
}
|
185 |
}
|
Line 240... |
Line 217... |
240 |
if (fwrite(buff, toread, 1, filefd) != 1) extract_res = -4; /* write data chunk to dst file */
|
217 |
if (fwrite(buff, toread, 1, filefd) != 1) extract_res = -4; /* write data chunk to dst file */
|
241 |
i += toread;
|
218 |
i += toread;
|
242 |
}
|
219 |
}
|
243 |
} else if (curzipnode->compmethod == 8) { /* if the file is deflated, inflate it */
|
220 |
} else if (curzipnode->compmethod == 8) { /* if the file is deflated, inflate it */
|
244 |
extract_res = inf(zipfd, filefd, buff, &cksum, curzipnode->compressedfilelen);
|
221 |
extract_res = inf(zipfd, filefd, buff, &cksum, curzipnode->compressedfilelen);
|
245 |
#ifndef NOLZMA
|
- |
|
246 |
} else if (curzipnode->compmethod == 14) { /* LZMA */
|
- |
|
247 |
#define lzmaoutbufflen 32768u
|
- |
|
248 |
long bytesread, bytesreadtotal = 0, byteswritetotal = 0;
|
- |
|
249 |
SizeT buffoutreslen;
|
- |
|
250 |
ISzAlloc g_alloc;
|
- |
|
251 |
ELzmaStatus lzmastatus;
|
- |
|
252 |
SRes lzmaresult;
|
- |
|
253 |
CLzmaDec lzmahandle;
|
- |
|
254 |
unsigned char lzmahdr[LZMA_PROPS_SIZE]; /* 5 bytes of properties */
|
- |
|
255 |
unsigned char *lzmaoutbuff;
|
- |
|
256 |
|
- |
|
257 |
extract_res = -5; /* assume we will fail. if we don't - then we will update this flag */
|
- |
|
258 |
lzmaoutbuff = malloc(lzmaoutbufflen);
|
- |
|
259 |
if (lzmaoutbuff == NULL) {
|
- |
|
260 |
free(buff);
|
- |
|
261 |
fclose(filefd); /* close the dst file */
|
- |
|
262 |
return(-33);
|
- |
|
263 |
}
|
- |
|
264 |
|
- |
|
265 |
fread(lzmahdr, 4, 1, zipfd); /* load the 4 bytes long 'zip-lzma header */
|
- |
|
266 |
bytesreadtotal = 4; /* remember we read 4 bytes already */
|
- |
|
267 |
|
- |
|
268 |
/* lzma properties should be exactly 5 bytes long. If it's not, it's either not valid lzma, or some version that wasn't existing yet when I wrote these words. Also, check that the lzma content is at least 9 bytes long and that our previous malloc() calls suceeded. */
|
- |
|
269 |
if ((lzmahdr[2] == 5) && (lzmahdr[3] == 0) && (curzipnode->compressedfilelen >= 9)) {
|
- |
|
270 |
|
- |
|
271 |
extract_res = 0; /* since we got so far, let's assume we will succeed now */
|
- |
|
272 |
|
- |
|
273 |
g_alloc.Alloc = SzAlloc; /* these will be used as callbacks by lzma to manage memory */
|
- |
|
274 |
g_alloc.Free = SzFree;
|
- |
|
275 |
|
- |
|
276 |
fread(lzmahdr, sizeof(lzmahdr), 1, zipfd); /* load the lzma header */
|
- |
|
277 |
bytesreadtotal += sizeof(lzmahdr);
|
- |
|
278 |
|
- |
|
279 |
/* Note, that in a 'normal' lzma stream we would have now 8 bytes with the uncompressed length of the file. Here we don't. ZIP cut this information out, since it stores it already in its own header. */
|
- |
|
280 |
|
- |
|
281 |
memset(&lzmahandle, 0, sizeof(lzmahandle)); /* reset the whole lzmahandle structure - not doing this leads to CRASHES!!! */
|
- |
|
282 |
LzmaDec_Init(&lzmahandle);
|
- |
|
283 |
lzmaresult = LzmaDec_Allocate(&lzmahandle, lzmahdr, LZMA_PROPS_SIZE, &g_alloc); /* forget not to LzmaDec_Free() later! */
|
- |
|
284 |
if (lzmaresult != 0) extract_res = -13;
|
- |
|
285 |
|
- |
|
286 |
while (extract_res == 0) {
|
- |
|
287 |
bytesread = buffsize;
|
- |
|
288 |
if (bytesread > curzipnode->compressedfilelen - bytesreadtotal) bytesread = curzipnode->compressedfilelen - bytesreadtotal;
|
- |
|
289 |
buffoutreslen = lzmaoutbufflen;
|
- |
|
290 |
/* printf("Will read %d bytes from input stream\n", bytesread); */
|
- |
|
291 |
fread(buff, bytesread, 1, zipfd); /* read stuff from input stream */
|
- |
|
292 |
fseek(zipfd, 0 - bytesread, SEEK_CUR); /* get back to the position at the start of our chunk of data */
|
- |
|
293 |
lzmaresult = LzmaDec_DecodeToBuf(&lzmahandle, lzmaoutbuff, &buffoutreslen, buff, (SizeT *)&bytesread, LZMA_FINISH_ANY, &lzmastatus);
|
- |
|
294 |
bytesreadtotal += bytesread;
|
- |
|
295 |
/* printf("expanded %ld bytes into %ld (total read: %ld bytes)\n", (long)bytesread, (long)buffoutreslen, (long)bytesreadtotal); */
|
- |
|
296 |
fseek(zipfd, bytesread, SEEK_CUR); /* go forward to the position next to the input we processed */
|
- |
|
297 |
if (lzmaresult != SZ_OK) {
|
- |
|
298 |
extract_res = -20;
|
- |
|
299 |
if (lzmaresult == SZ_ERROR_DATA) extract_res = -21; /* DATA ERROR */
|
- |
|
300 |
if (lzmaresult == SZ_ERROR_MEM) extract_res = -22; /* MEMORY ALLOC ERROR */
|
- |
|
301 |
if (lzmaresult == SZ_ERROR_UNSUPPORTED) extract_res = -23; /* UNSUPPORTED PROPERTY */
|
- |
|
302 |
if (lzmaresult == SZ_ERROR_INPUT_EOF) extract_res = -24; /* NEED MORE INPUT */
|
- |
|
303 |
break;
|
- |
|
304 |
}
|
- |
|
305 |
/* check that we haven't got TOO MUCH decompressed data, and trim if necessary. It happens that LZMA provides a few bytes more than it should at the end of the stream. */
|
- |
|
306 |
if (byteswritetotal + (long)buffoutreslen > curzipnode->filelen) {
|
- |
|
307 |
buffoutreslen = curzipnode->filelen - byteswritetotal;
|
- |
|
308 |
}
|
- |
|
309 |
byteswritetotal += buffoutreslen;
|
- |
|
310 |
fwrite(lzmaoutbuff, buffoutreslen, 1, filefd); /* write stuff to output file */
|
- |
|
311 |
crc32_feed(&cksum, lzmaoutbuff, buffoutreslen);
|
- |
|
312 |
/* if (lzmastatus == LZMA_STATUS_FINISHED_WITH_MARK) puts("lzma says we are done!"); */
|
- |
|
313 |
if ((lzmastatus == LZMA_STATUS_FINISHED_WITH_MARK) || (bytesreadtotal >= curzipnode->compressedfilelen)) {
|
- |
|
314 |
extract_res = 0; /* looks like we succeeded! */
|
- |
|
315 |
break;
|
- |
|
316 |
}
|
- |
|
317 |
}
|
- |
|
318 |
LzmaDec_Free(&lzmahandle, &g_alloc); /* this will free all the stuff we allocated via LzmaDec_Allocate() */
|
- |
|
319 |
/* printf("Processed %d bytes of input into %d bytes of output. CRC32: %08lX\n", bytesreadtotal, byteswritetotal, crc32); */
|
- |
|
320 |
}
|
- |
|
321 |
free(lzmaoutbuff);
|
- |
|
322 |
#endif
|
- |
|
323 |
}
|
222 |
}
|
324 |
|
223 |
|
325 |
/* clean up memory, close the dst file and terminates crc32 */
|
224 |
/* clean up memory, close the dst file and terminates crc32 */
|
326 |
free(buff);
|
225 |
free(buff);
|
327 |
fclose(filefd); /* close the dst file */
|
226 |
fclose(filefd); /* close the dst file */
|