Apply some changes of tizen 3.0
[platform/core/appfw/app-installers.git] / src / common / step / filesystem / step_remove_files.cc
1 // Copyright (c) 2014 Samsung Electronics Co., Ltd All Rights Reserved
2 // Use of this source code is governed by an apache 2.0 license that can be
3 // found in the LICENSE file.
4
5 #include "common/step/filesystem/step_remove_files.h"
6
7 #include <boost/filesystem/operations.hpp>
8 #include <boost/system/error_code.hpp>
9
10 #include <sys/types.h>
11 #include <tzplatform_config.h>
12
13 #include <algorithm>
14 #include <string>
15 #include <vector>
16
17 #include "common/pkgmgr_query.h"
18 #include "common/utils/file_util.h"
19
20 namespace bs = boost::system;
21 namespace bf = boost::filesystem;
22
23 namespace {
24
25 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
26
27 bool SkipRWDirectories(const bf::path& path) {
28   static const std::vector<std::string> dirs_to_ignore = {
29     {"cache"},
30     {"data"},
31     {"shared/data"},
32     {"shared/cache"},
33     {"shared/trusted"},
34   };
35   return std::find(dirs_to_ignore.begin(), dirs_to_ignore.end(), path) !=
36       dirs_to_ignore.end();
37 }
38
39 }  // namespace
40
41
42 namespace common_installer {
43 namespace filesystem {
44
45 Step::Status StepRemoveFiles::precheck() {
46   if (!context_->manifest_data.get()) {
47     LOG(ERROR) << "manifest_data attribute is empty";
48     return Step::Status::MANIFEST_NOT_FOUND;
49   }
50
51   // Even though, the below checks can fail, StepRemoveFiles should still try
52   // to remove the files
53   if (context_->pkg_path.get().empty())
54     LOG(ERROR) << "pkg_path attribute is empty";
55   else if (!bf::exists(context_->pkg_path.get()))
56     LOG(ERROR) << "pkg_path ("
57                << context_->pkg_path.get()
58                << ") path does not exist";
59
60   return Step::Status::OK;
61 }
62
63 Step::Status StepRemoveFiles::process() {
64   bf::path pkg_path(context_->pkg_path.get());
65
66   // We need to unmount external storage before removing package directory
67   // because mount point is inside
68   if (context_->external_storage)
69     context_->external_storage->Commit();
70
71   bool is_keep_rwdata = false;
72   if (context_->request_mode.get() != RequestMode::GLOBAL) {
73     if (QueryIsPackageInstalled(context_->pkgid.get(), kGlobalUserUid) ||
74         context_->keep_rwdata.get())
75       is_keep_rwdata = true;
76   }
77
78   bool is_error = false;
79   if (is_keep_rwdata) {
80     bool ret;
81     for (bf::directory_iterator itr(pkg_path); itr != bf::directory_iterator();
82         ++itr) {
83       if (bf::is_directory(itr->status())) {
84         if (SkipRWDirectories(itr->path().leaf())) {
85           LOG(DEBUG) << "Skipping remove dir:" << itr->path().c_str();
86           continue;
87         }
88         ret = RemoveAll(itr->path());
89       } else {
90         ret = Remove(itr->path());
91       }
92       if (!ret)
93         is_error = true;
94     }
95   } else {
96     if (!RemoveAll(pkg_path))
97       is_error = true;
98   }
99
100   if (is_error)
101     return Status::ERROR;
102
103   return Status::OK;
104 }
105
106 }  // namespace filesystem
107 }  // namespace common_installer