1282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 2282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copyright (C) 2006 The Android Open Source Project 3282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 4282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); 5282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * you may not use this file except in compliance with the License. 6282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * You may obtain a copy of the License at 7282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 8282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 10282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, 12282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See the License for the specific language governing permissions and 14282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * limitations under the License. 15282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 16282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 17282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 18282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// Access to entries in a Zip archive. 19282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski// 20282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 21282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#define LOG_TAG "zip" 22282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 23282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include "ZipEntry.h" 24282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <utils/Log.h> 25282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 26282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <stdio.h> 27282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <string.h> 28282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#include <assert.h> 29282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 30282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskiusing namespace android; 31282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 32282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 33282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Initialize a new ZipEntry structure from a FILE* positioned at a 34282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * CentralDirectoryEntry. 35282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 36282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * On exit, the file pointer will be at the start of the next CDE or 37282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * at the EOCD. 38282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 39282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::initFromCDE(FILE* fp) 40282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 41282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result; 42282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski long posn; 43282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski bool hasDD; 44282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 45282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //ALOGV("initFromCDE ---\n"); 46282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 47282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* read the CDE */ 48282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = mCDE.read(fp); 49282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 50282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD("mCDE.read failed\n"); 51282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 52282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 53282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 54282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //mCDE.dump(); 55282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 56282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* using the info in the CDE, go load up the LFH */ 57282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski posn = ftell(fp); 58282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fseek(fp, mCDE.mLocalHeaderRelOffset, SEEK_SET) != 0) { 59282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD("local header seek failed (%ld)\n", 60282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mLocalHeaderRelOffset); 61282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 62282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 63282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 64282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = mLFH.read(fp); 65282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (result != NO_ERROR) { 66282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD("mLFH.read failed\n"); 67282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 68282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 69282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 70282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fseek(fp, posn, SEEK_SET) != 0) 71282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 72282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 73282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //mLFH.dump(); 74282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 75282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 76282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * We *might* need to read the Data Descriptor at this point and 77282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * integrate it into the LFH. If this bit is set, the CRC-32, 78282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * compressed size, and uncompressed size will be zero. In practice 79282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * these seem to be rare. 80282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 81282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski hasDD = (mLFH.mGPBitFlag & kUsesDataDescr) != 0; 82282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (hasDD) { 83282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // do something clever 84282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //ALOGD("+++ has data descriptor\n"); 85282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 86282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 87282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 88282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Sanity-check the LFH. Note that this will fail if the "kUsesDataDescr" 89282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * flag is set, because the LFH is incomplete. (Not a problem, since we 90282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * prefer the CDE values.) 91282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 92282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (!hasDD && !compareHeaders()) { 93282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGW("warning: header mismatch\n"); 94282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // keep going? 95282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 96282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 97282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 98282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * If the mVersionToExtract is greater than 20, we may have an 99282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * issue unpacking the record -- could be encrypted, compressed 100282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * with something we don't support, or use Zip64 extensions. We 101282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * can defer worrying about that to when we're extracting data. 102282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 103282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 104282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 105282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 106282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 107282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 108282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Initialize a new entry. Pass in the file name and an optional comment. 109282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 110282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Initializes the CDE and the LFH. 111282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 112282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ZipEntry::initNew(const char* fileName, const char* comment) 113282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 114282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(fileName != NULL && *fileName != '\0'); // name required 115282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 116282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* most fields are properly initialized by constructor */ 117282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mVersionMadeBy = kDefaultMadeBy; 118282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mVersionToExtract = kDefaultVersion; 119282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mCompressionMethod = kCompressStored; 120282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mFileNameLength = strlen(fileName); 121282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (comment != NULL) 122282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mFileCommentLength = strlen(comment); 123282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mExternalAttrs = 0x81b60020; // matches what WinZip does 124282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 125282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileNameLength > 0) { 126282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1]; 127282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy((char*) mCDE.mFileName, fileName); 128282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 129282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileCommentLength > 0) { 130282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* TODO: stop assuming null-terminated ASCII here? */ 131282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1]; 132282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy((char*) mCDE.mFileComment, comment); 133282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 134282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 135282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski copyCDEtoLFH(); 136282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 137282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 138282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 139282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Initialize a new entry, starting with the ZipEntry from a different 140282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * archive. 141282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 142282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Initializes the CDE and the LFH. 143282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 144282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::initFromExternal(const ZipFile* pZipFile, 145282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski const ZipEntry* pEntry) 146282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 147282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 148282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Copy everything in the CDE over, then fix up the hairy bits. 149282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 150282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(&mCDE, &pEntry->mCDE, sizeof(mCDE)); 151282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 152282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileNameLength > 0) { 153282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mFileName = new unsigned char[mCDE.mFileNameLength+1]; 154282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileName == NULL) 155282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 156282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy((char*) mCDE.mFileName, (char*)pEntry->mCDE.mFileName); 157282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 158282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileCommentLength > 0) { 159282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mFileComment = new unsigned char[mCDE.mFileCommentLength+1]; 160282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileComment == NULL) 161282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 162282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy((char*) mCDE.mFileComment, (char*)pEntry->mCDE.mFileComment); 163282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 164282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mExtraFieldLength > 0) { 165282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* we null-terminate this, though it may not be a string */ 166282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mExtraField = new unsigned char[mCDE.mExtraFieldLength+1]; 167282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mExtraField == NULL) 168282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 169282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(mCDE.mExtraField, pEntry->mCDE.mExtraField, 170282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mExtraFieldLength+1); 171282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 172282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 173282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* construct the LFH from the CDE */ 174282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski copyCDEtoLFH(); 175282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 176282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* 177282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * The LFH "extra" field is independent of the CDE "extra", so we 178282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * handle it here. 179282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 180282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(mLFH.mExtraField == NULL); 181282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraFieldLength = pEntry->mLFH.mExtraFieldLength; 182282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mLFH.mExtraFieldLength > 0) { 183282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraField = new unsigned char[mLFH.mExtraFieldLength+1]; 184282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mLFH.mExtraField == NULL) 185282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 186282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(mLFH.mExtraField, pEntry->mLFH.mExtraField, 187282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraFieldLength+1); 188282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 189282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 190282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 191282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 192282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 193282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 194282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Insert pad bytes in the LFH by tweaking the "extra" field. This will 195282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * potentially confuse something that put "extra" data in here earlier, 196282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * but I can't find an actual problem. 197282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 198282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::addPadding(int padding) 199282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 200282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (padding <= 0) 201282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return INVALID_OPERATION; 202282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 203282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski //ALOGI("HEY: adding %d pad bytes to existing %d in %s\n", 204282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // padding, mLFH.mExtraFieldLength, mCDE.mFileName); 205282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 206282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mLFH.mExtraFieldLength > 0) { 207282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* extend existing field */ 208282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned char* newExtra; 209282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 210282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski newExtra = new unsigned char[mLFH.mExtraFieldLength + padding]; 211282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (newExtra == NULL) 212282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_MEMORY; 213282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(newExtra + mLFH.mExtraFieldLength, 0, padding); 214282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memcpy(newExtra, mLFH.mExtraField, mLFH.mExtraFieldLength); 215282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 216282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete[] mLFH.mExtraField; 217282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraField = newExtra; 218282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraFieldLength += padding; 219282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 220282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* create new field */ 221282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraField = new unsigned char[padding]; 222282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski memset(mLFH.mExtraField, 0, padding); 223282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mExtraFieldLength = padding; 224282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 225282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 226282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 227282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 228282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 229282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 230282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Set the fields in the LFH equal to the corresponding fields in the CDE. 231282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 232282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * This does not touch the LFH "extra" field. 233282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 234282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ZipEntry::copyCDEtoLFH(void) 235282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 236282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mVersionToExtract = mCDE.mVersionToExtract; 237282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mGPBitFlag = mCDE.mGPBitFlag; 238282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mCompressionMethod = mCDE.mCompressionMethod; 239282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mLastModFileTime = mCDE.mLastModFileTime; 240282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mLastModFileDate = mCDE.mLastModFileDate; 241282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mCRC32 = mCDE.mCRC32; 242282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mCompressedSize = mCDE.mCompressedSize; 243282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mUncompressedSize = mCDE.mUncompressedSize; 244282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mFileNameLength = mCDE.mFileNameLength; 245282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // the "extra field" is independent 246282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 247282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski delete[] mLFH.mFileName; 248282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mLFH.mFileNameLength > 0) { 249282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mFileName = new unsigned char[mLFH.mFileNameLength+1]; 250282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski strcpy((char*) mLFH.mFileName, (const char*) mCDE.mFileName); 251282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } else { 252282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLFH.mFileName = NULL; 253282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 254282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 255282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 256282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 257282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Set some information about a file after we add it. 258282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 259282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ZipEntry::setDataInfo(long uncompLen, long compLen, unsigned long crc32, 260282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int compressionMethod) 261282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 262282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mCompressionMethod = compressionMethod; 263282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mCRC32 = crc32; 264282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mCompressedSize = compLen; 265282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mUncompressedSize = uncompLen; 266282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mCompressionMethod = compressionMethod; 267282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (compressionMethod == kCompressDeflated) { 268282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mGPBitFlag |= 0x0002; // indicates maximum compression used 269282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 270282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski copyCDEtoLFH(); 271282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 272282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 273282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 274282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * See if the data in mCDE and mLFH match up. This is mostly useful for 275282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * debugging these classes, but it can be used to identify damaged 276282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * archives. 277282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 278282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Returns "false" if they differ. 279282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 280282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibool ZipEntry::compareHeaders(void) const 281282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 282282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mVersionToExtract != mLFH.mVersionToExtract) { 283282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: VersionToExtract\n"); 284282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 285282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 286282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mGPBitFlag != mLFH.mGPBitFlag) { 287282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: GPBitFlag\n"); 288282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 289282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 290282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mCompressionMethod != mLFH.mCompressionMethod) { 291282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: CompressionMethod\n"); 292282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 293282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 294282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mLastModFileTime != mLFH.mLastModFileTime) { 295282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: LastModFileTime\n"); 296282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 297282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 298282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mLastModFileDate != mLFH.mLastModFileDate) { 299282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: LastModFileDate\n"); 300282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 301282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 302282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mCRC32 != mLFH.mCRC32) { 303282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: CRC32\n"); 304282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 305282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 306282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mCompressedSize != mLFH.mCompressedSize) { 307282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: CompressedSize\n"); 308282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 309282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 310282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mUncompressedSize != mLFH.mUncompressedSize) { 311282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: UncompressedSize\n"); 312282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 313282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 314282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileNameLength != mLFH.mFileNameLength) { 315282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: FileNameLength\n"); 316282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 317282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 318282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#if 0 // this seems to be used for padding, not real data 319282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mExtraFieldLength != mLFH.mExtraFieldLength) { 320282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: ExtraFieldLength\n"); 321282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 322282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 323282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 324282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mCDE.mFileName != NULL) { 325282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (strcmp((char*) mCDE.mFileName, (char*) mLFH.mFileName) != 0) { 326282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGV("cmp: FileName\n"); 327282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return false; 328282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 329282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 330282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 331282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return true; 332282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 333282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 334282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 335282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 336282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Convert the DOS date/time stamp into a UNIX time stamp. 337282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 338282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskitime_t ZipEntry::getModWhen(void) const 339282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 340282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct tm parts; 341282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 342282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_sec = (mCDE.mLastModFileTime & 0x001f) << 1; 343282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_min = (mCDE.mLastModFileTime & 0x07e0) >> 5; 344282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_hour = (mCDE.mLastModFileTime & 0xf800) >> 11; 345282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_mday = (mCDE.mLastModFileDate & 0x001f); 346282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_mon = ((mCDE.mLastModFileDate & 0x01e0) >> 5) -1; 347282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_year = ((mCDE.mLastModFileDate & 0xfe00) >> 9) + 80; 348282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_wday = parts.tm_yday = 0; 349282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski parts.tm_isdst = -1; // DST info "not available" 350282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 351282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return mktime(&parts); 352282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 353282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 354282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 355282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Set the CDE/LFH timestamp from UNIX time. 356282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 357282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ZipEntry::setModWhen(time_t when) 358282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 359282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_LOCALTIME_R 360282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct tm tmResult; 361282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 362282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski time_t even; 363282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned short zdate, ztime; 364282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 365282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski struct tm* ptm; 366282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 367282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* round up to an even number of seconds */ 368282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski even = (time_t)(((unsigned long)(when) + 1) & (~1)); 369282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 370282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* expand */ 371282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#ifdef HAVE_LOCALTIME_R 372282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ptm = localtime_r(&even, &tmResult); 373282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#else 374282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ptm = localtime(&even); 375282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski#endif 376282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 377282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski int year; 378282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski year = ptm->tm_year; 379282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (year < 80) 380282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski year = 80; 381282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 382282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski zdate = (year - 80) << 9 | (ptm->tm_mon+1) << 5 | ptm->tm_mday; 383282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ztime = ptm->tm_hour << 11 | ptm->tm_min << 5 | ptm->tm_sec >> 1; 384282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 385282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mLastModFileTime = mLFH.mLastModFileTime = ztime; 386282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCDE.mLastModFileDate = mLFH.mLastModFileDate = zdate; 387282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 388282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 389282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 390282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 391282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * =========================================================================== 392282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * ZipEntry::LocalFileHeader 393282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * =========================================================================== 394282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 395282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 396282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 397282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Read a local file header. 398282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 399282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * On entry, "fp" points to the signature at the start of the header. 400282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * On exit, "fp" points to the start of data. 401282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 402282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::LocalFileHeader::read(FILE* fp) 403282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 404282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = NO_ERROR; 405282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned char buf[kLFHLen]; 406282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 407282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(mFileName == NULL); 408282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(mExtraField == NULL); 409282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 410282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(buf, 1, kLFHLen, fp) != kLFHLen) { 411282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 412282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 413282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 414282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 415282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) { 416282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD("whoops: didn't find expected signature\n"); 417282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 418282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 419282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 420282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 421282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mVersionToExtract = ZipEntry::getShortLE(&buf[0x04]); 422282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGPBitFlag = ZipEntry::getShortLE(&buf[0x06]); 423282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCompressionMethod = ZipEntry::getShortLE(&buf[0x08]); 424282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLastModFileTime = ZipEntry::getShortLE(&buf[0x0a]); 425282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLastModFileDate = ZipEntry::getShortLE(&buf[0x0c]); 426282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCRC32 = ZipEntry::getLongLE(&buf[0x0e]); 427282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCompressedSize = ZipEntry::getLongLE(&buf[0x12]); 428282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mUncompressedSize = ZipEntry::getLongLE(&buf[0x16]); 429282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileNameLength = ZipEntry::getShortLE(&buf[0x1a]); 430282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1c]); 431282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 432282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: validate sizes 433282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 434282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* grab filename */ 435282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileNameLength != 0) { 436282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileName = new unsigned char[mFileNameLength+1]; 437282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileName == NULL) { 438282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_MEMORY; 439282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 440282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 441282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) { 442282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 443282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 444282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 445282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileName[mFileNameLength] = '\0'; 446282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 447282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 448282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* grab extra field */ 449282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mExtraFieldLength != 0) { 450282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtraField = new unsigned char[mExtraFieldLength+1]; 451282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mExtraField == NULL) { 452282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_MEMORY; 453282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 454282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 455282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) { 456282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 457282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 458282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 459282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtraField[mExtraFieldLength] = '\0'; 460282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 461282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 462282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 463282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 464282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 465282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 466282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 467282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Write a local file header. 468282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 469282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::LocalFileHeader::write(FILE* fp) 470282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 471282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned char buf[kLFHLen]; 472282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 473282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x00], kSignature); 474282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x04], mVersionToExtract); 475282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x06], mGPBitFlag); 476282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x08], mCompressionMethod); 477282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x0a], mLastModFileTime); 478282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x0c], mLastModFileDate); 479282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x0e], mCRC32); 480282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x12], mCompressedSize); 481282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x16], mUncompressedSize); 482282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x1a], mFileNameLength); 483282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x1c], mExtraFieldLength); 484282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 485282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(buf, 1, kLFHLen, fp) != kLFHLen) 486282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 487282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 488282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* write filename */ 489282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileNameLength != 0) { 490282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength) 491282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 492282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 493282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 494282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* write "extra field" */ 495282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mExtraFieldLength != 0) { 496282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) 497282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 498282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 499282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 500282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 501282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 502282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 503282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 504282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 505282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Dump the contents of a LocalFileHeader object. 506282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 507282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ZipEntry::LocalFileHeader::dump(void) const 508282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 509282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" LocalFileHeader contents:\n"); 510282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" versToExt=%u gpBits=0x%04x compression=%u\n", 511282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mVersionToExtract, mGPBitFlag, mCompressionMethod); 512282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n", 513282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLastModFileTime, mLastModFileDate, mCRC32); 514282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" compressedSize=%lu uncompressedSize=%lu\n", 515282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCompressedSize, mUncompressedSize); 516282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" filenameLen=%u extraLen=%u\n", 517282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileNameLength, mExtraFieldLength); 518282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileName != NULL) 519282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" filename: '%s'\n", mFileName); 520282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 521282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 522282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 523282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 524282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * =========================================================================== 525282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * ZipEntry::CentralDirEntry 526282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * =========================================================================== 527282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 528282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 529282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 530282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Read the central dir entry that appears next in the file. 531282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * 532282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * On entry, "fp" should be positioned on the signature bytes for the 533282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * entry. On exit, "fp" will point at the signature word for the next 534282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * entry or for the EOCD. 535282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 536282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::CentralDirEntry::read(FILE* fp) 537282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 538282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski status_t result = NO_ERROR; 539282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned char buf[kCDELen]; 540282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 541282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* no re-use */ 542282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(mFileName == NULL); 543282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(mExtraField == NULL); 544282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski assert(mFileComment == NULL); 545282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 546282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(buf, 1, kCDELen, fp) != kCDELen) { 547282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 548282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 549282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 550282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 551282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (ZipEntry::getLongLE(&buf[0x00]) != kSignature) { 552282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD("Whoops: didn't find expected signature\n"); 553282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 554282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 555282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 556282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 557282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mVersionMadeBy = ZipEntry::getShortLE(&buf[0x04]); 558282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mVersionToExtract = ZipEntry::getShortLE(&buf[0x06]); 559282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mGPBitFlag = ZipEntry::getShortLE(&buf[0x08]); 560282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCompressionMethod = ZipEntry::getShortLE(&buf[0x0a]); 561282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLastModFileTime = ZipEntry::getShortLE(&buf[0x0c]); 562282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLastModFileDate = ZipEntry::getShortLE(&buf[0x0e]); 563282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCRC32 = ZipEntry::getLongLE(&buf[0x10]); 564282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCompressedSize = ZipEntry::getLongLE(&buf[0x14]); 565282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mUncompressedSize = ZipEntry::getLongLE(&buf[0x18]); 566282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileNameLength = ZipEntry::getShortLE(&buf[0x1c]); 567282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtraFieldLength = ZipEntry::getShortLE(&buf[0x1e]); 568282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileCommentLength = ZipEntry::getShortLE(&buf[0x20]); 569282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDiskNumberStart = ZipEntry::getShortLE(&buf[0x22]); 570282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mInternalAttrs = ZipEntry::getShortLE(&buf[0x24]); 571282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExternalAttrs = ZipEntry::getLongLE(&buf[0x26]); 572282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLocalHeaderRelOffset = ZipEntry::getLongLE(&buf[0x2a]); 573282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 574282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski // TODO: validate sizes and offsets 575282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 576282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* grab filename */ 577282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileNameLength != 0) { 578282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileName = new unsigned char[mFileNameLength+1]; 579282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileName == NULL) { 580282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_MEMORY; 581282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 582282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 583282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(mFileName, 1, mFileNameLength, fp) != mFileNameLength) { 584282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 585282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 586282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 587282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileName[mFileNameLength] = '\0'; 588282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 589282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 590282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* read "extra field" */ 591282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mExtraFieldLength != 0) { 592282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtraField = new unsigned char[mExtraFieldLength+1]; 593282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mExtraField == NULL) { 594282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_MEMORY; 595282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 596282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 597282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) { 598282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 599282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 600282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 601282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mExtraField[mExtraFieldLength] = '\0'; 602282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 603282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 604282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 605282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* grab comment, if any */ 606282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileCommentLength != 0) { 607282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileComment = new unsigned char[mFileCommentLength+1]; 608282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileComment == NULL) { 609282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = NO_MEMORY; 610282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 611282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 612282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fread(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength) 613282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski { 614282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski result = UNKNOWN_ERROR; 615282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski goto bail; 616282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 617282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileComment[mFileCommentLength] = '\0'; 618282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 619282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 620282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskibail: 621282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return result; 622282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 623282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 624282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 625282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Write a central dir entry. 626282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 627282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskistatus_t ZipEntry::CentralDirEntry::write(FILE* fp) 628282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 629282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski unsigned char buf[kCDELen]; 630282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 631282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x00], kSignature); 632282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x04], mVersionMadeBy); 633282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x06], mVersionToExtract); 634282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x08], mGPBitFlag); 635282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x0a], mCompressionMethod); 636282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x0c], mLastModFileTime); 637282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x0e], mLastModFileDate); 638282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x10], mCRC32); 639282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x14], mCompressedSize); 640282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x18], mUncompressedSize); 641282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x1c], mFileNameLength); 642282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x1e], mExtraFieldLength); 643282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x20], mFileCommentLength); 644282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x22], mDiskNumberStart); 645282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putShortLE(&buf[0x24], mInternalAttrs); 646282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x26], mExternalAttrs); 647282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ZipEntry::putLongLE(&buf[0x2a], mLocalHeaderRelOffset); 648282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 649282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(buf, 1, kCDELen, fp) != kCDELen) 650282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 651282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 652282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* write filename */ 653282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileNameLength != 0) { 654282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(mFileName, 1, mFileNameLength, fp) != mFileNameLength) 655282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 656282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 657282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 658282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* write "extra field" */ 659282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mExtraFieldLength != 0) { 660282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(mExtraField, 1, mExtraFieldLength, fp) != mExtraFieldLength) 661282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 662282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 663282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 664282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski /* write comment */ 665282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileCommentLength != 0) { 666282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (fwrite(mFileComment, 1, mFileCommentLength, fp) != mFileCommentLength) 667282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return UNKNOWN_ERROR; 668282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski } 669282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 670282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski return NO_ERROR; 671282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 672282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 673282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski/* 674282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski * Dump the contents of a CentralDirEntry object. 675282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski */ 676282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinskivoid ZipEntry::CentralDirEntry::dump(void) const 677282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski{ 678282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" CentralDirEntry contents:\n"); 679282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" versMadeBy=%u versToExt=%u gpBits=0x%04x compression=%u\n", 680282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mVersionMadeBy, mVersionToExtract, mGPBitFlag, mCompressionMethod); 681282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" modTime=0x%04x modDate=0x%04x crc32=0x%08lx\n", 682282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLastModFileTime, mLastModFileDate, mCRC32); 683282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" compressedSize=%lu uncompressedSize=%lu\n", 684282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mCompressedSize, mUncompressedSize); 685282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" filenameLen=%u extraLen=%u commentLen=%u\n", 686282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mFileNameLength, mExtraFieldLength, mFileCommentLength); 687282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" diskNumStart=%u intAttr=0x%04x extAttr=0x%08lx relOffset=%lu\n", 688282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mDiskNumberStart, mInternalAttrs, mExternalAttrs, 689282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski mLocalHeaderRelOffset); 690282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 691282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileName != NULL) 692282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" filename: '%s'\n", mFileName); 693282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski if (mFileComment != NULL) 694282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski ALOGD(" comment: '%s'\n", mFileComment); 695282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski} 696282e181b58cf72b6ca770dc7ca5f91f135444502Adam Lesinski 697