blob: 57c0abd2c5cb8c5cc243c632da780cfc38de6d27 [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
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 */
25typedef 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 */
41typedef 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 */
53typedef struct {
54 const char *str;
55 size_t len;
56} UnterminatedString;
57
58/*
Doug Zongker683c4622009-05-05 17:50:21 -070059 * The information we pass down to writeProcessFunction.
60 */
61typedef struct {
62 int fd;
63 unsigned char* aligned_buffer;
64} WriteInfo;
65
66/*
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -080067 * Open a Zip archive.
68 *
69 * On success, returns 0 and populates "pArchive". Returns nonzero errno
70 * value on failure.
71 */
72int mzOpenZipArchive(const char* fileName, ZipArchive* pArchive);
73
74/*
75 * Close archive, releasing resources associated with it.
76 *
77 * Depending on the implementation this could unmap pages used by classes
78 * stored in a Jar. This should only be done after unloading classes.
79 */
80void mzCloseZipArchive(ZipArchive* pArchive);
81
82
83/*
84 * Find an entry in the Zip archive, by name.
85 */
86const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
87 const char* entryName);
88
89/*
90 * Get the number of entries in the Zip archive.
91 */
92INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
93 return pArchive->numEntries;
94}
95
96/*
97 * Get an entry by index. Returns NULL if the index is out-of-bounds.
98 */
99INLINE const ZipEntry*
100mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
101{
102 if (index < pArchive->numEntries) {
103 return pArchive->pEntries + index;
104 }
105 return NULL;
106}
107
108/*
109 * Get the index number of an entry in the archive.
110 */
111INLINE unsigned int
112mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
113 return pEntry - pArchive->pEntries;
114}
115
116/*
117 * Simple accessors.
118 */
119INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
120 UnterminatedString ret;
121 ret.str = pEntry->fileName;
122 ret.len = pEntry->fileNameLen;
123 return ret;
124}
125INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
126 return pEntry->offset;
127}
128INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
129 return pEntry->uncompLen;
130}
131INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
132 return pEntry->modTime;
133}
134INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
135 return pEntry->crc32;
136}
137bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
138
139
140/*
141 * Type definition for the callback function used by
142 * mzProcessZipEntryContents().
143 */
144typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data,
145 int dataLen, void *cookie);
146
147/*
148 * Stream the uncompressed data through the supplied function,
149 * passing cookie to it each time it gets called. processFunction
150 * may be called more than once.
151 *
152 * If processFunction returns false, the operation is abandoned and
153 * mzProcessZipEntryContents() immediately returns false.
154 *
155 * This is useful for calculating the hash of an entry's uncompressed contents.
156 */
157bool mzProcessZipEntryContents(const ZipArchive *pArchive,
158 const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
159 void *cookie);
160
161/*
162 * Read an entry into a buffer allocated by the caller.
163 */
164bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
165 char* buf, int bufLen);
166
167/*
168 * Check the CRC on this entry; return true if it is correct.
169 * May do other internal checks as well.
170 */
171bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
172
173/*
174 * Inflate and write an entry to a file.
175 */
176bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
Doug Zongker683c4622009-05-05 17:50:21 -0700177 const ZipEntry *pEntry, WriteInfo *wi);
The Android Open Source Projectc24a8e62009-03-03 19:28:42 -0800178
179/*
180 * Inflate all entries under zipDir to the directory specified by
181 * targetDir, which must exist and be a writable directory.
182 *
183 * The immediate children of zipDir will become the immediate
184 * children of targetDir; e.g., if the archive contains the entries
185 *
186 * a/b/c/one
187 * a/b/c/two
188 * a/b/c/d/three
189 *
190 * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
191 * files will be
192 *
193 * /tmp/one
194 * /tmp/two
195 * /tmp/d/three
196 *
197 * flags is zero or more of the following:
198 *
199 * MZ_EXTRACT_FILES_ONLY - only unpack files, not directories or symlinks
200 * MZ_EXTRACT_DRY_RUN - don't do anything, but do invoke the callback
201 *
202 * If timestamp is non-NULL, file timestamps will be set accordingly.
203 *
204 * If callback is non-NULL, it will be invoked with each unpacked file.
205 *
206 * Returns true on success, false on failure.
207 */
208enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 };
209bool mzExtractRecursive(const ZipArchive *pArchive,
210 const char *zipDir, const char *targetDir,
211 int flags, const struct utimbuf *timestamp,
212 void (*callback)(const char *fn, void*), void *cookie);
213
214#endif /*_MINZIP_ZIP*/