/* * Copyright (C) 2017 bigbiff/Dees_Troy TeamWin * This file is part of TWRP/TeamWin Recovery Project. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #include "zipwrap.hpp" #include #include #include #include #include #include #ifdef USE_MINZIP #include "minzip/Zip.h" #include "minzip/SysUtil.h" #else #include #include "otautil/ZipUtil.h" #include "otautil/SysUtil.h" #endif ZipWrap::ZipWrap() { zip_open = false; } ZipWrap::~ZipWrap() { if (zip_open) Close(); } bool ZipWrap::Open(const char* file, MemMapping* map) { if (zip_open) { printf("ZipWrap '%s' is already open\n", zip_file.c_str()); return true; } zip_file = file; #ifdef USE_MINZIP if (mzOpenZipArchive(map->addr, map->length, &Zip) != 0) return false; #else if (OpenArchiveFromMemory(map->addr, map->length, file, &Zip) != 0) return false; #endif zip_open = true; return true; } void ZipWrap::Close() { if (zip_open) #ifdef USE_MINZIP mzCloseZipArchive(&Zip); #else CloseArchive(Zip); #endif zip_open = false; } bool ZipWrap::EntryExists(const string& filename) { #ifdef USE_MINZIP const ZipEntry* file_location = mzFindZipEntry(&Zip, filename.c_str()); if (file_location != NULL) return true; return false; #else ZipString zip_string(filename.c_str()); ZipEntry file_entry; if (FindEntry(Zip, zip_string, &file_entry) != 0) return false; return true; #endif } bool ZipWrap::ExtractEntry(const string& source_file, const string& target_file, mode_t mode) { if (access(target_file.c_str(), F_OK) == 0 && unlink(target_file.c_str()) != 0) printf("Unable to unlink '%s': %s\n", target_file.c_str(), strerror(errno)); int fd = creat(target_file.c_str(), mode); if (fd < 0) { printf("Failed to create '%s'\n", target_file.c_str()); return false; } #ifdef USE_MINZIP const ZipEntry* file_entry = mzFindZipEntry(&Zip, source_file.c_str()); if (file_entry == NULL) { printf("'%s' does not exist in zip '%s'\n", source_file.c_str(), zip_file.c_str()); return false; } int ret_val = mzExtractZipEntryToFile(&Zip, file_entry, fd); close(fd); if (!ret_val) { printf("Could not extract '%s'\n", target_file.c_str()); return false; } #else ZipString zip_string(source_file.c_str()); ZipEntry file_entry; if (FindEntry(Zip, zip_string, &file_entry) != 0) return false; int32_t ret_val = ExtractEntryToFile(Zip, &file_entry, fd); close(fd); if (ret_val != 0) { printf("Could not extract '%s'\n", target_file.c_str()); return false; } #endif return true; } bool ZipWrap::ExtractRecursive(const string& source_dir, const string& target_dir) { struct utimbuf timestamp = { 1217592000, 1217592000 }; // 8/1/2008 default #ifdef USE_MINZIP return mzExtractRecursive(&Zip, source_dir.c_str(), target_dir.c_str(), ×tamp, NULL, NULL, NULL); #else return ExtractPackageRecursive(Zip, source_dir, target_dir, ×tamp, NULL); #endif } long ZipWrap::GetUncompressedSize(const string& filename) { #ifdef USE_MINZIP const ZipEntry* file_entry = mzFindZipEntry(&Zip, filename.c_str()); if (file_entry == NULL) { printf("'%s' does not exist in zip '%s'\n", filename.c_str(), zip_file.c_str()); return 0; } return file_entry->uncompLen; #else ZipString zip_string(filename.c_str()); ZipEntry file_entry; if (FindEntry(Zip, zip_string, &file_entry) != 0) return 0; return file_entry.uncompressed_length; #endif } bool ZipWrap::ExtractToBuffer(const string& filename, uint8_t* buffer) { #ifdef USE_MINZIP const ZipEntry* file_entry = mzFindZipEntry(&Zip, filename.c_str()); if (file_entry == NULL) { printf("'%s' does not exist in zip '%s'\n", filename.c_str(), zip_file.c_str()); return false; } if (!mzExtractZipEntryToBuffer(&Zip, file_entry, buffer)) { printf("Failed to read '%s'\n", filename.c_str()); return false; } #else ZipString zip_string(filename.c_str()); ZipEntry file_entry; if (FindEntry(Zip, zip_string, &file_entry) != 0) return false; if (ExtractToMemory(Zip, &file_entry, buffer, file_entry.uncompressed_length) != 0) { printf("Failed to read '%s'\n", filename.c_str()); return false; } #endif return true; } #ifdef USE_MINZIP loff_t ZipWrap::GetEntryOffset(const string& filename) { const ZipEntry* file_entry = mzFindZipEntry(&Zip, filename.c_str()); if (file_entry == NULL) { printf("'%s' does not exist in zip '%s'\n", filename.c_str(), zip_file.c_str()); return 0; } return mzGetZipEntryOffset(file_entry); } #else off64_t ZipWrap::GetEntryOffset(const string& filename) { ZipString zip_string(filename.c_str()); ZipEntry file_entry; if (FindEntry(Zip, zip_string, &file_entry) != 0) { printf("'%s' does not exist in zip '%s'\n", filename.c_str(), zip_file.c_str()); return 0; } return file_entry.offset; } ZipArchiveHandle ZipWrap::GetZipArchiveHandle() { return Zip; } #endif