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