/*
 * Copyright 2006 The Android Open Source Project
 *
 * Simple Zip file support.
 */
#include "safe_iop.h"
#include "zlib.h"

#include <errno.h>
#include <fcntl.h>
#include <limits.h>
#include <stdint.h>     // for uintptr_t
#include <stdlib.h>
#include <sys/stat.h>   // for S_ISLNK()
#include <unistd.h>

#include <string>

#include <android-base/logging.h>
#include <android-base/stringprintf.h>
#include <assert.h>
#include <selinux/label.h>
#include <selinux/selinux.h>

#include "Zip.h"
#include "Bits.h"
#include "DirUtil.h"

#define SORT_ENTRIES 1

/*
 * Offset and length constants (java.util.zip naming convention).
 */
enum {
    CENSIG = 0x02014b50,      // PK12
    CENHDR = 46,

    CENVEM =  4,
    CENVER =  6,
    CENFLG =  8,
    CENHOW = 10,
    CENTIM = 12,
    CENCRC = 16,
    CENSIZ = 20,
    CENLEN = 24,
    CENNAM = 28,
    CENEXT = 30,
    CENCOM = 32,
    CENDSK = 34,
    CENATT = 36,
    CENATX = 38,
    CENOFF = 42,

    ENDSIG = 0x06054b50,     // PK56
    ENDHDR = 22,

    ENDSUB =  8,
    ENDTOT = 10,
    ENDSIZ = 12,
    ENDOFF = 16,
    ENDCOM = 20,

    EXTSIG = 0x08074b50,     // PK78
    EXTHDR = 16,

    EXTCRC =  4,
    EXTSIZ =  8,
    EXTLEN = 12,

    LOCSIG = 0x04034b50,      // PK34
    LOCHDR = 30,

    LOCVER =  4,
    LOCFLG =  6,
    LOCHOW =  8,
    LOCTIM = 10,
    LOCCRC = 14,
    LOCSIZ = 18,
    LOCLEN = 22,
    LOCNAM = 26,
    LOCEXT = 28,

    STORED = 0,
    DEFLATED = 8,

    CENVEM_UNIX = 3 << 8,   // the high byte of CENVEM
};


/*
 * For debugging, dump the contents of a ZipEntry.
 */
#if 0
static void dumpEntry(const ZipEntry* pEntry)
{
    LOGI(" %p '%.*s'\n", pEntry->fileName,pEntry->fileNameLen,pEntry->fileName);
    LOGI("   off=%u comp=%u uncomp=%u how=%d\n", pEntry->offset,
        pEntry->compLen, pEntry->uncompLen, pEntry->compression);
}
#endif

/*
 * (This is a mzHashTableLookup callback.)
 *
 * Compare two ZipEntry structs, by name.
 */
static int hashcmpZipEntry(const void* ventry1, const void* ventry2)
{
    const ZipEntry* entry1 = (const ZipEntry*) ventry1;
    const ZipEntry* entry2 = (const ZipEntry*) ventry2;

    if (entry1->fileNameLen != entry2->fileNameLen)
        return entry1->fileNameLen - entry2->fileNameLen;
    return memcmp(entry1->fileName, entry2->fileName, entry1->fileNameLen);
}

/*
 * (This is a mzHashTableLookup callback.)
 *
 * find a ZipEntry struct by name.
 */
static int hashcmpZipName(const void* ventry, const void* vname)
{
    const ZipEntry* entry = (const ZipEntry*) ventry;
    const char* name = (const char*) vname;
    unsigned int nameLen = strlen(name);

    if (entry->fileNameLen != nameLen)
        return entry->fileNameLen - nameLen;
    return memcmp(entry->fileName, name, nameLen);
}

/*
 * Compute the hash code for a ZipEntry filename.
 *
 * Not expected to be compatible with any other hash function, so we init
 * to 2 to ensure it doesn't happen to match.
 */
