step/filesystem/step_remove_icons.cc
step/filesystem/step_remove_per_user_storage_directories.cc
step/filesystem/step_remove_temporary_directory.cc
+ step/filesystem/step_remove_tep.cc
step/filesystem/step_remove_zip_image.cc
step/filesystem/step_unzip.cc
+ step/filesystem/step_update_tep.cc
step/mount/step_mount_install.cc
step/mount/step_mount_unpacked.cc
step/mount/step_mount_update.cc
step/pkgmgr/step_run_parser_plugins.cc
step/pkgmgr/step_unregister_app.cc
step/pkgmgr/step_update_app.cc
- step/pkgmgr/step_update_tep.cc
step/rds/step_rds_modify.cc
step/rds/step_rds_parse.cc
step/recovery/step_open_recovery_file.cc
#include "common/backup_paths.h"
+#include <pwd.h>
#include <tzplatform_config.h>
namespace bf = boost::filesystem;
namespace {
+const int32_t kPWBufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
const char kImageDir[] = ".image";
const char kBckExtension[] = ".bck";
+const char kExternalStorageDirPrefix[] = "SDCardA1";
boost::filesystem::path GetBackupPath(
const boost::filesystem::path& pkg_path) {
return backup_path;
}
+std::string GetUserNameForUID(uid_t uid) {
+ struct passwd pwd;
+ struct passwd *pwd_result;
+ char buf[kPWBufSize];
+ int ret = getpwuid_r(uid, &pwd, buf, sizeof(buf), &pwd_result);
+ if (ret != 0 || pwd_result == nullptr)
+ return {};
+ return pwd.pw_name;
+}
+
} // namespace
namespace common_installer {
return pkg_path / kImageDir / pkgid;
}
+boost::filesystem::path GetExternalCardPath() {
+ return bf::path(tzplatform_mkpath(TZ_SYS_MEDIA, kExternalStorageDirPrefix));
+}
+
+boost::filesystem::path GetExternalTepPath(RequestMode request_mode,
+ uid_t uid) {
+ bf::path result = GetExternalCardPath() / "tep";
+ if (request_mode == RequestMode::USER)
+ result /= GetUserNameForUID(uid);
+ return result;
+}
+
+boost::filesystem::path GetInternalTepPath(
+ const boost::filesystem::path& pkg_path) {
+ return pkg_path / "tep";
+}
+
} // namespace common_installer
#define COMMON_BACKUP_PATHS_H_
#include <boost/filesystem/path.hpp>
+#include <unistd.h>
#include <string>
+#include "common/request.h"
+
+// TODO(t.iwanek): rename this file from "backup_paths.h" to "paths.h"
+
namespace common_installer {
/**
boost::filesystem::path GetMountLocation(
const boost::filesystem::path& pkg_path);
+/**
+ * @brief GetExternalCardPath
+ * Returns full path to mounted filesystem of sd card
+ *
+ * @return path
+ */
+boost::filesystem::path GetExternalCardPath();
+
+/**
+ * @brief GetExternalTepPath
+ * Returns external installation location for tep package
+ * @param request_mode request type
+ * @param uid user id of request
+ *
+ * @return full directory path
+ */
+boost::filesystem::path GetExternalTepPath(RequestMode request_mode, uid_t uid);
+
+/**
+ * @brief GetInternalTepPath
+ * Returns internal installation location for tep package
+ * @param package path of installation request
+ *
+ * @return full directory path
+ */
+boost::filesystem::path GetInternalTepPath(
+ const boost::filesystem::path& pkg_path);
+
} // namespace common_installer
#endif // COMMON_BACKUP_PATHS_H_
return true;
}
+bool UpdateTepInfoInPkgmgr(const bf::path& tep_path, const std::string& pkgid,
+ uid_t uid, RequestMode request_mode) {
+ int ret = request_mode != RequestMode::GLOBAL ?
+ pkgmgr_parser_usr_update_tep(
+ pkgid.c_str(), tep_path.string().c_str(), uid) :
+ pkgmgr_parser_update_tep(
+ pkgid.c_str(), tep_path.string().c_str());
+
+ if (ret != 0) {
+ LOG(ERROR) << "Failed to upgrade tep info: " << pkgid;
+ return false;
+ }
+
+ return true;
+}
+
std::string QueryCertificateAuthorCertificate(const std::string& pkgid,
uid_t uid) {
pkgmgrinfo_certinfo_h handle;
RequestMode request_mode);
/**
+ * \brief Adapter interface for external PkgMgr module used for updating
+ * tep info about package within pkgmgr
+ *
+ * \param tep_path path of tep file
+ * \param pkgid package pkgid
+ * \param uid user id
+ * \param request_mode current request mode
+ *
+ * \return true if success
+ */
+bool UpdateTepInfoInPkgmgr(const boost::filesystem::path& tep_path,
+ const std::string& pkgid,
+ uid_t uid,
+ RequestMode request_mode);
+
+/**
* \brief Adapter interface for external PkgMgr module used for getting
* certificate information for given package
*
#include <vector>
#include <tuple>
+#include "common/backup_paths.h"
#include "common/security_registration.h"
#include "common/pkgmgr_registration.h"
#include "common/utils/base64.h"
const char kTrustedDir[] = "shared/trusted";
const char kSkelAppDir[] = "/etc/skel/apps_rw";
const char kPackagePattern[] = R"(^[0-9a-zA-Z_-]+(\.?[0-9a-zA-Z_-]+)*$)";
-const char kExternalStorageDirPrefix[] = "SDCardA1";
const int32_t kPWBufSize = sysconf(_SC_GETPW_R_SIZE_MAX);
const int32_t kGRBufSize = sysconf(_SC_GETGR_R_SIZE_MAX);
}
std::string GetDirectoryPathForExternalStorage() {
- const char* storage_path = tzplatform_mkpath(TZ_SYS_MEDIA,
- kExternalStorageDirPrefix);
- return std::string(storage_path);
+ return GetExternalCardPath().string();
}
bool PerformInternalDirectoryCreationForUser(uid_t user,
bool PerformExternalDirectoryCreationForUser(uid_t user,
const std::string& pkgid) {
+ bf::path storage_path = GetExternalCardPath();
+
// TODO(t.iwanek): trusted in this context means that we have signature
// this argument is not longer needed as all package must be signed
// so that trusted directory may be labeled correctly by security-manager in
// all cases. This parameter and its propagation should be removed.
bool trusted = true;
- const char* storage_path = tzplatform_mkpath(TZ_SYS_MEDIA,
- kExternalStorageDirPrefix);
const bool set_permissions = false;
if (!bf::exists(storage_path)) {
LOG(WARNING) << "External storage (SD Card) is not mounted.";
return false;
}
- bf::path storage_apps_path = bf::path(storage_path) / "apps";
+ bf::path storage_apps_path = storage_path / "apps";
if (!bf::exists(storage_apps_path)) {
bs::error_code error;
bf::create_directories(storage_apps_path, error);
bool PerformExternalDirectoryDeletionForUser(uid_t user,
const std::string& pkgid) {
- const char* storage_path = tzplatform_mkpath(TZ_SYS_MEDIA,
- kExternalStorageDirPrefix);
+ bf::path storage_path = GetExternalCardPath();
if (!bf::exists(storage_path)) {
LOG(WARNING) << "External storage (SD Card) is not mounted.";
return false;
}
} else {
if (!MoveFile(iter->path(), backup_path_ / iter->path().filename())) {
- LOG(ERROR) << "Fail to backup package file of: " << iter->path();
+ LOG(ERROR) << "Fail to backup package file: " << iter->path();
return false;
}
}
LOG(ERROR) << "Fail to backup package directory of: " << iter->path();
return false;
}
+ } else if (bf::is_symlink(iter->path())) {
+ bs::error_code error;
+ bf::copy_symlink(iter->path(), to / iter->path().filename(), error);
+ if (error) {
+ LOG(ERROR) << "Failed to backup package symlink: " << iter->path();
+ return false;
+ }
} else {
if (!MoveFile(iter->path(), to / iter->path().filename())) {
- LOG(ERROR) << "Fail to backup package file of: " << iter->path();
+ LOG(ERROR) << "Fail to backup package file: " << iter->path();
return false;
}
}
#include <cstring>
#include <string>
+#include "common/backup_paths.h"
#include "common/utils/file_util.h"
namespace common_installer {
context_->pkg_path.set(
context_->root_application_path.get() / context_->pkgid.get());
- bf::path tep_path =
- context_->pkg_path.get() / "tep" / context_->tep_path.get().filename();
+ bf::path tep_path;
+ if (context_->external_storage) {
+ tep_path = GetExternalTepPath(context_->request_mode.get(),
+ context_->uid.get());
+ } else {
+ tep_path = GetInternalTepPath(context_->pkg_path.get());
+ }
+
+ // Keep filename of app store supplied file. Filename contains hash that
+ // appstore uses to identify version of tep on device.
+ tep_path /= context_->tep_path.get().filename();
if (!bf::exists(tep_path.parent_path())) {
bs::error_code error;
}
Step::Status StepCopyTep::undo() {
- if (bf::exists(context_->tep_path.get()))
- bf::remove_all(context_->tep_path.get());
+ bs::error_code error;
+ if (bf::exists(context_->tep_path.get())) {
+ bf::remove_all(context_->tep_path.get(), error);
+ }
+
+ // remove tep file is installed outside package path
+ if (context_->external_storage) {
+ bf::path tep_path = GetExternalTepPath(context_->request_mode.get(),
+ context_->uid.get());
+ tep_path /= context_->tep_path.get().filename();
+ if (bf::exists(tep_path)) {
+ bf::remove_all(tep_path, error);
+ }
+ }
return Status::OK;
}
/**
* \brief step responsible for moving/copying TEP files from designated path to
- * final installed package destination during INSTALLATION/UPDATE.
+ * final installed package destination during INSTALLATION.
* Used by WGT and TPK
*/
class StepCopyTep : public Step {
#include "common/step/filesystem/step_move_installed_storage.h"
+#include <boost/filesystem/path.hpp>
+#include <boost/system/error_code.hpp>
+#include <tzplatform_config.h>
+
+#include <string>
+
+#include "common/backup_paths.h"
#include "common/external_storage.h"
+#include "common/utils/file_util.h"
+#include "common/pkgmgr_registration.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
namespace common_installer {
namespace filesystem {
return Status::APP_DIR_ERROR;
}
+ // move tep
+ if (context_->manifest_data.get()->tep_name) {
+ SetTepPaths();
+
+ if (new_location_ != old_location_)
+ if (!MoveTep())
+ return Status::APP_DIR_ERROR;
+ }
+ return Status::OK;
+}
+
+Step::Status StepMoveInstalledStorage::undo() {
+ if (context_->external_storage) {
+ if (new_location_ != old_location_)
+ if (!MoveBackTep())
+ return Status::APP_DIR_ERROR;
+ context_->external_storage->Abort();
+ }
return Status::OK;
}
+void StepMoveInstalledStorage::SetTepPaths() {
+ old_location_ = context_->manifest_data.get()->tep_name;
+ if (context_->is_move_to_external.get()) {
+ new_location_ = GetExternalTepPath(context_->request_mode.get(),
+ context_->uid.get());
+ new_location_ /= old_location_.filename();
+ } else {
+ new_location_ =
+ GetInternalTepPath(context_->pkg_path.get()) / old_location_.filename();
+ }
+}
+
+bool StepMoveInstalledStorage::MoveTep() {
+ if (!bf::exists(new_location_.parent_path())) {
+ bs::error_code error;
+ bf::create_directory(new_location_.parent_path(), error);
+ if (error) {
+ LOG(ERROR) << "Failed to destination path for new tep location";
+ return false;
+ }
+ }
+
+ if (!MoveFile(old_location_, new_location_)) {
+ LOG(ERROR) << "Cannot move tep file from: " << old_location_
+ << " to " << new_location_;
+ return false;
+ }
+
+ if (!UpdateTepInfoInPkgmgr(new_location_, context_->pkgid.get(),
+ context_->uid.get(), context_->request_mode.get())) {
+ LOG(ERROR) << "Failed to update tep package location in pkgmgr";
+ return false;
+ }
+ return true;
+}
+
+bool StepMoveInstalledStorage::MoveBackTep() {
+ if (bf::exists(new_location_)) {
+ if (!MoveFile(new_location_, old_location_)) {
+ LOG(ERROR) << "Cannot move tep file from: " << new_location_
+ << " to " << old_location_;
+ return false;
+ }
+
+ if (!UpdateTepInfoInPkgmgr(old_location_, context_->pkgid.get(),
+ context_->uid.get(), context_->request_mode.get())) {
+ LOG(ERROR) << "Failed to update tep package location in pkgmgr";
+ return false;
+ }
+ }
+ return true;
+}
+
} // namespace filesystem
} // namespace common_installer
Status process() override;
Status clean() override { return Status::OK; }
- Status undo() override { return Status::OK; }
+ Status undo() override;
Status precheck() override { return Status::OK; }
+ private:
+ void SetTepPaths();
+ bool MoveTep();
+ bool MoveBackTep();
+
+ boost::filesystem::path old_location_;
+ boost::filesystem::path new_location_;
+
STEP_NAME(MoveInstalledStorage)
};
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_remove_tep.h"
+
+#include <boost/filesystem/operations.hpp>
+#include <boost/filesystem/path.hpp>
+#include <boost/system/error_code.hpp>
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepRemoveTep::process() {
+ if (context_->manifest_data.get()->tep_name) {
+ bf::path tep_path(context_->manifest_data.get()->tep_name);
+ if (bf::exists(tep_path)) {
+ bs::error_code error;
+ bf::remove(tep_path, error);
+ if (error) {
+ // Deinstallation should not fail even if sd card is not inserted
+ // In spite of this, we print only warning
+ LOG(WARNING) << "Failed to remove tep file from: " << tep_path;
+ }
+ }
+ LOG(DEBUG) << "Tep package file removed: " << tep_path;
+ }
+ return Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache-2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_REMOVE_TEP_H_
+#define COMMON_STEP_FILESYSTEM_STEP_REMOVE_TEP_H_
+
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/step.h"
+
+namespace common_installer {
+namespace filesystem {
+
+/**
+ * @brief The StepRemoveTep class
+ * Removes tep package from internal or external location
+ */
+class StepRemoveTep : public Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override { return Status::OK; }
+
+ STEP_NAME(RemoveTep)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_REMOVE_TEP_H_
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by an apache 2.0 license that can be
+// found in the LICENSE file.
+
+#include "common/step/filesystem/step_update_tep.h"
+
+#include <pkgmgr-info.h>
+
+#include <boost/filesystem.hpp>
+
+#include <cstring>
+#include <string>
+
+#include "common/backup_paths.h"
+#include "common/pkgmgr_registration.h"
+#include "common/utils/file_util.h"
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+
+namespace common_installer {
+namespace filesystem {
+
+Step::Status StepUpdateTep::precheck() {
+ if (!context_->old_manifest_data.get()) {
+ LOG(ERROR) << "Old manifest data is not set";
+ return Status::INVALID_VALUE;
+ }
+ return StepCopyTep::precheck();
+}
+
+Step::Status StepUpdateTep::process() {
+ // copy new tep file to package path if possible
+ Status status = StepCopyTep::process();
+ if (status != Status::OK)
+ return status;
+
+ // preserve old tep path if no new tep is supplied
+ if (context_->tep_path.get().empty() &&
+ context_->old_manifest_data.get()->tep_name) {
+ context_->manifest_data.get()->tep_name =
+ strdup(context_->old_manifest_data.get()->tep_name);
+
+ // TODO(t.iwanek): some factoring in more inteligent way would be great for
+ // this. Tep doesn't need to be copied in mount update as this mode is not
+ // creating new package directory so tep is in place.
+ if (context_->request_type.get() == RequestType::MountUpdate)
+ return Status::OK;
+
+ // copy if necessary
+ if (!context_->external_storage) {
+ bf::path new_path = context_->manifest_data.get()->tep_name;
+ bf::path backup_path =
+ GetInternalTepPath(
+ GetBackupPathForPackagePath(context_->pkg_path.get()));
+ backup_path /= new_path.filename();
+ if (!bf::exists(new_path.parent_path())) {
+ bs::error_code error;
+ bf::create_directory(new_path.parent_path(), error);
+ if (error) {
+ LOG(ERROR) << "Cannot recreate directory for tep file";
+ return Status::APP_DIR_ERROR;
+ }
+ }
+ if (!CopyFile(backup_path, new_path)) {
+ LOG(ERROR) << "Failed to preserve tep file during update";
+ return Status::APP_DIR_ERROR;
+ }
+ }
+ }
+ return Status::OK;
+}
+
+Step::Status StepUpdateTep::clean() {
+ if (context_->external_storage) {
+ if (context_->old_manifest_data.get()->tep_name &&
+ strcmp(context_->old_manifest_data.get()->tep_name,
+ context_->manifest_data.get()->tep_name)) {
+ bf::path old_tep = context_->old_manifest_data.get()->tep_name;
+ bs::error_code error;
+ bf::remove(old_tep, error);
+ if (error) {
+ LOG(WARNING) << "Failed to cleanup old tep package from sd card";
+ }
+ }
+ }
+ return Status::OK;
+}
+
+Step::Status StepUpdateTep::undo() {
+ bs::error_code error;
+ if (bf::exists(context_->tep_path.get())) {
+ bf::remove_all(context_->tep_path.get(), error);
+ }
+ return Status::OK;
+}
+
+} // namespace filesystem
+} // namespace common_installer
--- /dev/null
+// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
+// Use of this source code is governed by a apache 2.0 license that can be
+// found in the LICENSE file.
+
+#ifndef COMMON_STEP_FILESYSTEM_STEP_UPDATE_TEP_H_
+#define COMMON_STEP_FILESYSTEM_STEP_UPDATE_TEP_H_
+
+#include <boost/filesystem/path.hpp>
+#include <manifest_parser/utils/logging.h>
+
+#include "common/installer_context.h"
+#include "common/step/filesystem/step_copy_tep.h"
+
+
+namespace common_installer {
+namespace filesystem {
+
+/**
+ * \brief step responsible for moving/copying TEP files from designated path to
+ * final installed package destination during UPDATE.
+ * Used by WGT and TPK
+ */
+class StepUpdateTep : public StepCopyTep {
+ public:
+ using StepCopyTep::StepCopyTep;
+
+ Status precheck() override;
+ Status process() override;
+ Status clean() override;
+ Status undo() override;
+
+ STEP_NAME(UpdateTep)
+};
+
+} // namespace filesystem
+} // namespace common_installer
+
+#endif // COMMON_STEP_FILESYSTEM_STEP_UPDATE_TEP_H_
+++ /dev/null
-// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
-// Use of this source code is governed by an apache 2.0 license that can be
-// found in the LICENSE file.
-
-#include "common/step/pkgmgr/step_update_tep.h"
-
-#include <pkgmgr-info.h>
-
-#include <boost/filesystem.hpp>
-
-#include <cstring>
-#include <string>
-
-#include "common/backup_paths.h"
-#include "common/pkgmgr_registration.h"
-#include "common/utils/file_util.h"
-
-namespace bf = boost::filesystem;
-
-namespace common_installer {
-namespace pkgmgr {
-
-Step::Status StepUpdateTep::process() {
- bf::path old_tep;
- if (context_->old_manifest_data.get()->tep_name)
- old_tep = context_->old_manifest_data.get()->tep_name;
- if (!old_tep.empty() && context_->tep_path.get().empty()) {
- // preserve old tep location during update if no new is given
- context_->manifest_data.get()->tep_name = strdup(old_tep.c_str());
-
- bf::path old_tep_location =
- GetBackupPathForPackagePath(
- context_->pkg_path.get()) / "tep" / old_tep.filename();
- bf::path new_tep_location = old_tep;
- if (!MoveFile(old_tep_location, new_tep_location)) {
- LOG(ERROR) << "Failed to copy tep file";
- return Status::APP_DIR_ERROR;
- }
- }
- return Status::OK;
-}
-
-Step::Status StepUpdateTep::undo() {
- bf::path old_tep;
- if (context_->old_manifest_data.get()->tep_name)
- old_tep = context_->old_manifest_data.get()->tep_name;
- if (!old_tep.empty() && context_->tep_path.get().empty()) {
- // restore old tep location during update rollback
- bf::path old_tep_location =
- GetBackupPathForPackagePath(
- context_->pkg_path.get()) / "tep" / old_tep.filename();
- bf::path new_tep_location = old_tep;
- if (!MoveFile(new_tep_location, old_tep_location)) {
- LOG(ERROR) << "Failed to copy tep file";
- return Status::APP_DIR_ERROR;
- }
- }
- return Status::OK;
-}
-
-} // namespace pkgmgr
-} // namespace common_installer
+++ /dev/null
-// Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
-// Use of this source code is governed by a apache 2.0 license that can be
-// found in the LICENSE file.
-
-#ifndef COMMON_STEP_PKGMGR_STEP_UPDATE_TEP_H_
-#define COMMON_STEP_PKGMGR_STEP_UPDATE_TEP_H_
-
-#include <manifest_parser/utils/logging.h>
-
-#include <boost/filesystem/path.hpp>
-
-#include "common/installer_context.h"
-#include "common/step/step.h"
-
-
-namespace common_installer {
-namespace pkgmgr {
-
-class StepUpdateTep : public Step {
- public:
- using Step::Step;
-
- Status process() override;
- Status clean() override { return Status::OK; }
- Status undo() override;
- Status precheck() override { return Status::OK; }
-
- STEP_NAME(UpdateTep)
-};
-
-} // namespace pkgmgr
-} // namespace common_installer
-
-#endif // COMMON_STEP_PKGMGR_STEP_UPDATE_TEP_H_