libextractor  1.11
About: GNU libextractor is a library used to extract meta-data from files of arbitrary type.
  Fossies Dox: libextractor-1.11.tar.gz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

unzip.c
Go to the documentation of this file.
1 /*
2  This file is part of libextractor.
3  Copyright (C) 2004, 2008, 2012 Vidyut Samanta and Christian Grothoff
4 
5  libextractor is free software; you can redistribute it and/or modify
6  it under the terms of the GNU General Public License as published
7  by the Free Software Foundation; either version 3, or (at your
8  option) any later version.
9 
10  libextractor is distributed in the hope that it will be useful, but
11  WITHOUT ANY WARRANTY; without even the implied warranty of
12  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13  General Public License for more details.
14 
15  You should have received a copy of the GNU General Public License
16  along with libextractor; see the file COPYING. If not, write to the
17  Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18  Boston, MA 02110-1301, USA.
19 */
20 /**
21  * @file common/unzip.c
22  * @brief API to access ZIP archives
23  * @author Christian Grothoff
24  *
25  * This code is based in part on
26  * unzip 1.00 Copyright 1998-2003 Gilles Vollant
27  * http://www.winimage.com/zLibDll"
28  *
29  *
30  * The filenames for each file in a zipfile are stored in two locations.
31  * There is one at the start of each entry, just before the compressed data,
32  * and another at the end in a 'central directory structure'.
33  *
34  * In order to catch self-extracting executables, we scan backwards from the end
35  * of the file looking for the central directory structure. The previous version
36  * of this went forewards through the local headers, but that only works for plain
37  * vanilla zip's and I don't feel like writing a special case for each of the dozen
38  * self-extracting executable stubs.
39  *
40  * This assumes that the zip file is considered to be non-corrupt/non-truncated.
41  * If it is truncated then it's not considered to be a zip and skipped.
42  *
43  * ZIP format description from appnote.iz and appnote.txt (more or less):
44  *
45  * (this is why you always need to put in the last floppy if you span disks)
46  *
47  * 0- 3 end of central dir signature 4 bytes (0x06054b50) P K ^E ^F
48  * 4- 5 number of this disk 2 bytes
49  * 6- 7 number of the disk with the
50  * start of the central directory 2 bytes
51  * 8- 9 total number of entries in
52  * the central dir on this disk 2 bytes
53  * 10-11 total number of entries in
54  * the central dir 2 bytes
55  * 12-15 size of the central directory 4 bytes
56  * 16-19 offset of start of central
57  * directory with respect to
58  * the starting disk number 4 bytes
59  * 20-21 zipfile comment length 2 bytes
60  * 22-?? zipfile comment (variable size) max length 65536 bytes
61  */
62 #include "platform.h"
63 #include <ctype.h>
64 #include "extractor.h"
65 #include "unzip.h"
66 
67 #define CASESENSITIVITY (0)
68 #define MAXFILENAME (256)
69 
70 #ifndef UNZ_BUFSIZE
71 #define UNZ_BUFSIZE (16384)
72 #endif
73 
74 #ifndef UNZ_MAXFILENAMEINZIP
75 #define UNZ_MAXFILENAMEINZIP (256)
76 #endif
77 
78 #define SIZECENTRALDIRITEM (0x2e)
79 #define SIZEZIPLOCALHEADER (0x1e)
80 
81 
82 /**
83  * IO callbacks for access to the ZIP data.
84  */
86 {
87  /**
88  * Callback for reading 'size' bytes from the ZIP archive into buf.
89  */
90  uLong (*zread_file) (voidpf opaque, void*buf, uLong size);
91 
92  /**
93  * Callback to obtain the current read offset in the ZIP archive.
94  */
95  long (*ztell_file) (voidpf opaque);
96 
97  /**
98  * Callback for seeking to a different position in the ZIP archive.
99  */
100  long (*zseek_file) (voidpf opaque, uLong offset, int origin);
101 
102  /**
103  * Opaque argument to pass to all IO functions.
104  */
105  voidpf opaque;
106 };
107 
108 
109 /**
110  * Macro to read using filefunc API.
111  *
112  * @param filefunc filefunc struct
113  * @param buf where to write data
114  * @param size number of bytes to read
115  * @return number of bytes copied to buf
116  */
117 #define ZREAD(filefunc,buf,size) ((*((filefunc).zread_file))((filefunc).opaque, \
118  buf, size))
119 
120 /**
121  * Macro to obtain current offset in file using filefunc API.
122  *
123  * @param filefunc filefunc struct
124  * @return current offset in file
125  */
126 #define ZTELL(filefunc) ((*((filefunc).ztell_file))((filefunc).opaque))
127 
128 /**
129  * Macro to seek using filefunc API.
130  *
131  * @param filefunc filefunc struct
132  * @param pos position to seek
133  * @param mode seek mode
134  * @return 0 on success
135  */
136 #define ZSEEK(filefunc,pos,mode) ((*((filefunc).zseek_file))((filefunc).opaque, \
137  pos, mode))
138 
139 
140 /**
141  * Global data about the ZIPfile
142  * These data comes from the end of central dir
143  */
145 {
146 
147  /**
148  * total number of entries in
149  * the central dir on this disk
150  */
152 
153  /**
154  * size of the global comment of the zipfile
155  */
157 
158  /**
159  * offset of the global comment in the zipfile
160  */
162 };
163 
164 
165 /**
166  * internal info about a file in zipfile
167  */
169 {
170 
171  /**
172  * relative offset of local header 4 bytes
173  */
175 
176 };
177 
178 
179 /**
180  * Information about a file in zipfile, when reading and
181  * decompressing it
182  */
184 {
185  /**
186  * internal buffer for compressed data
187  */
188  char *read_buffer;
189 
190  /**
191  * zLib stream structure for inflate
192  */
193  z_stream stream;
194 
195  /**
196  * position in byte on the zipfile, for fseek
197  */
199 
200  /**
201  * flag set if stream structure is initialised
202  */
204 
205  /**
206  * offset of the local extra field
207  */
209 
210  /**
211  * size of the local extra field
212  */
214 
215  /**
216  * position in the local extra field in read
217  */
219 
220  /**
221  * crc32 of all data uncompressed so far
222  */
223  uLong crc32;
224 
225  /**
226  * crc32 we must obtain after decompress all
227  */
228  uLong crc32_wait;
229 
230  /**
231  * number of bytes to be decompressed
232  */
234 
235  /**
236  * number of bytes to be obtained after decomp
237  */
239 
240  /**
241  * IO functions.
242  */
243  struct FileFuncDefs z_filefunc;
244 
245  /**
246  * compression method (0==store)
247  */
249 
250  /**
251  * byte before the zipfile, (>0 for sfx)
252  */
254 };
255 
256 
257 /**
258  * Handle for a ZIP archive.
259  * contains internal information about the zipfile
260  */
262 {
263  /**
264  * io structore of the zipfile
265  */
266  struct FileFuncDefs z_filefunc;
267 
268  /**
269  * public global information
270  */
271  struct GlobalInfo gi;
272 
273  /**
274  * byte before the zipfile, (>0 for sfx)
275  */
277 
278  /**
279  * number of the current file in the zipfile
280  */
281  uLong num_file;
282 
283  /**
284  * pos of the current file in the central dir
285  */
287 
288  /**
289  * flag about the usability of the current file
290  */
292 
293  /**
294  * position of the beginning of the central dir
295  */
296  uLong central_pos;
297 
298  /**
299  * size of the central directory
300  */
302 
303  /**
304  * offset of start of central directory with respect to the starting
305  * disk number
306  */
308 
309  /**
310  * public info about the current file in zip
311  */
313 
314  /**
315  * private info about it
316  */
318 
319  /**
320  * structure about the current file if we are decompressing it
321  */
323 
324  /**
325  * Is the file encrypted?
326  */
328 };
329 
330 
331 /**
332  * Read a byte from a gz_stream; update next_in and avail_in. Return EOF
333  * for end of file.
334  * IN assertion: the stream s has been successfully opened for reading.
335  *
336  * @param ffd functions for performing IO operations
337  * @param pi where to store the byte that was read
338  * @return #EXTRACTOR_UNZIP_OK on success, or #EXTRACTOR_UNZIP_EOF
339  */
340 static int
341 read_byte_from_ffd (const struct FileFuncDefs *ffd,
342  int *pi)
343 {
344  unsigned char c;
345 
346  if (1 != ZREAD (*ffd, &c, 1))
347  return EXTRACTOR_UNZIP_EOF;
348  *pi = (int) c;
349  return EXTRACTOR_UNZIP_OK;
350 }
351 
352 
353 /**
354  * Read a short (2 bytes) from a gz_stream; update next_in and avail_in. Return EOF
355  * for end of file.
356  * IN assertion: the stream s has been successfully opened for reading.
357  *
358  * @param ffd functions for performing IO operations
359  * @param pi where to store the short that was read
360  * @return #EXTRACTOR_UNZIP_OK on success, or #EXTRACTOR_UNZIP_EOF
361  */
362 static int
364  uLong *pX)
365 {
366  uLong x;
367  int i;
368  int err;
369 
370  *pX = 0;
371  if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
372  return err;
373  x = (uLong) i;
374  if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
375  return err;
376  x += ((uLong) i) << 8;
377  *pX = x;
378  return err;
379 }
380 
381 
382 /**
383  * Read a 'long' (4 bytes) from a gz_stream; update next_in and avail_in. Return EOF
384  * for end of file.
385  * IN assertion: the stream s has been successfully opened for reading.
386  *
387  * @param ffd functions for performing IO operations
388  * @param pi where to store the long that was read
389  * @return #EXTRACTOR_UNZIP_OK on success, or #EXTRACTOR_UNZIP_EOF
390  */
391 static int
392 read_long_from_ffd (const struct FileFuncDefs *ffd,
393  uLong *pX)
394 {
395  uLong x;
396  int i;
397  int err;
398 
399  *pX = 0;
400  if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
401  return err;
402  x = (uLong) i;
403  if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
404  return err;
405  x += ((uLong) i) << 8;
406  if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
407  return err;
408  x += ((uLong) i) << 16;
409  if (EXTRACTOR_UNZIP_OK != (err = read_byte_from_ffd (ffd, &i)))
410  return err;
411  x += ((uLong) i) << 24;
412  *pX = x;
413  return err;
414 }
415 
416 
417 #ifndef CASESENSITIVITYDEFAULT_NO
418 #if ! defined(unix) && ! defined(CASESENSITIVITYDEFAULT_YES)
419 #define CASESENSITIVITYDEFAULT_NO
420 #endif
421 #endif
422 
423 #ifdef CASESENSITIVITYDEFAULT_NO
424 #define CASESENSITIVITYDEFAULTVALUE 2
425 #else
426 #define CASESENSITIVITYDEFAULTVALUE 1
427 #endif
428 
429 
430 /**
431  * Compare two filenames (fileName1, fileName2).
432  *
433  * @param filename1 name of first file
434  * @param filename2 name of second file
435  * @param iCaseSensitivity, use 1 for case sensitivity (like strcmp);
436  * 2 for no case sensitivity (like strcmpi or strcasecmp); or
437  * 0 for default of your operating system (like 1 on Unix, 2 on Windows)
438  * @return 0 if names are equal
439  */
440 static int
442  const char*fileName2,
443  int iCaseSensitivity)
444 {
445  if (0 == iCaseSensitivity)
446  iCaseSensitivity = CASESENSITIVITYDEFAULTVALUE;
447  if (1 == iCaseSensitivity)
448  return strcmp (fileName1, fileName2);
449  return strcasecmp (fileName1, fileName2);
450 }
451 
452 
453 #ifndef BUFREADCOMMENT
454 #define BUFREADCOMMENT (0x400)
455 #endif
456 
457 
458 /**
459  * Locate the central directory in the ZIP file.
460  *
461  * @param ffd IO functions
462  * @return offset of central directory, 0 on error
463  */
464 static uLong
466 {
467  unsigned char buf[BUFREADCOMMENT + 4];
468  uLong uSizeFile;
469  uLong uBackRead;
470  uLong uMaxBack = 0xffff; /* maximum size of global comment */
471 
472  if (0 != ZSEEK (*ffd, 0, SEEK_END))
473  return 0;
474  uSizeFile = ZTELL (*ffd);
475  if (uMaxBack > uSizeFile)
476  uMaxBack = uSizeFile;
477  uBackRead = 4;
478  while (uBackRead < uMaxBack)
479  {
480  uLong uReadSize;
481  uLong uReadPos;
482  int i;
483 
484  if (uBackRead + BUFREADCOMMENT > uMaxBack)
485  uBackRead = uMaxBack;
486  else
487  uBackRead += BUFREADCOMMENT;
488  uReadPos = uSizeFile - uBackRead;
489  uReadSize = ((BUFREADCOMMENT + 4) < (uSizeFile - uReadPos))
490  ? (BUFREADCOMMENT + 4)
491  : (uSizeFile - uReadPos);
492  if (0 != ZSEEK (*ffd, uReadPos, SEEK_SET))
493  break;
494  if (ZREAD (*ffd, buf, uReadSize) != uReadSize)
495  break;
496  i = (int) uReadSize - 3;
497  while (i-- > 0)
498  if ( (0x50 == (*(buf + i))) &&
499  (0x4b == (*(buf + i + 1))) &&
500  (0x05 == (*(buf + i + 2))) &&
501  (0x06 == (*(buf + i + 3))) )
502  return uReadPos + i;
503  }
504  return 0;
505 }
506 
507 
508 /**
509  * Translate date/time from Dos format to `struct
510  * EXTRACTOR_UnzipDateTimeInfo` (readable more easilty)
511  *
512  * @param ulDosDate time in DOS format (input)
513  * @param ptm where to write time in readable format
514  */
515 static void
516 dos_date_to_tmu_date (uLong ulDosDate,
517  struct EXTRACTOR_UnzipDateTimeInfo*ptm)
518 {
519  uLong uDate;
520 
521  uDate = (uLong) (ulDosDate >> 16);
522  ptm->tm_mday = (uInt) (uDate & 0x1f);
523  ptm->tm_mon = (uInt) ((((uDate) & 0x1E0) / 0x20) - 1);
524  ptm->tm_year = (uInt) (((uDate & 0x0FE00) / 0x0200) + 1980);
525  ptm->tm_hour = (uInt) ((ulDosDate & 0xF800) / 0x800);
526  ptm->tm_min = (uInt) ((ulDosDate & 0x7E0) / 0x20);
527  ptm->tm_sec = (uInt) (2 * (ulDosDate & 0x1f));
528 }
529 
530 
531 /**
532  * Write info about the ZipFile in the *pglobal_info structure.
533  * No preparation of the structure is needed.
534  *
535  * @param file zipfile to manipulate
536  * @param pfile_info file information to initialize
537  * @param pfile_info_internal internal file information to initialize
538  * @param szFileName where to write the name of the current file
539  * @param fileNameBufferSize number of bytes available in @a szFileName
540  * @param extraField where to write extra data
541  * @param extraFieldBufferSize number of bytes available in extraField
542  * @param szComment where to write the comment on the current file
543  * @param commentBufferSize number of bytes available in @a szComment
544  * @return #EXTRACTOR_UNZIP_OK if there is no problem.
545  */
546 static int
548  struct EXTRACTOR_UnzipFileInfo *pfile_info,
549  struct UnzipFileInfoInternal *pfile_info_internal,
550  char *szFileName,
551  uLong fileNameBufferSize,
552  void *extraField,
553  uLong extraFieldBufferSize,
554  char *szComment,
555  uLong commentBufferSize)
556 {
557  struct EXTRACTOR_UnzipFileInfo file_info;
558  struct UnzipFileInfoInternal file_info_internal;
559  uLong uMagic;
560  long lSeek = 0;
561 
562  if (NULL == file)
564  if (0 != ZSEEK (file->z_filefunc,
566  SEEK_SET))
567  return EXTRACTOR_UNZIP_ERRNO;
568 
569  /* we check the magic */
570  if (EXTRACTOR_UNZIP_OK !=
571  read_long_from_ffd (&file->z_filefunc, &uMagic))
572  return EXTRACTOR_UNZIP_ERRNO;
573  if (0x02014b50 != uMagic)
575 
576  if ( (EXTRACTOR_UNZIP_OK !=
577  read_short_from_ffd (&file->z_filefunc, &file_info.version)) ||
579  read_short_from_ffd (&file->z_filefunc, &file_info.version_needed)) ||
581  read_short_from_ffd (&file->z_filefunc, &file_info.flag)) ||
584  &file_info.compression_method)) ||
586  read_long_from_ffd (&file->z_filefunc, &file_info.dosDate)) )
587  return EXTRACTOR_UNZIP_ERRNO;
588  dos_date_to_tmu_date (file_info.dosDate,
589  &file_info.tmu_date);
590  if ( (EXTRACTOR_UNZIP_OK !=
591  read_long_from_ffd (&file->z_filefunc, &file_info.crc)) ||
593  read_long_from_ffd (&file->z_filefunc, &file_info.compressed_size)) ||
595  read_long_from_ffd (&file->z_filefunc, &file_info.uncompressed_size)) ||
597  read_short_from_ffd (&file->z_filefunc, &file_info.size_filename)) ||
599  read_short_from_ffd (&file->z_filefunc, &file_info.size_file_extra)) ||
602  &file_info.size_file_comment)) ||
604  read_short_from_ffd (&file->z_filefunc, &file_info.disk_num_start)) ||
606  read_short_from_ffd (&file->z_filefunc, &file_info.internal_fa)) ||
608  read_long_from_ffd (&file->z_filefunc, &file_info.external_fa)) ||
611  &file_info_internal.offset_curfile)) )
612  return EXTRACTOR_UNZIP_ERRNO;
613 
614  lSeek += file_info.size_filename;
615  if (NULL != szFileName)
616  {
617  uLong uSizeRead;
618 
619  if (file_info.size_filename < fileNameBufferSize)
620  {
621  *(szFileName + file_info.size_filename) = '\0';
622  uSizeRead = file_info.size_filename;
623  }
624  else
625  uSizeRead = fileNameBufferSize;
626 
627  if ( (file_info.size_filename > 0) &&
628  (fileNameBufferSize > 0) )
629  if (ZREAD (file->z_filefunc, szFileName, uSizeRead) != uSizeRead)
630  return EXTRACTOR_UNZIP_ERRNO;
631  lSeek -= uSizeRead;
632  }
633 
634  if (NULL != extraField)
635  {
636  uLong uSizeRead;
637 
638  if (file_info.size_file_extra<extraFieldBufferSize)
639  uSizeRead = file_info.size_file_extra;
640  else
641  uSizeRead = extraFieldBufferSize;
642 
643  if (0 != lSeek)
644  {
645  if (0 == ZSEEK (file->z_filefunc, lSeek, SEEK_CUR))
646  lSeek = 0;
647  else
648  return EXTRACTOR_UNZIP_ERRNO;
649  }
650  if ( (file_info.size_file_extra > 0) &&
651  (extraFieldBufferSize > 0) &&
652  (ZREAD (file->z_filefunc,
653  extraField,
654  uSizeRead) != uSizeRead) )
655  return EXTRACTOR_UNZIP_ERRNO;
656  lSeek += file_info.size_file_extra - uSizeRead;
657  }
658  else
659  lSeek += file_info.size_file_extra;
660 
661  if (NULL != szComment)
662  {
663  uLong uSizeRead;
664 
665  if (file_info.size_file_comment < commentBufferSize)
666  {
667  *(szComment + file_info.size_file_comment) = '\0';
668  uSizeRead = file_info.size_file_comment;
669  }
670  else
671  {
672  *(szComment + commentBufferSize - 1) = '\0';
673  uSizeRead = commentBufferSize - 1;
674  }
675 
676  if (0 != lSeek)
677  {
678  if (0 == ZSEEK (file->z_filefunc, lSeek, SEEK_CUR))
679  lSeek = 0;
680  else
681  return EXTRACTOR_UNZIP_ERRNO;
682  }
683  if ( (file_info.size_file_comment > 0) &&
684  (commentBufferSize > 0) &&
685  (ZREAD (file->z_filefunc, szComment, uSizeRead) != uSizeRead) )
686  return EXTRACTOR_UNZIP_ERRNO;
687  lSeek += file_info.size_file_comment - uSizeRead;
688  }
689  else
690  lSeek += file_info.size_file_comment;
691 
692  if (NULL != pfile_info)
693  *pfile_info = file_info;
694  if (NULL != pfile_info_internal)
695  *pfile_info_internal = file_info_internal;
696  return EXTRACTOR_UNZIP_OK;
697 }
698 
699 
700 /**
701  * Set the current file of the zipfile to the first file.
702  *
703  * @param file zipfile to manipulate
704  * @return UNZ_OK if there is no problem
705  */
706 int
708 {
709  int err;
710 
711  if (NULL == file)
714  file->num_file = 0;
715  err = get_current_file_info (file,
716  &file->cur_file_info,
717  &file->cur_file_info_internal,
718  NULL, 0, NULL, 0, NULL, 0);
719  file->current_file_ok = (EXTRACTOR_UNZIP_OK == err);
720  return err;
721 }
722 
723 
724 /**
725  * Open a Zip file.
726  *
727  * @param ffd IO functions
728  * @return NULL on error
729  */
730 static struct EXTRACTOR_UnzipFile *
732 {
733  struct EXTRACTOR_UnzipFile us;
734  struct EXTRACTOR_UnzipFile *file;
735  uLong central_pos;
736  uLong uL;
737  uLong number_disk; /* number of the current dist, used for
738  spanning ZIP, unsupported, always 0*/
739  uLong number_disk_with_CD; /* number of the disk with central dir, used
740  for spanning ZIP, unsupported, always 0*/
741  uLong number_entry_CD; /* total number of entries in
742  the central dir
743  (same than number_entry on nospan) */
744 
745  memset (&us, 0, sizeof(us));
746  us.z_filefunc = *ffd;
748  if (0 == central_pos)
749  return NULL;
750  if (0 != ZSEEK (us.z_filefunc,
751  central_pos, SEEK_SET))
752  return NULL;
753 
754  /* the signature, already checked */
755  if (EXTRACTOR_UNZIP_OK !=
756  read_long_from_ffd (&us.z_filefunc, &uL))
757  return NULL;
758 
759  /* number of this disk */
760  if (EXTRACTOR_UNZIP_OK !=
761  read_short_from_ffd (&us.z_filefunc, &number_disk))
762  return NULL;
763 
764  /* number of the disk with the start of the central directory */
765  if (EXTRACTOR_UNZIP_OK !=
766  read_short_from_ffd (&us.z_filefunc, &number_disk_with_CD))
767  return NULL;
768 
769  /* total number of entries in the central dir on this disk */
770  if (EXTRACTOR_UNZIP_OK !=
772  return NULL;
773 
774  /* total number of entries in the central dir */
775  if (EXTRACTOR_UNZIP_OK !=
776  read_short_from_ffd (&us.z_filefunc, &number_entry_CD))
777  return NULL;
778 
779  if ( (number_entry_CD != us.gi.number_entry) ||
780  (0 != number_disk_with_CD) ||
781  (0 != number_disk) )
782  return NULL;
783 
784  /* size of the central directory */
785  if (EXTRACTOR_UNZIP_OK !=
787  return NULL;
788 
789  /* offset of start of central directory with respect to the
790  starting disk number */
791  if (EXTRACTOR_UNZIP_OK !=
793  return NULL;
794 
795  /* zipfile comment length */
796  if (EXTRACTOR_UNZIP_OK !=
798  return NULL;
799  us.gi.offset_comment = ZTELL (us.z_filefunc);
801  return NULL;
802 
806  us.pfile_in_zip_read = NULL;
807  us.encrypted = 0;
808 
809  if (NULL == (file = malloc (sizeof(struct EXTRACTOR_UnzipFile))))
810  return NULL;
811  *file = us;
813  return file;
814 }
815 
816 
817 /**
818  * Close the file in zip opened with #EXTRACTOR_common_unzip_open_current_file().
819  *
820  * @return #EXTRACTOR_UNZIP_CRCERROR if all the file was read but the CRC is not good
821  */
822 int
824 {
825  struct FileInZipReadInfo*pfile_in_zip_read_info;
826  int err = EXTRACTOR_UNZIP_OK;
827 
828  if (NULL == file)
830  if (NULL == (pfile_in_zip_read_info = file->pfile_in_zip_read))
832  if ( (0 == pfile_in_zip_read_info->rest_read_uncompressed) &&
833  (pfile_in_zip_read_info->crc32 != pfile_in_zip_read_info->crc32_wait) )
835  if (NULL != pfile_in_zip_read_info->read_buffer)
836  free (pfile_in_zip_read_info->read_buffer);
837  pfile_in_zip_read_info->read_buffer = NULL;
838  if (pfile_in_zip_read_info->stream_initialised)
839  inflateEnd (&pfile_in_zip_read_info->stream);
840  pfile_in_zip_read_info->stream_initialised = 0;
841  free (pfile_in_zip_read_info);
842  file->pfile_in_zip_read = NULL;
843  return err;
844 }
845 
846 
847 /**
848  * Close a ZipFile.
849  *
850  * @param file zip file to close
851  * @return #EXTRACTOR_UNZIP_OK if there is no problem.
852  */
853 int
855 {
856  if (NULL == file)
858  if (NULL != file->pfile_in_zip_read)
860  free (file);
861  return EXTRACTOR_UNZIP_OK;
862 }
863 
864 
865 /**
866  * Obtain the global comment from a ZIP file.
867  *
868  * @param file unzip file to inspect
869  * @param comment where to copy the comment
870  * @param comment_len maximum number of bytes available in comment
871  * @return #EXTRACTOR_UNZIP_OK on success
872  */
873 int
875  char *comment,
876  size_t comment_len)
877 {
878  if (NULL == file)
880  if (comment_len > file->gi.size_comment)
881  comment_len = file->gi.size_comment + 1;
882  if (0 !=
883  ZSEEK (file->z_filefunc, file->gi.offset_comment, SEEK_SET))
884  return EXTRACTOR_UNZIP_ERRNO;
885  if (comment_len - 1 !=
886  ZREAD (file->z_filefunc, comment, comment_len - 1))
887  return EXTRACTOR_UNZIP_ERRNO;
888  comment[comment_len - 1] = '\0';
889  return EXTRACTOR_UNZIP_OK;
890 }
891 
892 
893 /**
894  * Write info about the ZipFile in the *pglobal_info structure.
895  * No preparation of the structure is needed.
896  *
897  * @param file zipfile to manipulate
898  * @param pfile_info file information to initialize
899  * @param szFileName where to write the name of the current file
900  * @param fileNameBufferSize number of bytes available in szFileName
901  * @param extraField where to write extra data
902  * @param extraFieldBufferSize number of bytes available in extraField
903  * @param szComment where to write the comment on the current file
904  * @param commentBufferSize number of bytes available in szComment
905  * @return #EXTRACTOR_UNZIP_OK if there is no problem.
906  */
907 int
909  struct EXTRACTOR_UnzipFileInfo *
910  pfile_info,
911  char *szFileName,
912  uLong fileNameBufferSize,
913  void *extraField,
914  uLong extraFieldBufferSize,
915  char *szComment,
916  uLong commentBufferSize)
917 {
918  return get_current_file_info (file, pfile_info, NULL,
919  szFileName, fileNameBufferSize,
920  extraField, extraFieldBufferSize,
921  szComment, commentBufferSize);
922 }
923 
924 
925 /**
926  * Set the current file of the zipfile to the next file.
927  *
928  * @param file zipfile to manipulate
929  * @return #EXTRACTOR_UNZIP_OK if there is no problem,
930  * #EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the actual file was the latest.
931  */
932 int
934 {
935  int err;
936 
937  if (NULL == file)
939  if (! file->current_file_ok)
941  if (file->num_file + 1 == file->gi.number_entry)
947  file->num_file++;
948  err = get_current_file_info (file,
949  &file->cur_file_info,
950  &file->cur_file_info_internal,
951  NULL, 0, NULL, 0, NULL, 0);
952  file->current_file_ok = (EXTRACTOR_UNZIP_OK == err);
953  return err;
954 }
955 
956 
957 /**
958  * Try locate the file szFileName in the zipfile.
959  *
960  * @param file zipfile to manipulate
961  * @param szFileName name to find
962  * @param iCaseSensitivity, use 1 for case sensitivity (like strcmp);
963  * 2 for no case sensitivity (like strcmpi or strcasecmp); or
964  * 0 for default of your operating system (like 1 on Unix, 2 on Windows)
965  * @return #EXTRACTOR_UNZIP_OK if the file is found. It becomes the current file.
966  * #EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE if the file is not found
967  */
968 int
970  const char *szFileName,
971  int iCaseSensitivity)
972 {
973  int err;
974  /* We remember the 'current' position in the file so that we can jump
975  * back there if we fail.
976  */
977  struct EXTRACTOR_UnzipFileInfo cur_file_infoSaved;
978  struct UnzipFileInfoInternal cur_file_info_internalSaved;
979  uLong num_fileSaved;
980  uLong pos_in_central_dirSaved;
981 
982  if (NULL == file)
984  if (strlen (szFileName) >= UNZ_MAXFILENAMEINZIP)
986  if (! file->current_file_ok)
988 
989  /* Save the current state */
990  num_fileSaved = file->num_file;
991  pos_in_central_dirSaved = file->pos_in_central_dir;
992  cur_file_infoSaved = file->cur_file_info;
993  cur_file_info_internalSaved = file->cur_file_info_internal;
995 
996  while (EXTRACTOR_UNZIP_OK == err)
997  {
998  char szCurrentFileName[UNZ_MAXFILENAMEINZIP + 1];
999 
1000  if (EXTRACTOR_UNZIP_OK !=
1002  szCurrentFileName,
1003  sizeof (
1004  szCurrentFileName)
1005  - 1,
1006  NULL, 0, NULL, 0)))
1007  break;
1008  if (0 ==
1010  szFileName,
1011  iCaseSensitivity))
1012  return EXTRACTOR_UNZIP_OK;
1014  }
1015 
1016  /* We failed, so restore the state of the 'current file' to where we
1017  * were.
1018  */
1019  file->num_file = num_fileSaved;
1020  file->pos_in_central_dir = pos_in_central_dirSaved;
1021  file->cur_file_info = cur_file_infoSaved;
1022  file->cur_file_info_internal = cur_file_info_internalSaved;
1023  return err;
1024 }
1025 
1026 
1027 /**
1028  * Read bytes from the current file (must have been opened).
1029  *
1030  * @param buf contain buffer where data must be copied
1031  * @param len the size of buf.
1032  * @return the number of byte copied if some bytes are copied
1033  * 0 if the end of file was reached
1034  * <0 with error code if there is an error
1035  * (#EXTRACTOR_UNZIP_ERRNO for IO error, or zLib error for uncompress error)
1036  */
1037 ssize_t
1039  void *buf,
1040  size_t len)
1041 {
1042  int err = EXTRACTOR_UNZIP_OK;
1043  uInt iRead = 0;
1044  struct FileInZipReadInfo *pfile_in_zip_read_info;
1045 
1046  if (NULL == file)
1048  if (NULL == (pfile_in_zip_read_info = file->pfile_in_zip_read))
1050  if (NULL == pfile_in_zip_read_info->read_buffer)
1052  if (0 == len)
1053  return 0;
1054 
1055  pfile_in_zip_read_info->stream.next_out = (Bytef *) buf;
1056  pfile_in_zip_read_info->stream.avail_out = (uInt) len;
1057  if (len > pfile_in_zip_read_info->rest_read_uncompressed)
1058  pfile_in_zip_read_info->stream.avail_out =
1059  (uInt) pfile_in_zip_read_info->rest_read_uncompressed;
1060 
1061  while (pfile_in_zip_read_info->stream.avail_out > 0)
1062  {
1063  if ( (0 == pfile_in_zip_read_info->stream.avail_in) &&
1064  (pfile_in_zip_read_info->rest_read_compressed > 0) )
1065  {
1066  uInt uReadThis = UNZ_BUFSIZE;
1067  if (pfile_in_zip_read_info->rest_read_compressed<uReadThis)
1068  uReadThis = (uInt) pfile_in_zip_read_info->rest_read_compressed;
1069  if (0 == uReadThis)
1070  return EXTRACTOR_UNZIP_EOF;
1071  if (0 !=
1072  ZSEEK (pfile_in_zip_read_info->z_filefunc,
1073  pfile_in_zip_read_info->pos_in_zipfile
1074  + pfile_in_zip_read_info->byte_before_the_zipfile,
1075  SEEK_SET))
1076  return EXTRACTOR_UNZIP_ERRNO;
1077  if (ZREAD (pfile_in_zip_read_info->z_filefunc,
1078  pfile_in_zip_read_info->read_buffer,
1079  uReadThis) != uReadThis)
1080  return EXTRACTOR_UNZIP_ERRNO;
1081 
1082  pfile_in_zip_read_info->pos_in_zipfile += uReadThis;
1083  pfile_in_zip_read_info->rest_read_compressed -= uReadThis;
1084  pfile_in_zip_read_info->stream.next_in =
1085  (Bytef *) pfile_in_zip_read_info->read_buffer;
1086  pfile_in_zip_read_info->stream.avail_in = (uInt) uReadThis;
1087  }
1088 
1089  if (0 == pfile_in_zip_read_info->compression_method)
1090  {
1091  uInt uDoCopy;
1092 
1093  if ( (0 == pfile_in_zip_read_info->stream.avail_in) &&
1094  (0 == pfile_in_zip_read_info->rest_read_compressed) )
1095  return (0 == iRead) ? EXTRACTOR_UNZIP_EOF : iRead;
1096 
1097  if (pfile_in_zip_read_info->stream.avail_out <
1098  pfile_in_zip_read_info->stream.avail_in)
1099  uDoCopy = pfile_in_zip_read_info->stream.avail_out;
1100  else
1101  uDoCopy = pfile_in_zip_read_info->stream.avail_in;
1102  memcpy (pfile_in_zip_read_info->stream.next_out,
1103  pfile_in_zip_read_info->stream.next_in,
1104  uDoCopy);
1105  pfile_in_zip_read_info->crc32 = crc32 (pfile_in_zip_read_info->crc32,
1106  pfile_in_zip_read_info->stream.
1107  next_out,
1108  uDoCopy);
1109  pfile_in_zip_read_info->rest_read_uncompressed -= uDoCopy;
1110  pfile_in_zip_read_info->stream.avail_in -= uDoCopy;
1111  pfile_in_zip_read_info->stream.avail_out -= uDoCopy;
1112  pfile_in_zip_read_info->stream.next_out += uDoCopy;
1113  pfile_in_zip_read_info->stream.next_in += uDoCopy;
1114  pfile_in_zip_read_info->stream.total_out += uDoCopy;
1115  iRead += uDoCopy;
1116  }
1117  else
1118  {
1119  uLong uTotalOutBefore;
1120  uLong uTotalOutAfter;
1121  const Bytef *bufBefore;
1122  uLong uOutThis;
1123  int flush = Z_SYNC_FLUSH;
1124 
1125  uTotalOutBefore = pfile_in_zip_read_info->stream.total_out;
1126  bufBefore = pfile_in_zip_read_info->stream.next_out;
1127 
1128  /*
1129  if ((pfile_in_zip_read_info->rest_read_uncompressed ==
1130  pfile_in_zip_read_info->stream.avail_out) &&
1131  (pfile_in_zip_read_info->rest_read_compressed == 0))
1132  flush = Z_FINISH;
1133  */err = inflate (&pfile_in_zip_read_info->stream, flush);
1134 
1135  uTotalOutAfter = pfile_in_zip_read_info->stream.total_out;
1136  uOutThis = uTotalOutAfter - uTotalOutBefore;
1137 
1138  pfile_in_zip_read_info->crc32 =
1139  crc32 (pfile_in_zip_read_info->crc32, bufBefore,
1140  (uInt) (uOutThis));
1141 
1142  pfile_in_zip_read_info->rest_read_uncompressed -=
1143  uOutThis;
1144 
1145  iRead += (uInt) (uTotalOutAfter - uTotalOutBefore);
1146 
1147  if (Z_STREAM_END == err)
1148  return (0 == iRead) ? EXTRACTOR_UNZIP_EOF : iRead;
1149  if (Z_OK != err)
1150  break;
1151  }
1152  }
1153 
1154  if (Z_OK == err)
1155  return iRead;
1156  return err;
1157 }
1158 
1159 
1160 /**
1161  * Read the local header of the current zipfile. Check the coherency of
1162  * the local header and info in the end of central directory about
1163  * this file. Store in *piSizeVar the size of extra info in local
1164  * header (filename and size of extra field data)
1165  *
1166  * @param file zipfile to process
1167  * @param piSizeVar where to store the size of the extra info
1168  * @param poffset_local_extrafield where to store the offset of the local extrafield
1169  * @param psoze_local_extrafield where to store the size of the local extrafield
1170  * @return #EXTRACTOR_UNZIP_OK on success
1171  */
1172 static int
1174  uInt *piSizeVar,
1175  uLong *poffset_local_extrafield,
1176  uInt *psize_local_extrafield)
1177 {
1178  uLong uMagic;
1179  uLong uData;
1180  uLong uFlags;
1181  uLong size_filename;
1182  uLong size_extra_field;
1183 
1184  *piSizeVar = 0;
1185  *poffset_local_extrafield = 0;
1186  *psize_local_extrafield = 0;
1187 
1188  if (0 != ZSEEK (file->z_filefunc,
1190  + file->byte_before_the_zipfile,
1191  SEEK_SET))
1192  return EXTRACTOR_UNZIP_ERRNO;
1193  if (EXTRACTOR_UNZIP_OK !=
1195  &uMagic))
1196  return EXTRACTOR_UNZIP_ERRNO;
1197  if (0x04034b50 != uMagic)
1199  if ( (EXTRACTOR_UNZIP_OK !=
1200  read_short_from_ffd (&file->z_filefunc, &uData)) ||
1201  (EXTRACTOR_UNZIP_OK !=
1202  read_short_from_ffd (&file->z_filefunc, &uFlags)) )
1203  return EXTRACTOR_UNZIP_ERRNO;
1204  if (EXTRACTOR_UNZIP_OK != read_short_from_ffd (&file->z_filefunc, &uData))
1205  return EXTRACTOR_UNZIP_ERRNO;
1206  if (uData != file->cur_file_info.compression_method)
1208  if ( (0 != file->cur_file_info.compression_method) &&
1209  (Z_DEFLATED != file->cur_file_info.compression_method) )
1211  if (EXTRACTOR_UNZIP_OK !=
1212  read_long_from_ffd (&file->z_filefunc, &uData)) /* date/time */
1213  return EXTRACTOR_UNZIP_ERRNO;
1214  if (EXTRACTOR_UNZIP_OK !=
1215  read_long_from_ffd (&file->z_filefunc, &uData)) /* crc */
1216  return EXTRACTOR_UNZIP_ERRNO;
1217  if ( (uData != file->cur_file_info.crc) &&
1218  (0 == (uFlags & 8)) )
1220  if (EXTRACTOR_UNZIP_OK !=
1221  read_long_from_ffd (&file->z_filefunc, &uData)) /* size compr */
1222  return EXTRACTOR_UNZIP_ERRNO;
1223  if ( (uData != file->cur_file_info.compressed_size) &&
1224  (0 == (uFlags & 8)) )
1226  if (EXTRACTOR_UNZIP_OK !=
1228  &uData)) /* size uncompr */
1229  return EXTRACTOR_UNZIP_ERRNO;
1230  if ( (uData != file->cur_file_info.uncompressed_size) &&
1231  (0 == (uFlags & 8)))
1233  if (EXTRACTOR_UNZIP_OK !=
1234  read_short_from_ffd (&file->z_filefunc, &size_filename))
1235  return EXTRACTOR_UNZIP_ERRNO;
1236  if (size_filename != file->cur_file_info.size_filename)
1238  *piSizeVar += (uInt) size_filename;
1239  if (EXTRACTOR_UNZIP_OK !=
1241  &size_extra_field))
1242  return EXTRACTOR_UNZIP_ERRNO;
1243  *poffset_local_extrafield = file->cur_file_info_internal.offset_curfile
1244  + SIZEZIPLOCALHEADER + size_filename;
1245  *psize_local_extrafield = (uInt) size_extra_field;
1246  *piSizeVar += (uInt) size_extra_field;
1247 
1248  return EXTRACTOR_UNZIP_OK;
1249 }
1250 
1251 
1252 /**
1253  * Open for reading data the current file in the zipfile.
1254  *
1255  * @param file zipfile to manipulate
1256  * @return #EXTRACTOR_UNZIP_OK on success
1257  */
1258 int
1260 {
1261  int err;
1262  uInt iSizeVar;
1263  struct FileInZipReadInfo *pfile_in_zip_read_info;
1264  uLong offset_local_extrafield; /* offset of the local extra field */
1265  uInt size_local_extrafield; /* size of the local extra field */
1266 
1267  if (NULL == file)
1269  if (! file->current_file_ok)
1271  if (NULL != file->pfile_in_zip_read)
1273  if (EXTRACTOR_UNZIP_OK !=
1275  &iSizeVar,
1279  if (NULL == (pfile_in_zip_read_info = malloc (sizeof(struct
1280  FileInZipReadInfo))))
1282  if (NULL == (pfile_in_zip_read_info->read_buffer = malloc (UNZ_BUFSIZE)))
1283  {
1284  free (pfile_in_zip_read_info);
1286  }
1287  pfile_in_zip_read_info->offset_local_extrafield = offset_local_extrafield;
1288  pfile_in_zip_read_info->size_local_extrafield = size_local_extrafield;
1289  pfile_in_zip_read_info->pos_local_extrafield = 0;
1290  pfile_in_zip_read_info->stream_initialised = 0;
1291 
1292  if ( (0 != file->cur_file_info.compression_method) &&
1293  (Z_DEFLATED != file->cur_file_info.compression_method) )
1294  {
1295  // err = EXTRACTOR_UNZIP_BADZIPFILE;
1296  // FIXME: we don't do anything with this 'err' code.
1297  // Can this happen? Should we abort in this case?
1298  }
1299 
1300  pfile_in_zip_read_info->crc32_wait = file->cur_file_info.crc;
1301  pfile_in_zip_read_info->crc32 = 0;
1302  pfile_in_zip_read_info->compression_method =
1304  pfile_in_zip_read_info->z_filefunc = file->z_filefunc;
1305  pfile_in_zip_read_info->byte_before_the_zipfile =
1307  pfile_in_zip_read_info->stream.total_out = 0;
1308  if (Z_DEFLATED == file->cur_file_info.compression_method)
1309  {
1310  pfile_in_zip_read_info->stream.zalloc = (alloc_func) NULL;
1311  pfile_in_zip_read_info->stream.zfree = (free_func) NULL;
1312  pfile_in_zip_read_info->stream.opaque = NULL;
1313  pfile_in_zip_read_info->stream.next_in = NULL;
1314  pfile_in_zip_read_info->stream.avail_in = 0;
1315  if (Z_OK != (err = inflateInit2 (&pfile_in_zip_read_info->stream,
1316  -MAX_WBITS)))
1317  {
1318  free (pfile_in_zip_read_info->read_buffer);
1319  free (pfile_in_zip_read_info);
1320  return err;
1321  }
1322  pfile_in_zip_read_info->stream_initialised = 1;
1323  /* windowBits is passed < 0 to tell that there is no zlib header.
1324  * Note that in this case inflate *requires* an extra "dummy" byte
1325  * after the compressed stream in order to complete decompression and
1326  * return Z_STREAM_END.
1327  * In unzip, i don't wait absolutely Z_STREAM_END because I known the
1328  * size of both compressed and uncompressed data
1329  */}
1330  pfile_in_zip_read_info->rest_read_compressed =
1332  pfile_in_zip_read_info->rest_read_uncompressed =
1334  pfile_in_zip_read_info->pos_in_zipfile =
1336  + iSizeVar;
1337  pfile_in_zip_read_info->stream.avail_in = 0;
1338  file->pfile_in_zip_read = pfile_in_zip_read_info;
1339  return EXTRACTOR_UNZIP_OK;
1340 }
1341 
1342 
1343 /**
1344  * Callback to perform read operation using LE API.
1345  * Note that partial reads are not allowed.
1346  *
1347  * @param opaque the 'struct EXTRACTOR_ExtractContext'
1348  * @param buf where to write bytes read
1349  * @param size number of bytes desired
1350  * @return number of bytes copied to buf
1351  */
1352 static uLong
1353 ec_read_file_func (voidpf opaque,
1354  void*buf,
1355  uLong size)
1356 {
1357  struct EXTRACTOR_ExtractContext *ec = opaque;
1358  void *ptr;
1359  ssize_t ret;
1360  uLong done;
1361 
1362  done = 0;
1363  while (done < size)
1364  {
1365  ret = ec->read (ec->cls,
1366  &ptr,
1367  size - done);
1368  if (ret <= 0)
1369  return done;
1370  memcpy (buf + done, ptr, ret);
1371  done += ret;
1372  }
1373  return done;
1374 }
1375 
1376 
1377 /**
1378  * Callback to obtain current offset in file using LE API.
1379  *
1380  * @param opaque the 'struct EXTRACTOR_ExtractContext'
1381  * @return current offset in file, -1 on error
1382  */
1383 static long
1384 ec_tell_file_func (voidpf opaque)
1385 {
1386  struct EXTRACTOR_ExtractContext *ec = opaque;
1387 
1388  return ec->seek (ec->cls, 0, SEEK_CUR);
1389 }
1390 
1391 
1392 /**
1393  * Callback to perform seek operation using LE API.
1394  *
1395  * @param opaque the 'struct EXTRACTOR_ExtractContext'
1396  * @param offset where to seek
1397  * @param origin relative to where should we seek
1398  * @return #EXTRACTOR_UNZIP_OK on success
1399  */
1400 static long
1401 ec_seek_file_func (voidpf opaque,
1402  uLong offset,
1403  int origin)
1404 {
1405  struct EXTRACTOR_ExtractContext *ec = opaque;
1406 
1407  if (-1 == ec->seek (ec->cls, offset, origin))
1409  return EXTRACTOR_UNZIP_OK;
1410 }
1411 
1412 
1413 /**
1414  * Open a zip file for processing using the data access
1415  * functions from the extract context.
1416  *
1417  * @param ec extract context to use
1418  * @return handle to zip data, NULL on error
1419  */
1420 struct EXTRACTOR_UnzipFile *
1422 {
1423  struct FileFuncDefs ffd;
1424 
1428  ffd.opaque = ec;
1429 
1430  return unzip_open_using_ffd (&ffd);
1431 }
1432 
1433 
1434 /* end of unzip.c */
#define NULL
Definition: getopt1.c:60
plaform specifics
int64_t(* seek)(void *cls, int64_t pos, int whence)
Definition: extractor.h:509
ssize_t(* read)(void *cls, void **data, size_t size)
Definition: extractor.h:494
uLong compression_method
Definition: unzip.h:140
struct EXTRACTOR_UnzipDateTimeInfo tmu_date
Definition: unzip.h:195
struct UnzipFileInfoInternal cur_file_info_internal
Definition: unzip.c:317
uLong byte_before_the_zipfile
Definition: unzip.c:276
uLong central_pos
Definition: unzip.c:296
struct GlobalInfo gi
Definition: unzip.c:271
uLong offset_central_dir
Definition: unzip.c:307
struct FileFuncDefs z_filefunc
Definition: unzip.c:266
uLong pos_in_central_dir
Definition: unzip.c:286
struct FileInZipReadInfo * pfile_in_zip_read
Definition: unzip.c:322
uLong size_central_dir
Definition: unzip.c:301
uLong current_file_ok
Definition: unzip.c:291
struct EXTRACTOR_UnzipFileInfo cur_file_info
Definition: unzip.c:312
voidpf opaque
Definition: unzip.c:105
long(* ztell_file)(voidpf opaque)
Definition: unzip.c:95
uLong(* zread_file)(voidpf opaque, void *buf, uLong size)
Definition: unzip.c:90
long(* zseek_file)(voidpf opaque, uLong offset, int origin)
Definition: unzip.c:100
uLong offset_local_extrafield
Definition: unzip.c:208
uInt size_local_extrafield
Definition: unzip.c:213
uLong pos_in_zipfile
Definition: unzip.c:198
struct FileFuncDefs z_filefunc
Definition: unzip.c:243
char * read_buffer
Definition: unzip.c:188
uLong stream_initialised
Definition: unzip.c:203
uLong rest_read_uncompressed
Definition: unzip.c:238
uLong pos_local_extrafield
Definition: unzip.c:218
z_stream stream
Definition: unzip.c:193
uLong rest_read_compressed
Definition: unzip.c:233
uLong compression_method
Definition: unzip.c:248
uLong crc32_wait
Definition: unzip.c:228
uLong byte_before_the_zipfile
Definition: unzip.c:253
uLong number_entry
Definition: unzip.c:151
uLong size_comment
Definition: unzip.c:156
uLong offset_comment
Definition: unzip.c:161
uLong offset_curfile
Definition: unzip.c:174
static uLong ec_read_file_func(voidpf opaque, void *buf, uLong size)
Definition: unzip.c:1353
int EXTRACTOR_common_unzip_open_current_file(struct EXTRACTOR_UnzipFile *file)
Definition: unzip.c:1259
static int read_short_from_ffd(const struct FileFuncDefs *ffd, uLong *pX)
Definition: unzip.c:363
#define BUFREADCOMMENT
Definition: unzip.c:454
static int read_byte_from_ffd(const struct FileFuncDefs *ffd, int *pi)
Definition: unzip.c:341
#define CASESENSITIVITYDEFAULTVALUE
Definition: unzip.c:424
static int read_long_from_ffd(const struct FileFuncDefs *ffd, uLong *pX)
Definition: unzip.c:392
static long ec_seek_file_func(voidpf opaque, uLong offset, int origin)
Definition: unzip.c:1401
int EXTRACTOR_common_unzip_go_to_next_file(struct EXTRACTOR_UnzipFile *file)
Definition: unzip.c:933
#define SIZEZIPLOCALHEADER
Definition: unzip.c:79
static long ec_tell_file_func(voidpf opaque)
Definition: unzip.c:1384
static int EXTRACTOR_common_unzip_string_file_name_compare(const char *fileName1, const char *fileName2, int iCaseSensitivity)
Definition: unzip.c:441
ssize_t EXTRACTOR_common_unzip_read_current_file(struct EXTRACTOR_UnzipFile *file, void *buf, size_t len)
Definition: unzip.c:1038
int EXTRACTOR_common_unzip_go_find_local_file(struct EXTRACTOR_UnzipFile *file, const char *szFileName, int iCaseSensitivity)
Definition: unzip.c:969
int EXTRACTOR_common_unzip_get_current_file_info(struct EXTRACTOR_UnzipFile *file, struct EXTRACTOR_UnzipFileInfo *pfile_info, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition: unzip.c:908
struct EXTRACTOR_UnzipFile * EXTRACTOR_common_unzip_open(struct EXTRACTOR_ExtractContext *ec)
Definition: unzip.c:1421
static int get_current_file_info(struct EXTRACTOR_UnzipFile *file, struct EXTRACTOR_UnzipFileInfo *pfile_info, struct UnzipFileInfoInternal *pfile_info_internal, char *szFileName, uLong fileNameBufferSize, void *extraField, uLong extraFieldBufferSize, char *szComment, uLong commentBufferSize)
Definition: unzip.c:547
#define ZSEEK(filefunc, pos, mode)
Definition: unzip.c:136
static void dos_date_to_tmu_date(uLong ulDosDate, struct EXTRACTOR_UnzipDateTimeInfo *ptm)
Definition: unzip.c:516
static uLong locate_central_directory(const struct FileFuncDefs *ffd)
Definition: unzip.c:465
#define UNZ_MAXFILENAMEINZIP
Definition: unzip.c:75
#define ZREAD(filefunc, buf, size)
Definition: unzip.c:117
static int parse_current_file_coherency_header(struct EXTRACTOR_UnzipFile *file, uInt *piSizeVar, uLong *poffset_local_extrafield, uInt *psize_local_extrafield)
Definition: unzip.c:1173
#define UNZ_BUFSIZE
Definition: unzip.c:71
int EXTRACTOR_common_unzip_go_to_first_file(struct EXTRACTOR_UnzipFile *file)
Definition: unzip.c:707
int EXTRACTOR_common_unzip_close(struct EXTRACTOR_UnzipFile *file)
Definition: unzip.c:854
#define ZTELL(filefunc)
Definition: unzip.c:126
#define SIZECENTRALDIRITEM
Definition: unzip.c:78
static struct EXTRACTOR_UnzipFile * unzip_open_using_ffd(struct FileFuncDefs *ffd)
Definition: unzip.c:731
int EXTRACTOR_common_unzip_get_global_comment(struct EXTRACTOR_UnzipFile *file, char *comment, size_t comment_len)
Definition: unzip.c:874
int EXTRACTOR_common_unzip_close_current_file(struct EXTRACTOR_UnzipFile *file)
Definition: unzip.c:823
API to access ZIP archives.
#define EXTRACTOR_UNZIP_EOF
Definition: unzip.h:52
#define EXTRACTOR_UNZIP_OK
Definition: unzip.h:37
#define EXTRACTOR_UNZIP_ERRNO
Definition: unzip.h:47
#define EXTRACTOR_UNZIP_END_OF_LIST_OF_FILE
Definition: unzip.h:42
#define EXTRACTOR_UNZIP_BADZIPFILE
Definition: unzip.h:62
#define EXTRACTOR_UNZIP_PARAMERROR
Definition: unzip.h:57
#define EXTRACTOR_UNZIP_CRCERROR
Definition: unzip.h:72
#define EXTRACTOR_UNZIP_INTERNALERROR
Definition: unzip.h:67