Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / recovery_file.cc
index 966c06f..d7999ab 100644 (file)
@@ -4,22 +4,21 @@
 
 #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 {
 
@@ -30,6 +29,8 @@ const char kRecoveryRdsString[] = "RDS";
 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 = {
@@ -40,6 +41,10 @@ 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) {
@@ -55,8 +60,8 @@ namespace common_installer {
 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;
   }
@@ -69,8 +74,8 @@ std::unique_ptr<RecoveryFile> RecoveryFile::CreateRecoveryFile(
 }
 
 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;
   }
@@ -83,8 +88,10 @@ std::unique_ptr<RecoveryFile> RecoveryFile::OpenRecoveryFile(
   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();
@@ -103,6 +110,8 @@ RecoveryFile::RecoveryFile(const bf::path& path, RequestType type, bool load)
 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() {
@@ -114,7 +123,7 @@ bool RecoveryFile::is_detached() const {
 }
 
 void RecoveryFile::set_unpacked_dir(
-    boost::filesystem::path unpacked_dir) {
+    std::filesystem::path unpacked_dir) {
   unpacked_dir_ = std::move(unpacked_dir);
 }
 
@@ -122,11 +131,20 @@ void RecoveryFile::set_pkgid(std::string pkgid) {
   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_;
 }
 
@@ -138,6 +156,18 @@ RequestType RecoveryFile::type() const {
   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) {
@@ -169,52 +199,98 @@ bool RecoveryFile::ReadFileContent() {
     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
-