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