Skip the security registration if it is unnecessary
[platform/core/appfw/app-installers.git] / src / common / step / filesystem / step_recover_files.cc
index da13837..5bd1ff8 100644 (file)
 #include <boost/filesystem/path.hpp>
 #include <boost/system/error_code.hpp>
 
-#include "common/paths.h"
+#include "common/utils/paths.h"
+#include "common/recovery_file.h"
 #include "common/utils/file_util.h"
+#include "common/utils/request.h"
 
 namespace bf = boost::filesystem;
 namespace bs = boost::system;
 
+namespace {
+
+const char kExternalMemoryMountPoint[] = ".mmc";
+
+bool Move(const boost::filesystem::path& from,
+    const boost::filesystem::path& to,
+    common_installer::FSFlag flag = common_installer::FSFlag::FS_NONE) {
+  if (bf::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 {
 namespace filesystem {
 
 Step::Status StepRecoverFiles::RecoveryNew() {
-  if (!SetPackagePath()) {
-    LOG(DEBUG) << "Package files recovery not needed";
-    return Status::OK;
-  }
-  if (bf::exists(context_->pkg_path.get())) {
-    bs::error_code error;
-    bf::remove_all(context_->pkg_path.get(), error);
-  }
+  if (!RemoveAll(context_->GetPkgPath()))
+    return Status::RECOVERY_ERROR;
+
   LOG(INFO) << "Package files recovery done";
   return Status::OK;
 }
 
 Step::Status StepRecoverFiles::RecoveryUpdate() {
-  if (!SetPackagePath()) {
-    LOG(DEBUG) << "Package files recovery not needed";
-    return Status::OK;
-  }
-  bf::path backup_path = GetBackupPathForPackagePath(context_->pkg_path.get());
+  recovery::RecoveryFile* recovery_file =
+      context_->recovery_info.get().recovery_file.get();
+  bool backup_done = recovery_file->backup_done();
+  bf::path backup_path = GetBackupPathForPackagePath(context_->GetPkgPath());
   if (bf::exists(backup_path)) {
-    if (bf::exists(context_->pkg_path.get())) {
-      bs::error_code error;
-      bf::remove_all(context_->pkg_path.get(), error);
-      if (error) {
-        LOG(ERROR) << "Cannot restore widget files to its correct location";
-        return Status::RECOVERY_ERROR;
+    // Remove pkgdir only if backup original contents is completely done.
+    if (backup_done) {
+      for (bf::directory_iterator iter(context_->GetPkgPath());
+           iter != bf::directory_iterator(); ++iter) {
+        if (iter->path().filename() == kExternalMemoryMountPoint)
+          continue;
+
+        if (!RemoveAll(iter->path())) {
+          LOG(ERROR) << "Cannot restore widget files to its correct location";
+          return Status::RECOVERY_ERROR;
+        }
       }
+      // it may fail during recovery.
+      recovery_file->set_backup_done(false);
+      recovery_file->WriteAndCommitFileContent();
     }
-    (void) MoveDir(backup_path, context_->pkg_path.get());
+
+    // create copy of old package content skipping the external memory mount point
+    for (bf::directory_iterator iter(backup_path);
+         iter != bf::directory_iterator(); ++iter) {
+      if (!Move(iter->path(), context_->GetPkgPath()))
+        return Status::RECOVERY_ERROR;
+    }
+
+    RemoveAll(backup_path);
   }
   LOG(INFO) << "Package files recovery done";
   return Status::OK;
 }
 
-bool StepRecoverFiles::SetPackagePath() {
-  if (context_->pkgid.get().empty())
-    return false;
-  context_->pkg_path.set(
-      context_->root_application_path.get() / context_->pkgid.get());
-  return true;
+Step::Status StepRecoverFiles::RecoveryMountNew() {
+  bf::path zip_location = GetZipPackageLocation(
+        context_->GetPkgPath(), context_->pkgid.get());
+  Remove(zip_location);
+  RemoveAll(context_->GetPkgPath());
+  LOG(INFO) << "Package files recovery done";
+  return Status::OK;
+}
+
+Step::Status StepRecoverFiles::RecoveryMountUpdate() {
+  bf::path zip_location = GetZipPackageLocation(
+        context_->GetPkgPath(), context_->pkgid.get());
+  bf::path backup_zip_location = GetBackupPathForZipFile(zip_location);
+  if (bf::exists(backup_zip_location)) {
+    Remove(zip_location);
+    MoveFile(backup_zip_location, zip_location);
+  }
+
+  // During mount update some files are still backed up separately from zip
+  // package file. This is because of the fact that we need to access bin/, lib/
+  // directories without mounting zip package file. In other words in mount
+  // install or mount update mode we don't mount everything - some files are
+  // still unpacked due to necessity.
+  bf::path backup_path = GetBackupPathForPackagePath(context_->GetPkgPath());
+  if (bf::exists(backup_path)) {
+    if (!MoveDir(backup_path, context_->GetPkgPath(),
+                 FS_MERGE_OVERWRITE | FS_COMMIT_COPY_FILE)) {
+      LOG(ERROR) << "Failed to recovery backup file "
+                 << "in recovery of mount update";
+      return Status::APP_DIR_ERROR;
+    }
+  }
+
+  LOG(INFO) << "Package files recovery done";
+  return Status::OK;
+}
+
+Step::Status StepRecoverFiles::RecoveryReadonlyUpdateInstall() {
+  // Remove package directory at RW area
+  bf::path pkg_path =
+      bf::path(GetRootAppPath(false, context_->uid.get())) /
+      context_->pkgid.get();
+  if (!RemoveAll(pkg_path))
+    return Status::RECOVERY_ERROR;
+
+  LOG(INFO) << "Package files recovery done";
+  return Status::OK;
+}
+
+Step::Status StepRecoverFiles::Cleanup() {
+  recovery::RecoveryFile* recovery_file =
+      context_->recovery_info.get().recovery_file.get();
+  bf::path root_path(GetRootAppPath(
+      context_->is_readonly_package.get(), context_->uid.get()));
+  bf::path backup_path = GetBackupPathForPackagePath(
+      root_path / recovery_file->pkgid());
+  if (!bf::exists(backup_path))
+    return Status::OK;
+
+  if (!RemoveAll(backup_path)) {
+    LOG(ERROR) << "Failed to remove backup path";
+    return Status::RECOVERY_ERROR;
+  }
+
+  return Status::OK;
 }
 
 }  // namespace filesystem