context_->pkgid.set(pkgmgr->GetRequestInfo());
context_->file_path.set(kStrEmpty);
break;
+ case PkgMgrInterface::Type::Reinstall:
+ context_->unpacked_dir_path.set(pkgmgr->GetRequestInfo());
+ context_->pkgid.set(kStrEmpty);
+ context_->file_path.set(kStrEmpty);
+ break;
default:
// TODO(p.sikorski): should return unsupported, and display error
LOG(ERROR) <<
# Target - sources
SET(SRCS
+ rds_parser.cc
step/step_check_settings_level.cc
step/step_create_symbolic_link.cc
step/step_parse.cc
+ step/step_rds_parse.cc
+ step/step_rds_modify.cc
wgt_app_query_interface.cc
wgt_backend.cc
wgt_backend_data.cc
--- /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.
+
+#include "wgt/rds_parser.h"
+
+#include <fstream>
+
+namespace {
+const char kAdd[] = "#add";
+const char kModify[] = "#modify";
+const char kDelete[] = "#delete";
+}
+
+namespace wgt {
+namespace rds_parser {
+
+RDSParser::RDSParser(const std::string& path_to_delta)
+ : path_to_delta_(path_to_delta) {}
+
+bool RDSParser::Parse() {
+ std::vector<std::string>* current_container = nullptr;
+ std::string line;
+
+ std::ifstream file_to_parse(path_to_delta_);
+ if (!file_to_parse.is_open())
+ return false;
+ while (getline(file_to_parse, line)) {
+ if (line.compare(kDelete) == 0) {
+ current_container = &files_to_delete_;
+ continue;
+ }
+ if (line.compare(kAdd) == 0) {
+ current_container = &files_to_add_;
+ continue;
+ }
+ if (line.compare(kModify) == 0) {
+ current_container = &files_to_modify_;
+ continue;
+ }
+ if (current_container)
+ current_container->push_back(line);
+ }
+ file_to_parse.close();
+ return true;
+}
+
+const std::vector<std::string>& RDSParser::files_to_modify() const {
+ return files_to_modify_;
+}
+
+const std::vector<std::string>& RDSParser::files_to_add() const {
+ return files_to_add_;
+}
+
+const std::vector<std::string>& RDSParser::files_to_delete() const {
+ return files_to_delete_;
+}
+
+} // namespace rds_parser
+} // namespace wgt
--- /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 WGT_RDS_PARSER_H_
+#define WGT_RDS_PARSER_H_
+
+#include <string>
+#include <vector>
+namespace wgt {
+namespace rds_parser {
+
+class RDSParser {
+ public:
+ explicit RDSParser(const std::string& path_to_delta);
+
+ bool Parse();
+
+ const std::vector<std::string>& files_to_modify() const;
+ const std::vector<std::string>& files_to_add() const;
+ const std::vector<std::string>& files_to_delete() const;
+ private:
+ std::string path_to_delta_;
+ std::vector<std::string> files_to_modify_;
+ std::vector<std::string> files_to_add_;
+ std::vector<std::string> files_to_delete_;
+};
+
+} // namespace rds_parser
+} // namespace wgt
+
+#endif // WGT_RDS_PARSER_H_
--- /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.
+
+#include "wgt/step/step_rds_modify.h"
+
+#include <boost/system/error_code.hpp>
+
+#include "common/utils/file_util.h"
+#include "common/utils/logging.h"
+
+namespace wgt {
+namespace rds_modify {
+
+namespace bf = boost::filesystem;
+namespace bs = boost::system;
+namespace cu = common_installer;
+
+StepRDSModify::StepRDSModify(common_installer::ContextInstaller* context)
+ : Step(context),
+ backend_data_(nullptr) {}
+
+common_installer::Step::Status StepRDSModify::precheck() {
+ if (context_->unpacked_dir_path.get().empty()) {
+ LOG(ERROR) << "unpacked dir path is not set";
+ return common_installer::Step::Status::ERROR;
+ }
+ if (!bf::exists(context_->unpacked_dir_path.get())) {
+ LOG(ERROR) << "unpacked_dir_path ("
+ << context_->unpacked_dir_path.get()
+ << ") path does not exist";
+ return common_installer::Step::Status::ERROR;
+ }
+ if (context_->pkgid.get().empty()) {
+ LOG(ERROR) << "pkgid is not set";
+ return common_installer::Step::Status::ERROR;
+ }
+ if(!context_->manifest_data.get()) {
+ LOG(ERROR) << "no manifest info available";
+ return common_installer::Step::Status::ERROR;
+ }
+ // TODO(w.kosowicz): check if config of installed app was encrypted
+ backend_data_ = static_cast<WgtBackendData*>(context_->backend_data.get());
+ if (!backend_data_) {
+ LOG(ERROR) << "no backend data";
+ return common_installer::Step::Status::ERROR;
+ }
+ return common_installer::Step::Status::OK;
+}
+
+common_installer::Step::Status StepRDSModify::process() {
+ LOG(INFO) << "entered process of step modify";
+ if (!SetUpTempBackupDir()) {
+ LOG(ERROR) << "unable to setup temp directory";
+ return common_installer::Step::Status::ERROR;
+ }
+ context_->pkg_path.set(
+ context_->root_application_path.get() /context_->pkgid.get());
+ bf::path install_path = context_->pkg_path.get() /
+ context_->manifest_data.get()->mainapp_id;
+ bf::path unzip_path = context_->unpacked_dir_path.get();
+ if (!AddFiles(unzip_path, install_path) ||
+ !ModifyFiles(unzip_path, install_path) ||
+ !DeleteFiles(install_path)) {
+ LOG(ERROR) << "error during file operation";
+ return common_installer::Step::Status::ERROR;
+ }
+ return common_installer::Step::Status::OK;
+}
+
+common_installer::Step::Status StepRDSModify::undo() {
+ RestoreFiles();
+ return common_installer::Step::Status::OK;
+}
+
+common_installer::Step::Status StepRDSModify::clean() {
+ if (bf::exists(backup_temp_dir_))
+ bf::remove_all(backup_temp_dir_);
+ return common_installer::Step::Status::OK;
+}
+
+bool StepRDSModify::AddFiles(bf::path unzip_path, bf::path install_path) {
+ LOG(INFO) << "about to add files";
+ bs::error_code error;
+ for (const auto& file : backend_data_->files_to_add.get()) {
+ if (!PerformBackup(file, Operation::ADD)) {
+ LOG(ERROR) << "unable to perform backup of added file";
+ return false;
+ }
+ bf::path temp_install_path(install_path / file);
+ if (bf::is_directory(temp_install_path)) {
+ if (!bf::exists(temp_install_path) && (!cu::CreateDir(temp_install_path))) {
+ LOG(ERROR) << "unable to create dir for temp backup data";
+ return false;
+ }
+ } else {
+ if (!bf::exists(temp_install_path.parent_path()) &&
+ !cu::CreateDir(temp_install_path.parent_path())) {
+ LOG(ERROR) << "unable to create dir for temp backup data";
+ return false;
+ }
+ bf::path temp_unzip_path(unzip_path / file);
+ bf::copy_file(temp_unzip_path, temp_install_path, error);
+ if (error) {
+ LOG(ERROR) << "unable to add file " << error.message();
+ return false;
+ }
+ }
+ }
+ return true;
+}
+
+bool StepRDSModify::ModifyFiles(bf::path unzip_path, bf::path install_path) {
+ LOG(INFO) << "about to modify files";
+ bs::error_code error;
+ for (const auto& file : backend_data_->files_to_modify.get()) {
+ bf::path temp_install_path(install_path / file);
+ bf::path temp_unzip_path(unzip_path / file);
+ if (!PerformBackup(file, Operation::MODIFY)) {
+ LOG(ERROR) << "unable to perform backup of to be modified file";
+ return false;
+ }
+ bf::copy_file(temp_unzip_path, temp_install_path,
+ bf::copy_option::overwrite_if_exists, error);
+ if (error) {
+ LOG(ERROR) << "unable to modify file " << error.message();
+ return false;
+ }
+ }
+ return true;
+}
+
+bool StepRDSModify::DeleteFiles(bf::path install_path) {
+ LOG(INFO) << "about to delete files";
+ bs::error_code error;
+ for (const auto& file : backend_data_->files_to_delete.get()) {
+ if (!PerformBackup(file, Operation::DELETE)) {
+ LOG(ERROR) << "unable to perform backup of to be deleted file";
+ return false;
+ }
+ bf::remove(install_path / file, error);
+ if (error) {
+ LOG(ERROR) <<"unable to delete files " << error.message();
+ return false;
+ }
+ }
+ return true;
+}
+
+bool StepRDSModify::SetUpTempBackupDir() {
+ LOG(INFO) << "about to setup tmp backup dir";
+ bs::error_code error;
+ backup_temp_dir_ = "/tmp/" /
+ bf::unique_path("%%%%-%%%%-%%%%-%%%%", error);
+ if (error || !cu::CreateDir(backup_temp_dir_)) {
+ LOG(ERROR) << "unable to create backup data temp dir";
+ return false;
+ }
+ return true;
+}
+
+bool StepRDSModify::PerformBackup(std::string relative_path,
+ Operation operation) {
+ if (backup_temp_dir_.empty())
+ return false;
+ if (operation == Operation::DELETE || operation == Operation::MODIFY) {
+ bf::path app_path = context_->pkg_path.get() /
+ context_->manifest_data.get()->mainapp_id;;
+ bf::path source_path = app_path / relative_path;
+ if (bf::is_directory(source_path)) {
+ if (!cu::CreateDir(backup_temp_dir_ / relative_path)) {
+ LOG(ERROR) << "unable to create dir for temp backup data";
+ return false;
+ }
+ } else {
+ bs::error_code error;
+ bf::path tmp_dest_path = backup_temp_dir_ / relative_path;
+ if (!bf::exists((tmp_dest_path).parent_path()) &&
+ (!cu::CreateDir((tmp_dest_path).parent_path()))) {
+ LOG(ERROR) << "unable to create dir for temp backup data";
+ return false;
+ }
+ bf::copy_file(source_path, tmp_dest_path, error);
+ if (error) {
+ LOG(ERROR) << "unable to backup file " << error.message();
+ return false;
+ }
+ }
+ }
+ success_modifications_.push_back(std::make_pair(relative_path, operation));
+ return true;
+}
+
+void StepRDSModify::RestoreFiles() {
+ LOG(ERROR) << "error occured about to restore files";
+ bf::path app_path(context_->pkg_path.get());
+ for (std::pair<std::string, Operation>& modification :
+ success_modifications_) {
+ bf::path source_path(backup_temp_dir_ / modification.first);
+ bf::path destination_path(app_path / modification.first);
+ if (modification.second == Operation::ADD) {
+ if (bf::is_directory(source_path)) {
+ bf::remove_all(destination_path);
+ } else {
+ bf::remove(destination_path);
+ }
+ } else if (modification.second == Operation::MODIFY) {
+ bf::copy_file(source_path, destination_path,
+ bf::copy_option::overwrite_if_exists);
+ } else {
+ if (bf::is_directory(source_path)) {
+ cu::CreateDir(destination_path);
+ } else {
+ bf::copy_file(source_path, destination_path,
+ bf::copy_option::overwrite_if_exists);
+ }
+ }
+ }
+ // after files are restore delete temporary location
+ bf::remove_all(backup_temp_dir_);
+}
+
+} // namespace rds_modify
+} // namespace wgt
--- /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 WGT_STEP_STEP_RDS_MODIFY_H_
+#define WGT_STEP_STEP_RDS_MODIFY_H_
+
+#include <boost/filesystem.hpp>
+#include <string>
+#include <utility>
+#include <vector>
+
+#include "common/step/step.h"
+#include "wgt/wgt_backend_data.h"
+
+namespace wgt {
+namespace rds_modify {
+
+class StepRDSModify : public common_installer::Step {
+ public:
+ explicit StepRDSModify(common_installer::ContextInstaller* context);
+ Status process() override;
+ Status clean() override;
+ Status undo() override;
+ Status precheck() override;
+
+ private:
+ enum class Operation {
+ ADD,
+ MODIFY,
+ DELETE
+ };
+
+ bool AddFiles(boost::filesystem::path unzip_path,
+ boost::filesystem::path install_path);
+ bool ModifyFiles(boost::filesystem::path unzip_path,
+ boost::filesystem::path install_path);
+ bool DeleteFiles(boost::filesystem::path install_path);
+ bool SetUpTempBackupDir();
+ void DeleteTempBackupDir();
+ bool PerformBackup(std::string relative_path, Operation operation);
+ void RestoreFiles();
+
+ WgtBackendData* backend_data_;
+ std::vector<std::pair<std::string, Operation>> success_modifications_;
+ boost::filesystem::path backup_temp_dir_;
+ std::vector<std::string> files_to_modify_;
+ std::vector<std::string> files_to_add_;
+ std::vector<std::string> files_to_delete_;
+};
+} // namespace rds_modify
+} // namespace wgt
+#endif // WGT_STEP_STEP_RDS_MODIFY_H_
--- /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.
+
+#include "wgt/step/step_rds_parse.h"
+
+#include <memory>
+
+#include "common/utils/logging.h"
+#include "wgt/rds_parser.h"
+#include "wgt/wgt_backend_data.h"
+
+
+namespace wgt {
+namespace rds_parse {
+
+namespace bf = boost::filesystem;
+
+common_installer::Step::Status StepRDSParse::precheck() {
+ bf::path rdsPath(context_->unpacked_dir_path.get() / ".rds_delta");
+ if (!bf::exists(rdsPath)) {
+ LOG(ERROR) << "no rds_delta file";
+ return common_installer::Step::Status::ERROR;
+ }
+ rds_file_path_ = rdsPath;
+ return common_installer::Step::Status::OK;
+}
+
+common_installer::Step::Status StepRDSParse::process() {
+ wgt::rds_parser::RDSParser parser(rds_file_path_.native());
+ if (!parser.Parse()) {
+ LOG(ERROR) << "parsing of rds delta failed";
+ return common_installer::Step::Status::ERROR;
+ }
+
+ WgtBackendData* backend_data =
+ static_cast<WgtBackendData*>(context_->backend_data.get());
+ if (!backend_data) {
+ LOG(ERROR) << "no wgt backend data available";
+ return common_installer::Step::Status::ERROR;
+ }
+ backend_data->files_to_modify.set(parser.files_to_modify());
+ backend_data->files_to_add.set(parser.files_to_add());
+ backend_data->files_to_delete.set(parser.files_to_delete());
+ return common_installer::Step::Status::OK;
+}
+
+} // namespace rds_parse
+} // namespace wgt
--- /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 WGT_STEP_STEP_RDS_PARSE_H_
+#define WGT_STEP_STEP_RDS_PARSE_H_
+
+#include "common/step/step.h"
+
+#include <boost/filesystem.hpp>
+#include <string>
+#include <vector>
+
+namespace wgt {
+namespace rds_parse {
+
+class StepRDSParse : public common_installer::Step {
+ public:
+ using Step::Step;
+
+ Status process() override;
+ Status clean() override { return Status::OK; }
+ Status undo() override { return Status::OK; }
+ Status precheck() override;
+
+ private:
+ boost::filesystem::path rds_file_path_;
+};
+} // namespace rds_parse
+} // namespace wgt
+#endif // WGT_STEP_STEP_RDS_PARSE_H_
#include "wgt/step/step_create_symbolic_link.h"
#include "wgt/step/step_check_settings_level.h"
#include "wgt/step/step_parse.h"
+#include "wgt/step/step_rds_parse.h"
+#include "wgt/step/step_rds_modify.h"
#include "wgt/wgt_app_query_interface.h"
namespace ci = common_installer;
installer.AddStep<ci::revoke_security::StepRevokeSecurity>();
break;
}
+ case ci::PkgMgrInterface::Type::Reinstall: {
+ installer.AddStep<ci::configure::StepConfigure>();
+ installer.AddStep<wgt::parse::StepParse>();
+ installer.AddStep<ci::old_manifest::StepOldManifest>();
+ installer.AddStep<wgt::rds_parse::StepRDSParse>();
+ installer.AddStep<wgt::rds_modify::StepRDSModify>();
+ installer.AddStep<ci::update_security::StepUpdateSecurity>();
+
+ break;
+ }
default: {
// unsupported operation
return EINVAL;
#include <manifest_handlers/setting_handler.h>
+#include <string>
+#include <vector>
+
#include "common/context_installer.h"
#include "common/utils/property.h"
public:
WgtBackendData();
+ Property<std::vector<std::string>> files_to_add;
+ Property<std::vector<std::string>> files_to_modify;
+ Property<std::vector<std::string>> files_to_delete;
+
Property<parse::SettingInfo> settings;
};