aboutsummaryrefslogtreecommitdiffstats
path: root/minzip/Zip.h
blob: 92c20a0a5bccf704a6a3159a75c8f7ae74c2d5df (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
 * Copyright 2006 The Android Open Source Project
 *
 * Simple Zip archive support.
 */
#ifndef _MINZIP_ZIP
#define _MINZIP_ZIP

#include "inline_magic.h"

#include <stdlib.h>
#include <utime.h>

#include "Hash.h"
#include "SysUtil.h"

#ifdef __cplusplus
extern "C" {
#endif

#include <selinux/selinux.h>
#include <selinux/label.h>

/*
 * One entry in the Zip archive.  Treat this as opaque -- use accessors below.
 *
 * TODO: we're now keeping the pages mapped so we don't have to copy the
 * filename.  We can change the accessors to retrieve the various pieces
 * directly from the source file instead of copying them out, for a very
 * slight speed hit and a modest reduction in memory usage.
 */
typedef struct ZipEntry {
    unsigned int fileNameLen;
    const char*  fileName;       // not null-terminated
    long         offset;
    long         compLen;
    long         uncompLen;
    int          compression;
    long         modTime;
    long         crc32;
    int          versionMadeBy;
    long         externalFileAttributes;
} ZipEntry;

/*
 * One Zip archive.  Treat as opaque.
 */
typedef struct ZipArchive {
    unsigned int   numEntries;
    ZipEntry*      pEntries;
    HashTable*     pHash;          // maps file name to ZipEntry
    unsigned char* addr;
    size_t         length;
} ZipArchive;

/*
 * Represents a non-NUL-terminated string,
 * which is how entry names are stored.
 */
typedef struct {
    const char *str;
    size_t len;
} UnterminatedString;

/*
 * Open a Zip archive.
 *
 * On success, returns 0 and populates "pArchive".  Returns nonzero errno
 * value on failure.
 */
int mzOpenZipArchive(unsigned char* addr, size_t length, ZipArchive* pArchive);

/*
 * Close archive, releasing resources associated with it.
 *
 * Depending on the implementation this could unmap pages used by classes
 * stored in a Jar.  This should only be done after unloading classes.
 */
void mzCloseZipArchive(ZipArchive* pArchive);


/*
 * Find an entry in the Zip archive, by name.
 */
const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
        const char* entryName);

INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
    return pEntry->offset;
}
INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
    return pEntry->uncompLen;
}

/*
 * Type definition for the callback function used by
 * mzProcessZipEntryContents().
 */
typedef bool (*ProcessZipEntryContentsFunction)(const unsigned char *data,
    int dataLen, void *cookie);

/*
 * Stream the uncompressed data through the supplied function,
 * passing cookie to it each time it gets called.  processFunction
 * may be called more than once.
 *
 * If processFunction returns false, the operation is abandoned and
 * mzProcessZipEntryContents() immediately returns false.
 *
 * This is useful for calculating the hash of an entry's uncompressed contents.
 */
bool mzProcessZipEntryContents(const ZipArchive *pArchive,
    const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
    void *cookie);

/*
 * Similar to mzProcessZipEntryContents, but explicitly process the stream
 * using XZ/LZMA before calling processFunction.
 *
 * This is a separate function for use by the updater. LZMA provides huge
 * size reductions vs deflate, but isn't actually supported by the ZIP format.
 * We need to process it using as little memory as possible.
 */
bool mzProcessZipEntryContentsXZ(const ZipArchive *pArchive,
    const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
    void *cookie);

/*
 * Read an entry into a buffer allocated by the caller.
 */
bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
        char* buf, int bufLen);

/*
 * Inflate and write an entry to a file.
 */
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
    const ZipEntry *pEntry, int fd);

/*
 * Inflate and write an entry to a memory buffer, which must be long
 * enough to hold mzGetZipEntryUncomplen(pEntry) bytes.
 */
bool mzExtractZipEntryToBuffer(const ZipArchive *pArchive,
    const ZipEntry *pEntry, unsigned char* buffer);

/*
 * Inflate all files under zipDir to the directory specified by
 * targetDir, which must exist and be a writable directory.
 *
 * Directory entries and symlinks are not extracted.
 *
 *
 * The immediate children of zipDir will become the immediate
 * children of targetDir; e.g., if the archive contains the entries
 *
 *     a/b/c/one
 *     a/b/c/two
 *     a/b/c/d/three
 *
 * and mzExtractRecursive(a, "a/b/c", "/tmp", ...) is called, the resulting
 * files will be
 *
 *     /tmp/one
 *     /tmp/two
 *     /tmp/d/three
 *
 * If timestamp is non-NULL, file timestamps will be set accordingly.
 *
 * If callback is non-NULL, it will be invoked with each unpacked file.
 *
 * Returns true on success, false on failure.
 */
bool mzExtractRecursive(const ZipArchive *pArchive,
        const char *zipDir, const char *targetDir,
        const struct utimbuf *timestamp,
        void (*callback)(const char *fn, void*), void *cookie,
        struct selabel_handle *sehnd);

#ifdef __cplusplus
}
#endif

#endif /*_MINZIP_ZIP*/