static unsigned int computeHash(const char* name, int nameLen)
{
    unsigned int hash = 2;

    while (nameLen--)
        hash = hash * 31 + *name++;

    return hash;
}

static void addEntryToHashTable(HashTable* pHash, ZipEntry* pEntry)
{
    unsigned int itemHash = computeHash(pEntry->fileName, pEntry->fileNameLen);
    const ZipEntry* found;

    found = (const ZipEntry*)mzHashTableLookup(pHash,
                itemHash, pEntry, hashcmpZipEntry, true);
    if (found != pEntry) {
        LOG(WARNING) << "WARNING: duplicate entry '" << std::string(found->fileName,
                     found->fileNameLen) << "' in Zip";

        /* keep going */
    }
}

static int validFilename(const char *fileName, unsigned int fileNameLen)
{
    // Forbid super long filenames.
    if (fileNameLen >= PATH_MAX) {
        LOG(WARNING) << "Filename too long (" << fileNameLen << " chatacters)";
        return 0;
    }

    // Require all characters to be printable ASCII (no NUL, no UTF-8, etc).
    unsigned int i;
    for (i = 0; i < fileNameLen; ++i) {
        if (fileName[i] < 32 || fileName[i] >= 127) {
            LOG(WARNING) << android::base::StringPrintf(
                    "Filename contains invalid character '\%02x'\n", fileName[i]);
            return 0;
        }
    }

    return 1;
}

/*
 * Parse the contents of a Zip archive.  After confirming that the file
 * is in fact a Zip, we scan out the contents of the central directory and
 * store it in a hash table.
 *
 * Returns "true" on success.
 */
