android_bootable_recovery/minzip/Zip.h
Doug Zongker 683c462803 align data passed to write() on 32k boundaries
In donut, OTA installation often encounters the write() system call
doing short writes -- which is legal but unexpected -- or failing with
ENOSPC when plenty of space is available.  Passing aligned memory
buffers to write() appears to prevent (or at least reduce the
frequency) of these problems.  b/1833052 has been filed to look at the
underlying problem, but this change aligns buffers we use with write()
so we can OTA for now (or see if this problem still occurs).
2009-05-06 08:40:28 -07:00

215 lines
5.7 KiB
C

/*
* 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"
/*
* 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 {
int fd;
unsigned int numEntries;
ZipEntry* pEntries;
HashTable* pHash; // maps file name to ZipEntry
MemMapping map;
} ZipArchive;
/*
* Represents a non-NUL-terminated string,
* which is how entry names are stored.
*/
typedef struct {
const char *str;
size_t len;
} UnterminatedString;
/*
* The information we pass down to writeProcessFunction.
*/
typedef struct {
int fd;
unsigned char* aligned_buffer;
} WriteInfo;
/*
* Open a Zip archive.
*
* On success, returns 0 and populates "pArchive". Returns nonzero errno
* value on failure.
*/
int mzOpenZipArchive(const char* fileName, 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);
/*
* Get the number of entries in the Zip archive.
*/
INLINE unsigned int mzZipEntryCount(const ZipArchive* pArchive) {
return pArchive->numEntries;
}
/*
* Get an entry by index. Returns NULL if the index is out-of-bounds.
*/
INLINE const ZipEntry*
mzGetZipEntryAt(const ZipArchive* pArchive, unsigned int index)
{
if (index < pArchive->numEntries) {
return pArchive->pEntries + index;
}
return NULL;
}
/*
* Get the index number of an entry in the archive.
*/
INLINE unsigned int
mzGetZipEntryIndex(const ZipArchive *pArchive, const ZipEntry *pEntry) {
return pEntry - pArchive->pEntries;
}
/*
* Simple accessors.
*/
INLINE UnterminatedString mzGetZipEntryFileName(const ZipEntry* pEntry) {
UnterminatedString ret;
ret.str = pEntry->fileName;
ret.len = pEntry->fileNameLen;
return ret;
}
INLINE long mzGetZipEntryOffset(const ZipEntry* pEntry) {
return pEntry->offset;
}
INLINE long mzGetZipEntryUncompLen(const ZipEntry* pEntry) {
return pEntry->uncompLen;
}
INLINE long mzGetZipEntryModTime(const ZipEntry* pEntry) {
return pEntry->modTime;
}
INLINE long mzGetZipEntryCrc32(const ZipEntry* pEntry) {
return pEntry->crc32;
}
bool mzIsZipEntrySymlink(const ZipEntry* pEntry);
/*
* 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);
/*
* Read an entry into a buffer allocated by the caller.
*/
bool mzReadZipEntry(const ZipArchive* pArchive, const ZipEntry* pEntry,
char* buf, int bufLen);
/*
* Check the CRC on this entry; return true if it is correct.
* May do other internal checks as well.
*/
bool mzIsZipEntryIntact(const ZipArchive *pArchive, const ZipEntry *pEntry);
/*
* Inflate and write an entry to a file.
*/
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
const ZipEntry *pEntry, WriteInfo *wi);
/*
* Inflate all entries under zipDir to the directory specified by
* targetDir, which must exist and be a writable directory.
*
* 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
*
* flags is zero or more of the following:
*
* MZ_EXTRACT_FILES_ONLY - only unpack files, not directories or symlinks
* MZ_EXTRACT_DRY_RUN - don't do anything, but do invoke the callback
*
* 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.
*/
enum { MZ_EXTRACT_FILES_ONLY = 1, MZ_EXTRACT_DRY_RUN = 2 };
bool mzExtractRecursive(const ZipArchive *pArchive,
const char *zipDir, const char *targetDir,
int flags, const struct utimbuf *timestamp,
void (*callback)(const char *fn, void*), void *cookie);
#endif /*_MINZIP_ZIP*/