188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Copyright (C) 2008 The Android Open Source Project
388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *
488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License");
588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * you may not use this file except in compliance with the License.
688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * You may obtain a copy of the License at
788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *
888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *      http://www.apache.org/licenses/LICENSE-2.0
988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project *
1088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Unless required by applicable law or agreed to in writing, software
1188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS,
1288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * See the License for the specific language governing permissions and
1488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * limitations under the License.
1588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
1695ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden
1788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
1888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Zip alignment tool
1988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#include "ZipFile.h"
2188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project#include <stdio.h>
23404fd5bc4abc48ec7e0ef4f769846876b21db803Mark Salyzyn#include <stdlib.h>
24404fd5bc4abc48ec7e0ef4f769846876b21db803Mark Salyzyn#include <unistd.h>
2588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectusing namespace android;
2788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
2988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Show program usage.
3088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
3188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectvoid usage(void)
3288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{
3388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    fprintf(stderr, "Zip alignment utility\n");
3495ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden    fprintf(stderr, "Copyright (C) 2009 The Android Open Source Project\n\n");
3588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    fprintf(stderr,
3613e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov        "Usage: zipalign [-f] [-p] [-v] [-z] <align> infile.zip outfile.zip\n"
3701d6b59dcf72767885c4e8a878a99bb4ecef77a0Alex Klyubin        "       zipalign -c [-p] [-v] <align> infile.zip\n\n" );
3895ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden    fprintf(stderr,
3995ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden        "  <align>: alignment in bytes, e.g. '4' provides 32-bit alignment\n");
4095ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden    fprintf(stderr, "  -c: check alignment only (does not modify file)\n");
4195ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden    fprintf(stderr, "  -f: overwrite existing outfile.zip\n");
4201d6b59dcf72767885c4e8a878a99bb4ecef77a0Alex Klyubin    fprintf(stderr, "  -p: memory page alignment for stored shared object files\n");
4395ed76bd3e044f3812ddf42a26cb718879dd143cAndy McFadden    fprintf(stderr, "  -v: verbose output\n");
44093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien    fprintf(stderr, "  -z: recompress using Zopfli\n");
4588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project}
4688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
4713e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanovstatic int getAlignment(bool pageAlignSharedLibs, int defaultAlignment,
4813e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    ZipEntry* pEntry) {
4913e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov
50e0b8d19f3159edbeecb7eea4b3d18ffeca3dd33dNarayan Kamath    static const int kPageAlignment = 4096;
51e0b8d19f3159edbeecb7eea4b3d18ffeca3dd33dNarayan Kamath
5213e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    if (!pageAlignSharedLibs) {
5313e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov        return defaultAlignment;
5413e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    }
5513e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov
5613e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    const char* ext = strrchr(pEntry->getFileName(), '.');
5713e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    if (ext && strcmp(ext, ".so") == 0) {
5813e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov        return kPageAlignment;
5913e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    }
6013e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov
6113e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    return defaultAlignment;
6213e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov}
6313e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov
6488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
6588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Copy all entries from "pZin" to "pZout", aligning as needed.
6688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
6713e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanovstatic int copyAndAlign(ZipFile* pZin, ZipFile* pZout, int alignment, bool zopfli,
68b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen    bool pageAlignSharedLibs)
6988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{
7088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    int numEntries = pZin->getNumEntries();
7188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    ZipEntry* pEntry;
7288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    int bias = 0;
7388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    status_t status;
7488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
7588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    for (int i = 0; i < numEntries; i++) {
7688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        ZipEntry* pNewEntry;
7788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        int padding = 0;
7888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
7988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        pEntry = pZin->getEntryByIndex(i);
8088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        if (pEntry == NULL) {
8188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            fprintf(stderr, "ERROR: unable to retrieve entry %d\n", i);
8288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            return 1;
8388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        }
8488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
8588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        if (pEntry->isCompressed()) {
8688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            /* copy the entry without padding */
8788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            //printf("--- %s: orig at %ld len=%ld (compressed)\n",
8888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
8988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            //    (long) pEntry->getUncompressedLen());
9088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
91093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien            if (zopfli) {
92b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen                status = pZout->addRecompress(pZin, pEntry, &pNewEntry);
93093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien                bias += pNewEntry->getCompressedLen() - pEntry->getCompressedLen();
94093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien            } else {
95b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen                status = pZout->add(pZin, pEntry, padding, &pNewEntry);
96093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien            }
9788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        } else {
9813e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov            const int alignTo = getAlignment(pageAlignSharedLibs, alignment, pEntry);
9913e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov
10088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            /*
10188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project             * Copy the entry, adjusting as required.  We assume that the
10288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project             * file position in the new file will be equal to the file
10388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project             * position in the original.
10488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project             */
10588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            long newOffset = pEntry->getFileOffset() + bias;
10613e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov            padding = (alignTo - (newOffset % alignTo)) % alignTo;
10788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
10888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            //printf("--- %s: orig at %ld(+%d) len=%ld, adding pad=%d\n",
10988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            //    pEntry->getFileName(), (long) pEntry->getFileOffset(),
11088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            //    bias, (long) pEntry->getUncompressedLen(), padding);
111b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen            status = pZout->add(pZin, pEntry, padding, &pNewEntry);
11288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        }
11388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
11488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        if (status != NO_ERROR)
11588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            return 1;
11688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        bias += padding;
11788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        //printf(" added '%s' at %ld (pad=%d)\n",
11888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        //    pNewEntry->getFileName(), (long) pNewEntry->getFileOffset(),
11988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        //    padding);
12088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
12188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
12288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    return 0;
12388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project}
12488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
12588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
12688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Process a file.  We open the input and output files, failing if the
12788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * output file exists and "force" wasn't specified.
12888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
12988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectstatic int process(const char* inFileName, const char* outFileName,
130b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen    int alignment, bool force, bool zopfli, bool pageAlignSharedLibs)
13188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{
13288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    ZipFile zin, zout;
13388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
13488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    //printf("PROCESS: align=%d in='%s' out='%s' force=%d\n",
13588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    //    alignment, inFileName, outFileName, force);
13688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
13788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    /* this mode isn't supported -- do a trivial check */
13888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (strcmp(inFileName, outFileName) == 0) {
13988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        fprintf(stderr, "Input and output can't be same file\n");
14088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        return 1;
14188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
14288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
14388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    /* don't overwrite existing unless given permission */
14488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (!force && access(outFileName, F_OK) == 0) {
14588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        fprintf(stderr, "Output file '%s' exists\n", outFileName);
14688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        return 1;
14788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
14888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
14988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (zin.open(inFileName, ZipFile::kOpenReadOnly) != NO_ERROR) {
15088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        fprintf(stderr, "Unable to open '%s' as zip archive\n", inFileName);
15188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        return 1;
15288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
15388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (zout.open(outFileName,
15488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            ZipFile::kOpenReadWrite|ZipFile::kOpenCreate|ZipFile::kOpenTruncate)
15588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        != NO_ERROR)
15688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    {
157303213915dc15d3136c5410d2eeea10f5555d3bbJingwen Owen Ou        fprintf(stderr, "Unable to open '%s' as zip archive\n", outFileName);
15888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        return 1;
15988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
16088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
161b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen    int result = copyAndAlign(&zin, &zout, alignment, zopfli, pageAlignSharedLibs);
16288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (result != 0) {
16388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        printf("zipalign: failed rewriting '%s' to '%s'\n",
16488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            inFileName, outFileName);
16588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
16688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    return result;
16788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project}
16888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
16988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
17088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Verify the alignment of a zip archive.
17188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
17213e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanovstatic int verify(const char* fileName, int alignment, bool verbose,
17313e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    bool pageAlignSharedLibs)
17488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{
17588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    ZipFile zipFile;
17688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    bool foundBad = false;
17788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
17888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (verbose)
17988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        printf("Verifying alignment of %s (%d)...\n", fileName, alignment);
18088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
18188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (zipFile.open(fileName, ZipFile::kOpenReadOnly) != NO_ERROR) {
18288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        fprintf(stderr, "Unable to open '%s' for verification\n", fileName);
18388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        return 1;
18488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
18588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
18688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    int numEntries = zipFile.getNumEntries();
18788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    ZipEntry* pEntry;
18888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
18988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    for (int i = 0; i < numEntries; i++) {
19088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        pEntry = zipFile.getEntryByIndex(i);
19188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        if (pEntry->isCompressed()) {
19288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            if (verbose) {
1933f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker                printf("%8ld %s (OK - compressed)\n",
19488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                    (long) pEntry->getFileOffset(), pEntry->getFileName());
19588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            }
19688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        } else {
19788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            long offset = pEntry->getFileOffset();
19813e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov            const int alignTo = getAlignment(pageAlignSharedLibs, alignment, pEntry);
19913e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov            if ((offset % alignTo) != 0) {
20088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                if (verbose) {
2013f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker                    printf("%8ld %s (BAD - %ld)\n",
20288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                        (long) offset, pEntry->getFileName(),
20313e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov                        offset % alignTo);
20488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                }
20588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                foundBad = true;
20688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            } else {
20788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                if (verbose) {
20888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                    printf("%8ld %s (OK)\n",
20988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                        (long) offset, pEntry->getFileName());
21088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                }
21188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            }
21288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        }
21388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
21488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
21588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (verbose)
21688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        printf("Verification %s\n", foundBad ? "FAILED" : "succesful");
21788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
21888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    return foundBad ? 1 : 0;
21988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project}
22088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
22188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project/*
22288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project * Parse args.
22388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project */
22488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectint main(int argc, char* const argv[])
22588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project{
22688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    bool wantUsage = false;
2273f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker    bool check = false;
22888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    bool force = false;
22988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    bool verbose = false;
230093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien    bool zopfli = false;
23113e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov    bool pageAlignSharedLibs = false;
23288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    int result = 1;
23388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    int alignment;
23488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    char* endp;
23588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
23688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (argc < 4) {
23788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        wantUsage = true;
23888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        goto bail;
23988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
24088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
24188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    argc--;
24288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    argv++;
24388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
24488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    while (argc && argv[0][0] == '-') {
24588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        const char* cp = argv[0] +1;
24688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
24788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        while (*cp != '\0') {
24888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            switch (*cp) {
2493f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker            case 'c':
2503f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker                check = true;
2513f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker                break;
25288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            case 'f':
25388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                force = true;
25488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                break;
25588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            case 'v':
25688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                verbose = true;
25788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                break;
258093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien            case 'z':
259093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien                zopfli = true;
260093d04c631aa2a4af3317912e9561672c5642bb8Raph Levien                break;
26113e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov            case 'p':
26213e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov                pageAlignSharedLibs = true;
26313e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov                break;
26488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            default:
26588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                fprintf(stderr, "ERROR: unknown flag -%c\n", *cp);
26688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                wantUsage = true;
26788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project                goto bail;
26888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            }
26988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
27088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project            cp++;
27188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        }
27288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
27388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        argc--;
27488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        argv++;
27588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
27688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2773f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker    if (!((check && argc == 2) || (!check && argc == 3))) {
27888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        wantUsage = true;
27988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        goto bail;
28088b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
28188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
28288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    alignment = strtol(argv[0], &endp, 10);
28388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (*endp != '\0' || alignment <= 0) {
28488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        fprintf(stderr, "Invalid value for alignment: %s\n", argv[0]);
28588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        wantUsage = true;
28688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        goto bail;
28788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
28888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2893f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker    if (check) {
2903f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker        /* check existing archive for correct alignment */
29113e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov        result = verify(argv[1], alignment, verbose, pageAlignSharedLibs);
2923f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker    } else {
2933f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker        /* create the new archive */
294b589ae4e2661d42cbdc0a44193e2df384424e483Dan Willemsen        result = process(argv[1], argv[2], alignment, force, zopfli, pageAlignSharedLibs);
29588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
2963f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker        /* trust, but verify */
29713e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov        if (result == 0) {
29813e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov            result = verify(argv[2], alignment, verbose, pageAlignSharedLibs);
29913e5965306212a9051772ff1d5bc3a88e5fb519aDmitriy Ivanov        }
3003f2933b2091e388a4d5e9c09b0d69ffe691cf674Doug Zongker    }
30188b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
30288b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Projectbail:
30388b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    if (wantUsage) {
30488b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        usage();
30588b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project        result = 2;
30688b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    }
30788b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project
30888b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project    return result;
30988b607994a148f4af5bffee163e39ce8296750c6The Android Open Source Project}
310