static bool parseZipArchive(ZipArchive* pArchive)
{
    bool result = false;
    const unsigned char* ptr;
    unsigned int i, numEntries, cdOffset;
    unsigned int val;

    /*
     * The first 4 bytes of the file will either be the local header
     * signature for the first file (LOCSIG) or, if the archive doesn't
     * have any files in it, the end-of-central-directory signature (ENDSIG).
     */
    val = get4LE(pArchive->addr);
    if (val == ENDSIG) {
        LOG(WARNING) << "Found Zip archive, but it looks empty";
        goto bail;
    } else if (val != LOCSIG) {
        LOG(WARNING) << android::base::StringPrintf("Not a Zip archive (found 0x%08x)\n", val);
        goto bail;
    }

    /*
     * Find the EOCD.  We'll find it immediately unless they have a file
     * comment.
     */
    ptr = pArchive->addr + pArchive->length - ENDHDR;

    while (ptr >= (const unsigned char*) pArchive->addr) {
        if (*ptr == (ENDSIG & 0xff) && get4LE(ptr) == ENDSIG)
            break;
        ptr--;
    }
    if (ptr < (const unsigned char*) pArchive->addr) {
        LOG(WARNING) << "Could not find end-of-central-directory in Zip";
        goto bail;
    }

    /*
     * There are two interesting items in the EOCD block: the number of
     * entries in the file, and the file offset of the start of the
     * central directory.
     */
    numEntries = get2LE(ptr + ENDSUB);
    cdOffset = get4LE(ptr + ENDOFF);

    LOG(VERBOSE) << "numEntries=" << numEntries << " cdOffset=" << cdOffset;
    if (numEntries == 0 || cdOffset >= pArchive->length) {
        LOG(WARNING) << "Invalid entries=" << numEntries << " offset=" << cdOffset
                     << " (len=" << pArchive->length << ")";
        goto bail;
    }

    /*
     * Create data structures to hold entries.
     */
    pArchive->numEntries = numEntries;
    pArchive->pEntries = (ZipEntry*) calloc(numEntries, sizeof(ZipEntry));
    pArchive->pHash = mzHashTableCreate(mzHashSize(numEntries), NULL);
    if (pArchive->pEntries == NULL || pArchive->pHash == NULL)
        goto bail;

    ptr = pArchive->addr + cdOffset;
    for (i = 0; i < numEntries; i++) {
        ZipEntry* pEntry;
        unsigned int fileNameLen, extraLen, commentLen, localHdrOffset;
        const unsigned char* localHdr;
        const char *fileName;

        if (ptr + CENHDR > (const unsigned char*)pArchive->addr + pArchive->length) {
            LOG(WARNING) << "Ran off the end (at " << i << ")";
            goto bail;
        }
        if (get4LE(ptr) != CENSIG) {
            LOG(WARNING) << "Missed a central dir sig (at " << i << ")";
            goto bail;
        }

        localHdrOffset = get4LE(ptr + CENOFF);
        fileNameLen = get2LE(ptr + CENNAM);
        extraLen = get2LE(ptr + CENEXT);
        commentLen = get2LE(ptr + CENCOM);
        fileName = (const char*)ptr + CENHDR;
        if (fileName + fileNameLen > (const char*)pArchive->addr + pArchive->length) {
            LOG(WARNING) << "Filename ran off the end (at " << i << ")";
            goto bail;
        }
        if (!validFilename(fileName, fileNameLen)) {
            LOG(WARNING) << "Invalid filename (at " << i << ")";
            goto bail;
        }

#if SORT_ENTRIES
        /* Figure out where this entry should go (binary search).
         */
        if (i > 0) {
            int low, high;

            low = 0;
            high = i - 1;
            while (low <= high) {
                int mid;
                int diff;
                int diffLen;

                mid = low + ((high - low) / 2); // avoid overflow

                if (pArchive->pEntries[mid].fileNameLen < fileNameLen) {
                    diffLen = pArchive->pEntries[mid].fileNameLen;
                } else {
                    diffLen = fileNameLen;
                }
                diff = strncmp(pArchive->pEntries[mid].fileName, fileName,
                        diffLen);
                if (diff == 0) {
                    diff = pArchive->pEntries[mid].fileNameLen - fileNameLen;
                }
                if (diff < 0) {
                    low = mid + 1;
                } else if (diff > 0) {
                    high = mid - 1;
                } else {
                    high = mid;
                    break;
                }
            }

            unsigned int target = high + 1;
            assert(target <= i);
            if (target != i) {
                /* It belongs somewhere other than at the end of
                 * the list.  Make some room at [target].
                 */
                memmove(pArchive->pEntries + target + 1,
                        pArchive->pEntries + target,
                        (i - target) * sizeof(ZipEntry));
            }
            pEntry = &pArchive->pEntries[target];
        } else {
            pEntry = &pArchive->pEntries[0];
        }
#else
        pEntry = &pArchive->pEntries[i];
#endif
        pEntry->fileNameLen = fileNameLen;
        pEntry->fileName = fileName;

        pEntry->compLen = get4LE(ptr + CENSIZ);
        pEntry->uncompLen = get4LE(ptr + CENLEN);
        pEntry->compression = get2LE(ptr + CENHOW);
        pEntry->modTime = get4LE(ptr + CENTIM);
        pEntry->crc32 = get4LE(ptr + CENCRC);

        /* These two are necessary for finding the mode of the file.
         */
        pEntry->versionMadeBy = get2LE(ptr + CENVEM);
        if ((pEntry->versionMadeBy & 0xff00) != 0 &&
                (pEntry->versionMadeBy & 0xff00) != CENVEM_UNIX)
        {
            LOG(WARNING) << android::base::StringPrintf(
                    "Incompatible \"version made by\": 0x%02x (at %d)\n",
                    pEntry->versionMadeBy >> 8, i);
            goto bail;
        }
        pEntry->externalFileAttributes = get4LE(ptr + CENATX);

        // Perform pArchive->addr + localHdrOffset, ensuring that it won't
        // overflow. This is needed because localHdrOffset is untrusted.
        if (!safe_add((uintptr_t *)&localHdr, (uintptr_t)pArchive->addr,
            (uintptr_t)localHdrOffset)) {
            LOG(WARNING) << "Integer overflow adding in parseZipArchive";
            goto bail;
        }
        if ((uintptr_t)localHdr + LOCHDR >
            (uintptr_t)pArchive->addr + pArchive->length) {
            LOG(WARNING) << "Bad offset to local header: " << localHdrOffset
                         << " (at " << i << ")";
            goto bail;
        }
        if (get4LE(localHdr) != LOCSIG) {
            LOG(WARNING) << "Missed a local header sig (at " << i << ")";
            goto bail;
        }
        pEntry->offset = localHdrOffset + LOCHDR
            + get2LE(localHdr + LOCNAM) + get2LE(localHdr + LOCEXT);
        if (!safe_add(NULL, pEntry->offset, pEntry->compLen)) {
            LOG(WARNING) << "Integer overflow adding in parseZipArchive";
            goto bail;
        }
        if ((size_t)pEntry->offset + pEntry->compLen > pArchive->length) {
            LOG(WARNING) << "Data ran off the end (at " << i << ")";
            goto bail;
        }

#if !SORT_ENTRIES
        /* Add to hash table; no need to lock here.
         * Can't do this now if we're sorting, because entries
         * will move around.
         */
        addEntryToHashTable(pArchive->pHash, pEntry);
#endif

        //dumpEntry(pEntry);
        ptr += CENHDR + fileNameLen + extraLen + commentLen;
    }

#if SORT_ENTRIES
    /* If we're sorting, we have to wait until all entries
     * are in their final places, otherwise the pointers will
     * probably point to the wrong things.
     */
    for (i = 0; i < numEntries; i++) {
        /* Add to hash table; no need to lock here.
         */
        addEntryToHashTable(pArchive->pHash, &pArchive->pEntries[i]);
    }
#endif

    result = true;

bail:
    if (!result) {
        mzHashTableFree(pArchive->pHash);
        pArchive->pHash = NULL;
    }
    return result;
}

