Fix build warning
[platform/core/appfw/app-installers.git] / src / common / step / configuration / step_configure.cc
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.
4
5 #include "common/step/configuration/step_configure.h"
6
7 #include <boost/filesystem/path.hpp>
8
9 #include <pkgmgr-info.h>
10 #include <sys/stat.h>
11 #include <sys/types.h>
12 #include <unistd.h>
13 #include <tzplatform_config.h>
14
15 #include <memory>
16 #include <string>
17 #include <utility>
18
19 #include "common/pkgmgr_query.h"
20 #include "common/request.h"
21 #include "common/utils/file_util.h"
22 #include "common/utils/user_util.h"
23
24 namespace bf = boost::filesystem;
25
26 namespace common_installer {
27 namespace configuration {
28
29 const char kStrEmpty[] = "";
30 const char kAppFWUser[] = "app_fw";
31
32 StepConfigure::StepConfigure(InstallerContext* context, PkgMgrPtr pkgmgr)
33     : Step(context),
34       pkgmgr_(pkgmgr) {
35 }
36
37 Step::Status StepConfigure::process() {
38   SetupRequestMode(pkgmgr_->GetUid());
39   SetupRequestType();
40   SetupFileCreationMask();
41   SetupDebugMode();
42   SetupSkipCheckReference();
43   SetupSkipOptimization();
44
45   if (!SetupRootAppDirectory())
46     return Status::CONFIG_ERROR;
47
48   RequestType request_type = context_->request_type.get();
49   switch (request_type) {
50     case RequestType::Install:
51     case RequestType::Update:
52       context_->file_path.set(pkgmgr_->GetRequestInfo());
53       if (!pkgmgr_->GetTepPath().empty()) {
54         context_->tep_path.set(pkgmgr_->GetTepPath());
55         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
56       }
57       break;
58     case RequestType::PartialUninstall:
59     case RequestType::Uninstall:
60       if (request_type == RequestType::PartialUninstall)
61         SetupIsPartialRW();
62       SetupIsKeepRWData();
63       SetupIsForceRemoval();
64       context_->pkgid.set(pkgmgr_->GetRequestInfo());
65       context_->file_path.set(kStrEmpty);
66       break;
67     case RequestType::Reinstall:
68       context_->unpacked_dir_path.set(
69           bf::path(tzplatform_getenv(TZ_SDK_TOOLS)) / "tmp" /
70           pkgmgr_->GetRequestInfo());
71       context_->pkgid.set(pkgmgr_->GetRequestInfo());
72       context_->file_path.set(kStrEmpty);
73       break;
74     case RequestType::Delta:
75       context_->unpacked_dir_path.set(kStrEmpty);
76       context_->pkgid.set(pkgmgr_->GetRequestInfo());
77       context_->file_path.set(pkgmgr_->GetRequestInfo());
78       break;
79     case RequestType::Move:
80       context_->pkgid.set(pkgmgr_->GetRequestInfo());
81       context_->is_move_to_external.set(pkgmgr_->GetIsMoveToExternal());
82       SetupMoveType();
83       break;
84     case RequestType::Recovery:
85       context_->file_path.set(pkgmgr_->GetRequestInfo());
86       break;
87     case RequestType::MountInstall:
88     case RequestType::MountUpdate:
89       context_->file_path.set(pkgmgr_->GetRequestInfo());
90       if (!pkgmgr_->GetTepPath().empty()) {
91         context_->tep_path.set(pkgmgr_->GetTepPath());
92         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
93       }
94       break;
95     case RequestType::ManifestPartialInstall:
96     case RequestType::ManifestPartialUpdate:
97     case RequestType::ManifestDirectInstall:
98     case RequestType::ManifestDirectUpdate: {
99       if (request_type == RequestType::ManifestPartialInstall ||
100           request_type == RequestType::ManifestPartialUpdate)
101         SetupIsPartialRW();
102       context_->pkgid.set(pkgmgr_->GetRequestInfo());
103       bf::path xml_path =
104           bf::path(getUserManifestPath(context_->uid.get(),
105               context_->is_readonly_package.get()))
106           / bf::path(context_->pkgid.get());
107       xml_path += ".xml";
108       context_->unpacked_dir_path.set(context_->GetPkgPath());
109       context_->xml_path.set(xml_path);
110       break;
111     }
112     case RequestType::ReadonlyUpdateInstall:
113       context_->file_path.set(pkgmgr_->GetRequestInfo());
114       if (!pkgmgr_->GetTepPath().empty()) {
115         context_->tep_path.set(pkgmgr_->GetTepPath());
116         context_->is_tep_move.set(pkgmgr_->GetIsTepMove());
117       }
118       break;
119     case RequestType::ReadonlyUpdateUninstall: {
120       context_->pkgid.set(pkgmgr_->GetRequestInfo());
121       bf::path original_path =
122           bf::path(tzplatform_getenv(TZ_SYS_RO_APP)) / context_->pkgid.get();
123       context_->unpacked_dir_path.set(original_path);
124       context_->file_path.set(kStrEmpty);
125       break;
126     }
127     case RequestType::DisablePkg:
128     case RequestType::EnablePkg:
129       context_->pkgid.set(pkgmgr_->GetRequestInfo());
130       break;
131     case RequestType::MigrateExtImg: {
132       context_->pkgid.set(pkgmgr_->GetRequestInfo());
133       break;
134     }
135     case RequestType::RecoverDB: {
136       context_->pkgid.set(pkgmgr_->GetRequestInfo());
137       break;
138     }
139     default:
140       LOG(ERROR) << "Unknown request type";
141       return Status::CONFIG_ERROR;
142   }
143
144   LOG(INFO) << "Request Type: " << GetRequestTypeString(request_type);
145
146   return Status::OK;
147 }
148
149 Step::Status StepConfigure::precheck() {
150   SetupIsPreloadRequest();
151   SetupIsPreloadRWRequest();
152
153   bool is_readonly = context_->is_readonly_package.get();
154   bool is_preload_rw = context_->is_preload_rw_package.get();
155   if (is_readonly && is_preload_rw) {
156     LOG(ERROR) << "Conflict of preload request!";
157     return Status::ERROR;
158   }
159
160   if (is_readonly || is_preload_rw)
161     SetupIsNoRemoval();
162
163   uid_t uid = pkgmgr_->GetUid();
164   context_->uid.set(uid);
165   if (getuid() == 0)
166     return Status::OK;
167
168   boost::optional<uid_t> appfw_uid = GetUidByUserName(kAppFWUser);
169   if (!appfw_uid)
170     return Status::ERROR;
171
172   if (getuid() != *appfw_uid) {
173     LOG(ERROR) << "App-installer should not run with normal user!";
174     return Status::OPERATION_NOT_ALLOWED;
175   }
176
177   return Status::OK;
178 }
179
180 bool StepConfigure::SetupRootAppDirectory() {
181   if (context_->root_application_path.get().empty()) {
182     std::string root_app_path =
183         GetRootAppPath(context_->is_readonly_package.get(),
184         context_->uid.get());
185     if (root_app_path.empty())
186       return false;
187
188     context_->root_application_path.set(root_app_path);
189   }
190   if (!boost::filesystem::exists(context_->root_application_path.get())) {
191     boost::system::error_code error;
192     boost::filesystem::create_directories(
193         context_->root_application_path.get());
194     if (error) {
195       LOG(ERROR) << "Cannot create directory: "
196                  << context_->root_application_path.get();
197       return false;
198     }
199   }
200   LOG(INFO) << "AppDir(" << context_->root_application_path.get() << ")";
201   return true;
202 }
203
204 void StepConfigure::SetupRequestMode(uid_t uid) {
205   context_->request_mode.set(GetRequestMode(uid));
206 }
207
208 void StepConfigure::SetupRequestType() {
209   context_->request_type.set(pkgmgr_->GetRequestType());
210 }
211
212 void StepConfigure::SetupFileCreationMask() {
213   mode_t old_mask, new_mask;
214   old_mask = new_mask = 0;
215
216   switch (context_->request_mode.get()) {
217     case RequestMode::USER:
218       new_mask = 033;  // results in 744 privileges
219       break;
220     case RequestMode::GLOBAL:
221       new_mask = 022;  // results in 755 privileges
222       break;
223   }
224
225   old_mask = umask(new_mask);
226
227   LOG(INFO) << "Changed file creation mask from " << std::oct <<  old_mask
228       << " to " << std::oct <<  new_mask;
229 }
230
231 void StepConfigure::SetupIsPreloadRequest() {
232   context_->is_readonly_package.set(pkgmgr_->GetIsPreloadRequest());
233 }
234
235 void StepConfigure::SetupIsPreloadRWRequest() {
236   context_->is_preload_rw_package.set(pkgmgr_->GetIsPreloadRWRequest());
237 }
238
239 void StepConfigure::SetupIsForceRemoval() {
240   context_->force_remove.set(pkgmgr_->GetIsForceRemoval());
241 }
242
243 void StepConfigure::SetupIsNoRemoval() {
244   context_->no_remove.set(pkgmgr_->GetIsNoRemoval());
245 }
246
247 void StepConfigure::SetupIsKeepRWData() {
248   context_->keep_rwdata.set(pkgmgr_->GetIsKeepRWData());
249 }
250
251 void StepConfigure::SetupIsPartialRW() {
252   context_->partial_rw.set(pkgmgr_->GetIsPartialRW());
253 }
254
255 void StepConfigure::SetupDebugMode() {
256   context_->debug_mode.set(pkgmgr_->GetDebugMode());
257 }
258
259 void StepConfigure::SetupSkipCheckReference() {
260   context_->skip_check_reference.set(pkgmgr_->GetIsSkipCheckReference());
261 }
262
263 void StepConfigure::SetupSkipOptimization() {
264   context_->skip_optimization.set(pkgmgr_->GetSkipOptimization());
265 }
266
267 void StepConfigure::SetupMoveType() {
268   int move_type = pkgmgr_->GetMoveType();
269   switch (move_type) {
270     case 0:
271       context_->move_type.set(MoveType::TO_INTERNAL);
272       break;
273     case 1:
274       context_->move_type.set(MoveType::TO_EXTERNAL);
275       break;
276     case 2:
277       context_->move_type.set(MoveType::TO_EXTENDED);
278       break;
279     default:
280       context_->move_type.set(MoveType::TO_INTERNAL);
281       break;
282   }
283 }
284
285 }  // namespace configuration
286 }  // namespace common_installer