1fb299fa2Sopenharmony_ci/* 2fb299fa2Sopenharmony_ci * Copyright (c) 2021 Huawei Device Co., Ltd. 3fb299fa2Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4fb299fa2Sopenharmony_ci * you may not use this file except in compliance with the License. 5fb299fa2Sopenharmony_ci * You may obtain a copy of the License at 6fb299fa2Sopenharmony_ci * 7fb299fa2Sopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8fb299fa2Sopenharmony_ci * 9fb299fa2Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10fb299fa2Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11fb299fa2Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12fb299fa2Sopenharmony_ci * See the License for the specific language governing permissions and 13fb299fa2Sopenharmony_ci * limitations under the License. 14fb299fa2Sopenharmony_ci */ 15fb299fa2Sopenharmony_ci#include "pkg_pkgfile.h" 16fb299fa2Sopenharmony_ci#include <ctime> 17fb299fa2Sopenharmony_ci#include <limits> 18fb299fa2Sopenharmony_ci#include <memory> 19fb299fa2Sopenharmony_ci#include "dump.h" 20fb299fa2Sopenharmony_ci#include "pkg_gzipfile.h" 21fb299fa2Sopenharmony_ci#include "pkg_lz4file.h" 22fb299fa2Sopenharmony_ci#include "pkg_stream.h" 23fb299fa2Sopenharmony_ci#include "pkg_upgradefile.h" 24fb299fa2Sopenharmony_ci#include "pkg_utils.h" 25fb299fa2Sopenharmony_ci#include "pkg_zipfile.h" 26fb299fa2Sopenharmony_ci 27fb299fa2Sopenharmony_cinamespace Hpackage { 28fb299fa2Sopenharmony_ciPkgFileImpl::~PkgFileImpl() 29fb299fa2Sopenharmony_ci{ 30fb299fa2Sopenharmony_ci auto iter = pkgEntryMapId_.begin(); 31fb299fa2Sopenharmony_ci while (iter != pkgEntryMapId_.end()) { 32fb299fa2Sopenharmony_ci auto entry = iter->second; 33fb299fa2Sopenharmony_ci delete entry; 34fb299fa2Sopenharmony_ci iter = pkgEntryMapId_.erase(iter); 35fb299fa2Sopenharmony_ci } 36fb299fa2Sopenharmony_ci pkgEntryMapId_.clear(); 37fb299fa2Sopenharmony_ci pkgEntryMapFileName_.clear(); 38fb299fa2Sopenharmony_ci PkgManager::StreamPtr tmpStream = pkgStream_; 39fb299fa2Sopenharmony_ci pkgManager_->ClosePkgStream(tmpStream); 40fb299fa2Sopenharmony_ci} 41fb299fa2Sopenharmony_ci 42fb299fa2Sopenharmony_ciPkgEntryPtr PkgFileImpl::AddPkgEntry(const std::string &fileName) 43fb299fa2Sopenharmony_ci{ 44fb299fa2Sopenharmony_ci uint32_t nodeId = ++nodeId_; 45fb299fa2Sopenharmony_ci PkgEntryPtr entry = nullptr; 46fb299fa2Sopenharmony_ci switch (type_) { 47fb299fa2Sopenharmony_ci case PKG_TYPE_UPGRADE: 48fb299fa2Sopenharmony_ci entry = new UpgradeFileEntry(this, nodeId); 49fb299fa2Sopenharmony_ci break; 50fb299fa2Sopenharmony_ci case PKG_TYPE_ZIP: 51fb299fa2Sopenharmony_ci entry = new ZipFileEntry(this, nodeId); 52fb299fa2Sopenharmony_ci break; 53fb299fa2Sopenharmony_ci case PKG_TYPE_LZ4: { 54fb299fa2Sopenharmony_ci entry = new Lz4FileEntry(this, nodeId); 55fb299fa2Sopenharmony_ci break; 56fb299fa2Sopenharmony_ci } 57fb299fa2Sopenharmony_ci case PKG_TYPE_GZIP: { 58fb299fa2Sopenharmony_ci entry = new GZipFileEntry(this, nodeId); 59fb299fa2Sopenharmony_ci break; 60fb299fa2Sopenharmony_ci } 61fb299fa2Sopenharmony_ci default: 62fb299fa2Sopenharmony_ci return nullptr; 63fb299fa2Sopenharmony_ci } 64fb299fa2Sopenharmony_ci pkgEntryMapId_.insert(std::pair<uint32_t, PkgEntryPtr>(nodeId, entry)); 65fb299fa2Sopenharmony_ci pkgEntryMapFileName_.insert(std::pair<std::string, PkgEntryPtr>(fileName, entry)); 66fb299fa2Sopenharmony_ci return entry; 67fb299fa2Sopenharmony_ci} 68fb299fa2Sopenharmony_ci 69fb299fa2Sopenharmony_ciint32_t PkgFileImpl::ExtractFile(const PkgEntryPtr node, PkgStreamPtr output) 70fb299fa2Sopenharmony_ci{ 71fb299fa2Sopenharmony_ci PKG_LOGI("ExtractFile %s", output->GetFileName().c_str()); 72fb299fa2Sopenharmony_ci if (!CheckState({PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_WORKING)) { 73fb299fa2Sopenharmony_ci PKG_LOGE("error state curr %d ", state_); 74fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_STATE); 75fb299fa2Sopenharmony_ci return PKG_INVALID_STATE; 76fb299fa2Sopenharmony_ci } 77fb299fa2Sopenharmony_ci auto entry = static_cast<PkgEntryPtr>(node); 78fb299fa2Sopenharmony_ci if (entry == nullptr) { 79fb299fa2Sopenharmony_ci PKG_LOGE("error get entry %s", pkgStream_->GetFileName().c_str()); 80fb299fa2Sopenharmony_ci UPDATER_LAST_WORD(PKG_INVALID_PARAM); 81fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 82fb299fa2Sopenharmony_ci } 83fb299fa2Sopenharmony_ci return entry->Unpack(output); 84fb299fa2Sopenharmony_ci} 85fb299fa2Sopenharmony_ci 86fb299fa2Sopenharmony_ciPkgEntryPtr PkgFileImpl::FindPkgEntry(const std::string &fileName) 87fb299fa2Sopenharmony_ci{ 88fb299fa2Sopenharmony_ci if (!CheckState({PKG_FILE_STATE_WORKING}, PKG_FILE_STATE_WORKING)) { 89fb299fa2Sopenharmony_ci PKG_LOGE("error state curr %d ", state_); 90fb299fa2Sopenharmony_ci return nullptr; 91fb299fa2Sopenharmony_ci } 92fb299fa2Sopenharmony_ci std::multimap<std::string, PkgEntryPtr>::iterator iter = pkgEntryMapFileName_.find(fileName); 93fb299fa2Sopenharmony_ci if (iter != pkgEntryMapFileName_.end()) { 94fb299fa2Sopenharmony_ci return (*iter).second; 95fb299fa2Sopenharmony_ci } 96fb299fa2Sopenharmony_ci return nullptr; 97fb299fa2Sopenharmony_ci} 98fb299fa2Sopenharmony_ci 99fb299fa2Sopenharmony_cibool PkgFileImpl::CheckState(std::vector<uint32_t> states, uint32_t state) 100fb299fa2Sopenharmony_ci{ 101fb299fa2Sopenharmony_ci bool ret = false; 102fb299fa2Sopenharmony_ci for (auto s : states) { 103fb299fa2Sopenharmony_ci if (state_ == s) { 104fb299fa2Sopenharmony_ci state_ = state; 105fb299fa2Sopenharmony_ci ret = true; 106fb299fa2Sopenharmony_ci break; 107fb299fa2Sopenharmony_ci } 108fb299fa2Sopenharmony_ci } 109fb299fa2Sopenharmony_ci return ret; 110fb299fa2Sopenharmony_ci} 111fb299fa2Sopenharmony_ci 112fb299fa2Sopenharmony_ciint32_t PkgFileImpl::ConvertBufferToString(std::string &fileName, const PkgBuffer &buffer) 113fb299fa2Sopenharmony_ci{ 114fb299fa2Sopenharmony_ci for (uint32_t i = 0; i < buffer.length; ++i) { 115fb299fa2Sopenharmony_ci if (buffer.buffer[i] < 32 || buffer.buffer[i] >= 127) { // 32,127 : should be printable character 116fb299fa2Sopenharmony_ci break; 117fb299fa2Sopenharmony_ci } 118fb299fa2Sopenharmony_ci fileName.push_back(buffer.buffer[i]); 119fb299fa2Sopenharmony_ci } 120fb299fa2Sopenharmony_ci return PKG_SUCCESS; 121fb299fa2Sopenharmony_ci} 122fb299fa2Sopenharmony_ci 123fb299fa2Sopenharmony_ciint32_t PkgFileImpl::ConvertStringToBuffer(const std::string &fileName, const PkgBuffer &buffer, size_t &realLen) 124fb299fa2Sopenharmony_ci{ 125fb299fa2Sopenharmony_ci if (buffer.length < fileName.size()) { 126fb299fa2Sopenharmony_ci PKG_LOGE("Invalid buffer"); 127fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 128fb299fa2Sopenharmony_ci } 129fb299fa2Sopenharmony_ci for (uint32_t i = 0; i < fileName.size(); ++i) { 130fb299fa2Sopenharmony_ci buffer.buffer[i] = static_cast<uint8_t>(fileName[i]); 131fb299fa2Sopenharmony_ci (realLen)++; 132fb299fa2Sopenharmony_ci } 133fb299fa2Sopenharmony_ci return PKG_SUCCESS; 134fb299fa2Sopenharmony_ci} 135fb299fa2Sopenharmony_ci 136fb299fa2Sopenharmony_ciint32_t PkgEntry::Init(PkgManager::FileInfoPtr localFileInfo, const PkgManager::FileInfoPtr fileInfo, 137fb299fa2Sopenharmony_ci PkgStreamPtr inStream) 138fb299fa2Sopenharmony_ci{ 139fb299fa2Sopenharmony_ci if (localFileInfo == nullptr || fileInfo == nullptr || inStream == nullptr) { 140fb299fa2Sopenharmony_ci PKG_LOGE("Failed to check input param"); 141fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 142fb299fa2Sopenharmony_ci } 143fb299fa2Sopenharmony_ci 144fb299fa2Sopenharmony_ci fileName_.assign(inStream->GetFileName()); 145fb299fa2Sopenharmony_ci localFileInfo->identity.assign(fileInfo->identity); 146fb299fa2Sopenharmony_ci localFileInfo->flags = fileInfo->flags; 147fb299fa2Sopenharmony_ci localFileInfo->digestMethod = fileInfo->digestMethod; 148fb299fa2Sopenharmony_ci localFileInfo->packMethod = fileInfo->packMethod; 149fb299fa2Sopenharmony_ci localFileInfo->modifiedTime = fileInfo->modifiedTime; 150fb299fa2Sopenharmony_ci localFileInfo->packedSize = fileInfo->packedSize; 151fb299fa2Sopenharmony_ci localFileInfo->unpackedSize = fileInfo->unpackedSize; 152fb299fa2Sopenharmony_ci 153fb299fa2Sopenharmony_ci // 填充file信息,默认值使用原始文件长度 154fb299fa2Sopenharmony_ci if (localFileInfo->unpackedSize == 0) { 155fb299fa2Sopenharmony_ci localFileInfo->unpackedSize = inStream->GetFileLength(); 156fb299fa2Sopenharmony_ci } 157fb299fa2Sopenharmony_ci if (localFileInfo->packedSize == 0) { 158fb299fa2Sopenharmony_ci localFileInfo->packedSize = inStream->GetFileLength(); 159fb299fa2Sopenharmony_ci } 160fb299fa2Sopenharmony_ci if (localFileInfo->unpackedSize == 0) { 161fb299fa2Sopenharmony_ci PKG_LOGE("Failed to check unpackedSize = 0"); 162fb299fa2Sopenharmony_ci return PKG_INVALID_PARAM; 163fb299fa2Sopenharmony_ci } 164fb299fa2Sopenharmony_ci if (localFileInfo->modifiedTime == 0) { 165fb299fa2Sopenharmony_ci time(&localFileInfo->modifiedTime); 166fb299fa2Sopenharmony_ci } 167fb299fa2Sopenharmony_ci return PKG_SUCCESS; 168fb299fa2Sopenharmony_ci} 169fb299fa2Sopenharmony_ci 170fb299fa2Sopenharmony_civoid PkgFileImpl::AddSignData(uint8_t digestMethod, size_t currOffset, size_t &signOffset) 171fb299fa2Sopenharmony_ci{ 172fb299fa2Sopenharmony_ci signOffset = currOffset; 173fb299fa2Sopenharmony_ci if (digestMethod == PKG_DIGEST_TYPE_NONE) { 174fb299fa2Sopenharmony_ci return; 175fb299fa2Sopenharmony_ci } 176fb299fa2Sopenharmony_ci std::vector<uint8_t> buffer(SIGN_SHA256_LEN + SIGN_SHA384_LEN, 0); 177fb299fa2Sopenharmony_ci int32_t ret = pkgStream_->Write(buffer, buffer.size(), currOffset); 178fb299fa2Sopenharmony_ci if (ret != PKG_SUCCESS) { 179fb299fa2Sopenharmony_ci PKG_LOGE("Fail write sign for %s", pkgStream_->GetFileName().c_str()); 180fb299fa2Sopenharmony_ci return; 181fb299fa2Sopenharmony_ci } 182fb299fa2Sopenharmony_ci pkgStream_->Flush(currOffset + buffer.size()); 183fb299fa2Sopenharmony_ci PKG_LOGI("SavePackage success file length: %zu signOffset %zu", pkgStream_->GetFileLength(), signOffset); 184fb299fa2Sopenharmony_ci} 185fb299fa2Sopenharmony_ci} // namespace Hpackage 186