/*
 * Open a Zip archive and scan out the contents.
 *
 * The easiest way to do this is to mmap() the whole thing and do the
 * traditional backward scan for central directory.  Since the EOCD is
 * a relatively small bit at the end, we should end up only touching a
 * small set of pages.
 *
 * This will be called on non-Zip files, especially during startup, so
 * we don't want to be too noisy about failures.  (Do we want a "quiet"
 * flag?)
 *
 * On success, we fill out the contents of "pArchive".
 */
int mzOpenZipArchive(unsigned char* addr, size_t length, ZipArchive* pArchive)
{
    int err;

    if (length < ENDHDR) {
        err = -1;
        LOG(WARNING) << "Archive " << pArchive << " is too small to be zip ("
                     << length << ")";
        goto bail;
    }

    pArchive->addr = addr;
    pArchive->length = length;

    if (!parseZipArchive(pArchive)) {
        err = -1;
        LOG(WARNING) << "Parsing archive " << pArchive << " failed";
        goto bail;
    }

    err = 0;

bail:
    if (err != 0)
        mzCloseZipArchive(pArchive);
    return err;
}

/*
 * Close a ZipArchive, closing the file and freeing the contents.
 *
 * NOTE: the ZipArchive may not have been fully created.
 */
void mzCloseZipArchive(ZipArchive* pArchive)
{
    LOG(VERBOSE) << "Closing archive " << pArchive;

    free(pArchive->pEntries);

    mzHashTableFree(pArchive->pHash);

    pArchive->pHash = NULL;
    pArchive->pEntries = NULL;
}

/*
 * Find a matching entry.
 *
 * Returns NULL if no matching entry found.
 */
