+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fstream>
+#include <string>
+
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "launchpad_parser_plugin.hh"
+#include "log_private.hh"
+
+#define LOADERS_DIRECTORY_PATH "/opt/share/loaders/"
+
+using namespace std;
+namespace launchpad_parser_plugin {
+
+string LaunchpadParser::GetFilePath(string id) {
+ return "/opt/share/loaders/" + id + ".loader";
+}
+
+int LaunchpadParser::WriteToFile(string pkgid) {
+ if (access(LOADERS_DIRECTORY_PATH, F_OK) != 0)
+ mkdir(LOADERS_DIRECTORY_PATH, 0644);
+
+ LOGI("write to file (%d)", loader_list_.size());
+ for (auto& i : loader_list_) {
+ std::ofstream out_file;
+ LOGI("write ID (%s)", i->GetId().c_str());
+ out_file.open(GetFilePath(i->GetId()));
+ out_file << "[LOADER]\n";
+ out_file << "NAME " + i->GetId() + "\n";
+ out_file << "EXE /usr/bin/launchpad-loader \n";
+ out_file << "APP_TYPE capp|c++app \n";
+ out_file << "DETECTION_METHOD TIMEOUT|VISIBILITY \n";
+ out_file << "TIMEOUT 5000 \n";
+ out_file << "TTL " + to_string(i->GetTimeToLive()) + "\n";
+ out_file << "OWNER " + pkgid + "\n";
+ out_file << "EXTRA loader_type common-loader \n";
+ if (i->GetPreloadLib().size() > 0) {
+ out_file << "EXTRA_ARRAY preload \n";
+ for (auto& lib : i->GetPreloadLib()) {
+ out_file << "EXTRA_ARRAY_VAL /usr/lib/" + lib + "\n";
+ }
+ }
+ out_file.close();
+ }
+ return 0;
+}
+
+bool LaunchpadParser::IsValidId(string loader_id, string pkgid) {
+ ifstream in_file(GetFilePath(loader_id).c_str());
+ if (!in_file.good())
+ return true;
+ string key, val;
+ in_file >> key;
+ while (in_file >> key >> val) {
+ if (key == "OWNER") {
+ LOGI("key (%s), val (%s)", key.c_str(), val.c_str());
+ if (val == pkgid)
+ return true;
+ }
+ }
+ return false;
+}
+
+int LaunchpadParser::Install(xmlDocPtr doc, string pkgid) {
+ xmlNode* root = xmlDocGetRootElement(doc);
+ for (xmlNode* node = root->children; node; node = node->next) {
+ if (!node->name)
+ continue;
+
+ string name = string((char*)node->name);
+ if (name != "provides-appdefined-loader")
+ continue;
+
+ xmlChar* val = xmlGetProp(node, (const xmlChar *)"id");
+ shared_ptr<LoaderInfo> info = make_shared<LoaderInfo>(string((char*)val));
+ if (!IsValidId(info->GetId(), pkgid))
+ return -1;
+
+ xmlChar* ttl = xmlGetProp(node, (const xmlChar *)"time-to-live");
+ if (ttl)
+ info->SetTimeToLive(stoi(string((char*)ttl)));
+
+ for (xmlNode* iter = node->children; iter; iter = iter->next) {
+ if (!iter->name)
+ continue;
+ string child_name = string((char*)iter->name);
+ if (child_name == "preload-library") {
+ xmlChar* libname = xmlGetProp(iter, (const xmlChar *)"name");
+ if (!libname)
+ continue;
+ info->AddPreloadLib(string((char*)libname));
+ }
+ }
+ loader_list_.push_back(info);
+ }
+ WriteToFile(pkgid);
+
+ return 0;
+}
+
+int LaunchpadParser::Upgrade(xmlDocPtr doc, std::string pkgid) {
+ if (UnInstall(doc, pkgid) != 0)
+ return -1;
+
+ return Install(doc, pkgid);
+}
+
+int LaunchpadParser::UnInstall(xmlDocPtr doc, std::string pkgid) {
+ xmlNode* root = xmlDocGetRootElement(doc);
+ for (xmlNode* node = root->children; node; node = node->next) {
+ if (!node->name)
+ continue;
+
+ string name = string((char*)node->name);
+ if (name != "provides-appdefined-loader")
+ continue;
+
+ xmlChar* val = xmlGetProp(node, (const xmlChar *)"id");
+ if (!val)
+ return -1;
+
+ string id = string((char*)val);
+ if (!IsValidId(id, pkgid))
+ return -1;
+ remove(GetFilePath(id).c_str());
+ }
+ return 0;
+}
+
+} // namspace launchpad_parser_plugin