/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#include "signtool.h"
#include "zip.h"
#include "zlib.h"
#include "prmem.h"

static void inttox(int in, char *out);
static void longtox(long in, char *out);

/****************************************************************
 *
 * J z i p O p e n
 *
 * Opens a new ZIP file and creates a new ZIPfile structure to
 * control the process of installing files into a zip.
 */
ZIPfile *
JzipOpen(char *filename, char *comment)
{
    ZIPfile *zipfile;
    PRExplodedTime prtime;

    zipfile = PORT_ZAlloc(sizeof(ZIPfile));
    if (!zipfile)
        out_of_memory();

    /* Construct time and date */
    PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters, &prtime);
    zipfile->date = ((prtime.tm_year - 1980) << 9) |
                    ((prtime.tm_month + 1) << 5) |
                    prtime.tm_mday;
    zipfile->time = (prtime.tm_hour << 11) |
                    (prtime.tm_min << 5) |
                    (prtime.tm_sec & 0x3f);

    zipfile->fp = NULL;
    if (filename &&
        (zipfile->fp = PR_Open(filename,
                               PR_WRONLY |
                                   PR_CREATE_FILE |
                                   PR_TRUNCATE,
                               0777)) == NULL) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "%s: can't open output jar, %s.%s\n",
                   PROGRAM_NAME,
                   filename, nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }

    zipfile->list = NULL;
    if (filename) {
        zipfile->filename = PORT_ZAlloc(strlen(filename) + 1);
        if (!zipfile->filename)
            out_of_memory();
        PORT_Strcpy(zipfile->filename, filename);
    }
    if (comment) {
        zipfile->comment = PORT_ZAlloc(strlen(comment) + 1);
        if (!zipfile->comment)
            out_of_memory();
        PORT_Strcpy(zipfile->comment, comment);
    }

    return zipfile;
}

static void *
my_alloc_func(void *opaque, uInt items, uInt size)
{
    return PORT_Alloc(items * size);
}

static void
my_free_func(void *opaque, void *address)
{
    PORT_Free(address);
}

static void
handle_zerror(int err, char *msg)
{
    if (!msg) {
        msg = "";
    }

    errorCount++; /* unless Z_OK...see below */

    switch (err) {
        case Z_OK:
            PR_fprintf(errorFD, "No error: %s\n", msg);
            errorCount--; /* this was incremented above */
            break;
        case Z_MEM_ERROR:
            PR_fprintf(errorFD, "Deflation ran out of memory: %s\n", msg);
            break;
        case Z_STREAM_ERROR:
            PR_fprintf(errorFD, "Invalid compression level: %s\n", msg);
            break;
        case Z_VERSION_ERROR:
            PR_fprintf(errorFD, "Incompatible compression library version: %s\n",
                       msg);
            break;
        case Z_DATA_ERROR:
            PR_fprintf(errorFD, "Compression data error: %s\n", msg);
            break;
        default:
            PR_fprintf(errorFD, "Unknown error in compression library: %s\n", msg);
            break;
    }
}

/****************************************************************
 *
 * J z i p A d d
 *
 * Adds a new file into a ZIP file.  The ZIP file must have already
 * been opened with JzipOpen.
 */