const ZipEntry* mzFindZipEntry(const ZipArchive* pArchive,
        const char* entryName)
{
    unsigned int itemHash = computeHash(entryName, strlen(entryName));

    return (const ZipEntry*)mzHashTableLookup(pArchive->pHash,
                itemHash, (char*) entryName, hashcmpZipName, false);
}

/*
 * Return true if the entry is a symbolic link.
 */
static bool mzIsZipEntrySymlink(const ZipEntry* pEntry)
{
    if ((pEntry->versionMadeBy & 0xff00) == CENVEM_UNIX) {
        return S_ISLNK(pEntry->externalFileAttributes >> 16);
    }
    return false;
}

/* Call processFunction on the uncompressed data of a STORED entry.
 */
static bool processStoredEntry(const ZipArchive *pArchive,
    const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
    void *cookie)
{
    return processFunction(pArchive->addr + pEntry->offset, pEntry->uncompLen, cookie);
}

static bool processDeflatedEntry(const ZipArchive *pArchive,
    const ZipEntry *pEntry, ProcessZipEntryContentsFunction processFunction,
    void *cookie)
{
    bool success = false;
    unsigned long totalOut = 0;
    unsigned char procBuf[32 * 1024];
    z_stream zstream;
    int zerr;

    /*
     * Initialize the zlib stream.
     */
    memset(&zstream, 0, sizeof(zstream));
    zstream.zalloc = Z_NULL;
    zstream.zfree = Z_NULL;
    zstream.opaque = Z_NULL;
    zstream.next_in = pArchive->addr + pEntry->offset;
    zstream.avail_in = pEntry->compLen;
    zstream.next_out = (Bytef*) procBuf;
    zstream.avail_out = sizeof(procBuf);
    zstream.data_type = Z_UNKNOWN;

    /*
     * Use the undocumented "negative window bits" feature to tell zlib
     * that there's no zlib header waiting for it.
     */
    zerr = inflateInit2(&zstream, -MAX_WBITS);
    if (zerr != Z_OK) {
        if (zerr == Z_VERSION_ERROR) {
            LOG(ERROR) << "Installed zlib is not compatible with linked version ("
                       << ZLIB_VERSION << ")";
        } else {
            LOG(ERROR) << "Call to inflateInit2 failed (zerr=" << zerr << ")";
        }
        goto bail;
    }

    /*
     * Loop while we have data.
     */
    do {
        /* uncompress the data */
        zerr = inflate(&zstream, Z_NO_FLUSH);
        if (zerr != Z_OK && zerr != Z_STREAM_END) {
            LOG(WARNING) << "zlib inflate call failed (zerr=" << zerr << ")";
            goto z_bail;
        }

        /* write when we're full or when we're done */
        if (zstream.avail_out == 0 ||
            (zerr == Z_STREAM_END && zstream.avail_out != sizeof(procBuf)))
        {
            long procSize = zstream.next_out - procBuf;
            LOG(VERBOSE) << "+++ processing " << procSize << " bytes";
            bool ret = processFunction(procBuf, procSize, cookie);
            if (!ret) {
                LOG(WARNING) << "Process function elected to fail (in inflate)";
                goto z_bail;
            }

            zstream.next_out = procBuf;
            zstream.avail_out = sizeof(procBuf);
        }
    } while (zerr == Z_OK);

    assert(zerr == Z_STREAM_END);       /* other errors should've been caught */

    // success!
    totalOut = zstream.total_out;
    success = true;

z_bail:
    inflateEnd(&zstream);        /* free up any allocated structures */

bail:
    if (totalOut != pEntry->uncompLen) {
        if (success) {       // error already shown?
            LOG(WARNING) << "Size mismatch on inflated file (" << totalOut << " vs "
                         << pEntry->uncompLen << ")";
        }
        return false;
    }
    return true;
}

