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 18 extern "C" { 19 #endif 20 21 #include <selinux/selinux.h> 22 #include <selinux/label.h> 23 24 /* 25 * One entry in the Zip archive. Treat this as opaque -- use accessors below. 26 * 27 * TODO: we're now keeping the pages mapped so we don't have to copy the 28 * filename. We can change the accessors to retrieve the various pieces 29 * directly from the source file instead of copying them out, for a very 30 * slight speed hit and a modest reduction in memory usage. 31 */ 32 typedef struct ZipEntry { 33 unsigned int fileNameLen; 34 const char* fileName; // not null-terminated 35 long offset; 36 long compLen; 37 long uncompLen; 38 int compression; 39 long modTime; 40 long crc32; 41 int versionMadeBy; 42 long externalFileAttributes; 43 } ZipEntry; 44 45 /* 46 * One Zip archive. Treat as opaque. 47 */ 48 typedef struct ZipArchive { 49 unsigned int numEntries; 50 ZipEntry* pEntries; 51 HashTable* pHash; // maps file name to ZipEntry 52 unsigned char* addr; 53 size_t length; 54 } ZipArchive; 55 56 /* 57 * Represents a non-NUL-terminated string, 58 * which is how entry names are stored. 59 */ 60 typedef struct { 61 const char *str; 62 size_t len; 63 } UnterminatedString; 64 65 /* 66 * Open a Zip archive. 67 * 68 * On success, returns 0 and populates "pArchive". Returns nonzero errno 69 * value on failure. 70 */ 71 int mzOpenZipArchive(unsigned char* addr, size_t length, ZipArchive* pArchive); 72 73 /* 74 * Close archive, releasing resources associated with it. 75 * 76 * Depending on the implementation this could unmap pages used by classes 77 * stored in a Jar. This should only be done after unloading classes. 78 */ 79 void mzCloseZipArchive(ZipArchive* pArchive); 80 81 82 /* 83 * Find an entry in the Zip archive, by name. 84 */ 85 const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive, 86 const char* entryName); 87 88 INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) { 89 return pEntry->offset; 90 } 91 INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) { 92 return pEntry->uncompLen; 93 } 94 95 /* 96 * Type definition for the callback function used by 97 * mzProcessZipEntryContents(). 98 */ 99 typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data, 100 int dataLen, void *cookie); 101 102 /* 103 * Stream the uncompressed data through the supplied function, 104 * passing cookie to it each time it gets called. processFunction 105 * may be called more than once. 106 * 107 * If processFunction returns false, the operation is abandoned and 108 * mzProcessZipEntryContents() immediately returns false. 109 * 110 * This is useful for calculating the hash of an entry's uncompressed contents. 111 */ 112 bool mzProcessZipEntryContents(const ZipArchive *pArchive, 113 const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction, 114 void *cookie); 115 116 /* 117 * Read an entry into a buffer allocated by the caller. 118 */ 119 bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry, 120 char* buf, int bufLen); 121 122 /* 123 * Inflate and write an entry to a file. 124 */ 125 bool mzExtractZipEntryToFile(const ZipArchive *pArchive, 126 const ZipEntry *pEntry, int fd); 127 128 /* 129 * Inflate and write an entry to a memory buffer, which must be long 130 * enough to hold mzGetZipEntryUncomplen(pEntry) bytes. 131 */ 132 bool mzExtractZipEntryToBuffer(const ZipArchive *pArchive, 133 const ZipEntry *pEntry, unsigned char* buffer); 134 135 /* 136 * Inflate all files under zipDir to the directory specified by 137 * targetDir, which must exist and be a writable directory. 138 * 139 * Directory entries and symlinks are not extracted. 140 * 141 * 142 * The immediate children of zipDir will become the immediate 143 * children of targetDir; e.g., if the archive contains the entries 144 * 145 * a/b/c/one 146 * a/b/c/two 147 * a/b/c/d/three 148 * 149 * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting 150 * files will be 151 * 152 * /tmp/one 153 * /tmp/two 154 * /tmp/d/three 155 * 156 * If timestamp is non-NULL, file timestamps will be set accordingly. 157 * 158 * If callback is non-NULL, it will be invoked with each unpacked file. 159 * 160 * Returns true on success, false on failure. 161 */ 162 bool mzExtractRecursive(const ZipArchive *pArchive, 163 const char *zipDir, const char *targetDir, 164 const struct utimbuf *timestamp, 165 void (*callback)(const char *fn, void*), void *cookie, 166 struct selabel_handle *sehnd); 167 168 #ifdef __cplusplus 169 } 170 #endif 171 172 #endif /*_MINZIP_ZIP*/ 173