Subversion Repositories SvarDOS

Rev

Rev 219 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 219 Rev 223
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 */