/*
 * 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)
{
    bool ret = false;

    switch (pEntry->compression) {
    case STORED:
        ret = processStoredEntry(pArchive, pEntry, processFunction, cookie);
        break;
    case DEFLATED:
        ret = processDeflatedEntry(pArchive, pEntry, processFunction, cookie);
        break;
    default:
        LOG(ERROR) << "Unsupported compression type " << pEntry->compression
                   << " for entry '" << pEntry->fileName << "'";
        break;
    }

    return ret;
}

typedef struct {
    char *buf;
    int bufLen;
} CopyProcessArgs;

static bool copyProcessFunction(const unsigned char *data, int dataLen,
        void *cookie)
{
    CopyProcessArgs *args = (CopyProcessArgs *)cookie;
    if (dataLen <= args->bufLen) {
        memcpy(args->buf, data, dataLen);
        args->buf += dataLen;
        args->bufLen -= dataLen;
        return true;
    }
    return false;
}

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

    args.buf = buf;
    args.bufLen = bufLen;
    ret = mzProcessZipEntryContents(pArchive, pEntry, copyProcessFunction,
            (void *)&args);
    if (!ret) {
        LOG(ERROR) << "Can't extract entry to buffer";
        return false;
    }
    return true;
}

static bool writeProcessFunction(const unsigned char *data, int dataLen,
                                 void *cookie)
{
    int fd = (int)(intptr_t)cookie;
    if (dataLen == 0) {
        return true;
    }
    ssize_t soFar = 0;
    while (true) {
        ssize_t n = TEMP_FAILURE_RETRY(write(fd, data+soFar, dataLen-soFar));
        if (n <= 0) {
            PLOG(ERROR) << "Error writing " << dataLen-soFar << " bytes from zip file from "
                        << data+soFar;
            return false;
        } else if (n > 0) {
            soFar += n;
            if (soFar == dataLen) return true;
            if (soFar > dataLen) {
                LOG(ERROR) << "write overrun?  (" << soFar << " bytes instead of "
                           << dataLen << ")";
                return false;
            }
        }
    }
}

/*
 * Uncompress "pEntry" in "pArchive" to "fd" at the current offset.
 */
bool mzExtractZipEntryToFile(const ZipArchive *pArchive,
    const ZipEntry *pEntry, int fd)
{
    bool ret = mzProcessZipEntryContents(pArchive, pEntry, writeProcessFunction,
                                         (void*)(intptr_t)fd);
    if (!ret) {
        LOG(ERROR) << "Can't extract entry to file.";
        return false;
    }
    return true;
}

typedef struct {
    unsigned char* buffer;
    long len;
} BufferExtractCookie;

static bool bufferProcessFunction(const unsigned char *data, int dataLen,
    void *cookie) {
    BufferExtractCookie *bec = (BufferExtractCookie*)cookie;

    memmove(bec->buffer, data, dataLen);
    bec->buffer += dataLen;
    bec->len -= dataLen;

    return true;
}

/*
 * Uncompress "pEntry" in "pArchive" to buffer, which must be large
 * enough to hold mzGetZipEntryUncomplen(pEntry) bytes.
 */
bool mzExtractZipEntryToBuffer(const ZipArchive *pArchive,
    const ZipEntry *pEntry, unsigned char *buffer)
{
    BufferExtractCookie bec;
    bec.buffer = buffer;
    bec.len = mzGetZipEntryUncompLen(pEntry);

    bool ret = mzProcessZipEntryContents(pArchive, pEntry,
        bufferProcessFunction, (void*)&bec);
    if (!ret || bec.len != 0) {
        LOG(ERROR) << "Can't extract entry to memory buffer.";
        return false;
    }
    return true;
}


/* Helper state to make path translation easier and less malloc-happy.
 */
typedef struct {
    const char *targetDir;
    const char *zipDir;
    char *buf;
    int targetDirLen;
    int zipDirLen;
    int bufLen;
} MzPathHelper;

/* Given the values of targetDir and zipDir in the helper,
 * return the target filename of the provided entry.
 * The helper must be initialized first.
 */
