1 // Copyright (c) 2016 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 "wgt/step/filesystem/step_wgt_undo_patch_storage_directories.h"
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/filesystem/path.hpp>
9 #include <boost/system/error_code.hpp>
11 #include <common/utils/file_util.h>
13 namespace bf = boost::filesystem;
14 namespace bs = boost::system;
15 namespace ci = common_installer;
19 const char kSharedLocation[] = "shared";
20 const char kSharedResLocation[] = "shared/res";
21 const char kResWgtSubPath[] = "res/wgt";
26 namespace filesystem {
28 ci::Step::Status StepWgtUndoPatchStorageDirectories::process() {
29 int version = std::stoi(context_->manifest_data.get()->api_version);
32 "Unlinking and moving widget's shared/res directory content back in "
33 << context_->GetPkgPath();
34 if (!UndoShareDirFor3x())
35 return Status::APP_DIR_ERROR;
41 ci::Step::Status StepWgtUndoPatchStorageDirectories::clean() {
42 if (!backup_dir_.empty())
43 ci::RemoveAll(backup_dir_);
47 ci::Step::Status StepWgtUndoPatchStorageDirectories::undo() {
48 if (!backup_dir_.empty()) {
49 LOG(DEBUG) << "Restore res/wgt/shared/res from backup dir";
51 bf::path wgt_shared_res_dir =
52 context_->GetPkgPath() / kResWgtSubPath / kSharedResLocation;
53 bf::path backup_wgt_shared_res = backup_dir_ / "wgt_shared_res";
54 if (!backup_wgt_shared_res.empty()) {
55 if (!ci::RemoveAll(wgt_shared_res_dir)) {
56 LOG(ERROR) << "Failed to remove res/wgt/shared/res";
57 return Status::APP_DIR_ERROR;
59 if (!ci::CopyDir(backup_dir_, wgt_shared_res_dir,
60 ci::FS_MERGE_OVERWRITE, false)) {
61 LOG(ERROR) << "Failed to copy from backup";
62 return Status::APP_DIR_ERROR;
65 // restore original contents
66 bf::path shared_res_dir = context_->GetPkgPath() / kSharedResLocation;
67 bf::path backup_shared_res = backup_dir_ / "shared_res";
68 if (!backup_shared_res.empty()) {
69 if (!ci::CopyDir(backup_dir_, shared_res_dir,
70 ci::FS_MERGE_OVERWRITE, false)) {
71 LOG(ERROR) << "Failed to copy from backup";
72 return Status::APP_DIR_ERROR;
79 bool StepWgtUndoPatchStorageDirectories::UndoShareDirFor3x() {
80 // check if ${pkg_path}/shared/res exists
81 bf::path shared_res_dir = context_->GetPkgPath() / kSharedResLocation;
82 if (!bf::exists(shared_res_dir))
84 bf::path wgt_shared_res_dir =
85 context_->GetPkgPath() / kResWgtSubPath / kSharedResLocation;
86 if (!bf::exists(wgt_shared_res_dir))
89 if (bf::is_symlink(wgt_shared_res_dir)) {
90 LOG(ERROR) << "Can't support this step, pkg should be fully updated";
95 backup_dir_ = context_->unpacked_dir_path.get();
96 backup_dir_ += ".SharedRes";
97 bf::path backup_shared_res = backup_dir_ / "shared_res";
98 if (!ci::CreateDir(backup_shared_res))
100 bf::path backup_wgt_shared_res = backup_dir_ / "wgt_shared_res";
101 if (!ci::CopyDir(wgt_shared_res_dir, backup_wgt_shared_res,
102 ci::FS_MERGE_OVERWRITE, false)) {
107 // unlink and move all linked contents from ${pkg_path}/shared/res
108 // to ${pkg_path}/res/wgt/shared/res
109 bf::directory_iterator end_itr;
110 for (bf::directory_iterator itr(wgt_shared_res_dir); itr != end_itr; ++itr) {
111 bf::path link_file = itr->path();
112 if (!bf::is_symlink(link_file)) {
115 bf::path link_target = bf::read_symlink(link_file);
116 if (link_target.native().substr(0, shared_res_dir.native().length()) !=
117 shared_res_dir.native()) {
120 if (!ci::Remove(link_file))
122 bf::path tmp_backup = backup_shared_res / link_target.filename();
123 if (bf::is_directory(link_target)) {
124 if (!ci::CopyDir(link_target, tmp_backup, ci::FS_MERGE_OVERWRITE, false))
126 if (!ci::MoveDir(link_target, link_file, ci::FS_MERGE_OVERWRITE))
129 if (!ci::CopyFile(link_target, tmp_backup))
131 if (!ci::MoveFile(link_target, link_file, true))
139 } // namespace filesystem