• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2006 The Android Open Source Project
3  *
4  * Simple Zip archive support.
5  */
6 #ifndef _MINZIP_ZIP
7 #define _MINZIP_ZIP
8 
9 #include "inline_magic.h"
10 
11 #include <stdlib.h>
12 #include <utime.h>
13 
14 #include "Hash.h"
15 #include "SysUtil.h"
16 
17 /*
18  * One entry in the Zip archive.  Treat this as opaque -- use accessors below.
19  *
20  * TODO: we're now keeping the pages mapped so we don't have to copy the
21  * filename.  We can change the accessors to retrieve the various pieces
22  * directly from the source file instead of copying them out, for a very
23  * slight speed hit and a modest reduction in memory usage.
24  */
25 typedef struct ZipEntry {
26     unsigned int fileNameLen;
27     const char*  fileName;       // not null-terminated
28     long         offset;
29     long         compLen;
30     long         uncompLen;
31     int          compression;
32     long         modTime;
33     long         crc32;
34     int          versionMadeBy;
35     long         externalFileAttributes;
36 } ZipEntry;
37 
38 /*
39  * One Zip archive.  Treat as opaque.
40  */
41 typedef struct ZipArchive {
42     int         fd;
43     unsigned int numEntries;
44     ZipEntry*   pEntries;
45     HashTable*  pHash;          // maps file name to ZipEntry
46     MemMapping  map;
47 } ZipArchive;
48 
49 /*
50  * Represents a non-NUL-terminated string,
51  * which is how entry names are stored.
52  */
53 typedef struct {
54     const char *str;
55     size_t len;
56 } UnterminatedString;
57 
58 /*
59  * Open a Zip archive.
60  *
61  * On success, returns 0 and populates "pArchive".  Returns nonzero errno
62  * value on failure.
63  */
64 int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive);
65 
66 /*
67  * Close archive, releasing resources associated with it.
68  *
69  * Depending on the implementation this could unmap pages used by classes
70  * stored in a Jar.  This should only be done after unloading classes.
71  */
72 void mzCloseZipArchive(ZipArchive* pArchive);
73 
74 
75 /*
76  * Find an entry in the Zip archive, by name.
77  */
78 const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
79         const char* entryName);
80 
81 /*
82  * Get the number of entries in the Zip archive.
83  */
mzZipEntryCount(const ZipArchive * pArchive)84 INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
85     return pArchive->numEntries;
86 }
87 
88 /*
89  * Get an entry by index.  Returns NULL if the index is out-of-bounds.
90  */
91 INLINE const ZipEntry*
mzGetZipEntryAt(const ZipArchive * pArchive,unsigned int index)92 mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
93 {
94     if (index < pArchive->numEntries) {
95         return pArchive->pEntries + index;
96     }
97     return NULL;
98 }
99 
100 /*
101  * Get the index number of an entry in the archive.
102  */
103 INLINE unsigned int
mzGetZipEntryIndex(const ZipArchive * pArchive,const ZipEntry * pEntry)104 mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
105     return pEntry - pArchive->pEntries;
106 }
107 
108 /*
109  * Simple accessors.
110  */
mzGetZipEntryFileName(const ZipEntry * pEntry)111 INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
112     UnterminatedString ret;
113     ret.str = pEntry->fileName;
114     ret.len = pEntry->fileNameLen;
115     return ret;
116 }
mzGetZipEntryOffset(const ZipEntry * pEntry)117 INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
118     return pEntry->offset;
119 }
mzGetZipEntryUncompLen(const ZipEntry * pEntry)120 INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
121     return pEntry->uncompLen;
122 }
mzGetZipEntryModTime(const ZipEntry * pEntry)123 INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
124     return pEntry->modTime;
125 }
mzGetZipEntryCrc32(const ZipEntry * pEntry)126 INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
127     return pEntry->crc32;
128 }
129 bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
130 
131 
132 /*
133  * Type definition for the callback function used by
134  * mzProcessZipEntryContents().
135  */
136 typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data,
137     int dataLen, void *cookie);
138 
139 /*
140  * Stream the uncompressed data through the supplied function,
141  * passing cookie to it each time it gets called.  processFunction
142  * may be called more than once.
143  *
144  * If processFunction returns false, the operation is abandoned and
145  * mzProcessZipEntryContents() immediately returns false.
146  *
147  * This is useful for calculating the hash of an entry's uncompressed contents.
148  */
149 bool mzProcessZipEntryContents(const ZipArchive *pArchive,
150     const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
151     void *cookie);
152 
153 /*
154  * Read an entry into a buffer allocated by the caller.
155  */
156 bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
157         char* buf, int bufLen);
158 
159 /*
160  * Check the CRC on this entry; return true if it is correct.
161  * May do other internal checks as well.
162  */
163 bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
164 
165 /*
166  * Inflate and write an entry to a file.
167  */
168 bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
169     const ZipEntry *pEntry, int fd);
170 
171 /*
172  * Inflate all entries under zipDir to the directory specified by
173  * targetDir, which must exist and be a writable directory.
174  *
175  * The immediate children of zipDir will become the immediate
176  * children of targetDir; e.g., if the archive contains the entries
177  *
178  *     a/b/c/one
179  *     a/b/c/two
180  *     a/b/c/d/three
181  *
182  * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
183  * files will be
184  *
185  *     /tmp/one
186  *     /tmp/two
187  *     /tmp/d/three
188  *
189  * flags is zero or more of the following:
190  *
191  *     MZ_EXTRACT_FILES_ONLY - only unpack files, not directories or symlinks
192  *     MZ_EXTRACT_DRY_RUN - don't do anything, but do invoke the callback
193  *
194  * If timestamp is non-NULL, file timestamps will be set accordingly.
195  *
196  * If callback is non-NULL, it will be invoked with each unpacked file.
197  *
198  * Returns true on success, false on failure.
199  */
200 enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 };
201 bool mzExtractRecursive(const ZipArchive *pArchive,
202         const char *zipDir, const char *targetDir,
203         int flags, const struct utimbuf *timestamp,
204         void (*callback)(const char *fn, void*), void *cookie);
205 
206 #endif /*_MINZIP_ZIP*/
207