int
JzipAdd(char *fullname, char *filename, ZIPfile *zipfile, int lvl)
{
    ZIPentry *entry;
    PRFileDesc *readfp;
    PRFileDesc *zipfp;
    unsigned long crc;
    unsigned long local_size_pos;
    int num;
    int err;
    int deflate_percent;
    z_stream zstream;
    Bytef inbuf[BUFSIZ];
    Bytef outbuf[BUFSIZ];

    if (!fullname || !filename || !zipfile) {
        return -1;
    }

    zipfp = zipfile->fp;
    if (!zipfp)
        return -1;

    if ((readfp = PR_Open(fullname, PR_RDONLY, 0777)) == NULL) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "%s: %s\n", fullname, nsprErr ? nsprErr : "");
        errorCount++;
        if (nsprErr)
            PR_Free(nsprErr);
        exit(ERRX);
    }

    /*
     * Make sure the input file is not the output file.
     * Add a few bytes to the end of the JAR file and see if the input file
     * twitches
     */
    {
        PRInt32 endOfJar;
        PRInt32 inputSize;
        PRBool isSame;

        inputSize = PR_Available(readfp);

        endOfJar = PR_Seek(zipfp, 0L, PR_SEEK_CUR);

        if (PR_Write(zipfp, "abcde", 5) < 5) {
            char *nsprErr;

            if (PR_GetErrorTextLength()) {
                nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                PR_GetErrorText(nsprErr);
            } else {
                nsprErr = NULL;
            }
            PR_fprintf(errorFD, "Writing to zip file: %s\n",
                       nsprErr ? nsprErr : "");
            if (nsprErr)
                PR_Free(nsprErr);
            errorCount++;
            exit(ERRX);
        }

        isSame = (PR_Available(readfp) != inputSize);

        PR_Seek(zipfp, endOfJar, PR_SEEK_SET);

        if (isSame) {
            /* It's the same file! Forget it! */
            PR_Close(readfp);
            return 0;
        }
    }

    if (verbosity >= 0) {
        PR_fprintf(outputFD, "adding %s to %s...", fullname, zipfile->filename);
    }

    entry = PORT_ZAlloc(sizeof(ZIPentry));
    if (!entry)
        out_of_memory();

    entry->filename = PORT_Strdup(filename);
    entry->comment = NULL;

    /* Set up local file header */
    longtox(LSIG, entry->local.signature);
    inttox(strlen(filename), entry->local.filename_len);
    inttox(zipfile->time, entry->local.time);
    inttox(zipfile->date, entry->local.date);
    inttox(Z_DEFLATED, entry->local.method);

    /* Set up central directory entry */
    longtox(CSIG, entry->central.signature);
    inttox(strlen(filename), entry->central.filename_len);
    if (entry->comment) {
        inttox(strlen(entry->comment), entry->central.commentfield_len);
    }
    longtox(PR_Seek(zipfile->fp, 0, PR_SEEK_CUR),
            entry->central.localhdr_offset);
    inttox(zipfile->time, entry->central.time);
    inttox(zipfile->date, entry->central.date);
    inttox(Z_DEFLATED, entry->central.method);

    /* Compute crc.  Too bad we have to process the whole file to do this*/
    crc = crc32(0L, NULL, 0);
    while ((num = PR_Read(readfp, inbuf, BUFSIZ)) > 0) {
        crc = crc32(crc, inbuf, num);
    }
    PR_Seek(readfp, 0L, PR_SEEK_SET);

    /* Store CRC */
    longtox(crc, entry->local.crc32);
    longtox(crc, entry->central.crc32);

    /* Stick this entry onto the end of the list */
    entry->next = NULL;
    if (zipfile->list == NULL) {
        /* First entry */
        zipfile->list = entry;
    } else {
        ZIPentry *pe;

        pe = zipfile->list;
        while (pe->next != NULL) {
            pe = pe->next;
        }
        pe->next = entry;
    }

    /*
     * Start writing stuff out
     */

    local_size_pos = PR_Seek(zipfp, 0, PR_SEEK_CUR) + 18;
    /* File header */
    if (PR_Write(zipfp, &entry->local, sizeof(struct ZipLocal)) <
        sizeof(struct ZipLocal)) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }

    /* File Name */
    if (PR_Write(zipfp, filename, strlen(filename)) < strlen(filename)) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }

    /*
     * File data
     */
    /* Initialize zstream */
    zstream.zalloc = my_alloc_func;
    zstream.zfree = my_free_func;
    zstream.opaque = NULL;
    zstream.next_in = inbuf;
    zstream.avail_in = BUFSIZ;
    zstream.next_out = outbuf;
    zstream.avail_out = BUFSIZ;
    /* Setting the windowBits to -MAX_WBITS is an undocumented feature of
     * zlib (see deflate.c in zlib).  It is the same thing that Java does
     * when you specify the nowrap option for deflation in java.util.zip.
     * It causes zlib to leave out its headers and footers, which don't
     * work in PKZIP files.
     */
    err = deflateInit2(&zstream, lvl, Z_DEFLATED,
                       -MAX_WBITS, 8 /*default*/, Z_DEFAULT_STRATEGY);
    if (err != Z_OK) {
        handle_zerror(err, zstream.msg);
        exit(ERRX);
    }

    while ((zstream.avail_in = PR_Read(readfp, inbuf, BUFSIZ)) > 0) {
        zstream.next_in = inbuf;
        /* Process this chunk of data */
        while (zstream.avail_in > 0) {
            err = deflate(&zstream, Z_NO_FLUSH);
            if (err != Z_OK) {
                handle_zerror(err, zstream.msg);
                exit(ERRX);
            }
            if (zstream.avail_out <= 0) {
                if (PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) {
                    char *nsprErr;
                    if (PR_GetErrorTextLength()) {
                        nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                        PR_GetErrorText(nsprErr);
                    } else {
                        nsprErr = NULL;
                    }
                    PR_fprintf(errorFD, "Writing zip data: %s\n",
                               nsprErr ? nsprErr : "");
                    if (nsprErr)
                        PR_Free(nsprErr);
                    errorCount++;
                    exit(ERRX);
                }
                zstream.next_out = outbuf;
                zstream.avail_out = BUFSIZ;
            }
        }
    }

    /* Now flush everything */
    while (1) {
        err = deflate(&zstream, Z_FINISH);
        if (err == Z_STREAM_END) {
            break;
        } else if (err == Z_OK) {
            /* output buffer full, repeat */
        } else {
            handle_zerror(err, zstream.msg);
            exit(ERRX);
        }
        if (PR_Write(zipfp, outbuf, BUFSIZ) < BUFSIZ) {
            char *nsprErr;
            if (PR_GetErrorTextLength()) {
                nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                PR_GetErrorText(nsprErr);
            } else {
                nsprErr = NULL;
            }
            PR_fprintf(errorFD, "Writing zip data: %s\n",
                       nsprErr ? nsprErr : "");
            if (nsprErr)
                PR_Free(nsprErr);
            errorCount++;
            exit(ERRX);
        }
        zstream.avail_out = BUFSIZ;
        zstream.next_out = outbuf;
    }

    /* If there's any output left, write it out. */
    if (zstream.next_out != outbuf) {
        if (PR_Write(zipfp, outbuf, zstream.next_out - outbuf) <
            zstream.next_out - outbuf) {
            char *nsprErr;
            if (PR_GetErrorTextLength()) {
                nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                PR_GetErrorText(nsprErr);
            } else {
                nsprErr = NULL;
            }
            PR_fprintf(errorFD, "Writing zip data: %s\n",
                       nsprErr ? nsprErr : "");
            if (nsprErr)
                PR_Free(nsprErr);
            errorCount++;
            exit(ERRX);
        }
        zstream.avail_out = BUFSIZ;
        zstream.next_out = outbuf;
    }

    /* Now that we know the compressed size, write this to the headers */
    longtox(zstream.total_in, entry->local.orglen);
    longtox(zstream.total_out, entry->local.size);
    if (PR_Seek(zipfp, local_size_pos, PR_SEEK_SET) == -1) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "Accessing zip file: %s\n", nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }
    if (PR_Write(zipfp, entry->local.size, 8) != 8) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "Writing zip data: %s\n", nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }
    if (PR_Seek(zipfp, 0L, PR_SEEK_END) == -1) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "Accessing zip file: %s\n",
                   nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }
    longtox(zstream.total_in, entry->central.orglen);
    longtox(zstream.total_out, entry->central.size);

    /* Close out the deflation operation */
    err = deflateEnd(&zstream);
    if (err != Z_OK) {
        handle_zerror(err, zstream.msg);
        exit(ERRX);
    }

    PR_Close(readfp);

    if ((zstream.total_in > zstream.total_out) && (zstream.total_in > 0)) {
        deflate_percent = (int)((zstream.total_in -
                                 zstream.total_out) *
                                100 / zstream.total_in);
    } else {
        deflate_percent = 0;
    }
    if (verbosity >= 0) {
        PR_fprintf(outputFD, "(deflated %d%%)\n", deflate_percent);
    }

    return 0;
}

