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>
14 #include "common/installer_context.h"
15 #include "common/utils/logging.h"
17 namespace bf = boost::filesystem;
18 namespace bs = boost::system;
19 namespace ci = common_installer;
23 const char kRecoveryNewInstallationString[] = "NEW";
24 const char kRecoveryUpdateInstallationString[] = "UPDATE";
25 const char kRecoveryUninstallationString[] = "UNINSTALLATION";
26 const char kRecoveryRdsString[] = "RDS";
27 const char kRecoveryDeltaString[] = "DELTA";
28 const char kRecoveryUnknownString[] = "UNKNOWN";
30 const std::map<std::string, ci::RequestType> kStringToRequestMap = {
31 {kRecoveryNewInstallationString, ci::RequestType::Install},
32 {kRecoveryUpdateInstallationString, ci::RequestType::Update},
33 {kRecoveryUninstallationString, ci::RequestType::Uninstall},
34 {kRecoveryRdsString, ci::RequestType::Reinstall},
35 {kRecoveryDeltaString, ci::RequestType::Delta}
38 std::string TruncateNewLine(const char* data) {
39 int length = strlen(data);
40 if (data[length - 1] == '\n')
42 return std::string(data, length);
47 namespace common_installer {
50 std::unique_ptr<RecoveryFile> RecoveryFile::CreateRecoveryFileForPath(
51 const boost::filesystem::path& path) {
52 if (bf::exists(path)) {
53 LOG(ERROR) << "Recovery file already exists!";
56 std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, false));
57 if (file->is_detached()) {
58 LOG(ERROR) << "Failed to access file";
64 std::unique_ptr<RecoveryFile> RecoveryFile::OpenRecoveryFileForPath(
65 const boost::filesystem::path& path) {
66 if (!bf::exists(path)) {
67 LOG(ERROR) << "Cannot open recovery file";
70 std::unique_ptr<RecoveryFile> file(new RecoveryFile(path, true));
71 if (file->is_detached()) {
72 LOG(ERROR) << "Failed to read recovery file";
78 RecoveryFile::RecoveryFile(const bf::path& path, bool load)
81 if (!ReadFileContent()) {
87 FILE* handle = fopen(path.c_str(), "w");
93 LOG(DEBUG) << "Recovery file " << path_ << " created";
97 RecoveryFile::~RecoveryFile() {
100 bf::remove(path_, error);
101 LOG(DEBUG) << "Recovery file " << path_ << " removed";
105 void RecoveryFile::Detach() {
109 bool RecoveryFile::is_detached() const {
110 return path_.empty();
113 void RecoveryFile::set_unpacked_dir(
114 const boost::filesystem::path& unpacked_dir) {
115 unpacked_dir_ = unpacked_dir;
118 void RecoveryFile::set_pkgid(const std::string& pkgid) {
122 void RecoveryFile::set_type(RequestType type) {
126 const boost::filesystem::path& RecoveryFile::unpacked_dir() const {
127 return unpacked_dir_;
130 const std::string& RecoveryFile::pkgid() const {
134 RequestType RecoveryFile::type() const {
138 bool RecoveryFile::ReadFileContent() {
139 FILE* handle = fopen(path_.c_str(), "r");
141 LOG(ERROR) << "Cannot read recovery file";
144 std::array<char, 200> data;
146 if (!fgets(data.data(), data.size(), handle)) {
147 type_ = RequestType::Unknown;
151 std::string mode(TruncateNewLine(data.data()));
152 auto iter = kStringToRequestMap.find(mode);
153 if (iter == kStringToRequestMap.end()) {
154 type_ = RequestType::Unknown;
156 type_ = iter->second;
159 if (!fgets(data.data(), data.size(), handle)) {
163 unpacked_dir_ = TruncateNewLine(data.data());
164 if (!fgets(data.data(), data.size(), handle)) {
168 pkgid_ = TruncateNewLine(data.data());
173 bool RecoveryFile::WriteAndCommitFileContent() {
174 FILE* handle = fopen(path_.c_str(), "w");
176 LOG(ERROR) << "Cannot write recovery file";
180 case RequestType::Install:
181 fputs(kRecoveryNewInstallationString, handle);
183 case RequestType::Update:
184 fputs(kRecoveryUpdateInstallationString, handle);
186 case RequestType::Uninstall:
187 fputs(kRecoveryUninstallationString, handle);
189 case RequestType::Reinstall:
190 fputs(kRecoveryRdsString, handle);
192 case RequestType::Delta:
193 fputs(kRecoveryDeltaString, handle);
196 fputs(kRecoveryUnknownString, handle);
200 fputs(unpacked_dir_.c_str(), handle);
202 fputs(pkgid_.c_str(), handle);
208 } // namespace recovery
209 } // namespace common_installer