#include <string>
#include <vector>
-#include "common/pkgmgr_query.h"
+#include "common/utils/pkgmgr_query.h"
+#include "common/utils/file_util.h"
+#include "common/utils/user_util.h"
+#include "common/shared_dirs.h"
namespace bs = boost::system;
namespace bf = boost::filesystem;
namespace {
const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
+const char kSubsesionDir[] = "subsession";
-bool SkipDirectoryIfGlobal(const bf::path& path) {
+bool SkipRWDirectories(const bf::path& path) {
static const std::vector<std::string> dirs_to_ignore = {
{"cache"},
{"data"},
- {"shared"},
+ {"shared/data"},
+ {"shared/cache"},
+ {"shared/trusted"},
};
return std::find(dirs_to_ignore.begin(), dirs_to_ignore.end(), path) !=
dirs_to_ignore.end();
}
+bool RemoveSignature(const std::string& pkgid, bool is_readonly) {
+ bf::path signature_path = bf::path(is_readonly ?
+ tzplatform_getenv(TZ_SYS_RO_SHARE) : tzplatform_getenv(TZ_SYS_SHARE)) /
+ "signatures";
+ signature_path /= std::string(pkgid + ".txt");
+ if (!common_installer::Remove(signature_path))
+ return false;
+
+ return true;
+}
+
} // namespace
// Even though, the below checks can fail, StepRemoveFiles should still try
// to remove the files
- if (context_->pkg_path.get().empty())
+ if (context_->GetPkgPath().empty())
LOG(ERROR) << "pkg_path attribute is empty";
- else if (!bf::exists(context_->pkg_path.get()))
+ else if (!bf::exists(context_->GetPkgPath()))
LOG(ERROR) << "pkg_path ("
- << context_->pkg_path.get()
+ << context_->GetPkgPath()
<< ") path does not exist";
return Step::Status::OK;
}
Step::Status StepRemoveFiles::process() {
- bs::error_code error;
- bf::path pkg_path(context_->pkg_path.get());
-
// We need to unmount external storage before removing package directory
// because mount point is inside
if (context_->external_storage)
context_->external_storage->Commit();
- if (QueryIsPackageInstalled(context_->pkgid.get(), kGlobalUserUid)) {
- for (bf::directory_iterator itr(pkg_path); itr != bf::directory_iterator();
- ++itr) {
- if (bf::is_symlink(symlink_status(itr->path()))) {
- // for removing symlink to .mmc/bin,lib,res
- bf::remove_all(itr->path(), error);
- } else if (bf::is_directory(itr->status())) {
- if (SkipDirectoryIfGlobal(itr->path().leaf())) {
- LOG(DEBUG) << "Skipping remove dir:" << itr->path().c_str();
- continue;
- }
- bf::remove_all(itr->path(), error);
- if (error) {
- LOG(ERROR) << "Can't remove dir:" << context_->pkg_path.get().c_str();
+ bool is_keep_rwdata = false;
+ if (context_->request_mode.get() != RequestMode::GLOBAL) {
+ PkgQueryInterface pkg_query(context_->pkgid.get(), kGlobalUserUid);
+ if (pkg_query.IsPackageInstalled() ||
+ context_->keep_rwdata.get())
+ is_keep_rwdata = true;
+ }
+
+ bool is_error = false;
+ std::vector<bf::path> root_paths;
+ // Use RootAppPath + Pkgid because of ReadonlyUpdateUninstall
+ root_paths.push_back(context_->root_application_path.get());
+
+ for (auto& lw_user : GetLightUserList(context_->uid.get()))
+ root_paths.push_back(context_->root_application_path.get() / kSubsesionDir /
+ lw_user);
+
+ for (auto& root_path : root_paths) {
+ if (is_keep_rwdata) {
+ bool ret;
+ for (bf::directory_iterator itr(root_path / context_->pkgid.get());
+ itr != bf::directory_iterator(); ++itr) {
+ if (bf::is_directory(itr->status())) {
+ if (SkipRWDirectories(itr->path().leaf())) {
+ LOG(DEBUG) << "Skipping remove dir:" << itr->path().c_str();
+ continue;
+ }
+ ret = RemoveAll(itr->path());
+ } else {
+ ret = Remove(itr->path());
}
- } else if (bf::is_regular_file(itr->status())) {
- bf::remove_all(itr->path(), error);
+ if (!ret)
+ is_error = true;
}
- }
- } else {
- bf::remove_all(pkg_path, error);
- if (error) {
- LOG(ERROR) << "Can't remove directory:" <<
- context_->pkg_path.get().c_str();
} else {
- LOG(DEBUG) << "Removed directory: " << context_->pkg_path.get();
+ if (!RemoveAll(root_path / context_->pkgid.get()) ||
+ !common_installer::DeleteSharedDirectories(root_path,
+ context_->pkgid.get()))
+ is_error = true;
+ }
+
+ if (is_error)
+ return Status::ERROR;
+ }
+
+ // Remove package files at extended storage
+ if (context_->storage.get() == Storage::EXTENDED) {
+ bf::path extended_path =
+ bf::path(GetExtendedRootAppPath(context_->uid.get())) /
+ context_->pkgid.get();
+ if (!RemoveAll(extended_path))
+ return Status::APP_DIR_ERROR;
+ }
+
+ for (auto& lw_user : GetLightUserList(context_->uid.get())) {
+ if (context_->storage.get() == Storage::EXTENDED) {
+ bf::path extended_path =
+ bf::path(GetExtendedRootAppPath(context_->uid.get())) /
+ kSubsesionDir / lw_user / context_->pkgid.get();
+ if (!RemoveAll(extended_path))
+ return Status::APP_DIR_ERROR;
}
}
+ // Remove stored signature file
+ if (!RemoveSignature(context_->pkgid.get(),
+ context_->is_readonly_package.get()))
+ return Status::APP_DIR_ERROR;
return Status::OK;
}