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