575afd629f1ecbbab104e206b022c5c3783a4f01
[platform/core/appfw/launchpad.git] / src / launchpad-parser / launchpad_parser_plugin.cc
1 /*
2  * Copyright (c) 2020 Samsung Electronics Co., Ltd.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <pkgmgr_installer_info.h>
18 #include <sys/stat.h>
19 #include <sys/types.h>
20 #include <unistd.h>
21
22 #include <fstream>
23 #include <string>
24
25 #include "launchpad-parser/launchpad_parser_plugin.hh"
26 #include "launchpad-parser/log_private.hh"
27
28 #define LOADERS_DIRECTORY_PATH "/opt/share/loaders/"
29
30 namespace launchpad_parser_plugin {
31
32 std::string LaunchpadParser::GetFilePath(std::string id) {
33   return "/opt/share/loaders/" + id + ".loader";
34 }
35
36 int LaunchpadParser::WriteToFile(std::string pkgid) {
37   if (access(LOADERS_DIRECTORY_PATH, F_OK) != 0)
38     mkdir(LOADERS_DIRECTORY_PATH, 0644);
39
40   LOGI("write to file (%zu)", loader_list_.size());
41   for (auto& i : loader_list_) {
42     std::ofstream out_file;
43     LOGI("write ID (%s)", i->GetId().c_str());
44     out_file.open(GetFilePath(i->GetId()));
45     out_file << "[LOADER]\n";
46     out_file << "NAME " + i->GetId() + "\n";
47     out_file << "EXE  /usr/bin/launchpad-loader \n";
48     out_file << "APP_TYPE  capp|c++app \n";
49     out_file << "DETECTION_METHOD  TIMEOUT|VISIBILITY \n";
50     out_file << "TIMEOUT    5000 \n";
51     out_file << "TTL    " + std::to_string(i->GetTimeToLive()) + "\n";
52     out_file << "OWNER    " + pkgid + "\n";
53     out_file << "EXTRA    loader_type  common-loader \n";
54     if (i->GetPreloadLib().size() > 0) {
55       out_file << "EXTRA_ARRAY    preload \n";
56       for (auto& lib : i->GetPreloadLib()) {
57         out_file << "EXTRA_ARRAY_VAL    " LIBDIR "/" + lib + "\n";
58       }
59     }
60     out_file.close();
61   }
62   return 0;
63 }
64
65 bool LaunchpadParser::IsValidId(std::string loader_id, std::string pkgid) {
66   std::string needle("../");
67   size_t found = loader_id.find(needle);
68   if (found != std::string::npos) {
69     _E("Invalid loader_id(%s)", loader_id.c_str());
70     return false;
71   }
72
73   std::ifstream in_file(GetFilePath(loader_id).c_str());
74   if (!in_file.good())
75     return true;
76   std::string key, val;
77   in_file >> key;
78   while (in_file >> key >> val) {
79     if (key == "OWNER") {
80       LOGI("key (%s), val (%s)", key.c_str(), val.c_str());
81       if (val == pkgid)
82         return true;
83     }
84   }
85   return false;
86 }
87
88 int LaunchpadParser::Install(xmlDocPtr doc, std::string pkgid) {
89   pkgmgr_privilege_level level;
90   pkgmgr_installer_info_get_privilege_level(&level);
91   if (level != PM_PRIVILEGE_PLATFORM) {
92     LOGE("Privilege level(%d) is not platform", static_cast<int>(level));
93     return -1;
94   }
95
96   xmlNode* root = xmlDocGetRootElement(doc);
97   if (root == nullptr)
98     return -1;
99
100   for (xmlNode* node = root->children; node; node = node->next) {
101     if (!node->name)
102       continue;
103
104     std::string name = std::string(reinterpret_cast<const char*>(node->name));
105     if (name != "provides-appdefined-loader")
106       continue;
107
108     xmlChar* val = xmlGetProp(node, reinterpret_cast<const xmlChar*>("id"));
109     if (val == nullptr)
110       continue;
111
112     std::shared_ptr<LoaderInfo> info =
113         std::make_shared<LoaderInfo>(std::string(reinterpret_cast<char*>(val)));
114     xmlFree(val);
115     if (!IsValidId(info->GetId(), pkgid))
116       return -1;
117
118     xmlChar* ttl = xmlGetProp(node,
119         reinterpret_cast<const xmlChar*>("time-to-live"));
120     if (ttl) {
121       info->SetTimeToLive(std::stoi(std::string(reinterpret_cast<char*>(ttl))));
122       xmlFree(ttl);
123     }
124
125     for (xmlNode* iter = node->children; iter; iter = iter->next) {
126       if (!iter->name)
127         continue;
128       std::string child_name =
129           std::string(reinterpret_cast<const char*>(iter->name));
130       if (child_name == "preload-library") {
131         xmlChar* libname = xmlGetProp(iter,
132             reinterpret_cast<const xmlChar*>("name"));
133         if (!libname)
134           continue;
135         info->AddPreloadLib(std::string(reinterpret_cast<char*>(libname)));
136         xmlFree(libname);
137       }
138     }
139     loader_list_.push_back(info);
140   }
141   WriteToFile(pkgid);
142
143   return 0;
144 }
145
146 int LaunchpadParser::Upgrade(xmlDocPtr doc, std::string pkgid) {
147   if (UnInstall(doc, pkgid) != 0)
148     return -1;
149
150   return Install(doc, pkgid);
151 }
152
153 int LaunchpadParser::UnInstall(xmlDocPtr doc, std::string pkgid) {
154   xmlNode* root = xmlDocGetRootElement(doc);
155   if (root == nullptr)
156     return -1;
157
158   for (xmlNode* node = root->children; node; node = node->next) {
159     if (!node->name)
160       continue;
161
162     std::string name = std::string(reinterpret_cast<const char*>(node->name));
163     if (name != "provides-appdefined-loader")
164       continue;
165
166     xmlChar* val = xmlGetProp(node, reinterpret_cast<const xmlChar*>("id"));
167     if (!val)
168       return -1;
169
170     std::string id = std::string(reinterpret_cast<char*>(val));
171     xmlFree(val);
172     if (!IsValidId(id, pkgid))
173       return -1;
174     remove(GetFilePath(id).c_str());
175   }
176   return 0;
177 }
178
179 }   // namspace launchpad_parser_plugin