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/utils/pkgmgr_query.h"
20 #include "common/utils/file_util.h"
21 #include "common/utils/user_util.h"
22 #include "common/utils/request.h"
24 namespace bf = boost::filesystem;
26 namespace common_installer {
27 namespace configuration {
29 const char kStrEmpty[] = "";
30 const char kAppFWUser[] = "app_fw";
31 const char kRpmPkgType[] = "rpm";
32 const char kRpmInstaller[] = "tpk";
34 StepConfigure::StepConfigure(InstallerContext* context, PkgMgrPtr pkgmgr)
39 Step::Status StepConfigure::process() {
40 SetupRequestMode(pkgmgr_->GetUid());
42 SetupFileCreationMask();
44 SetupSkipCheckReference();
45 SetupSkipOptimization();
47 if (!SetupRootAppDirectory())
48 return Status::CONFIG_ERROR;
50 RequestType request_type = context_->request_type.get();
51 switch (request_type) {
52 case RequestType::Install:
53 case RequestType::Update: {
54 context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
55 if (!pkgmgr_->GetTepPath().empty()) {
56 context_->tep_path.set(pkgmgr_->GetTepPath());
57 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
59 context_->pkgid.set(GetPkgIdFromFile());
62 case RequestType::PartialUninstall:
63 case RequestType::Uninstall:
64 if (request_type == RequestType::PartialUninstall)
67 SetupIsForceRemoval();
68 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
69 context_->file_path.set(kStrEmpty);
71 case RequestType::Reinstall:
72 context_->unpacked_dir_path.set(
73 bf::path(tzplatform_getenv(TZ_SDK_TOOLS)) / "tmp" /
74 pkgmgr_->GetRequestInfo(context_->index.get()));
75 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
76 context_->file_path.set(kStrEmpty);
78 case RequestType::Delta:
79 context_->unpacked_dir_path.set(kStrEmpty);
80 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
81 context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
83 case RequestType::Move:
84 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
85 context_->is_move_to_external.set(pkgmgr_->GetIsMoveToExternal());
88 case RequestType::Recovery:
89 context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
90 context_->recovery_info.set(
91 RecoveryInfo(context_->file_path.get(),
92 pkgmgr_->GetRecoveryCleanup()));
94 case RequestType::MountInstall:
95 case RequestType::MountUpdate: {
96 context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
97 if (!pkgmgr_->GetTepPath().empty()) {
98 context_->tep_path.set(pkgmgr_->GetTepPath());
99 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
101 context_->pkgid.set(GetPkgIdFromFile());
104 case RequestType::ManifestPartialInstall:
105 case RequestType::ManifestPartialUpdate:
106 case RequestType::ManifestDirectInstall:
107 case RequestType::ManifestDirectUpdate: {
108 if (request_type == RequestType::ManifestPartialInstall ||
109 request_type == RequestType::ManifestPartialUpdate)
111 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
113 bf::path(getUserManifestPath(context_->uid.get(),
114 context_->is_readonly_package.get()))
115 / bf::path(context_->pkgid.get());
117 context_->unpacked_dir_path.set(context_->GetPkgPath());
118 context_->xml_path.set(xml_path);
121 case RequestType::ReadonlyUpdateInstall: {
122 context_->file_path.set(pkgmgr_->GetRequestInfo(context_->index.get()));
123 if (!pkgmgr_->GetTepPath().empty()) {
124 context_->tep_path.set(pkgmgr_->GetTepPath());
125 context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
127 context_->pkgid.set(GetPkgIdFromFile());
130 case RequestType::ReadonlyUpdateUninstall: {
131 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
132 bf::path original_path =
133 bf::path(tzplatform_getenv(TZ_SYS_RO_APP)) / context_->pkgid.get();
134 context_->unpacked_dir_path.set(original_path);
135 context_->file_path.set(kStrEmpty);
139 case RequestType::DisablePkg:
140 case RequestType::EnablePkg:
141 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
143 case RequestType::MigrateExtImg: {
144 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
147 case RequestType::RecoverDB: {
148 context_->pkgid.set(pkgmgr_->GetRequestInfo(context_->index.get()));
152 LOG(ERROR) << "Unknown request type";
153 return Status::CONFIG_ERROR;
156 if (!CheckInvalidBackendUsage())
157 return Status::OPERATION_NOT_ALLOWED;
159 LOG(INFO) << "Request Type: " << GetRequestTypeString(request_type);
164 Step::Status StepConfigure::precheck() {
165 SetupIsPreloadRequest();
166 SetupIsPreloadRWRequest();
168 bool is_readonly = context_->is_readonly_package.get();
169 bool is_preload_rw = context_->is_preload_rw_package.get();
170 if (is_readonly && is_preload_rw) {
171 LOG(ERROR) << "Conflict of preload request!";
172 return Status::ERROR;
175 if (is_readonly || is_preload_rw)
178 uid_t uid = pkgmgr_->GetUid();
179 context_->uid.set(uid);
183 boost::optional<uid_t> appfw_uid = GetUidByUserName(kAppFWUser);
185 return Status::ERROR;
187 if (getuid() != *appfw_uid) {
188 LOG(ERROR) << "App-installer should not run with normal user!";
189 return Status::OPERATION_NOT_ALLOWED;
195 bool StepConfigure::SetupRootAppDirectory() {
196 if (context_->root_application_path.get().empty()) {
197 std::string root_app_path =
198 GetRootAppPath(context_->is_readonly_package.get(),
199 context_->uid.get());
200 if (root_app_path.empty())
203 context_->root_application_path.set(root_app_path);
205 if (!boost::filesystem::exists(context_->root_application_path.get())) {
206 boost::system::error_code error;
207 boost::filesystem::create_directories(
208 context_->root_application_path.get());
210 LOG(ERROR) << "Cannot create directory: "
211 << context_->root_application_path.get();
215 LOG(INFO) << "AppDir(" << context_->root_application_path.get() << ")";
219 void StepConfigure::SetupRequestMode(uid_t uid) {
220 context_->request_mode.set(GetRequestMode(uid));
223 void StepConfigure::SetupRequestType() {
224 context_->request_type.set(pkgmgr_->GetRequestType(context_->index.get()));
227 void StepConfigure::SetupFileCreationMask() {
228 mode_t old_mask, new_mask;
229 old_mask = new_mask = 0;
231 switch (context_->request_mode.get()) {
232 case RequestMode::USER:
233 new_mask = 033; // results in 744 privileges
235 case RequestMode::GLOBAL:
236 new_mask = 022; // results in 755 privileges
240 old_mask = umask(new_mask);
242 LOG(INFO) << "Changed file creation mask from " << std::oct << old_mask
243 << " to " << std::oct << new_mask;
246 void StepConfigure::SetupIsPreloadRequest() {
247 context_->is_readonly_package.set(pkgmgr_->GetIsPreloadRequest());
250 void StepConfigure::SetupIsPreloadRWRequest() {
251 context_->is_preload_rw_package.set(pkgmgr_->GetIsPreloadRWRequest());
254 void StepConfigure::SetupIsForceRemoval() {
255 context_->force_remove.set(pkgmgr_->GetIsForceRemoval());
258 void StepConfigure::SetupIsNoRemoval() {
259 context_->no_remove.set(pkgmgr_->GetIsNoRemoval());
262 void StepConfigure::SetupIsKeepRWData() {
263 context_->keep_rwdata.set(pkgmgr_->GetIsKeepRWData());
266 void StepConfigure::SetupIsPartialRW() {
267 context_->partial_rw.set(pkgmgr_->GetIsPartialRW());
270 void StepConfigure::SetupDebugMode() {
271 context_->debug_mode.set(pkgmgr_->GetDebugMode());
274 void StepConfigure::SetupSkipCheckReference() {
275 context_->skip_check_reference.set(pkgmgr_->GetIsSkipCheckReference());
278 void StepConfigure::SetupSkipOptimization() {
279 context_->skip_optimization.set(pkgmgr_->GetSkipOptimization());
282 void StepConfigure::SetupMoveType() {
283 int move_type = pkgmgr_->GetMoveType();
286 context_->move_type.set(MoveType::TO_INTERNAL);
289 context_->move_type.set(MoveType::TO_EXTERNAL);
292 context_->move_type.set(MoveType::TO_EXTENDED);
295 context_->move_type.set(MoveType::TO_INTERNAL);
300 std::string StepConfigure::GetPkgIdFromFile() {
301 auto app_query_interface = pkgmgr_->GetAppQueryInterface();
302 if (!app_query_interface)
305 return app_query_interface->GetPkgId(
306 pkgmgr_->GetRequestInfo(context_->index.get()));
309 bool StepConfigure::CheckInvalidBackendUsage() {
310 if (context_->pkgid.get().empty())
313 PkgQueryInterface pkg_query(context_->pkgid.get().c_str(),
314 context_->uid.get());
315 if (!pkg_query.IsValid()) {
316 LOG(INFO) << "pkg[" << context_->pkgid.get()
317 << "] is not installed, skip checking backend with installed pkg";
321 const std::string& backend_type = context_->pkg_type.get();
322 std::string installed_pkg_type = pkg_query.Type();
323 if (installed_pkg_type == kRpmPkgType)
324 installed_pkg_type = kRpmInstaller;
326 if (installed_pkg_type != backend_type) {
327 LOG(ERROR) << "Wrong use of backend : package's type [" << pkg_query.Type()
328 << "] mismatched backend [" << backend_type << "]";
335 } // namespace configuration
336 } // namespace common_installer