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 kRecoveryInstallString[] = "NEW";
26 const char kRecoveryUpdateString[] = "UPDATE";
27 const char kRecoveryUninstallationString[] = "UNINSTALL";
28 const char kRecoveryRdsString[] = "RDS";
29 const char kRecoveryDeltaString[] = "DELTA";
30 const char kRecoveryMountInstallString[] = "MOUNTINSTALL";
31 const char kRecoveryMountUpdateString[] = "MOUNTUPDATE";
32 const char kRecoveryUnknownString[] = "UNKNOWN";
34 const std::map<std::string, ci::RequestType> kStringToRequestMap = {
35 {kRecoveryInstallString, ci::RequestType::Install},
36 {kRecoveryUpdateString, ci::RequestType::Update},
37 {kRecoveryUninstallationString, ci::RequestType::Uninstall},
38 {kRecoveryRdsString, ci::RequestType::Reinstall},
39 {kRecoveryDeltaString, ci::RequestType::Delta},
40 {kRecoveryMountInstallString, ci::RequestType::MountInstall},
41 {kRecoveryMountUpdateString, ci::RequestType::MountUpdate},
44 std::string TruncateNewLine(const char* data) {
45 int length = strlen(data);
46 if (data[length - 1] == '\n')
48 return std::string(data, length);
53 namespace common_installer {
56 std::unique_ptr<RecoveryFile> RecoveryFile::CreateRecoveryFileForPath(
57 const boost::filesystem::path& path) {
58 if (bf::exists(path)) {
59 LOG(ERROR) << "Recovery file already exists!";
62 std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, false));
63 if (file->is_detached()) {
64 LOG(ERROR) << "Failed to access file";
70 std::unique_ptr<RecoveryFile> RecoveryFile::OpenRecoveryFileForPath(
71 const boost::filesystem::path& path) {
72 if (!bf::exists(path)) {
73 LOG(ERROR) << "Cannot open recovery file";
76 std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, true));
77 if (file->is_detached()) {
78 LOG(ERROR) << "Failed to read recovery file";
84 RecoveryFile::RecoveryFile(const bf::path& path, bool load)
87 if (!ReadFileContent()) {
93 FILE* handle = fopen(path.c_str(), "w");
99 LOG(DEBUG) << "Recovery file " << path_ << " created";
103 RecoveryFile::~RecoveryFile() {
104 if (!path_.empty()) {
105 bs::error_code error;
106 bf::remove(path_, error);
107 LOG(DEBUG) << "Recovery file " << path_ << " removed";
111 void RecoveryFile::Detach() {
115 bool RecoveryFile::is_detached() const {
116 return path_.empty();
119 void RecoveryFile::set_unpacked_dir(
120 boost::filesystem::path unpacked_dir) {
121 unpacked_dir_ = std::move(unpacked_dir);
124 void RecoveryFile::set_pkgid(std::string pkgid) {
125 pkgid_ = std::move(pkgid);
128 void RecoveryFile::set_type(RequestType type) {
132 const boost::filesystem::path& RecoveryFile::unpacked_dir() const {
133 return unpacked_dir_;
136 const std::string& RecoveryFile::pkgid() const {
140 RequestType RecoveryFile::type() const {
144 bool RecoveryFile::ReadFileContent() {
145 FILE* handle = fopen(path_.c_str(), "r");
147 LOG(ERROR) << "Cannot read recovery file";
150 std::array<char, 200> data;
152 if (!fgets(data.data(), data.size(), handle)) {
153 type_ = RequestType::Unknown;
157 std::string mode(TruncateNewLine(data.data()));
158 auto iter = kStringToRequestMap.find(mode);
159 if (iter == kStringToRequestMap.end()) {
160 type_ = RequestType::Unknown;
162 type_ = iter->second;
165 if (!fgets(data.data(), data.size(), handle)) {
169 unpacked_dir_ = TruncateNewLine(data.data());
170 if (!fgets(data.data(), data.size(), handle)) {
174 pkgid_ = TruncateNewLine(data.data());
179 bool RecoveryFile::WriteAndCommitFileContent() {
180 FILE* handle = fopen(path_.c_str(), "w");
182 LOG(ERROR) << "Cannot write recovery file";
186 case RequestType::Install:
187 fputs(kRecoveryInstallString, handle);
189 case RequestType::Update:
190 fputs(kRecoveryUpdateString, handle);
192 case RequestType::Uninstall:
193 fputs(kRecoveryUninstallationString, handle);
195 case RequestType::Reinstall:
196 fputs(kRecoveryRdsString, handle);
198 case RequestType::Delta:
199 fputs(kRecoveryDeltaString, handle);
201 case RequestType::MountInstall:
202 fputs(kRecoveryMountInstallString, handle);
204 case RequestType::MountUpdate:
205 fputs(kRecoveryMountUpdateString, handle);
208 fputs(kRecoveryUnknownString, handle);
212 fputs(unpacked_dir_.c_str(), handle);
214 fputs(pkgid_.c_str(), handle);
220 } // namespace recovery
221 } // namespace common_installer