Release version 0.15.20
[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 using namespace std;
31 namespace launchpad_parser_plugin {
32
33 string LaunchpadParser::GetFilePath(string id) {
34   return "/opt/share/loaders/" + id + ".loader";
35 }
36
37 int LaunchpadParser::WriteToFile(string pkgid) {
38   if (access(LOADERS_DIRECTORY_PATH, F_OK) != 0)
39     mkdir(LOADERS_DIRECTORY_PATH, 0644);
40
41   LOGI("write to file (%zu)", loader_list_.size());
42   for (auto& i : loader_list_) {
43     std::ofstream out_file;
44     LOGI("write ID (%s)", i->GetId().c_str());
45     out_file.open(GetFilePath(i->GetId()));
46     out_file << "[LOADER]\n";
47     out_file << "NAME " + i->GetId() + "\n";
48     out_file << "EXE  /usr/bin/launchpad-loader \n";
49     out_file << "APP_TYPE  capp|c++app \n";
50     out_file << "DETECTION_METHOD  TIMEOUT|VISIBILITY \n";
51     out_file << "TIMEOUT    5000 \n";
52     out_file << "TTL    " + to_string(i->GetTimeToLive()) + "\n";
53     out_file << "OWNER    " + pkgid + "\n";
54     out_file << "EXTRA    loader_type  common-loader \n";
55     if (i->GetPreloadLib().size() > 0) {
56       out_file << "EXTRA_ARRAY    preload \n";
57       for (auto& lib : i->GetPreloadLib()) {
58         out_file << "EXTRA_ARRAY_VAL    /usr/lib/" + lib + "\n";
59       }
60     }
61     out_file.close();
62   }
63   return 0;
64 }
65
66 bool LaunchpadParser::IsValidId(string loader_id, string pkgid) {
67   std::string needle("../");
68   std::size_t found = loader_id.find(needle);
69   if (found != std::string::npos) {
70     _E("Invalid loader_id(%s)", loader_id.c_str());
71     return false;
72   }
73
74   ifstream in_file(GetFilePath(loader_id).c_str());
75   if (!in_file.good())
76     return true;
77   string key, val;
78   in_file >> key;
79   while (in_file >> key >> val) {
80     if (key == "OWNER") {
81       LOGI("key (%s), val (%s)", key.c_str(), val.c_str());
82       if (val == pkgid)
83         return true;
84     }
85   }
86   return false;
87 }
88
89 int LaunchpadParser::Install(xmlDocPtr doc, string pkgid) {
90   pkgmgr_privilege_level level;
91   pkgmgr_installer_info_get_privilege_level(&level);
92   if (level != PM_PRIVILEGE_PLATFORM) {
93     LOGE("Privilege level(%d) is not platform", static_cast<int>(level));
94     return -1;
95   }
96
97   xmlNode* root = xmlDocGetRootElement(doc);
98   for (xmlNode* node = root->children; node; node = node->next) {
99     if (!node->name)
100       continue;
101
102     string name = string((char*)node->name);
103     if (name != "provides-appdefined-loader")
104       continue;
105
106     xmlChar* val = xmlGetProp(node, (const xmlChar *)"id");
107     shared_ptr<LoaderInfo> info = make_shared<LoaderInfo>(string((char*)val));
108     if (!IsValidId(info->GetId(), pkgid))
109       return -1;
110
111     xmlChar* ttl = xmlGetProp(node, (const xmlChar *)"time-to-live");
112     if (ttl)
113       info->SetTimeToLive(stoi(string((char*)ttl)));
114
115     for (xmlNode* iter = node->children; iter; iter = iter->next) {
116       if (!iter->name)
117         continue;
118       string child_name = string((char*)iter->name);
119       if (child_name == "preload-library") {
120         xmlChar* libname = xmlGetProp(iter, (const xmlChar *)"name");
121         if (!libname)
122           continue;
123         info->AddPreloadLib(string((char*)libname));
124       }
125     }
126     loader_list_.push_back(info);
127   }
128   WriteToFile(pkgid);
129
130   return 0;
131 }
132
133 int LaunchpadParser::Upgrade(xmlDocPtr doc, std::string pkgid) {
134   if (UnInstall(doc, pkgid) != 0)
135     return -1;
136
137   return Install(doc, pkgid);
138 }
139
140 int LaunchpadParser::UnInstall(xmlDocPtr doc, std::string pkgid) {
141   xmlNode* root = xmlDocGetRootElement(doc);
142   for (xmlNode* node = root->children; node; node = node->next) {
143     if (!node->name)
144       continue;
145
146     string name = string((char*)node->name);
147     if (name != "provides-appdefined-loader")
148       continue;
149
150     xmlChar* val = xmlGetProp(node, (const xmlChar *)"id");
151     if (!val)
152       return -1;
153
154     string id = string((char*)val);
155     if (!IsValidId(id, pkgid))
156         return -1;
157     remove(GetFilePath(id).c_str());
158   }
159   return 0;
160 }
161
162 }   // namspace launchpad_parser_plugin