#include "common/recovery_file.h"
-#include <boost/filesystem/operations.hpp>
-#include <boost/system/error_code.hpp>
-
#include <manifest_parser/utils/logging.h>
#include <array>
#include <cstring>
+#include <fstream>
+#include <string>
+#include <system_error>
#include <map>
#include <utility>
#include "common/installer_context.h"
#include "common/utils/file_util.h"
-namespace bf = boost::filesystem;
-namespace bs = boost::system;
namespace ci = common_installer;
+namespace fs = std::filesystem;
namespace {
const char kRecoveryDeltaString[] = "DELTA";
const char kRecoveryMountInstallString[] = "MOUNTINSTALL";
const char kRecoveryMountUpdateString[] = "MOUNTUPDATE";
+const char kRecoveryReadonlyUpdateInstallString[] = "READONLYUPDATEINSTALL";
+const char kRecoveryReadonlyUpdateUninstallString[] = "READONLYUPDATEUNINSTALL";
const char kRecoveryUnknownString[] = "UNKNOWN";
const std::map<std::string, ci::RequestType> kStringToRequestMap = {
{kRecoveryDeltaString, ci::RequestType::Delta},
{kRecoveryMountInstallString, ci::RequestType::MountInstall},
{kRecoveryMountUpdateString, ci::RequestType::MountUpdate},
+ {kRecoveryReadonlyUpdateInstallString,
+ ci::RequestType::ReadonlyUpdateInstall},
+ {kRecoveryReadonlyUpdateUninstallString,
+ ci::RequestType::ReadonlyUpdateUninstall},
};
std::string TruncateNewLine(const char* data) {
namespace recovery {
std::unique_ptr<RecoveryFile> RecoveryFile::CreateRecoveryFile(
- const boost::filesystem::path& path, RequestType type) {
- if (bf::exists(path)) {
+ const std::filesystem::path& path, RequestType type) {
+ if (fs::exists(path)) {
LOG(ERROR) << "Recovery file already exists!";
return nullptr;
}
}
std::unique_ptr<RecoveryFile> RecoveryFile::OpenRecoveryFile(
- const boost::filesystem::path& path) {
- if (!bf::exists(path)) {
+ const std::filesystem::path& path) {
+ if (!fs::exists(path)) {
LOG(ERROR) << "Cannot open recovery file";
return nullptr;
}
return file;
}
-RecoveryFile::RecoveryFile(const bf::path& path, RequestType type, bool load)
- : type_(type), path_(path) {
+RecoveryFile::RecoveryFile(const fs::path& path, RequestType type, bool load)
+ : type_(type), path_(path), backup_done_(false), cleanup_(false),
+ security_operation_done_(false) {
+ backup_path_ = path_.string() + ".bck";
if (load) {
if (!ReadFileContent()) {
path_.clear();
RecoveryFile::~RecoveryFile() {
if (Remove(path_))
LOG(DEBUG) << "Recovery file " << path_ << " removed";
+ if (Remove(backup_path_))
+ LOG(DEBUG) << "Recovery file " << backup_path_ << " removed";
}
void RecoveryFile::Detach() {
}
void RecoveryFile::set_unpacked_dir(
- boost::filesystem::path unpacked_dir) {
+ std::filesystem::path unpacked_dir) {
unpacked_dir_ = std::move(unpacked_dir);
}
pkgid_ = std::move(pkgid);
}
-void RecoveryFile::set_type(RequestType type) {
- type_ = type;
+
+void RecoveryFile::set_backup_done(bool backup_done) {
+ backup_done_ = backup_done;
}
-const boost::filesystem::path& RecoveryFile::unpacked_dir() const {
+void RecoveryFile::set_cleanup(bool cleanup) {
+ cleanup_ = cleanup;
+}
+
+void RecoveryFile::set_security_operation_done(bool security_operation_done) {
+ security_operation_done_ = security_operation_done;
+}
+
+const std::filesystem::path& RecoveryFile::unpacked_dir() const {
return unpacked_dir_;
}
return type_;
}
+bool RecoveryFile::backup_done() const {
+ return backup_done_;
+}
+
+bool RecoveryFile::cleanup() const {
+ return cleanup_;
+}
+
+bool RecoveryFile::security_operation_done() const {
+ return security_operation_done_;
+}
+
bool RecoveryFile::ReadFileContent() {
FILE* handle = fopen(path_.c_str(), "r");
if (!handle) {
return true;
}
pkgid_ = TruncateNewLine(data.data());
+ if (!fgets(data.data(), data.size(), handle)) {
+ fclose(handle);
+ return true;
+ }
+ std::string backup_flag = TruncateNewLine(data.data());
+ if (backup_flag == "true")
+ backup_done_ = true;
+ else
+ backup_done_ = false;
+ if (!fgets(data.data(), data.size(), handle)) {
+ fclose(handle);
+ return true;
+ }
+ std::string cleanup_flag = TruncateNewLine(data.data());
+ if (cleanup_flag == "cleanup")
+ cleanup_ = true;
+ else
+ cleanup_ = false;
+ if (!fgets(data.data(), data.size(), handle)) {
+ fclose(handle);
+ return true;
+ }
+ std::string security_operation_done_flag = TruncateNewLine(data.data());
+ if (security_operation_done_flag == "true")
+ security_operation_done_ = true;
+ else
+ security_operation_done_ = false;
fclose(handle);
return true;
}
bool RecoveryFile::WriteAndCommitFileContent() {
- FILE* handle = fopen(path_.c_str(), "w");
- if (!handle) {
+ if (fs::exists(path_)) {
+ std::error_code error;
+ fs::rename(path_, backup_path_, error);
+ if (error) {
+ LOG(ERROR) << "Cannot backup recovery file:" << path_ <<
+ ", error: " << error;
+ return false;
+ }
+ }
+
+ std::ofstream ofs(path_);
+ if (!ofs) {
LOG(ERROR) << "Cannot write recovery file";
return false;
}
+
switch (type_) {
case RequestType::Install:
- fputs(kRecoveryInstallString, handle);
+ ofs << kRecoveryInstallString << std::endl;
break;
case RequestType::Update:
- fputs(kRecoveryUpdateString, handle);
+ ofs << kRecoveryUpdateString << std::endl;
break;
case RequestType::Uninstall:
- fputs(kRecoveryUninstallationString, handle);
+ ofs << kRecoveryUninstallationString << std::endl;
break;
case RequestType::Reinstall:
- fputs(kRecoveryRdsString, handle);
+ ofs << kRecoveryRdsString << std::endl;
break;
case RequestType::Delta:
- fputs(kRecoveryDeltaString, handle);
+ ofs << kRecoveryDeltaString << std::endl;
break;
case RequestType::MountInstall:
- fputs(kRecoveryMountInstallString, handle);
+ ofs << kRecoveryMountInstallString << std::endl;
break;
case RequestType::MountUpdate:
- fputs(kRecoveryMountUpdateString, handle);
+ ofs << kRecoveryMountUpdateString << std::endl;
+ break;
+ case RequestType::ReadonlyUpdateInstall:
+ ofs << kRecoveryReadonlyUpdateInstallString << std::endl;
+ break;
+ case RequestType::ReadonlyUpdateUninstall:
+ ofs << kRecoveryReadonlyUpdateUninstallString << std::endl;
break;
default:
- fputs(kRecoveryUnknownString, handle);
+ ofs << kRecoveryUnknownString << std::endl;
break;
}
- fputs("\n", handle);
- fputs(unpacked_dir_.c_str(), handle);
- fputs("\n", handle);
- fputs(pkgid_.c_str(), handle);
- fputs("\n", handle);
- fclose(handle);
- sync();
+ ofs << unpacked_dir_.c_str() << std::endl;
+ ofs << pkgid_ << std::endl;
+ ofs << (backup_done_ ? "true" : "false") << std::endl;
+ ofs << (cleanup_ ? "cleanup" : "rollback") << std::endl;
+ ofs << (security_operation_done_ ? "true" : "false") << std::endl;
+ ofs.flush();
+ ofs.close();
+ SyncFile(path_);
+
+ Remove(backup_path_);
return true;
}
} // namespace recovery
} // namespace common_installer
-