Remove boost dependency
[platform/core/appfw/app-installers.git] / src / pkg_initdb / init_pkg_db.cc
1 // Copyright (c) 2020 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 <tzplatform_config.h>
6
7 #include <pkgmgr_parser_db.h>
8 #include <pkgmgr-info.h>
9
10 #include <filesystem>
11 #include <iostream>
12 #include <list>
13 #include <string>
14
15 #include "pkg_initdb/init_pkg_db.h"
16 #include "pkg_initdb/manifest_loader.h"
17 #include "pkg_initdb/option_checker.h"
18
19 #include "common/utils/file_util.h"
20 #include "common/utils/subprocess.h"
21
22 namespace ci = common_installer;
23 namespace fs = std::filesystem;
24
25 namespace {
26
27 const uid_t kRootUserUid = 0;
28 const uid_t kGlobalUserUid = tzplatform_getuid(TZ_SYS_GLOBALAPP_USER);
29 const char kBackendDirectoryPath[] = "/etc/package-manager/backend/";
30
31 void RemoveDatabase(const std::string& path) {
32   ci::Remove(path);
33   ci::Remove(path + "-journal");
34 }
35
36 void RemoveOldDatabases(uid_t uid, bool is_global) {
37   char *parser_db = getUserPkgParserDBPathUID(uid);
38
39   if (parser_db == nullptr) {
40     std::cerr << "Failed to get db path, cannot remove old databases";
41     return;
42   }
43
44   RemoveDatabase(parser_db);
45   free(parser_db);
46
47   if (!is_global)
48     return;
49
50   char *cert_db = getUserPkgCertDBPath();
51   if (!cert_db) {
52     std::cerr << "Failed to get cert db path" << std::endl;
53     return;
54   }
55
56   RemoveDatabase(cert_db);
57   free(cert_db);
58 }
59
60 }  // namespace
61
62 bool InitPkgDB::Init(int argc, char *argv[]) {
63   return option_checker_.Init(argc, argv);
64 }
65
66 bool InitPkgDB::RunBackend(const std::string& pkgid,
67     const std::string& type, bool preload) {
68   fs::path backend_path(kBackendDirectoryPath);
69   backend_path /= type;
70   ci::Subprocess backend(backend_path.string());
71   auto params = option_checker_.GetParams(preload, pkgid);
72   if (preload) {
73     if (option_checker_.GetUid() != kRootUserUid) {
74       std::cerr << "Preload request for non-root user" << std::endl;
75       return false;
76     }
77     params.emplace_back("--preload");
78   }
79
80   if (!backend.RunWithArgs(params)) {
81     std::cerr << "Failed to start backend" << std::endl;
82     return false;
83   }
84   int status = backend.Wait();
85   if (WIFEXITED(status) == 0 || WEXITSTATUS(status) != 0) {
86     std::cerr << "Backend operation failed" << std::endl;
87     return false;
88   }
89
90   return true;
91 }
92
93 bool InitPkgDB::LoadDirectory(const std::string& path,
94     bool preload) {
95   ManifestLoader manifest_loader(path);
96   std::list<ManifestInfo> manifest_list = manifest_loader.LoadManifest();
97   bool result = true;
98
99   for (auto &manifest_info : manifest_list) {
100     std::cerr << "Manifest : " << std::get<0>(manifest_info) <<
101         (option_checker_.IsPartialRW() ? " (rw-only)":" (all)") << std::endl;
102     if (!RunBackend(std::get<1>(manifest_info),
103                     std::get<2>(manifest_info), preload))
104       result = false;
105   }
106   return result;
107 }
108
109 bool InitPkgDB::Run() {
110   if (!HandleDatabase())
111     return false;
112
113   bool result = true;
114   if (option_checker_.IsGlobal()) {
115     if (!option_checker_.IsRWOnly())
116       if (!LoadDirectory(tzplatform_getenv(TZ_SYS_RO_PACKAGES), true))
117         result = false;
118
119     if (option_checker_.IsROOnly())
120       return result;
121
122     if (!LoadDirectory(tzplatform_getenv(TZ_SYS_RW_PACKAGES), false))
123       result = false;
124   } else {
125     // Specified user location
126     tzplatform_set_user(option_checker_.GetUid());
127     std::string user_dir(tzplatform_getenv(TZ_USER_PACKAGES));
128     tzplatform_reset_user();
129     if (!LoadDirectory(user_dir, false))
130       result = false;
131   }
132
133   return result;
134 }
135
136 bool InitPkgDB::HandleDatabase() {
137   if (option_checker_.GetKeepDb())
138     return true;
139
140   uid_t uid = option_checker_.GetUid();
141   RemoveOldDatabases(uid, option_checker_.IsGlobal());
142   if (pkgmgr_parser_create_and_initialize_db(uid) < 0) {
143     std::cerr << "Cannot create db" << std::endl;
144     return false;
145   }
146
147   return true;
148 }