/********************************************************************
 * J z i p C l o s e
 *
 * Finishes the ZipFile. ALSO DELETES THE ZIPFILE STRUCTURE PASSED IN!!
 */
int
JzipClose(ZIPfile *zipfile)
{
    ZIPentry *pe, *dead;
    PRFileDesc *zipfp;
    struct ZipEnd zipend;
    unsigned int entrycount = 0;

    if (!zipfile) {
        return -1;
    }

    if (!zipfile->filename) {
        /* bogus */
        return 0;
    }

    zipfp = zipfile->fp;
    zipfile->central_start = PR_Seek(zipfp, 0L, PR_SEEK_CUR);

    /* Write out all the central directories */
    pe = zipfile->list;
    while (pe) {
        entrycount++;

        /* Write central directory info */
        if (PR_Write(zipfp, &pe->central, sizeof(struct ZipCentral)) <
            sizeof(struct ZipCentral)) {
            char *nsprErr;
            if (PR_GetErrorTextLength()) {
                nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                PR_GetErrorText(nsprErr);
            } else {
                nsprErr = NULL;
            }
            PR_fprintf(errorFD, "Writing zip data: %s\n",
                       nsprErr ? nsprErr : "");
            if (nsprErr)
                PR_Free(nsprErr);
            errorCount++;
            exit(ERRX);
        }

        /* Write filename */
        if (PR_Write(zipfp, pe->filename, strlen(pe->filename)) <
            strlen(pe->filename)) {
            char *nsprErr;
            if (PR_GetErrorTextLength()) {
                nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                PR_GetErrorText(nsprErr);
            } else {
                nsprErr = NULL;
            }
            PR_fprintf(errorFD, "Writing zip data: %s\n",
                       nsprErr ? nsprErr : "");
            if (nsprErr)
                PR_Free(nsprErr);
            errorCount++;
            exit(ERRX);
        }

        /* Write file comment */
        if (pe->comment) {
            if (PR_Write(zipfp, pe->comment, strlen(pe->comment)) <
                strlen(pe->comment)) {
                char *nsprErr;
                if (PR_GetErrorTextLength()) {
                    nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                    PR_GetErrorText(nsprErr);
                } else {
                    nsprErr = NULL;
                }
                PR_fprintf(errorFD, "Writing zip data: %s\n",
                           nsprErr ? nsprErr : "");
                if (nsprErr)
                    PR_Free(nsprErr);
                errorCount++;
                exit(ERRX);
            }
        }

        /* Delete the structure */
        dead = pe;
        pe = pe->next;
        if (dead->filename) {
            PORT_Free(dead->filename);
        }
        if (dead->comment) {
            PORT_Free(dead->comment);
        }
        PORT_Free(dead);
    }
    zipfile->central_end = PR_Seek(zipfile->fp, 0L, PR_SEEK_CUR);

    /* Create the ZipEnd structure */
    PORT_Memset(&zipend, 0, sizeof(zipend));
    longtox(ESIG, zipend.signature);
    inttox(entrycount, zipend.total_entries_disk);
    inttox(entrycount, zipend.total_entries_archive);
    longtox(zipfile->central_end - zipfile->central_start,
            zipend.central_dir_size);
    longtox(zipfile->central_start, zipend.offset_central_dir);
    if (zipfile->comment) {
        inttox(strlen(zipfile->comment), zipend.commentfield_len);
    }

    /* Write out ZipEnd xtructure */
    if (PR_Write(zipfp, &zipend, sizeof(zipend)) < sizeof(zipend)) {
        char *nsprErr;
        if (PR_GetErrorTextLength()) {
            nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
            PR_GetErrorText(nsprErr);
        } else {
            nsprErr = NULL;
        }
        PR_fprintf(errorFD, "Writing zip data: %s\n",
                   nsprErr ? nsprErr : "");
        if (nsprErr)
            PR_Free(nsprErr);
        errorCount++;
        exit(ERRX);
    }

    /* Write out Zipfile comment */
    if (zipfile->comment) {
        if (PR_Write(zipfp, zipfile->comment, strlen(zipfile->comment)) <
            strlen(zipfile->comment)) {
            char *nsprErr;
            if (PR_GetErrorTextLength()) {
                nsprErr = PR_Malloc(PR_GetErrorTextLength() + 1);
                PR_GetErrorText(nsprErr);
            } else {
                nsprErr = NULL;
            }
            PR_fprintf(errorFD, "Writing zip data: %s\n",
                       nsprErr ? nsprErr : "");
            if (nsprErr)
                PR_Free(nsprErr);
            errorCount++;
            exit(ERRX);
        }
    }

    PR_Close(zipfp);

    /* Free the memory of the zipfile structure */
    if (zipfile->filename) {
        PORT_Free(zipfile->filename);
    }
    if (zipfile->comment) {
        PORT_Free(zipfile->comment);
    }
    PORT_Free(zipfile);

    return 0;
}

/**********************************************
 *  i n t t o x
 *
 *  Converts a two byte ugly endianed integer
 *  to our platform's integer.
 *
 */

static void
inttox(int in, char *out)
{
    out[0] = (in & 0xFF);
    out[1] = (in & 0xFF00) >> 8;
}

/*********************************************
 *  l o n g t o x
 *
 *  Converts a four byte ugly endianed integer
 *  to our platform's integer.
 *
 */

static void
longtox(long in, char *out)
{
    out[0] = (in & 0xFF);
    out[1] = (in & 0xFF00) >> 8;
    out[2] = (in & 0xFF0000) >> 16;
    out[3] = (in & 0xFF000000) >> 24;
}