static const char *targetEntryPath(MzPathHelper *helper, ZipEntry *pEntry)
{
    int needLen;
    bool firstTime = (helper->buf == NULL);

    /* target file <-- targetDir + / + entry[zipDirLen:]
     */
    needLen = helper->targetDirLen + 1 +
            pEntry->fileNameLen - helper->zipDirLen + 1;
    if (firstTime || needLen > helper->bufLen) {
        char *newBuf;

        needLen *= 2;
        newBuf = (char *)realloc(helper->buf, needLen);
        if (newBuf == NULL) {
            return NULL;
        }
        helper->buf = newBuf;
        helper->bufLen = needLen;
    }

    /* Every path will start with the target path and a slash.
     */
    if (firstTime) {
        char *p = helper->buf;
        memcpy(p, helper->targetDir, helper->targetDirLen);
        p += helper->targetDirLen;
        if (p == helper->buf || p[-1] != '/') {
            helper->targetDirLen += 1;
            *p++ = '/';
        }
    }

    /* Replace the custom part of the path with the appropriate
     * part of the entry's path.
     */
    char *epath = helper->buf + helper->targetDirLen;
    memcpy(epath, pEntry->fileName + helper->zipDirLen,
            pEntry->fileNameLen - helper->zipDirLen);
    epath += pEntry->fileNameLen - helper->zipDirLen;
    *epath = '\0';

    return helper->buf;
}

