return true;
}
+bool BackupSharedDataDirectories(const bf::path& apps_rw,
+ const std::string& pkgid) {
+ if (!ci::MakeBackup(apps_rw / pkgid / kSharedDataDir))
+ return false;
+ if (!ci::MakeBackup(apps_rw / kSharedDir / pkgid / kData))
+ return false;
+ if (!ci::MakeBackup(apps_rw / kSharedTmpDir / pkgid))
+ return false;
+ return true;
+}
+
+bool RestoreSharedDataDirectories(const bf::path& apps_rw,
+ const std::string& pkgid) {
+ if (!ci::RestoreBackup(apps_rw / pkgid / kSharedDataDir))
+ return false;
+ if (!ci::RestoreBackup(apps_rw / kSharedDir / pkgid / kData))
+ return false;
+ if (!ci::RestoreBackup(apps_rw / kSharedTmpDir / pkgid))
+ return false;
+ return true;
+}
+
+bool RemoveBackupSharedDataDirectories(const bf::path& apps_rw,
+ const std::string& pkgid) {
+ if (!ci::RemoveBackup(apps_rw / pkgid / kSharedDataDir))
+ return false;
+ if (!ci::RemoveBackup(apps_rw / kSharedDir / pkgid / kData))
+ return false;
+ if (!ci::RemoveBackup(apps_rw / kSharedTmpDir / pkgid))
+ return false;
+ return true;
+}
+
} // namespace
namespace common_installer {
return result;
}
-bool UpdateSkelDirectories(const std::string& pkgid,
- bool is_remove_shareddata) {
- bf::path root_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelAppDir);
- LOG(DEBUG) << ((is_remove_shareddata) ? "Removing" : "Creating")
- << " skel directory for pkgid: " << pkgid;
- if (is_remove_shareddata) {
- if (!DeleteSharedDataDirectories(root_path, pkgid))
- return false;
- return true;
- }
-
- if (!CreateSharedDataDirectories(root_path, pkgid))
- return false;
-
- std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, root_path / pkgid, kGlobalUserUid,
- false, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: "
- << root_path / pkgid
- << ", error_message: " << error_message;
- return false;
- }
-
- return true;
-}
-
bool DeleteSkelDirectories(const std::string& pkgid) {
bf::path path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
bf::path(kSkelAppDir);
return true;
}
-bool CreateSharedData(const bf::path& path,
- const std::string& pkgid) {
- return CreateSharedDataDirectories(path, pkgid);
-}
-
-bool UpdateUserDirectory(const std::string& pkgid, bool is_remove_shareddata) {
- UserList list = ci::GetUserList();
- for (auto l : list) {
- bf::path root_path(std::get<2>(l) / "apps_rw");
- bf::path pkg_path(root_path / pkgid);
- uid_t uid = std::get<0>(l);
- LOG(DEBUG) << ((is_remove_shareddata) ? "Deleting" : "Adding")
- << " shareddata directory for uid: " << uid;
-
- if (is_remove_shareddata)
- return DeleteSharedDataDirectories(root_path, pkgid);
-
- if (!CreateSharedDataDirectories(root_path, pkgid)) {
- LOG(ERROR) << "Failed to create shared directory: "
- << root_path / pkgid;
- return false;
- }
-
- gid_t gid = std::get<1>(l);
- std::vector<std::string> shared_dirs(kSharedDataEntries);
- for (auto entry : shared_dirs) {
- bf::path dst = root_path / entry / pkgid;
- if (!SetDirectoryOwnerAndPermissions(dst, uid, gid))
- return false;
- for (bf::recursive_directory_iterator iter(dst);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetSharedDirOwnerAndPermissions(iter->path(), uid))
- return false;
- }
- }
-
- if (!SetDirectoryOwnerAndPermissions(pkg_path, uid, gid))
- return false;
- for (bf::recursive_directory_iterator iter(pkg_path);
- iter != bf::recursive_directory_iterator(); ++iter) {
- if (!SetDirectoryOwnerAndPermissions(iter->path(),
- uid, gid))
- return false;
- }
-
- std::string error_message;
- if (!RegisterSecurityContextForPath(pkgid, pkg_path, uid,
- false, &error_message)) {
- LOG(ERROR) << "Failed to register security context for path: "
- << pkg_path << ", error_message: " << error_message;
- return false;
- }
- }
- return true;
-}
-
bool CreateGlobalAppSymlinksForAllUsers(const std::string& pkgid) {
bf::path src_dir = bf::path(tzplatform_getenv(TZ_SYS_RW_APP)) / pkgid;
if (!bf::exists(src_dir)) {
return false;
}
+bool CreateSharedDataDir(const std::string& pkgid, uid_t uid) {
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ if (!CreateSharedDataDirectories(apps_rw, pkgid))
+ return false;
+
+ bf::path path = apps_rw / pkgid;
+ std::string error_message;
+ if (!ci::RegisterSecurityContextForPath(pkgid, path, uid, false,
+ &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: " << path
+ << ", error_message: " << error_message;
+ return false;
+ }
+
+ return true;
+}
+
+bool CreatePerUserSharedDataDir(const std::string& pkgid) {
+ // create skel dir
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ LOG(DEBUG) << "Creating directory : " << skel_apps_rw;
+ if (!CreateSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ std::string error_message;
+ if (!ci::RegisterSecurityContextForPath(pkgid, skel_apps_rw / pkgid,
+ kGlobalUserUid, false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << skel_apps_rw / pkgid << ", error_message: " << error_message;
+ return false;
+ }
+
+ // create per user dir
+ ci::UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ LOG(DEBUG) << "Adding shareddata directory for uid: " << uid;
+
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ if (!CreateSharedDataDirectories(apps_rw, pkgid))
+ return false;
+
+ std::string error_message;
+ if (!ci::RegisterSecurityContextForPath(pkgid, apps_rw / pkgid, uid,
+ false, &error_message)) {
+ LOG(ERROR) << "Failed to register security context for path: "
+ << apps_rw / pkgid << ", error_message: " << error_message;
+ return false;
+ }
+ }
+
+ return true;
+}
+
+bool DeleteSharedDataDir(const std::string& pkgid, uid_t uid) {
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ return DeleteSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool DeletePerUserSharedDataDir(const std::string& pkgid) {
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ if (!DeleteSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ if (!DeleteSharedDataDirectories(apps_rw, pkgid))
+ return false;
+ }
+
+ return true;
+}
+
+bool BackupSharedDataDir(const std::string& pkgid, uid_t uid) {
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ return BackupSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool BackupPerUserSharedDataDir(const std::string& pkgid) {
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ if (!BackupSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ if (!BackupSharedDataDir(pkgid, uid))
+ return false;
+ }
+
+ return true;
+}
+
+bool RestoreSharedDataDir(const std::string& pkgid, uid_t uid) {
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ return RestoreSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool RestorePerUserSharedDataDir(const std::string& pkgid) {
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ if (!RestoreSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ if (!RestoreSharedDataDir(pkgid, uid))
+ return false;
+ }
+
+ return true;
+}
+
+bool RemoveBackupSharedDataDir(const std::string& pkgid, uid_t uid) {
+ bf::path apps_rw = ci::GetRootAppPath(false, uid);
+ return RemoveBackupSharedDataDirectories(apps_rw, pkgid);
+}
+
+bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid) {
+ bf::path skel_apps_rw = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
+ bf::path(kSkelAppDir);
+ if (!RemoveBackupSharedDataDirectories(skel_apps_rw, pkgid))
+ return false;
+
+ ci::UserList list = ci::GetUserList();
+ for (auto l : list) {
+ uid_t uid = std::get<0>(l);
+ if (!RemoveBackupSharedDataDir(pkgid, uid))
+ return false;
+ }
+
+ return true;
+}
+
} // namespace common_installer
bool DeleteSkelDirectories(const std::string& pkgid);
/**
- * \brief Update skel directory
- *
- * \param pkgid package id
- * \param is_remove_shareddata shared/data directory add/delete flag
- *
- * \return true if succeed, false otherwise
- *
- */
-bool UpdateSkelDirectories(const std::string& pkgid,
- bool is_remove_shareddata);
-
-/**
* \brief Delete per-user directories
*
* \param pkgid package id
bool CopyUserDirectories(const std::string& pkgid);
/**
- * \brief Update per-user directory
- *
- * \param pkgid package id
- * \param is_remove_shareddata shared/data directory add/delete flag
- *
- * \return true if succeed, false otherwise
- *
- */
-bool UpdateUserDirectory(const std::string& pkgid,
- bool is_remove_shareddata);
-
-/**
- * \brief Create shared-data directories
- *
- * \param path root path
- * \param pkgid package id
- *
- * \return true if succeed, false otherwise
- *
- */
-bool CreateSharedData(const boost::filesystem::path& path,
- const std::string& pkgid);
-
-/**
* \brief Returns path prefix for internal storage, typically '/home'
*
* \return path prefix
*/
bool ShouldSupportLegacySharedDataDir(const std::string& api_version);
+/**
+ * \brief Creates shared data directory for specific package
+ *
+ * \param pkgid package id
+ * \param uid user id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool CreateSharedDataDir(const std::string& pkgid, uid_t uid);
+
+/**
+ * \brief Creates per user shared data directories for specific package
+ *
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool CreatePerUserSharedDataDir(const std::string& pkgid);
+
+/**
+ * \brief Deletes of shared data directory for specific package
+ *
+ * \param pkgid package id
+ * \param uid user id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool DeleteSharedDataDir(const std::string& pkgid, uid_t uid);
+
+/**
+ * \brief Deletes per user shared data directories for specific package
+ *
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool DeletePerUserSharedDataDir(const std::string& pkgid);
+
+/**
+ * \brief Backups shared data directories for specific package
+ *
+ * \param pkgid package id
+ * \param uid user id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool BackupSharedDataDir(const std::string& pkgid, uid_t uid);
+
+/**
+ * \brief Backups per user shared data directories for specific package
+ *
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool BackupPerUserSharedDataDir(const std::string& pkgid);
+
+/**
+ * \brief Restores shared data directories for specific package
+ *
+ * \param pkgid package id
+ * \param uid user id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool RestoreSharedDataDir(const std::string& pkgid, uid_t uid);
+
+/**
+ * \brief Restores per user shared data directories for specific package
+ *
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool RestorePerUserSharedDataDir(const std::string& pkgid);
+
+/**
+ * \brief Removes backup of shared data directories for specific package
+ *
+ * \param pkgid package id
+ * \param uid user id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool RemoveBackupSharedDataDir(const std::string& pkgid, uid_t uid);
+
+/**
+ * \brief Removes backup of per user shared data directories for specific package
+ *
+ * \param pkgid package id
+ *
+ * \return true if succeed, false otherwise
+ */
+bool RemoveBackupPerUserSharedDataDir(const std::string& pkgid);
+
} // namespace common_installer
#endif // COMMON_SHARED_DIRS_H_
#include <string>
#include <vector>
+#include "common/paths.h"
#include "common/privileges.h"
+#include "common/security_registration.h"
#include "common/shared_dirs.h"
#include "common/utils/file_util.h"
#include "common/utils/glist_range.h"
+#include "common/utils/user_util.h"
namespace bf = boost::filesystem;
namespace bs = boost::system;
namespace {
-const char kSharedData[] = "shared/data";
-const char kSkelApp[] = "skel/apps_rw";
-
-bool RemovePerUserSharedDir(const std::string& pkgid) {
- bf::path shareddir_path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) /
- bf::path(kSkelApp) / pkgid / kSharedData;
- if (!bf::exists(shareddir_path))
- return true;
-
- if (!common_installer::UpdateSkelDirectories(pkgid, true)) {
- LOG(ERROR) << "Failed to remove shared data directory";
- return false;
- }
-
- if (!common_installer::UpdateUserDirectory(pkgid, true)) {
- LOG(ERROR) << "Failed to remove shared data directory";
- return false;
- }
-
- return true;
-}
-
-bool CreatePerUserSharedDir(const std::string& pkgid) {
- if (!common_installer::UpdateSkelDirectories(pkgid, false)) {
- LOG(ERROR) << "Failed to remove shared data directory";
- return false;
- }
-
- if (!common_installer::UpdateUserDirectory(pkgid, false)) {
- LOG(ERROR) << "Failed to remove shared data directory";
- return false;
- }
-
- return true;
-}
+const char kSharedDataDir[] = "shared/data";
+const char kSkelAppDir[] = "skel/apps_rw";
bool ShouldCreateSharedDataDir(manifest_x* manifest) {
if (ci::ShouldSupportLegacySharedDataDir(manifest->api_version))
namespace filesystem {
bool StepUpdateStorageDirectories::UpdatePerUserStorageDirectories() {
- manifest_x* manifest = context_->manifest_data.get();
- if (ShouldCreateSharedDataDir(manifest))
- return CreatePerUserSharedDir(context_->pkgid.get());
+ if (mode_ == UpdateMode::CREATE)
+ return ci::CreatePerUserSharedDataDir(context_->pkgid.get());
else
- return RemovePerUserSharedDir(context_->pkgid.get());
+ return ci::BackupPerUserSharedDataDir(context_->pkgid.get());
}
bool StepUpdateStorageDirectories::UpdateStorageDirectories() {
- manifest_x* manifest = context_->manifest_data.get();
- if (ShouldCreateSharedDataDir(manifest)) {
- return CreateSharedData(
- context_->root_application_path.get(), context_->pkgid.get());
- } else {
- return DeleteSharedDirectories(
- context_->root_application_path.get(), context_->pkgid.get());
- }
+ if (mode_ == UpdateMode::CREATE)
+ return ci::CreateSharedDataDir(context_->pkgid.get(), context_->uid.get());
+ else
+ return ci::BackupSharedDataDir(context_->pkgid.get(), context_->uid.get());
+}
- return true;
+bool StepUpdateStorageDirectories::CleanUpdatePerUserStorageDirectories() {
+ if (mode_ == UpdateMode::CREATE)
+ return true;
+ else
+ return ci::RemoveBackupPerUserSharedDataDir(context_->pkgid.get());
+}
+
+bool StepUpdateStorageDirectories::CleanUpdateStorageDirectories() {
+ if (mode_ == UpdateMode::CREATE)
+ return true;
+ else
+ return ci::RemoveBackupSharedDataDir(context_->pkgid.get(),
+ context_->uid.get());
+}
+
+bool StepUpdateStorageDirectories::UndoUpdatePerUserStorageDirectories() {
+ if (mode_ == UpdateMode::CREATE)
+ return ci::DeletePerUserSharedDataDir(context_->pkgid.get());
+ else
+ return ci::RestorePerUserSharedDataDir(context_->pkgid.get());
+}
+
+bool StepUpdateStorageDirectories::UndoUpdateStorageDirectories() {
+ if (mode_ == UpdateMode::CREATE)
+ return ci::DeleteSharedDataDir(context_->pkgid.get(), context_->uid.get());
+ else
+ return ci::RestoreSharedDataDir(context_->pkgid.get(), context_->uid.get());
}
Step::Status StepUpdateStorageDirectories::precheck() {
if (!context_->manifest_data.get())
return Status::INVALID_VALUE;
+
+ bf::path path;
+ if (context_->request_mode.get() == RequestMode::GLOBAL)
+ path = bf::path(tzplatform_getenv(TZ_SYS_ETC)) / bf::path(kSkelAppDir) /
+ context_->pkgid.get() / kSharedDataDir;
+ else
+ path = bf::path(ci::GetRootAppPath(false, context_->uid.get())) /
+ context_->pkgid.get() / kSharedDataDir;
+
+ bool old_shared_data_exists = bf::exists(path);
+ bool should_create_shared_data = ShouldCreateSharedDataDir(
+ context_->manifest_data.get());
+
+ if ((old_shared_data_exists && should_create_shared_data) ||
+ (!old_shared_data_exists && !should_create_shared_data))
+ mode_ = UpdateMode::NONE;
+ else if (!old_shared_data_exists && should_create_shared_data)
+ mode_ = UpdateMode::CREATE;
+ else
+ mode_ = UpdateMode::DELETE;
+
return Status::OK;
}
Step::Status StepUpdateStorageDirectories::process() {
+ if (mode_ == UpdateMode::NONE)
+ return Status::OK;
+
if (context_->request_mode.get() == RequestMode::GLOBAL) {
if (!UpdatePerUserStorageDirectories())
return Status::APP_DIR_ERROR;
return Status::OK;
}
+Step::Status StepUpdateStorageDirectories::clean() {
+ recovery::RecoveryFile* recovery_file =
+ context_->recovery_info.get().recovery_file.get();
+ recovery_file->set_cleanup(true);
+ recovery_file->WriteAndCommitFileContent();
+ if (mode_ == UpdateMode::NONE)
+ return Status::OK;
+
+ if (context_->request_mode.get() == RequestMode::GLOBAL) {
+ if (!CleanUpdatePerUserStorageDirectories())
+ return Status::APP_DIR_ERROR;
+ } else {
+ if (!CleanUpdateStorageDirectories())
+ return Status::APP_DIR_ERROR;
+ }
+ return Status::OK;
+}
+
+Step::Status StepUpdateStorageDirectories::undo() {
+ if (mode_ == UpdateMode::NONE)
+ return Status::OK;
+
+ if (context_->request_mode.get() == RequestMode::GLOBAL) {
+ if (!UndoUpdatePerUserStorageDirectories())
+ return Status::APP_DIR_ERROR;
+ } else {
+ if (!UndoUpdateStorageDirectories())
+ return Status::APP_DIR_ERROR;
+ }
+ return Status::OK;
+}
+
} // namespace filesystem
} // namespace common_installer
#ifndef COMMON_STEP_FILESYSTEM_STEP_UPDATE_STORAGE_DIRECTORIES_H_
#define COMMON_STEP_FILESYSTEM_STEP_UPDATE_STORAGE_DIRECTORIES_H_
+#include <boost/filesystem/path.hpp>
+
#include <manifest_parser/utils/logging.h>
#include "common/step/step.h"
using Step::Step;
Status process() override;
- Status clean() override { return Status::OK; }
- Status undo() override { return Status::OK; }
+ Status clean() override;
+ Status undo() override;
Status precheck() override;
STEP_NAME(UpdateStorageDirectories)
private:
+ enum class UpdateMode : int {
+ NONE,
+ CREATE,
+ DELETE,
+ };
+
bool UpdatePerUserStorageDirectories();
bool UpdateStorageDirectories();
+ bool CleanUpdatePerUserStorageDirectories();
+ bool CleanUpdateStorageDirectories();
+ bool UndoUpdatePerUserStorageDirectories();
+ bool UndoUpdateStorageDirectories();
+
+ UpdateMode mode_;
};
} // namespace filesystem
#include <string>
#include <vector>
+#include "common/paths.h"
#include "common/utils/byte_size_literals.h"
namespace ba = boost::algorithm;
return true;
}
+bool RestoreBackup(const bf::path& path) {
+ bf::path backup_path = GetBackupPathForPackagePath(path);
+ if (!bf::exists(backup_path) &&
+ !bf::is_symlink(bf::symlink_status(backup_path))) {
+ LOG(WARNING) << backup_path << " does not exist";
+ return true;
+ }
+ return MoveDir(backup_path, path);
+}
+
+bool MakeBackup(const bf::path& path) {
+ if (!bf::exists(path) && !bf::is_symlink(bf::symlink_status(path))) {
+ LOG(WARNING) << path << " does not exist";
+ return true;
+ }
+ bf::path backup_path = GetBackupPathForPackagePath(path);
+ return MoveDir(path, backup_path);
+}
+
+bool RemoveBackup(const bf::path& path) {
+ bf::path backup_path = GetBackupPathForPackagePath(path);
+ if (!bf::exists(backup_path) &&
+ !bf::is_symlink(bf::symlink_status(backup_path))) {
+ LOG(WARNING) << backup_path << " does not exist";
+ return true;
+ }
+ return RemoveAll(backup_path);
+}
+
bool RemoveAll(const bf::path& path) {
if (!exists(path))
return true;
bool CopyFile(const boost::filesystem::path& src,
const boost::filesystem::path& dst);
+bool RestoreBackup(const boost::filesystem::path& path);
+
+bool MakeBackup(const boost::filesystem::path& path);
+
+bool RemoveBackup(const boost::filesystem::path& path);
+
bool RemoveAll(const boost::filesystem::path& path);
bool Remove(const boost::filesystem::path& path);