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