/*
 * 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
 *
 * 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)
{
    if (zipDir[0] == '/') {
        LOG(ERROR) << "mzExtractRecursive(): zipDir must be a relative path.";
        return false;
    }
    if (targetDir[0] != '/') {
        LOG(ERROR) << "mzExtractRecursive(): targetDir must be an absolute path.\n";
        return false;
    }

    unsigned int zipDirLen;
    char *zpath;

    zipDirLen = strlen(zipDir);
    zpath = (char *)malloc(zipDirLen + 2);
    if (zpath == NULL) {
        LOG(ERROR) << "Can't allocate " << (zipDirLen + 2) << " bytes for zip path";
        return false;
    }
    /* If zipDir is empty, we'll extract the entire zip file.
     * Otherwise, canonicalize the path.
     */
    if (zipDirLen > 0) {
        /* Make sure there's (hopefully, exactly one) slash at the
         * end of the path.  This way we don't need to worry about
         * accidentally extracting "one/twothree" when a path like
         * "one/two" is specified.
         */
        memcpy(zpath, zipDir, zipDirLen);
        if (zpath[zipDirLen-1] != '/') {
            zpath[zipDirLen++] = '/';
        }
    }
    zpath[zipDirLen] = '\0';

    /* Set up the helper structure that we'll use to assemble paths.
     */
    MzPathHelper helper;
    helper.targetDir = targetDir;
    helper.targetDirLen = strlen(helper.targetDir);
    helper.zipDir = zpath;
    helper.zipDirLen = strlen(helper.zipDir);
    helper.buf = NULL;
    helper.bufLen = 0;

    /* Walk through the entries and extract anything whose path begins
     * with zpath.
    //TODO: since the entries are sorted, binary search for the first match
    //      and stop after the first non-match.
     */
    unsigned int i;
    bool seenMatch = false;
    int ok = true;
    int extractCount = 0;
    for (i = 0; i < pArchive->numEntries; i++) {
        ZipEntry *pEntry = pArchive->pEntries + i;
        if (pEntry->fileNameLen < zipDirLen) {
       //TODO: look out for a single empty directory entry that matches zpath, but
       //      missing the trailing slash.  Most zip files seem to include
       //      the trailing slash, but I think it's legal to leave it off.
       //      e.g., zpath "a/b/", entry "a/b", with no children of the entry.
            /* No chance of matching.
             */
#if SORT_ENTRIES
            if (seenMatch) {
                /* Since the entries are sorted, we can give up
                 * on the first mismatch after the first match.
                 */
                break;
            }
#endif
            continue;
        }
        /* If zpath is empty, this strncmp() will match everything,
         * which is what we want.
         */
        if (strncmp(pEntry->fileName, zpath, zipDirLen) != 0) {
#if SORT_ENTRIES
            if (seenMatch) {
                /* Since the entries are sorted, we can give up
                 * on the first mismatch after the first match.
                 */
                break;
            }
#endif
            continue;
        }
        /* This entry begins with zipDir, so we'll extract it.
         */
        seenMatch = true;

        /* Find the target location of the entry.
         */
        const char *targetFile = targetEntryPath(&helper, pEntry);
        if (targetFile == NULL) {
            LOG(ERROR) << "Can't assemble target path for \"" << std::string(pEntry->fileName,
                       pEntry->fileNameLen) << "\"";
            ok = false;
            break;
        }

#define UNZIP_DIRMODE 0755
#define UNZIP_FILEMODE 0644
        /*
         * Create the file or directory. We ignore directory entries
         * because we recursively create paths to each file entry we encounter
         * in the zip archive anyway.
         *
         * NOTE: A "directory entry" in a zip archive is just a zero length
         * entry that ends in a "/". They're not mandatory and many tools get
         * rid of them. We need to process them only if we want to preserve
         * empty directories from the archive.
         */
        if (pEntry->fileName[pEntry->fileNameLen-1] != '/') {
            /* This is not a directory.  First, make sure that
             * the containing directory exists.
             */
            int ret = dirCreateHierarchy(
                    targetFile, UNZIP_DIRMODE, timestamp, true, sehnd);
            if (ret != 0) {
                PLOG(ERROR) << "Can't create containing directory for \"" << targetFile << "\"";
                ok = false;
                break;
            }

            /*
             * The entry is a regular file or a symlink. Open the target for writing.
             *
             * TODO: This behavior for symlinks seems rather bizarre. For a
             * symlink foo/bar/baz -> foo/tar/taz, we will create a file called
             * "foo/bar/baz" whose contents are the literal "foo/tar/taz". We
             * warn about this for now and preserve older behavior.
             */
            if (mzIsZipEntrySymlink(pEntry)) {
                LOG(ERROR) << "Symlink entry \"" << std::string(pEntry->fileName,
                           pEntry->fileNameLen) << "\" will be output as a regular file.";
            }

            char *secontext = NULL;

            if (sehnd) {
                selabel_lookup(sehnd, &secontext, targetFile, UNZIP_FILEMODE);
                setfscreatecon(secontext);
            }

            int fd = open(targetFile, O_CREAT|O_WRONLY|O_TRUNC,
                UNZIP_FILEMODE);

            if (secontext) {
                freecon(secontext);
                setfscreatecon(NULL);
            }

            if (fd < 0) {
                PLOG(ERROR) << "Can't create target file \"" << targetFile << "\"";
                ok = false;
                break;
            }

            bool ok = mzExtractZipEntryToFile(pArchive, pEntry, fd);
            if (ok) {
                ok = (fsync(fd) == 0);
            }
            if (close(fd) != 0) {
                ok = false;
            }
            if (!ok) {
                LOG(ERROR) << "Error extracting \"" << targetFile << "\"";
                ok = false;
                break;
            }

            if (timestamp != NULL && utime(targetFile, timestamp)) {
                LOG(ERROR) << "Error touching \"" << targetFile << "\"";
                ok = false;
                break;
            }

            LOG(VERBOSE) <<"Extracted file \"" << targetFile << "\"";
            ++extractCount;
        }

        if (callback != NULL) callback(targetFile, cookie);
    }

    LOG(VERBOSE) << "Extracted " << extractCount << " file(s)";

    free(helper.buf);
    free(zpath);

    return ok;
}
