1 // Copyright (c) 2015 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by a apache 2.0 license that can be
3 // found in the LICENSE file.
5 #include "common/step/configuration/step_configure.h"
7 #include <boost/filesystem/path.hpp>
9 #include <pkgmgr-info.h>
11 #include <sys/types.h>
13 #include <tzplatform_config.h>
19 #include "common/request.h"
20 #include "common/utils/file_util.h"
21 #include "common/utils/user_util.h"
23 namespace bf = boost::filesystem;
25 namespace common_installer {
26 namespace configuration {
28 const char kStrEmpty[] = "";
29 const char kAppFWUser[] = "app_fw";
31 StepConfigure::StepConfigure(InstallerContext* context, PkgMgrPtr pkgmgr)
36 Step::Status StepConfigure::process() {
37 SetupRequestMode(pkgmgr_->GetUid());
39 SetupFileCreationMask();
42 if (!SetupRootAppDirectory())
43 return Status::CONFIG_ERROR;
45 switch (pkgmgr_->GetRequestType()) {
46 case RequestType::Install:
47 context_->file_path.set(pkgmgr_->GetRequestInfo());
48 context_->pkgid.set(kStrEmpty);
49 if (!pkgmgr_->GetTepPath().empty()) {
50 context_->tep_path.set(pkgmgr_->GetTepPath());
51 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
54 case RequestType::Update:
55 context_->file_path.set(pkgmgr_->GetRequestInfo());
56 context_->pkgid.set(kStrEmpty);
57 if (!pkgmgr_->GetTepPath().empty()) {
58 context_->tep_path.set(pkgmgr_->GetTepPath());
59 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
62 case RequestType::PartialUninstall:
64 case RequestType::Uninstall:
65 if (context_->is_preload_rw_package.get())
67 SetupIsForceRemoval();
68 context_->pkgid.set(pkgmgr_->GetRequestInfo());
69 context_->file_path.set(kStrEmpty);
71 case RequestType::Reinstall:
72 context_->unpacked_dir_path.set(
73 context_->root_application_path.get() / "tmp" /
74 pkgmgr_->GetRequestInfo());
75 context_->pkgid.set(pkgmgr_->GetRequestInfo());
76 context_->file_path.set(kStrEmpty);
78 case RequestType::Delta:
79 context_->unpacked_dir_path.set(kStrEmpty);
80 context_->pkgid.set(kStrEmpty);
81 context_->file_path.set(pkgmgr_->GetRequestInfo());
83 case RequestType::Move:
84 context_->pkgid.set(pkgmgr_->GetRequestInfo());
85 context_->is_move_to_external.set(pkgmgr_->GetIsMoveToExternal());
87 case RequestType::Recovery:
88 context_->file_path.set(pkgmgr_->GetRequestInfo());
89 context_->pkgid.set(kStrEmpty);
91 case RequestType::MountInstall:
92 case RequestType::MountUpdate:
93 context_->file_path.set(pkgmgr_->GetRequestInfo());
94 context_->pkgid.set(kStrEmpty);
95 if (!pkgmgr_->GetTepPath().empty()) {
96 context_->tep_path.set(pkgmgr_->GetTepPath());
97 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
100 case RequestType::ManifestPartialInstall:
101 case RequestType::ManifestPartialUpdate:
103 case RequestType::ManifestDirectInstall:
104 case RequestType::ManifestDirectUpdate: {
105 context_->pkgid.set(pkgmgr_->GetRequestInfo());
106 bf::path package_directory =
107 context_->root_application_path.get() / context_->pkgid.get();
109 bf::path(getUserManifestPath(context_->uid.get(),
110 context_->is_readonly_package.get()))
111 / bf::path(context_->pkgid.get());
113 context_->unpacked_dir_path.set(package_directory);
114 context_->pkg_path.set(package_directory);
115 context_->xml_path.set(xml_path);
118 case RequestType::ReadonlyUpdateInstall:
119 context_->file_path.set(pkgmgr_->GetRequestInfo());
120 context_->pkgid.set(kStrEmpty);
121 if (!pkgmgr_->GetTepPath().empty()) {
122 context_->tep_path.set(pkgmgr_->GetTepPath());
123 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
126 case RequestType::ReadonlyUpdateUninstall: {
127 context_->pkgid.set(pkgmgr_->GetRequestInfo());
128 bf::path original_path =
129 bf::path(tzplatform_getenv(TZ_SYS_RO_APP)) / context_->pkgid.get();
130 context_->unpacked_dir_path.set(original_path);
131 context_->file_path.set(kStrEmpty);
134 case RequestType::DisablePkg:
135 case RequestType::EnablePkg:
136 context_->pkgid.set(pkgmgr_->GetRequestInfo());
138 case RequestType::MigrateExtImg: {
139 context_->pkgid.set(pkgmgr_->GetRequestInfo());
140 bf::path package_directory =
141 context_->root_application_path.get() / context_->pkgid.get();
142 context_->pkg_path.set(package_directory);
147 "Only installation, update and uninstallation is now supported";
148 return Status::CONFIG_ERROR;
152 // Record recovery file
153 if (pkgmgr_->GetRequestType() == RequestType::Install ||
154 pkgmgr_->GetRequestType() == RequestType::Update ||
155 pkgmgr_->GetRequestType() == RequestType::Delta ||
156 pkgmgr_->GetRequestType() == RequestType::MountInstall ||
157 pkgmgr_->GetRequestType() == RequestType::MountUpdate) {
158 std::unique_ptr<recovery::RecoveryFile> recovery_file =
159 recovery::RecoveryFile::CreateRecoveryFileForPath(
160 GenerateTemporaryPath(
161 context_->root_application_path.get() / "recovery"));
162 if (!recovery_file) {
163 LOG(ERROR) << "Failed to create recovery file";
164 return Status::CONFIG_ERROR;
166 recovery_file->set_type(pkgmgr_->GetRequestType());
167 if (!recovery_file->WriteAndCommitFileContent()) {
168 LOG(ERROR) << "Failed to write recovery file";
169 return Status::CONFIG_ERROR;
171 context_->recovery_info.set(RecoveryInfo(std::move(recovery_file)));
177 Step::Status StepConfigure::precheck() {
178 SetupIsPreloadRequest();
179 SetupIsPreloadRWRequest();
180 if (context_->is_readonly_package.get())
183 bool is_readonly = context_->is_readonly_package.get();
184 bool is_preload_rw = context_->is_preload_rw_package.get();
185 if (is_readonly && is_preload_rw) {
186 LOG(ERROR) << "Conflict of preload request!";
187 return Status::ERROR;
190 uid_t uid = pkgmgr_->GetUid();
191 context_->uid.set(uid);
195 boost::optional<uid_t> appfw_uid = GetUidByUserName(kAppFWUser);
197 return Status::ERROR;
199 if (getuid() != *appfw_uid) {
200 LOG(ERROR) << "App-installer should not run with normal user!";
201 return Status::OPERATION_NOT_ALLOWED;
207 Step::Status StepConfigure::clean() {
208 // Clean up operations should not be covered by recovery
209 // as backup information is being lost during clean up
210 context_->recovery_info.get().recovery_file.reset();
214 bool StepConfigure::SetupRootAppDirectory() {
215 if (context_->root_application_path.get().empty()) {
216 std::string root_app_path =
217 GetRootAppPath(context_->is_readonly_package.get(),
218 context_->uid.get());
219 if (root_app_path.empty())
222 context_->root_application_path.set(root_app_path);
224 if (!boost::filesystem::exists(context_->root_application_path.get())) {
225 boost::system:: error_code error;
226 boost::filesystem::create_directories(
227 context_->root_application_path.get());
229 LOG(ERROR) << "Cannot create directory: "
230 << context_->root_application_path.get();
234 LOG(INFO) << "AppDir(" << context_->root_application_path.get() << ")";
238 void StepConfigure::SetupRequestMode(uid_t uid) {
239 context_->request_mode.set(GetRequestMode(uid));
242 void StepConfigure::SetupRequestType() {
243 context_->request_type.set(pkgmgr_->GetRequestType());
246 void StepConfigure::SetupFileCreationMask() {
247 mode_t old_mask, new_mask;
248 old_mask = new_mask = 0;
250 switch (context_->request_mode.get()) {
251 case RequestMode::USER:
252 new_mask = 033; // results in 744 privileges
254 case RequestMode::GLOBAL:
255 new_mask = 022; // results in 755 privileges
259 old_mask = umask(new_mask);
261 LOG(INFO) << "Changed file creation mask from " << std::oct << old_mask
262 << " to " << std::oct << new_mask;
265 void StepConfigure::SetupIsPreloadRequest() {
266 context_->is_readonly_package.set(pkgmgr_->GetIsPreloadRequest());
269 void StepConfigure::SetupIsPreloadRWRequest() {
270 context_->is_preload_rw_package.set(pkgmgr_->GetIsPreloadRWRequest());
273 void StepConfigure::SetupIsForceRemoval() {
274 context_->force_remove.set(pkgmgr_->GetIsForceRemoval());
277 void StepConfigure::SetupIsNoRemoval() {
278 context_->no_remove.set(pkgmgr_->GetIsNoRemoval());
281 void StepConfigure::SetupIsKeepRWData() {
282 context_->keep_rwdata.set(pkgmgr_->GetIsKeepRWData());
285 void StepConfigure::SetupIsPartialRW() {
286 context_->partial_rw.set(pkgmgr_->GetIsPartialRW());
289 void StepConfigure::SetupDebugMode() {
290 context_->debug_mode.set(pkgmgr_->GetDebugMode());
293 } // namespace configuration
294 } // namespace common_installer