19066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 29066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copyright (C) 2006 The Android Open Source Project 39066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 49066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Licensed under the Apache License, Version 2.0 (the "License"); 59066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * you may not use this file except in compliance with the License. 69066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * You may obtain a copy of the License at 79066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 89066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * http://www.apache.org/licenses/LICENSE-2.0 99066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Unless required by applicable law or agreed to in writing, software 119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * distributed under the License is distributed on an "AS IS" BASIS, 129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See the License for the specific language governing permissions and 149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * limitations under the License. 159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// Access to entries in a Zip archive. 199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project// 209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#define LOG_TAG "zip" 229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2355e3d60da5626752ffe1d15150d35ccb8fa644e7Mathias Agopian#include "ZipEntry.h" 248ae2335a3c93d0c00e998fdec18f64dfe43b94cbMathias Agopian#include <utils/Log.h> 259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <stdio.h> 279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <string.h> 289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#include <assert.h> 299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectusing namespace android; 319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initialize a new ZipEntry structure from a FILE* positioned at a 349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * CentralDirectoryEntry. 359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On exit, the file pointer will be at the start of the next CDE or 379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * at the EOCD. 389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::initFromCDE(FILE* fp) 409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result; 429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project long posn; 439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project bool hasDD; 449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block //ALOGV("initFromCDE ---\n"); 469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* read the CDE */ 489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = mCDE.read(fp); 499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 505baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("mCDE.read failed\n"); 519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //mCDE.dump(); 559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* using the info in the CDE, go load up the LFH */ 579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project posn = ftell(fp); 589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { 595baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("local header seek failed (%ld)\n", 609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mLocalHeaderRelOffset); 619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = mLFH.read(fp); 659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (result != NO_ERROR) { 665baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("mLFH.read failed\n"); 679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fseek(fp, posn, SEEK_SET) != 0) 719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project //mLFH.dump(); 749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * We *might* need to read the Data Descriptor at this point and 779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * integrate it into the LFH. If this bit is set, the CRC-32, 789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * compressed size, and uncompressed size will be zero. In practice 799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * these seem to be rare. 809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0; 829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (hasDD) { 839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // do something clever 845baa3a62a97544669fba6d65a11c07f252e654ddSteve Block //ALOGD("+++ has data descriptor\n"); 859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Sanity-check the LFH. Note that this will fail if the "kUsesDataDescr" 899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * flag is set, because the LFH is incomplete. (Not a problem, since we 909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * prefer the CDE values.) 919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (!hasDD && !compareHeaders()) { 938564c8da817a845353d213acd8636b76f567b234Steve Block ALOGW("warning: header mismatch\n"); 949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // keep going? 959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * If the mVersionToExtract is greater than 20, we may have an 999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * issue unpacking the record -- could be encrypted, compressed 1009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * with something we don't support, or use Zip64 extensions. We 1019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * can defer worrying about that to when we're extracting data. 1029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initialize a new entry. Pass in the file name and an optional comment. 1099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initializes the CDE and the LFH. 1119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ZipEntry::initNew(const char* fileName, const char* comment) 1139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(fileName != NULL && *fileName != '\0'); // name required 1159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* most fields are properly initialized by constructor */ 1179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mVersionMadeBy = kDefaultMadeBy; 1189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mVersionToExtract = kDefaultVersion; 1199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mCompressionMethod = kCompressStored; 1209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mFileNameLength = strlen(fileName); 1219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (comment != NULL) 1229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mFileCommentLength = strlen(comment); 1239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mExternalAttrs = 0x81b60020; // matches what WinZip does 1249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileNameLength > 0) { 1269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1]; 1279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char*) mCDE.mFileName, fileName); 1289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileCommentLength > 0) { 1309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* TODO: stop assuming null-terminated ASCII here? */ 1319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1]; 1329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char*) mCDE.mFileComment, comment); 1339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copyCDEtoLFH(); 1369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initialize a new entry, starting with the ZipEntry from a different 1409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * archive. 1419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 1429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Initializes the CDE and the LFH. 1439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::initFromExternal(const ZipFile* pZipFile, 1459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project const ZipEntry* pEntry) 1469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 1479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Copy everything in the CDE over, then fix up the hairy bits. 1499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE)); 1519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileNameLength > 0) { 1539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1]; 1549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileName == NULL) 1559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 1569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName); 1579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileCommentLength > 0) { 1599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1]; 1609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileComment == NULL) 1619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 1629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment); 1639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mExtraFieldLength > 0) { 1659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* we null-terminate this, though it may not be a string */ 1669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1]; 1679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mExtraField == NULL) 1689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 1699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField, 1709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mExtraFieldLength+1); 1719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* construct the LFH from the CDE */ 1749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copyCDEtoLFH(); 1759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* 1779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * The LFH "extra" field is independent of the CDE "extra", so we 1789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * handle it here. 1799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mLFH.mExtraField == NULL); 1819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength; 1829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLFH.mExtraFieldLength > 0) { 1839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1]; 1849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLFH.mExtraField == NULL) 1859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 1869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField, 1879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraFieldLength+1); 1889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 1899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 1919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 1929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 1939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 1949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Insert pad bytes in the LFH by tweaking the "extra" field. This will 1959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * potentially confuse something that put "extra" data in here earlier, 1969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * but I can't find an actual problem. 1979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 1989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::addPadding(int padding) 1999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (padding <= 0) 2019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return INVALID_OPERATION; 2029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2036215d3ff4b5dfa52a5d8b9a42e343051f31066a5Steve Block //ALOGI("HEY: adding %d pad bytes to existing %d in %s\n", 2049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // padding, mLFH.mExtraFieldLength, mCDE.mFileName); 2059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLFH.mExtraFieldLength > 0) { 2079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* extend existing field */ 2089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char* newExtra; 2099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project newExtra = new unsigned char[mLFH.mExtraFieldLength + padding]; 2119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (newExtra == NULL) 2129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_MEMORY; 2139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(newExtra + mLFH.mExtraFieldLength, 0, padding); 2149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength); 2159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mLFH.mExtraField; 2179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraField = newExtra; 2189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraFieldLength += padding; 2199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* create new field */ 2219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraField = new unsigned char[padding]; 2229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project memset(mLFH.mExtraField, 0, padding); 2239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mExtraFieldLength = padding; 2249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 2279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the fields in the LFH equal to the corresponding fields in the CDE. 2319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * This does not touch the LFH "extra" field. 2339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ZipEntry::copyCDEtoLFH(void) 2359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mVersionToExtract = mCDE.mVersionToExtract; 2379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mGPBitFlag = mCDE.mGPBitFlag; 2389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mCompressionMethod = mCDE.mCompressionMethod; 2399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mLastModFileTime = mCDE.mLastModFileTime; 2409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mLastModFileDate = mCDE.mLastModFileDate; 2419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mCRC32 = mCDE.mCRC32; 2429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mCompressedSize = mCDE.mCompressedSize; 2439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mUncompressedSize = mCDE.mUncompressedSize; 2449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mFileNameLength = mCDE.mFileNameLength; 2459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // the "extra field" is independent 2469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project delete[] mLFH.mFileName; 2489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mLFH.mFileNameLength > 0) { 2499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1]; 2509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName); 2519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } else { 2529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLFH.mFileName = NULL; 2539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set some information about a file after we add it. 2589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32, 2609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int compressionMethod) 2619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mCompressionMethod = compressionMethod; 2639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mCRC32 = crc32; 2649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mCompressedSize = compLen; 2659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mUncompressedSize = uncompLen; 2669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mCompressionMethod = compressionMethod; 2679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (compressionMethod == kCompressDeflated) { 2689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mGPBitFlag |= 0x0002; // indicates maximum compression used 2699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project copyCDEtoLFH(); 2719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 2729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 2739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 2749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * See if the data in mCDE and mLFH match up. This is mostly useful for 2759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * debugging these classes, but it can be used to identify damaged 2769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * archives. 2779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 2789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Returns "false" if they differ. 2799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 2809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbool ZipEntry::compareHeaders(void) const 2819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 2829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) { 28371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: VersionToExtract\n"); 2849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) { 28771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: GPBitFlag\n"); 2889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) { 29171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: CompressionMethod\n"); 2929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) { 29571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: LastModFileTime\n"); 2969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 2979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 2989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) { 29971f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: LastModFileDate\n"); 3009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mCRC32 != mLFH.mCRC32) { 30371f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: CRC32\n"); 3049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mCompressedSize != mLFH.mCompressedSize) { 30771f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: CompressedSize\n"); 3089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) { 31171f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: UncompressedSize\n"); 3129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileNameLength != mLFH.mFileNameLength) { 31571f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: FileNameLength\n"); 3169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#if 0 // this seems to be used for padding, not real data 3199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) { 32071f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: ExtraFieldLength\n"); 3219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mCDE.mFileName != NULL) { 3259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) { 32671f2cf116aab893e224056c38ab146bd1538dd3eSteve Block ALOGV("cmp: FileName\n"); 3279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return false; 3289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 3309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return true; 3329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Convert the DOS date/time stamp into a UNIX time stamp. 3379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projecttime_t ZipEntry::getModWhen(void) const 3399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct tm parts; 3419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1; 3439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5; 3449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11; 3459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_mday = (mCDE.mLastModFileDate & 0x001f); 3469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1; 3479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80; 3489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_wday = parts.tm_yday = 0; 3499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project parts.tm_isdst = -1; // DST info "not available" 3509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return mktime(&parts); 3529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Set the CDE/LFH timestamp from UNIX time. 3569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ZipEntry::setModWhen(time_t when) 3589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 3599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_LOCALTIME_R 3609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct tm tmResult; 3619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project time_t even; 3639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned short zdate, ztime; 3649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project struct tm* ptm; 3669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* round up to an even number of seconds */ 3689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project even = (time_t)(((unsigned long)(when) + 1) & (~1)); 3699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* expand */ 3719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#ifdef HAVE_LOCALTIME_R 3729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ptm = localtime_r(&even, &tmResult); 3739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#else 3749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ptm = localtime(&even); 3759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project#endif 3769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project int year; 3789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project year = ptm->tm_year; 3799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (year < 80) 3809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project year = 80; 3819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday; 3839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1; 3849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime; 3869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate; 3879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 3889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 3929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ZipEntry::LocalFileHeader 3939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 3949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 3959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 3969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 3979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read a local file header. 3989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 3999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On entry, "fp" points to the signature at the start of the header. 4009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On exit, "fp" points to the start of data. 4019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::LocalFileHeader::read(FILE* fp) 4039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = NO_ERROR; 4059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char buf[kLFHLen]; 4069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFileName == NULL); 4089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mExtraField == NULL); 4099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(buf, 1, kLFHLen, fp) != kLFHLen) { 4119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 4129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) { 4165baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("whoops: didn't find expected signature\n"); 4179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 4189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]); 4229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]); 4239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]); 4249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]); 4259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]); 4269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCRC32 = ZipEntry::getLongLE(&buf[0x0e]); 4279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedSize = ZipEntry::getLongLE(&buf[0x12]); 4289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]); 4299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]); 4309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]); 4319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: validate sizes 4339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* grab filename */ 4359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileNameLength != 0) { 4369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileName = new unsigned char[mFileNameLength+1]; 4379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileName == NULL) { 4389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_MEMORY; 4399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) { 4429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 4439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileName[mFileNameLength] = '\0'; 4469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* grab extra field */ 4499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExtraFieldLength != 0) { 4509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExtraField = new unsigned char[mExtraFieldLength+1]; 4519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExtraField == NULL) { 4529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_MEMORY; 4539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) { 4569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 4579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 4589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExtraField[mExtraFieldLength] = '\0'; 4609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 4639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 4649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 4659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 4679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Write a local file header. 4689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 4699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::LocalFileHeader::write(FILE* fp) 4709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 4719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char buf[kLFHLen]; 4729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x00], kSignature); 4749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x04], mVersionToExtract); 4759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x06], mGPBitFlag); 4769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x08], mCompressionMethod); 4779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime); 4789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate); 4799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x0e], mCRC32); 4809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x12], mCompressedSize); 4819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x16], mUncompressedSize); 4829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x1a], mFileNameLength); 4839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength); 4849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen) 4869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 4879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* write filename */ 4899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileNameLength != 0) { 4909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength) 4919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 4929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 4949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* write "extra field" */ 4959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExtraFieldLength != 0) { 4969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) 4979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 4989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 4999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 5019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Dump the contents of a LocalFileHeader object. 5069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ZipEntry::LocalFileHeader::dump(void) const 5089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5095baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" LocalFileHeader contents:\n"); 5105baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" versToExt=%u gpBits=0x%04x compression=%u\n", 5119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVersionToExtract, mGPBitFlag, mCompressionMethod); 5125baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n", 5139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastModFileTime, mLastModFileDate, mCRC32); 5145baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" compressedSize=%lu uncompressedSize=%lu\n", 5159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedSize, mUncompressedSize); 5165baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" filenameLen=%u extraLen=%u\n", 5179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileNameLength, mExtraFieldLength); 5189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileName != NULL) 5195baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" filename: '%s'\n", mFileName); 5209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 5219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 5259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * ZipEntry::CentralDirEntry 5269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * =========================================================================== 5279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 5309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Read the central dir entry that appears next in the file. 5319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * 5329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * On entry, "fp" should be positioned on the signature bytes for the 5339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * entry. On exit, "fp" will point at the signature word for the next 5349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * entry or for the EOCD. 5359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 5369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::CentralDirEntry::read(FILE* fp) 5379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 5389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project status_t result = NO_ERROR; 5399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char buf[kCDELen]; 5409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* no re-use */ 5429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFileName == NULL); 5439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mExtraField == NULL); 5449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project assert(mFileComment == NULL); 5459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(buf, 1, kCDELen, fp) != kCDELen) { 5479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 5489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) { 5525baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD("Whoops: didn't find expected signature\n"); 5539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 5549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]); 5589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]); 5599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]); 5609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]); 5619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]); 5629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]); 5639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCRC32 = ZipEntry::getLongLE(&buf[0x10]); 5649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedSize = ZipEntry::getLongLE(&buf[0x14]); 5659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]); 5669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]); 5679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]); 5689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]); 5699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]); 5709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]); 5719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]); 5729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]); 5739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project // TODO: validate sizes and offsets 5759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* grab filename */ 5779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileNameLength != 0) { 5789066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileName = new unsigned char[mFileNameLength+1]; 5799066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileName == NULL) { 5809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_MEMORY; 5819066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5839066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) { 5849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 5859066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5879066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileName[mFileNameLength] = '\0'; 5889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 5909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* read "extra field" */ 5919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExtraFieldLength != 0) { 5929066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExtraField = new unsigned char[mExtraFieldLength+1]; 5939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExtraField == NULL) { 5949066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_MEMORY; 5959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 5969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 5979066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) { 5989066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 5999066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 6009066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6019066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mExtraField[mExtraFieldLength] = '\0'; 6029066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6039066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6049066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6059066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* grab comment, if any */ 6069066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileCommentLength != 0) { 6079066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileComment = new unsigned char[mFileCommentLength+1]; 6089066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileComment == NULL) { 6099066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = NO_MEMORY; 6109066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 6119066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6129066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength) 6139066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project { 6149066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project result = UNKNOWN_ERROR; 6159066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project goto bail; 6169066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6179066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileComment[mFileCommentLength] = '\0'; 6189066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6199066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6209066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectbail: 6219066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return result; 6229066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6239066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6249066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6259066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Write a central dir entry. 6269066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6279066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectstatus_t ZipEntry::CentralDirEntry::write(FILE* fp) 6289066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6299066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project unsigned char buf[kCDELen]; 6309066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6319066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x00], kSignature); 6329066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy); 6339066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x06], mVersionToExtract); 6349066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x08], mGPBitFlag); 6359066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod); 6369066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime); 6379066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate); 6389066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x10], mCRC32); 6399066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x14], mCompressedSize); 6409066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x18], mUncompressedSize); 6419066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x1c], mFileNameLength); 6429066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength); 6439066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x20], mFileCommentLength); 6449066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart); 6459066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putShortLE(&buf[0x24], mInternalAttrs); 6469066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x26], mExternalAttrs); 6479066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset); 6489066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6499066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(buf, 1, kCDELen, fp) != kCDELen) 6509066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 6519066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6529066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* write filename */ 6539066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileNameLength != 0) { 6549066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength) 6559066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 6569066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6579066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6589066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* write "extra field" */ 6599066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mExtraFieldLength != 0) { 6609066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) 6619066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 6629066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6639066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6649066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project /* write comment */ 6659066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileCommentLength != 0) { 6669066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength) 6679066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return UNKNOWN_ERROR; 6689066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project } 6699066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6709066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project return NO_ERROR; 6719066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6729066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6739066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project/* 6749066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project * Dump the contents of a CentralDirEntry object. 6759066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project */ 6769066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Projectvoid ZipEntry::CentralDirEntry::dump(void) const 6779066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project{ 6785baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" CentralDirEntry contents:\n"); 6795baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n", 6809066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod); 6815baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n", 6829066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLastModFileTime, mLastModFileDate, mCRC32); 6835baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" compressedSize=%lu uncompressedSize=%lu\n", 6849066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mCompressedSize, mUncompressedSize); 6855baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" filenameLen=%u extraLen=%u commentLen=%u\n", 6869066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mFileNameLength, mExtraFieldLength, mFileCommentLength); 6875baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n", 6889066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mDiskNumberStart, mInternalAttrs, mExternalAttrs, 6899066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project mLocalHeaderRelOffset); 6909066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 6919066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileName != NULL) 6925baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" filename: '%s'\n", mFileName); 6939066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project if (mFileComment != NULL) 6945baa3a62a97544669fba6d65a11c07f252e654ddSteve Block ALOGD(" comment: '%s'\n", mFileComment); 6959066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project} 6969066cfe9886ac131c34d59ed0e2d287b0e3c0087The Android Open Source Project 697