1 /*
2 * Copyright (c) 2021 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 #include "applypatch/data_writer.h"
16 #include <cerrno>
17 #include <cstdio>
18 #include <fcntl.h>
19 #include <memory>
20 #include <string>
21 #include <unistd.h>
22 #include "applypatch/block_writer.h"
23 #include "fs_manager/mount.h"
24 #include "log/log.h"
25 #include "raw_writer.h"
26
27 namespace updater {
28 UpdaterEnv *DataWriter::env_ = nullptr;
OpenPartition(const std::string & partitionName)29 int DataWriter::OpenPartition(const std::string &partitionName)
30 {
31 if (partitionName.empty()) {
32 LOG(ERROR) << "Datawriter: partition name is empty.";
33 return -1;
34 }
35 auto devPath = GetBlockDeviceByMountPoint(partitionName);
36 if (devPath.empty()) {
37 LOG(ERROR) << "Datawriter: cannot find device path for partition \'" <<
38 partitionName.substr(1, partitionName.size()) << "\'.";
39 return -1;
40 }
41
42 if (access(devPath.c_str(), W_OK) < 0) {
43 LOG(ERROR) << "Datawriter: " << devPath << " is not writable.";
44 return -1;
45 }
46 char *realPath = realpath(devPath.c_str(), NULL);
47 UPDATER_FILE_CHECK(realPath != nullptr, "realPath is NULL", return -1);
48 int fd = open(realPath, O_WRONLY | O_EXCL);
49 free(realPath);
50 UPDATER_FILE_CHECK(fd >= 0, "Datawriter: open block device " << devPath << " failed ", return fd);
51 UPDATER_CHECK_FILE_OP(lseek(fd, 0, SEEK_SET) != -1, "Datawriter: seek " << devPath << "failed ", fd, fd = -1);
52 return fd;
53 }
54
CreateDataWriter(WriteMode mode,const std::string & partitionName)55 std::unique_ptr<DataWriter> DataWriter::CreateDataWriter(WriteMode mode, const std::string &partitionName)
56 {
57 switch (mode) {
58 case WRITE_RAW:
59 {
60 std::unique_ptr<RawWriter> writer(std::make_unique<RawWriter>(partitionName));
61 return std::move(writer);
62 }
63 case WRITE_DECRYPT:
64 LOG(WARNING) << "Unsupported writer mode.";
65 break;
66 default:
67 break;
68 }
69 return nullptr;
70 }
71
GetUpdaterEnv()72 UpdaterEnv *DataWriter::GetUpdaterEnv()
73 {
74 return env_;
75 }
76
CreateDataWriter(WriteMode mode,const std::string & partitionName,UpdaterEnv * env)77 std::unique_ptr<DataWriter> DataWriter::CreateDataWriter(WriteMode mode, const std::string &partitionName,
78 UpdaterEnv *env)
79 {
80 env_ = env;
81 return CreateDataWriter(mode, partitionName);
82 }
83
ReleaseDataWriter(std::unique_ptr<DataWriter> & writer)84 void DataWriter::ReleaseDataWriter(std::unique_ptr<DataWriter> &writer)
85 {
86 writer.reset();
87 }
88 } // namespace updater
89