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#ifdef __cplusplus 18extern "C" { 19#endif 20 21#ifdef HAVE_SELINUX 22#include <selinux/selinux.h> 23#include <selinux/label.h> 24#else 25struct selabel_handle; 26#endif 27 28/* 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, 180 const ZipEntry *pEntry, int fd); 181 182/* 183 * 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/* 190 * 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, 222 void (*callback)(const char *fn, void*), void *cookie, 223 struct selabel_handle *sehnd); 224 225#ifdef __cplusplus 226} 227#endif 228 229#endif /*_MINZIP_ZIP*/ 230