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