Remove boost dependency
[platform/core/appfw/app-installers.git] / src / common / step / backup / step_copy_backup.cc
index 10f8465..6460cf2 100644 (file)
@@ -7,38 +7,39 @@
 #include <sys/types.h>
 #include <tzplatform_config.h>
 
-#include <boost/filesystem/operations.hpp>
-#include <boost/system/error_code.hpp>
-
+#include <algorithm>
 #include <cassert>
 #include <cstdint>
+#include <filesystem>
 #include <string>
+#include <system_error>
 
-#include "common/paths.h"
+#include "common/utils/paths.h"
+#include "common/shared_dirs.h"
 #include "common/utils/file_util.h"
 #include "common/utils/user_util.h"
-#include "common/shared_dirs.h"
 
-namespace bf = boost::filesystem;
-namespace bs = boost::system;
 namespace ci = common_installer;
+namespace fs = std::filesystem;
 
 namespace {
 
 const char kExternalMemoryMountPoint[] = ".mmc";
 const char kSharedResPath[] = "shared/res";
 
-bool CheckFreeSpace(const bf::path& backup_path, const bf::path& shared_path) {
+bool CheckFreeSpace(const fs::path& backup_path, const fs::path& shared_path) {
   int64_t shared_size = ci::GetDirectorySize(shared_path);
+
   if (!ci::CheckFreeSpaceAtPath(shared_size, backup_path))
     return false;
 
   return true;
 }
 
-bool CreateSharedRes(const bf::path& src, const bf::path& dst) {
-  bs::error_code error;
-  bf::create_directories(dst / kSharedResPath, error);
+bool CreateSharedRes(const fs::path& src, const fs::path& dst) {
+  std::error_code error;
+
+  fs::create_directories(dst / kSharedResPath, error);
   if (error) {
     LOG(ERROR) << "Cannot create package directory";
     return false;
@@ -52,6 +53,24 @@ bool CreateSharedRes(const bf::path& src, const bf::path& dst) {
   return true;
 }
 
+bool Move(const std::filesystem::path& from,
+    const std::filesystem::path& to,
+    common_installer::FSFlag flag = common_installer::FSFlag::FS_NONE) {
+  if (fs::is_directory(from)) {
+    if (!common_installer::MoveDir(from, to / from.filename(), flag)) {
+      LOG(ERROR) << "Failed to move directory: " << from;
+      return false;
+    }
+  } else {
+    if (!common_installer::MoveFile(from, to / from.filename())) {
+      LOG(ERROR) << "Fail to move file: " << from;
+      return false;
+    }
+  }
+
+  return true;
+}
+
 }  // namespace
 
 namespace common_installer {
@@ -62,6 +81,7 @@ Step::Status StepCopyBackup::precheck() {
     LOG(ERROR) << "pkgid attribute is empty";
     return Step::Status::PACKAGE_NOT_FOUND;
   }
+
   if (context_->root_application_path.get().empty()) {
     LOG(ERROR) << "root_application_path attribute is empty";
     return Step::Status::INVALID_VALUE;
@@ -70,7 +90,13 @@ Step::Status StepCopyBackup::precheck() {
   install_path_ = context_->GetPkgPath();
   backup_path_ = GetBackupPathForPackagePath(context_->GetPkgPath());
 
-  if (!CheckFreeSpace(backup_path_, install_path_ / "shared")) {
+  // We only "copy" shared dir for backup.
+  // So if there is no shared dir, we don't need to check free space.
+  fs::path shared_dir = install_path_ / "shared";
+  if (!fs::exists(shared_dir))
+    return Status::OK;
+
+  if (!CheckFreeSpace(backup_path_, shared_dir)) {
     LOG(ERROR) << "not enough space for backup";
     return Step::Status::OUT_OF_SPACE;
   }
@@ -79,9 +105,9 @@ Step::Status StepCopyBackup::precheck() {
 }
 
 Step::Status StepCopyBackup::process() {
-  // if backup file exists
   if (!CleanBackupDirectory())
     return Status::APP_DIR_ERROR;
+
   if (!Backup())
     return Status::APP_DIR_ERROR;
 
@@ -89,20 +115,13 @@ Step::Status StepCopyBackup::process() {
     return Status::APP_DIR_ERROR;
 
   RemoveContent();
+
   return Status::OK;
 }
 
 Step::Status StepCopyBackup::clean() {
-  recovery::RecoveryFile* recovery_file =
-      context_->recovery_info.get().recovery_file.get();
-  recovery_file->set_cleanup(true);
-  recovery_file->WriteAndCommitFileContent();
-
-  if (!CleanBackupDirectory()) {
-    LOG(DEBUG) << "Cannot remove backup directory";
-    return Status::APP_DIR_ERROR;
-  }
-  LOG(DEBUG) << "Applications files backup directory removed";
+  LOG(DEBUG) << "Remove Applications files backup directory";
+  CleanBackupDirectory();
 
   if (context_->external_storage)
     context_->external_storage->Commit();
@@ -114,31 +133,32 @@ Step::Status StepCopyBackup::undo() {
   if (context_->external_storage)
     context_->external_storage->Abort();
 
-  // if backup was created then restore files
-  if (bf::exists(backup_path_)) {
-    if (!RollbackApplicationDirectory()) {
-      LOG(ERROR) << "Failed to revert package directory";
-      return Status::APP_DIR_ERROR;
-    }
-    LOG(DEBUG) << "Application files reverted from backup";
+  if (!fs::exists(backup_path_))
+    return Status::OK;
+
+  if (!RollbackApplicationDirectory()) {
+    LOG(ERROR) << "Failed to revert package directory";
+    return Status::APP_DIR_ERROR;
   }
+
+  LOG(DEBUG) << "Application files reverted from backup";
+
   return Status::OK;
 }
 
 bool StepCopyBackup::Backup() {
-  // create backup directory
-  bs::error_code error;
+  std::error_code error;
 
-  if (!bf::exists(backup_path_)) {
-    bf::create_directories(backup_path_, error);
+  if (!fs::exists(backup_path_)) {
+    fs::create_directories(backup_path_, error);
     if (error) {
       LOG(ERROR) << "Failed to create backup directory: " << backup_path_;
       return false;
     }
   }
   // create copy of old package content skipping the external memory mount point
-  for (bf::directory_iterator iter(context_->GetPkgPath());
-       iter != bf::directory_iterator(); ++iter) {
+  for (fs::directory_iterator iter(context_->GetPkgPath());
+       iter != fs::directory_iterator(); ++iter) {
     if (iter->path().filename() == kExternalMemoryMountPoint)
       continue;
 
@@ -147,7 +167,7 @@ bool StepCopyBackup::Backup() {
     if (context_->external_storage) {
       auto& ext_dirs = context_->external_storage->external_dirs();
       auto found = std::find(ext_dirs.begin(), ext_dirs.end(),
-                             iter->path().filename());
+                             iter->path().filename().string());
       if (found != ext_dirs.end()) {
         bool done = MoveMountPointContent(iter->path(),
             backup_path_ / iter->path().filename());
@@ -159,108 +179,84 @@ bool StepCopyBackup::Backup() {
       }
     }
 
-    if (bf::is_directory(iter->path())) {
-      if (!MoveDir(iter->path(), backup_path_ / iter->path().filename())) {
-        LOG(ERROR) << "Fail to backup package directory of: " << iter->path();
-        return false;
-      }
-    } else {
-      if (!MoveFile(iter->path(), backup_path_ / iter->path().filename())) {
-        LOG(ERROR) << "Fail to backup package file: " << iter->path();
-        return false;
-      }
-    }
+    if (!Move(iter->path(), backup_path_))
+      return false;
   }
 
-  if (bf::exists(backup_path_ / kSharedResPath) &&
-      bf::exists(context_->unpacked_dir_path.get() / kSharedResPath))
-    if (!CreateSharedRes(backup_path_, context_->GetPkgPath()))
-      return false;
+  AddRecoveryInfo();
 
-  recovery::RecoveryFile* recovery_file =
-      context_->recovery_info.get().recovery_file.get();
-  recovery_file->set_backup_done(true);
-  recovery_file->WriteAndCommitFileContent();
   LOG(INFO) << "Old package context saved to: " << backup_path_;
   return true;
 }
 
 
-bool StepCopyBackup::MoveMountPointContent(const boost::filesystem::path& from,
-                                           const boost::filesystem::path& to) {
-  bs::error_code error;
-  bf::create_directories(to, error);
+bool StepCopyBackup::MoveMountPointContent(const std::filesystem::path& from,
+                                           const std::filesystem::path& to) {
+  std::error_code error;
+  fs::create_directories(to, error);
 
-  for (bf::directory_iterator iter(from);
-       iter != bf::directory_iterator(); ++iter) {
-    if (bf::is_directory(iter->path())) {
-      if (!MoveDir(iter->path(), to / iter->path().filename())) {
-        LOG(ERROR) << "Fail to backup package directory of: " << iter->path();
-        return false;
-      }
-    } else if (bf::is_symlink(symlink_status(iter->path()))) {
-      bs::error_code error;
-      bf::copy_symlink(iter->path(), to / iter->path().filename(), error);
+  for (fs::directory_iterator iter(from);
+       iter != fs::directory_iterator(); ++iter) {
+    if (fs::is_symlink(symlink_status(iter->path()))) {
+      fs::copy_symlink(iter->path(), to / iter->path().filename(), error);
       if (error) {
         LOG(ERROR) << "Failed to backup package symlink: " << iter->path();
         return false;
       }
     } else {
-      if (!MoveFile(iter->path(), to / iter->path().filename())) {
+      if (!Move(iter->path(), to)) {
         LOG(ERROR) << "Fail to backup package file: " << iter->path();
         return false;
       }
     }
   }
+
   return true;
 }
 
 void StepCopyBackup::RemoveContent() {
   if (context_->request_type.get() == RequestType::Update &&
-    !context_->external_storage && bf::exists(install_path_ / ".mmc")) {
+    !context_->external_storage && fs::exists(install_path_ / ".mmc")) {
     LOG(WARNING) << "Remove unnecessary files for external storage";
-    bs::error_code error;
-    bf::remove((install_path_ / ".mmc"), error);
+
+    std::error_code error;
+    fs::remove((install_path_ / ".mmc"), error);
     if (error)
       LOG(WARNING) << "error while remove files";
   }
 }
 
 bool StepCopyBackup::NewContent() {
-  bs::error_code error;
-  bf::create_directories(install_path_.parent_path(), error);
+  ci::RemoveRWDirectories(context_->unpacked_dir_path.get());
+
+  std::error_code error;
+  fs::create_directories(install_path_.parent_path(), error);
   if (error) {
     LOG(ERROR) << "Cannot create package directory";
     return false;
   }
-  for (bf::directory_iterator iter(context_->unpacked_dir_path.get());
-       iter != bf::directory_iterator(); ++iter) {
-    if (bf::is_directory(iter->path())) {
-      if (!MoveDir(iter->path(), install_path_ / iter->path().filename(),
-        FS_MERGE_SKIP)) {
-        LOG(ERROR) << "Fail to copy tmp dir: " << iter->path()
-                   << " to dst dir: " << install_path_;
-        return false;
-      }
-    } else {
-      if (!MoveFile(iter->path(), install_path_ / iter->path().filename())) {
-        LOG(ERROR) << "Fail to copy tmp dir: " << iter->path()
-                   << " to dst dir: " << install_path_;
-        return false;
-      }
-    }
+
+  if (ShouldBackupSharedRes()) {
+    if (!CreateSharedRes(backup_path_, context_->GetPkgPath()))
+      return false;
+  }
+
+  for (fs::directory_iterator iter(context_->unpacked_dir_path.get());
+       iter != fs::directory_iterator(); ++iter) {
+    if (!Move(iter->path(), install_path_, FS_MERGE_SKIP))
+      return false;
   }
 
   // If other application tries to access shared/res of package being installed,
   // it will be failed due to permission deny. Set its permission before
   // StepChangeOwnershipAndPermission to prevent it.
   uid_t uid = context_->uid.get();
-  boost::optional<gid_t> gid = common_installer::GetGidByUid(uid);
+  std::optional<gid_t> gid = common_installer::GetGidByUid(uid);
   if (!gid) {
     LOG(ERROR) << "Failed to get gid";
     return false;
   }
-  if (bf::exists(install_path_ / "shared/res") &&
+  if (fs::exists(install_path_ / "shared/res") &&
       !common_installer::SetOwnershipAll(
           install_path_ / "shared/res", uid, *gid)) {
     LOG(ERROR) << "Failed to set ownership";
@@ -274,27 +270,29 @@ bool StepCopyBackup::NewContent() {
 }
 
 bool StepCopyBackup::CleanBackupDirectory() {
-  if (bf::exists(backup_path_)) {
-    bs::error_code error;
-    bf::remove_all(backup_path_, error);
-    if (error)
-      return false;
-  }
-  return true;
+  return ci::RemoveAll(backup_path_);
 }
 
 bool StepCopyBackup::RollbackApplicationDirectory() {
-  bs::error_code error;
-  if (bf::exists(context_->GetPkgPath())) {
-    bf::remove_all(context_->GetPkgPath(), error);
-    if (error) {
-      return false;
+  std::error_code error;
+  fs::path root_path = context_->GetPkgPath();
+  if (fs::exists(root_path)) {
+    for (fs::directory_iterator iter(root_path);
+         iter != fs::directory_iterator(); ++iter) {
+      fs::remove_all(iter->path(), error);
+      if (error)
+        return false;
     }
   }
 
-  if (!MoveDir(backup_path_, context_->GetPkgPath())) {
-    return false;
+  for (fs::directory_iterator iter(backup_path_);
+       iter != fs::directory_iterator(); ++iter) {
+    if (!Move(iter->path(), root_path)) {
+      LOG(ERROR) << "Failed to recovery backup file(" << iter->path() << ")";
+      return false;
+    }
   }
+  RemoveAll(backup_path_);
 
   uid_t uid = context_->uid.get();
   // restore ownership changed during installation
@@ -304,5 +302,20 @@ bool StepCopyBackup::RollbackApplicationDirectory() {
   return true;
 }
 
+void StepCopyBackup::AddRecoveryInfo() {
+  recovery::RecoveryFile* recovery_file =
+      context_->recovery_info.get().recovery_file.get();
+  recovery_file->set_backup_done(true);
+  recovery_file->WriteAndCommitFileContent();
+}
+
+bool StepCopyBackup::ShouldBackupSharedRes() {
+  if (fs::exists(backup_path_ / kSharedResPath) &&
+      fs::exists(context_->unpacked_dir_path.get() / kSharedResPath))
+    return true;
+
+  return false;
+}
+
 }  // namespace backup
 }  // namespace common_installer