13344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 23344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Copyright (C) 2006 The Android Open Source Project 33344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 43344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Licensed under the Apache License, Version 2.0 (the "License"); 53344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * you may not use this file except in compliance with the License. 63344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * You may obtain a copy of the License at 73344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 83344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * http://www.apache.org/licenses/LICENSE-2.0 93344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 103344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Unless required by applicable law or agreed to in writing, software 113344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * distributed under the License is distributed on an "AS IS" BASIS, 123344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * See the License for the specific language governing permissions and 143344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * limitations under the License. 153344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 163344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian// 183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian// Access to entries in a Zip archive. 193344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian// 203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#define LOG_TAG "zip" 223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#include "ZipEntry.h" 243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#include <utils/Log.h> 253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 263344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#include <stdio.h> 273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#include <string.h> 283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#include <assert.h> 293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianusing namespace android; 313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Initialize a new ZipEntry structure from a FILE* positioned at a 343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * CentralDirectoryEntry. 353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * On exit, the file pointer will be at the start of the next CDE or 373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * at the EOCD. 383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::initFromCDE(FILE* fp) 403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian status_t result; 423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian long posn; 433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian bool hasDD; 443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 452da72c6265bab1322876fa9702f7580bff7fd8beSteve Block //ALOGV("initFromCDE ---\n"); 463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* read the CDE */ 483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = mCDE.read(fp); 493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (result != NO_ERROR) { 5015fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD("mCDE.read failed\n"); 513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return result; 523344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian //mCDE.dump(); 553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* using the info in the CDE, go load up the LFH */ 573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian posn = ftell(fp); 583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { 5915fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD("local header seek failed (%ld)\n", 603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mLocalHeaderRelOffset); 613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = mLFH.read(fp); 653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (result != NO_ERROR) { 6615fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD("mLFH.read failed\n"); 673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return result; 683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fseek(fp, posn, SEEK_SET) != 0) 713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian //mLFH.dump(); 743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* 763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * We *might* need to read the Data Descriptor at this point and 773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * integrate it into the LFH. If this bit is set, the CRC-32, 783344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * compressed size, and uncompressed size will be zero. In practice 793344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * these seem to be rare. 803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 813344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0; 823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (hasDD) { 833344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian // do something clever 8415fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block //ALOGD("+++ has data descriptor\n"); 853344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 873344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* 883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Sanity-check the LFH. Note that this will fail if the "kUsesDataDescr" 893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * flag is set, because the LFH is incomplete. (Not a problem, since we 903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * prefer the CDE values.) 913344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 923344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (!hasDD && !compareHeaders()) { 93c0b74df335aa99e3c3f6f752de531836faa0c7c5Steve Block ALOGW("WARNING: header mismatch\n"); 943344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian // keep going? 953344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 973344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* 983344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * If the mVersionToExtract is greater than 20, we may have an 993344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * issue unpacking the record -- could be encrypted, compressed 1003344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * with something we don't support, or use Zip64 extensions. We 1013344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * can defer worrying about that to when we're extracting data. 1023344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 1033344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1043344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_ERROR; 1053344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 1063344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1073344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 1083344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Initialize a new entry. Pass in the file name and an optional comment. 1093344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 1103344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Initializes the CDE and the LFH. 1113344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 1123344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianvoid ZipEntry::initNew(const char* fileName, const char* comment) 1133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 1143344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(fileName != NULL && *fileName != '\0'); // name required 1153344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1163344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* most fields are properly initialized by constructor */ 1173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mVersionMadeBy = kDefaultMadeBy; 1183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mVersionToExtract = kDefaultVersion; 1193344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mCompressionMethod = kCompressStored; 1203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mFileNameLength = strlen(fileName); 1213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (comment != NULL) 1223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mFileCommentLength = strlen(comment); 1233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mExternalAttrs = 0x81b60020; // matches what WinZip does 1243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileNameLength > 0) { 1263344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1]; 1273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian strcpy((char*) mCDE.mFileName, fileName); 1283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 1293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileCommentLength > 0) { 1303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* TODO: stop assuming null-terminated ASCII here? */ 1313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1]; 1323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian strcpy((char*) mCDE.mFileComment, comment); 1333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 1343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian copyCDEtoLFH(); 1363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 1373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 1393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Initialize a new entry, starting with the ZipEntry from a different 1403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * archive. 1413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 1423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Initializes the CDE and the LFH. 1433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 1443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::initFromExternal(const ZipFile* pZipFile, 1453344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian const ZipEntry* pEntry) 1463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 1473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* 1483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Copy everything in the CDE over, then fix up the hairy bits. 1493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 1503344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE)); 1513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1523344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileNameLength > 0) { 1533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1]; 1543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileName == NULL) 1553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_MEMORY; 1563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName); 1573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 1583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileCommentLength > 0) { 1593344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1]; 1603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileComment == NULL) 1613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_MEMORY; 1623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment); 1633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 1643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mExtraFieldLength > 0) { 1653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* we null-terminate this, though it may not be a string */ 1663344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1]; 1673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mExtraField == NULL) 1683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_MEMORY; 1693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField, 1703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mExtraFieldLength+1); 1713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 1723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* construct the LFH from the CDE */ 1743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian copyCDEtoLFH(); 1753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* 1773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * The LFH "extra" field is independent of the CDE "extra", so we 1783344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * handle it here. 1793344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 1803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(mLFH.mExtraField == NULL); 1813344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength; 1823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mLFH.mExtraFieldLength > 0) { 1833344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1]; 1843344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mLFH.mExtraField == NULL) 1853344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_MEMORY; 1863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField, 1873344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraFieldLength+1); 1883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 1893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_ERROR; 1913344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 1923344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 1933344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 1943344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Insert pad bytes in the LFH by tweaking the "extra" field. This will 1953344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * potentially confuse something that put "extra" data in here earlier, 1963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * but I can't find an actual problem. 1973344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 1983344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::addPadding(int padding) 1993344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 2003344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (padding <= 0) 2013344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return INVALID_OPERATION; 2023344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 203934443b2751691adc9b06026d79f50efe9365ce1Steve Block //ALOGI("HEY: adding %d pad bytes to existing %d in %s\n", 2043344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian // padding, mLFH.mExtraFieldLength, mCDE.mFileName); 2053344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2063344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mLFH.mExtraFieldLength > 0) { 2073344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* extend existing field */ 2083344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian unsigned char* newExtra; 2093344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2103344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian newExtra = new unsigned char[mLFH.mExtraFieldLength + padding]; 2113344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (newExtra == NULL) 2123344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_MEMORY; 2133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian memset(newExtra + mLFH.mExtraFieldLength, 0, padding); 2143344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength); 2153344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2163344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian delete[] mLFH.mExtraField; 2173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraField = newExtra; 2183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraFieldLength += padding; 2193344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } else { 2203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* create new field */ 2213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraField = new unsigned char[padding]; 2223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian memset(mLFH.mExtraField, 0, padding); 2233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mExtraFieldLength = padding; 2243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2263344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_ERROR; 2273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 2283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 2303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Set the fields in the LFH equal to the corresponding fields in the CDE. 2313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 2323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * This does not touch the LFH "extra" field. 2333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 2343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianvoid ZipEntry::copyCDEtoLFH(void) 2353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 2363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mVersionToExtract = mCDE.mVersionToExtract; 2373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mGPBitFlag = mCDE.mGPBitFlag; 2383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mCompressionMethod = mCDE.mCompressionMethod; 2393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mLastModFileTime = mCDE.mLastModFileTime; 2403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mLastModFileDate = mCDE.mLastModFileDate; 2413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mCRC32 = mCDE.mCRC32; 2423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mCompressedSize = mCDE.mCompressedSize; 2433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mUncompressedSize = mCDE.mUncompressedSize; 2443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mFileNameLength = mCDE.mFileNameLength; 2453344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian // the "extra field" is independent 2463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian delete[] mLFH.mFileName; 2483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mLFH.mFileNameLength > 0) { 2493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1]; 2503344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName); 2513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } else { 2523344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLFH.mFileName = NULL; 2533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 2553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 2573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Set some information about a file after we add it. 2583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 2593344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianvoid ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32, 2603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian int compressionMethod) 2613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 2623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mCompressionMethod = compressionMethod; 2633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mCRC32 = crc32; 2643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mCompressedSize = compLen; 2653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mUncompressedSize = uncompLen; 2663344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mCompressionMethod = compressionMethod; 2673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (compressionMethod == kCompressDeflated) { 2683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mGPBitFlag |= 0x0002; // indicates maximum compression used 2693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian copyCDEtoLFH(); 2713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 2723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 2733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 2743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * See if the data in mCDE and mLFH match up. This is mostly useful for 2753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * debugging these classes, but it can be used to identify damaged 2763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * archives. 2773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 2783344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Returns "false" if they differ. 2793344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 2803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianbool ZipEntry::compareHeaders(void) const 2813344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 2823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) { 2832da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: VersionToExtract\n"); 2843344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 2853344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) { 2872da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: GPBitFlag\n"); 2883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 2893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) { 2912da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: CompressionMethod\n"); 2923344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 2933344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2943344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) { 2952da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: LastModFileTime\n"); 2963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 2973344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 2983344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) { 2992da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: LastModFileDate\n"); 3003344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3013344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3023344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mCRC32 != mLFH.mCRC32) { 3032da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: CRC32\n"); 3043344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3053344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3063344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mCompressedSize != mLFH.mCompressedSize) { 3072da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: CompressedSize\n"); 3083344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3093344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3103344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) { 3112da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: UncompressedSize\n"); 3123344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3143344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileNameLength != mLFH.mFileNameLength) { 3152da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: FileNameLength\n"); 3163344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#if 0 // this seems to be used for padding, not real data 3193344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) { 3202da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: ExtraFieldLength\n"); 3213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#endif 3243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mCDE.mFileName != NULL) { 3253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) { 3262da72c6265bab1322876fa9702f7580bff7fd8beSteve Block ALOGV("cmp: FileName\n"); 3273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return false; 3283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 3303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return true; 3323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 3333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 3363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Convert the DOS date/time stamp into a UNIX time stamp. 3373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 3383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopiantime_t ZipEntry::getModWhen(void) const 3393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 3403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian struct tm parts; 3413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1; 3433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5; 3443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11; 3453344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_mday = (mCDE.mLastModFileDate & 0x001f); 3463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1; 3473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80; 3483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_wday = parts.tm_yday = 0; 3493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian parts.tm_isdst = -1; // DST info "not available" 3503344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return mktime(&parts); 3523344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 3533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 3553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Set the CDE/LFH timestamp from UNIX time. 3563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 3573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianvoid ZipEntry::setModWhen(time_t when) 3583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 3593344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#ifdef HAVE_LOCALTIME_R 3603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian struct tm tmResult; 3613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#endif 3623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian time_t even; 3633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian unsigned short zdate, ztime; 3643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian struct tm* ptm; 3663344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* round up to an even number of seconds */ 3683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian even = (time_t)(((unsigned long)(when) + 1) & (~1)); 3693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* expand */ 3713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#ifdef HAVE_LOCALTIME_R 3723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ptm = localtime_r(&even, &tmResult); 3733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#else 3743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ptm = localtime(&even); 3753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian#endif 3763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian int year; 3783344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian year = ptm->tm_year; 3793344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (year < 80) 3803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian year = 80; 3813344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday; 3833344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1; 3843344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3853344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime; 3863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate; 3873344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 3883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 3913344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * =========================================================================== 3923344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * ZipEntry::LocalFileHeader 3933344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * =========================================================================== 3943344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 3953344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 3963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 3973344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Read a local file header. 3983344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 3993344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * On entry, "fp" points to the signature at the start of the header. 4003344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * On exit, "fp" points to the start of data. 4013344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 4023344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::LocalFileHeader::read(FILE* fp) 4033344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 4043344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian status_t result = NO_ERROR; 4053344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian unsigned char buf[kLFHLen]; 4063344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4073344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(mFileName == NULL); 4083344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(mExtraField == NULL); 4093344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4103344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(buf, 1, kLFHLen, fp) != kLFHLen) { 4113344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 4123344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 4133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4143344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4153344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) { 41615fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD("whoops: didn't find expected signature\n"); 4173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 4183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 4193344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]); 4223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]); 4233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]); 4243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]); 4253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]); 4263344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCRC32 = ZipEntry::getLongLE(&buf[0x0e]); 4273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCompressedSize = ZipEntry::getLongLE(&buf[0x12]); 4283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]); 4293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]); 4303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]); 4313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian // TODO: validate sizes 4333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* grab filename */ 4353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileNameLength != 0) { 4363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileName = new unsigned char[mFileNameLength+1]; 4373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileName == NULL) { 4383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = NO_MEMORY; 4393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 4403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) { 4423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 4433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 4443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4453344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileName[mFileNameLength] = '\0'; 4463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* grab extra field */ 4493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mExtraFieldLength != 0) { 4503344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExtraField = new unsigned char[mExtraFieldLength+1]; 4513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mExtraField == NULL) { 4523344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = NO_MEMORY; 4533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 4543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) { 4563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 4573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 4583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4593344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExtraField[mExtraFieldLength] = '\0'; 4603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianbail: 4633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return result; 4643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 4653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4663344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 4673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Write a local file header. 4683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 4693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::LocalFileHeader::write(FILE* fp) 4703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 4713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian unsigned char buf[kLFHLen]; 4723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x00], kSignature); 4743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x04], mVersionToExtract); 4753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x06], mGPBitFlag); 4763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x08], mCompressionMethod); 4773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime); 4783344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate); 4793344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x0e], mCRC32); 4803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x12], mCompressedSize); 4813344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x16], mUncompressedSize); 4823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x1a], mFileNameLength); 4833344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength); 4843344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4853344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen) 4863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 4873344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* write filename */ 4893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileNameLength != 0) { 4903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength) 4913344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 4923344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4933344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 4943344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* write "extra field" */ 4953344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mExtraFieldLength != 0) { 4963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) 4973344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 4983344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 4993344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5003344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_ERROR; 5013344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 5023344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5033344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5043344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 5053344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Dump the contents of a LocalFileHeader object. 5063344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 5073344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianvoid ZipEntry::LocalFileHeader::dump(void) const 5083344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 50915fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" LocalFileHeader contents:\n"); 51015fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" versToExt=%u gpBits=0x%04x compression=%u\n", 5113344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mVersionToExtract, mGPBitFlag, mCompressionMethod); 51215fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n", 5133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLastModFileTime, mLastModFileDate, mCRC32); 51415fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" compressedSize=%lu uncompressedSize=%lu\n", 5153344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCompressedSize, mUncompressedSize); 51615fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" filenameLen=%u extraLen=%u\n", 5173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileNameLength, mExtraFieldLength); 5183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileName != NULL) 51915fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" filename: '%s'\n", mFileName); 5203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 5213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 5243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * =========================================================================== 5253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * ZipEntry::CentralDirEntry 5263344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * =========================================================================== 5273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 5283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 5303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Read the central dir entry that appears next in the file. 5313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * 5323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * On entry, "fp" should be positioned on the signature bytes for the 5333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * entry. On exit, "fp" will point at the signature word for the next 5343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * entry or for the EOCD. 5353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 5363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::CentralDirEntry::read(FILE* fp) 5373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 5383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian status_t result = NO_ERROR; 5393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian unsigned char buf[kCDELen]; 5403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* no re-use */ 5423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(mFileName == NULL); 5433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(mExtraField == NULL); 5443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian assert(mFileComment == NULL); 5453344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(buf, 1, kCDELen, fp) != kCDELen) { 5473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 5483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 5493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 5503344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) { 55215fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD("Whoops: didn't find expected signature\n"); 5533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 5543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 5553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 5563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]); 5583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]); 5593344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]); 5603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]); 5613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]); 5623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]); 5633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCRC32 = ZipEntry::getLongLE(&buf[0x10]); 5643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCompressedSize = ZipEntry::getLongLE(&buf[0x14]); 5653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]); 5663344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]); 5673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]); 5683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]); 5693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]); 5703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]); 5713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]); 5723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]); 5733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian // TODO: validate sizes and offsets 5753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* grab filename */ 5773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileNameLength != 0) { 5783344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileName = new unsigned char[mFileNameLength+1]; 5793344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileName == NULL) { 5803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = NO_MEMORY; 5813344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 5823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 5833344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) { 5843344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 5853344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 5863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 5873344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileName[mFileNameLength] = '\0'; 5883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 5893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 5903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* read "extra field" */ 5913344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mExtraFieldLength != 0) { 5923344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExtraField = new unsigned char[mExtraFieldLength+1]; 5933344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mExtraField == NULL) { 5943344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = NO_MEMORY; 5953344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 5963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 5973344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) { 5983344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 5993344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 6003344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6013344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mExtraField[mExtraFieldLength] = '\0'; 6023344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6033344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6043344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6053344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* grab comment, if any */ 6063344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileCommentLength != 0) { 6073344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileComment = new unsigned char[mFileCommentLength+1]; 6083344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileComment == NULL) { 6093344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = NO_MEMORY; 6103344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 6113344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6123344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength) 6133344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian { 6143344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian result = UNKNOWN_ERROR; 6153344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian goto bail; 6163344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6173344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileComment[mFileCommentLength] = '\0'; 6183344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6193344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6203344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianbail: 6213344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return result; 6223344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 6233344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6243344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 6253344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Write a central dir entry. 6263344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 6273344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianstatus_t ZipEntry::CentralDirEntry::write(FILE* fp) 6283344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 6293344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian unsigned char buf[kCDELen]; 6303344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6313344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x00], kSignature); 6323344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy); 6333344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x06], mVersionToExtract); 6343344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x08], mGPBitFlag); 6353344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod); 6363344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime); 6373344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate); 6383344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x10], mCRC32); 6393344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x14], mCompressedSize); 6403344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x18], mUncompressedSize); 6413344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x1c], mFileNameLength); 6423344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength); 6433344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x20], mFileCommentLength); 6443344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart); 6453344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putShortLE(&buf[0x24], mInternalAttrs); 6463344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x26], mExternalAttrs); 6473344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset); 6483344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6493344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(buf, 1, kCDELen, fp) != kCDELen) 6503344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 6513344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6523344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* write filename */ 6533344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileNameLength != 0) { 6543344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength) 6553344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 6563344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6573344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6583344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* write "extra field" */ 6593344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mExtraFieldLength != 0) { 6603344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) 6613344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 6623344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6633344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6643344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian /* write comment */ 6653344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileCommentLength != 0) { 6663344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength) 6673344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return UNKNOWN_ERROR; 6683344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian } 6693344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6703344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian return NO_ERROR; 6713344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 6723344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6733344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian/* 6743344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian * Dump the contents of a CentralDirEntry object. 6753344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian */ 6763344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopianvoid ZipEntry::CentralDirEntry::dump(void) const 6773344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian{ 67815fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" CentralDirEntry contents:\n"); 67915fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n", 6803344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod); 68115fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n", 6823344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLastModFileTime, mLastModFileDate, mCRC32); 68315fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" compressedSize=%lu uncompressedSize=%lu\n", 6843344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mCompressedSize, mUncompressedSize); 68515fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" filenameLen=%u extraLen=%u commentLen=%u\n", 6863344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mFileNameLength, mExtraFieldLength, mFileCommentLength); 68715fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n", 6883344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mDiskNumberStart, mInternalAttrs, mExternalAttrs, 6893344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian mLocalHeaderRelOffset); 6903344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 6913344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileName != NULL) 69215fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" filename: '%s'\n", mFileName); 6933344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian if (mFileComment != NULL) 69415fab1aa8c1ac4d92222dba349c473a8edd7ce99Steve Block ALOGD(" comment: '%s'\n", mFileComment); 6953344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian} 6963344b2e9b27466111524dfcfb64d7258153e0cb7Mathias Agopian 697