bool StepCopyStorageDirectories::MoveAppStorage(
const bf::path& in_src,
const bf::path& in_dst,
- const char *key) {
+ const char *key,
+ bool merge_dirs) {
bf::path src = in_src / key;
bf::path dst = in_dst / key;
- return common_installer::MoveDir(src, dst);
+ return common_installer::MoveDir(src, dst,
+ merge_dirs ? common_installer::FS_MERGE_DIRECTORIES
+ : common_installer::FS_NONE);
}
common_installer::Step::Status StepCopyStorageDirectories::precheck() {
if (!MoveAppStorage(backup_path_,
context_->pkg_path.get(),
- kSharedLocation)) {
+ kSharedLocation, true)) {
LOG(ERROR) << "Failed to restore shared directory for widget in update";
return Status::APP_DIR_ERROR;
}
return true;
}
-bool CopyDir(const bf::path& src, const bf::path& dst) {
+bool CopyDir(const bf::path& src, const bf::path& dst, FSFlag flags) {
try {
// Check whether the function call is valid
if (!bf::exists(src) || !bf::is_directory(src)) {
- LOG(ERROR) << "Source directory " << src.string()
+ LOG(ERROR) << "Source directory " << src
<< " does not exist or is not a directory.";
return false;
}
- if (bf::exists(dst)) {
- LOG(ERROR) << "Destination directory " << dst.string()
- << " already exists.";
- return false;
- }
- // Create the destination directory
- if (!CreateDir(dst)) {
- LOG(ERROR) << "Unable to create destination directory" << dst.string();
- return false;
+ if (!bf::exists(dst)) {
+ // Create the destination directory
+ if (!CreateDir(dst)) {
+ LOG(ERROR) << "Unable to create destination directory" << dst;
+ return false;
+ }
+ } else {
+ if (!(flags & FS_MERGE_DIRECTORIES)) {
+ LOG(ERROR) << "Destination directory " << dst.string()
+ << " already exists.";
+ return false;
+ }
}
} catch (const bf::filesystem_error& error) {
LOG(ERROR) << "Failed to copy directory: " << error.what();
++file) {
try {
bf::path current(file->path());
+ bf::path target = dst / current.filename();
if (bf::is_directory(current)) {
// Found directory: Recursion
- if (!CopyDir(current, dst / current.filename())) {
+ if (!CopyDir(current, target, flags)) {
return false;
}
} else if (bf::is_symlink(current)) {
- // Found symlink
- bf::copy_symlink(current, dst / current.filename());
+ if ((flags & FS_MERGE_DIRECTORIES) && bf::exists(target))
+ continue;
+ bf::copy_symlink(current, target);
} else {
- // Found file: Copy
- bf::copy_file(current, dst / current.filename());
+ if ((flags & FS_MERGE_DIRECTORIES) && bf::exists(target))
+ continue;
+ bf::copy_file(current, target);
}
} catch (const bf::filesystem_error& error) {
LOG(ERROR) << "Failed to copy directory: " << error.what();
return true;
}
-bool MoveDir(const bf::path& src, const bf::path& dst) {
- if (bf::exists(dst)) {
- LOG(ERROR) << "Destination directory does not exist: " << dst;
+bool MoveDir(const bf::path& src, const bf::path& dst, FSFlag flags) {
+ if (bf::exists(dst) && !(flags & FS_MERGE_DIRECTORIES)) {
+ LOG(ERROR) << "Destination directory does exist: " << dst;
return false;
}
bf::rename(src, dst, error);
if (error) {
LOG(WARNING) << "Cannot move directory: " << src << ". Will copy/remove...";
- if (!CopyDir(src, dst)) {
+ if (!CopyDir(src, dst, flags)) {
LOG(ERROR) << "Cannot copy directory: " << src;
return false;
}
namespace common_installer {
+enum FSFlag {
+ FS_NONE = 0,
+ FS_MERGE_DIRECTORIES = (1 << 0)
+};
+
bool CreateDir(const boost::filesystem::path& path);
bool CopyDir(const boost::filesystem::path& src,
- const boost::filesystem::path& dst);
+ const boost::filesystem::path& dst, FSFlag flags = FS_NONE);
bool CopyFile(const boost::filesystem::path& src,
const boost::filesystem::path& dst);
bool MoveDir(const boost::filesystem::path& src,
- const boost::filesystem::path& dst);
+ const boost::filesystem::path& dst, FSFlag flags = FS_NONE);
bool MoveFile(const boost::filesystem::path& src,
const boost::filesystem::path& dst);