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 "applypatch/data_writer.h" 16fb299fa2Sopenharmony_ci#include <cerrno> 17fb299fa2Sopenharmony_ci#include <cstdio> 18fb299fa2Sopenharmony_ci#include <fcntl.h> 19fb299fa2Sopenharmony_ci#include <memory> 20fb299fa2Sopenharmony_ci#include <string> 21fb299fa2Sopenharmony_ci#include <unistd.h> 22fb299fa2Sopenharmony_ci#include "applypatch/block_writer.h" 23fb299fa2Sopenharmony_ci#include "fs_manager/mount.h" 24fb299fa2Sopenharmony_ci#include "log/log.h" 25fb299fa2Sopenharmony_ci#include "raw_writer.h" 26fb299fa2Sopenharmony_ci 27fb299fa2Sopenharmony_cinamespace Updater { 28fb299fa2Sopenharmony_ciUpdaterEnv *DataWriter::env_ = nullptr; 29fb299fa2Sopenharmony_ciint DataWriter::OpenPath(const std::string &path) 30fb299fa2Sopenharmony_ci{ 31fb299fa2Sopenharmony_ci if (path.empty()) { 32fb299fa2Sopenharmony_ci LOG(ERROR) << "Datawriter: partition name is empty."; 33fb299fa2Sopenharmony_ci return -1; 34fb299fa2Sopenharmony_ci } 35fb299fa2Sopenharmony_ci 36fb299fa2Sopenharmony_ci if (access(path.c_str(), W_OK) < 0) { 37fb299fa2Sopenharmony_ci LOG(ERROR) << "Datawriter: " << path << " is not writable."; 38fb299fa2Sopenharmony_ci return -1; 39fb299fa2Sopenharmony_ci } 40fb299fa2Sopenharmony_ci char *realPath = realpath(path.c_str(), NULL); 41fb299fa2Sopenharmony_ci if (realPath == nullptr) { 42fb299fa2Sopenharmony_ci LOG(ERROR) << "realPath is NULL" << " : " << strerror(errno); 43fb299fa2Sopenharmony_ci return -1; 44fb299fa2Sopenharmony_ci } 45fb299fa2Sopenharmony_ci int fd = open(realPath, O_RDWR | O_LARGEFILE); 46fb299fa2Sopenharmony_ci free(realPath); 47fb299fa2Sopenharmony_ci if (fd < 0) { 48fb299fa2Sopenharmony_ci LOG(ERROR) << "Datawriter: open block device " << path << " failed " << " : " << strerror(errno); 49fb299fa2Sopenharmony_ci return fd; 50fb299fa2Sopenharmony_ci } 51fb299fa2Sopenharmony_ci if (lseek(fd, 0, SEEK_SET) == -1) { 52fb299fa2Sopenharmony_ci LOG(ERROR) << "Datawriter: seek " << path << "failed " << " : " << strerror(errno); 53fb299fa2Sopenharmony_ci close(fd); 54fb299fa2Sopenharmony_ci fd = -1; 55fb299fa2Sopenharmony_ci } 56fb299fa2Sopenharmony_ci return fd; 57fb299fa2Sopenharmony_ci} 58fb299fa2Sopenharmony_ci 59fb299fa2Sopenharmony_cistd::unique_ptr<DataWriter> DataWriter::CreateDataWriter(WriteMode mode, const std::string &path, 60fb299fa2Sopenharmony_ci uint64_t offset) 61fb299fa2Sopenharmony_ci{ 62fb299fa2Sopenharmony_ci switch (mode) { 63fb299fa2Sopenharmony_ci case WRITE_RAW: 64fb299fa2Sopenharmony_ci return std::make_unique<RawWriter>(path, offset); 65fb299fa2Sopenharmony_ci case WRITE_DECRYPT: 66fb299fa2Sopenharmony_ci LOG(WARNING) << "Unsupported writer mode."; 67fb299fa2Sopenharmony_ci break; 68fb299fa2Sopenharmony_ci default: 69fb299fa2Sopenharmony_ci break; 70fb299fa2Sopenharmony_ci } 71fb299fa2Sopenharmony_ci return nullptr; 72fb299fa2Sopenharmony_ci} 73fb299fa2Sopenharmony_ci 74fb299fa2Sopenharmony_ciUpdaterEnv *DataWriter::GetUpdaterEnv() 75fb299fa2Sopenharmony_ci{ 76fb299fa2Sopenharmony_ci return env_; 77fb299fa2Sopenharmony_ci} 78fb299fa2Sopenharmony_ci 79fb299fa2Sopenharmony_civoid DataWriter::SetUpdaterEnv(UpdaterEnv *env) 80fb299fa2Sopenharmony_ci{ 81fb299fa2Sopenharmony_ci env_ = env; 82fb299fa2Sopenharmony_ci} 83fb299fa2Sopenharmony_ci 84fb299fa2Sopenharmony_cistd::unique_ptr<DataWriter> DataWriter::CreateDataWriter(WriteMode mode, const std::string &path, 85fb299fa2Sopenharmony_ci UpdaterEnv *env, uint64_t offset) 86fb299fa2Sopenharmony_ci{ 87fb299fa2Sopenharmony_ci env_ = env; 88fb299fa2Sopenharmony_ci return CreateDataWriter(mode, path, offset); 89fb299fa2Sopenharmony_ci} 90fb299fa2Sopenharmony_ci 91fb299fa2Sopenharmony_cistd::unique_ptr<DataWriter> DataWriter::CreateDataWriter(const std::string &mode, const std::string &path, 92fb299fa2Sopenharmony_ci const std::string &partName, uint64_t startAddr, uint64_t offset) 93fb299fa2Sopenharmony_ci{ 94fb299fa2Sopenharmony_ci if (auto it = constructorMap_.find(mode); it != constructorMap_.end()) { 95fb299fa2Sopenharmony_ci return it->second(path, partName, startAddr, offset); 96fb299fa2Sopenharmony_ci } 97fb299fa2Sopenharmony_ci LOG(ERROR) << "create writer failed, can not find writer mode: " << mode; 98fb299fa2Sopenharmony_ci return nullptr; 99fb299fa2Sopenharmony_ci} 100fb299fa2Sopenharmony_ci 101fb299fa2Sopenharmony_civoid DataWriter::ReleaseDataWriter(std::unique_ptr<DataWriter> &writer) 102fb299fa2Sopenharmony_ci{ 103fb299fa2Sopenharmony_ci writer.reset(); 104fb299fa2Sopenharmony_ci} 105fb299fa2Sopenharmony_ci 106fb299fa2Sopenharmony_civoid DataWriter::RegisterDataWriter(const std::string &mode, WriterConstructor constructor) 107fb299fa2Sopenharmony_ci{ 108fb299fa2Sopenharmony_ci if (mode.empty() || constructor == nullptr) { 109fb299fa2Sopenharmony_ci LOG(ERROR) << "invalid input"; 110fb299fa2Sopenharmony_ci return; 111fb299fa2Sopenharmony_ci } 112fb299fa2Sopenharmony_ci if (!constructorMap_.emplace(mode, constructor).second) { 113fb299fa2Sopenharmony_ci LOG(ERROR) << "register writer failed, mode: " << mode; 114fb299fa2Sopenharmony_ci } 115fb299fa2Sopenharmony_ci} 116fb299fa2Sopenharmony_ci} // namespace Updater 117