1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache-2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/recovery_file.h"
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/system/error_code.hpp>
10 #include <manifest_parser/utils/logging.h>
17 #include "common/installer_context.h"
19 namespace bf = boost::filesystem;
20 namespace bs = boost::system;
21 namespace ci = common_installer;
25 const char kRecoveryNewInstallationString[] = "NEW";
26 const char kRecoveryUpdateInstallationString[] = "UPDATE";
27 const char kRecoveryUninstallationString[] = "UNINSTALLATION";
28 const char kRecoveryRdsString[] = "RDS";
29 const char kRecoveryDeltaString[] = "DELTA";
30 const char kRecoveryUnknownString[] = "UNKNOWN";
32 const std::map<std::string, ci::RequestType> kStringToRequestMap = {
33 {kRecoveryNewInstallationString, ci::RequestType::Install},
34 {kRecoveryUpdateInstallationString, ci::RequestType::Update},
35 {kRecoveryUninstallationString, ci::RequestType::Uninstall},
36 {kRecoveryRdsString, ci::RequestType::Reinstall},
37 {kRecoveryDeltaString, ci::RequestType::Delta}
40 std::string TruncateNewLine(const char* data) {
41 int length = strlen(data);
42 if (data[length - 1] == '\n')
44 return std::string(data, length);
49 namespace common_installer {
52 std::unique_ptr<RecoveryFile> RecoveryFile::CreateRecoveryFileForPath(
53 const boost::filesystem::path& path) {
54 if (bf::exists(path)) {
55 LOG(ERROR) << "Recovery file already exists!";
58 std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, false));
59 if (file->is_detached()) {
60 LOG(ERROR) << "Failed to access file";
66 std::unique_ptr<RecoveryFile> RecoveryFile::OpenRecoveryFileForPath(
67 const boost::filesystem::path& path) {
68 if (!bf::exists(path)) {
69 LOG(ERROR) << "Cannot open recovery file";
72 std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, true));
73 if (file->is_detached()) {
74 LOG(ERROR) << "Failed to read recovery file";
80 RecoveryFile::RecoveryFile(const bf::path& path, bool load)
83 if (!ReadFileContent()) {
89 FILE* handle = fopen(path.c_str(), "w");
95 LOG(DEBUG) << "Recovery file " << path_ << " created";
99 RecoveryFile::~RecoveryFile() {
100 if (!path_.empty()) {
101 bs::error_code error;
102 bf::remove(path_, error);
103 LOG(DEBUG) << "Recovery file " << path_ << " removed";
107 void RecoveryFile::Detach() {
111 bool RecoveryFile::is_detached() const {
112 return path_.empty();
115 void RecoveryFile::set_unpacked_dir(
116 boost::filesystem::path unpacked_dir) {
117 unpacked_dir_ = std::move(unpacked_dir);
120 void RecoveryFile::set_pkgid(std::string pkgid) {
121 pkgid_ = std::move(pkgid);
124 void RecoveryFile::set_type(RequestType type) {
128 const boost::filesystem::path& RecoveryFile::unpacked_dir() const {
129 return unpacked_dir_;
132 const std::string& RecoveryFile::pkgid() const {
136 RequestType RecoveryFile::type() const {
140 bool RecoveryFile::ReadFileContent() {
141 FILE* handle = fopen(path_.c_str(), "r");
143 LOG(ERROR) << "Cannot read recovery file";
146 std::array<char, 200> data;
148 if (!fgets(data.data(), data.size(), handle)) {
149 type_ = RequestType::Unknown;
153 std::string mode(TruncateNewLine(data.data()));
154 auto iter = kStringToRequestMap.find(mode);
155 if (iter == kStringToRequestMap.end()) {
156 type_ = RequestType::Unknown;
158 type_ = iter->second;
161 if (!fgets(data.data(), data.size(), handle)) {
165 unpacked_dir_ = TruncateNewLine(data.data());
166 if (!fgets(data.data(), data.size(), handle)) {
170 pkgid_ = TruncateNewLine(data.data());
175 bool RecoveryFile::WriteAndCommitFileContent() {
176 FILE* handle = fopen(path_.c_str(), "w");
178 LOG(ERROR) << "Cannot write recovery file";
182 case RequestType::Install:
183 fputs(kRecoveryNewInstallationString, handle);
185 case RequestType::Update:
186 fputs(kRecoveryUpdateInstallationString, handle);
188 case RequestType::Uninstall:
189 fputs(kRecoveryUninstallationString, handle);
191 case RequestType::Reinstall:
192 fputs(kRecoveryRdsString, handle);
194 case RequestType::Delta:
195 fputs(kRecoveryDeltaString, handle);
198 fputs(kRecoveryUnknownString, handle);
202 fputs(unpacked_dir_.c_str(), handle);
204 fputs(pkgid_.c_str(), handle);
210 } // namespace recovery
211 } // namespace common_installer