+/*
+ * Copyright (c) 2020 Samsung Electronics Co., Ltd All Rights Reserved
+ *
+ * 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 "log.h"
+#include "utils.h"
+
+#include <regex>
+#include <vector>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
+
+typedef struct _xmlDoc xmlDoc;
+typedef xmlDoc* xmlDocPtr;
+
+bool pluginInstalled = false;
+
+extern "C" int PKGMGR_PARSER_PLUGIN_INSTALL(xmlDocPtr doc, const char* pkgId)
+{
+ // Can be multiple apps in one package
+ if (pluginInstalled) {
+ _INFO("Plugin already installed");
+ return 0;
+ }
+ pluginInstalled = true;
+
+ std::string appType = getAppType(pkgId);
+ if (appType.empty()) {
+ _ERR("Failed to get app type from [%s]", pkgId);
+ return 0;
+ }
+
+ if (appType.find("dotnet") == std::string::npos) {
+ return 0;
+ }
+
+ std::string rootPath = getRootPath(pkgId);
+ if (rootPath.empty()) {
+ _ERR("Failed to get root path from [%s]", pkgId);
+ return 0;
+ }
+
+ std::string runtimesDir = concatPath(rootPath, "bin/runtimes");
+ if (!bf::exists(runtimesDir)) {
+ return 0;
+ }
+
+ char buffer[128];
+ sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER);
+ std::regex pattern(buffer);
+
+ std::vector<std::string> unusedDir;
+ try {
+ for (auto& path : bf::recursive_directory_iterator(runtimesDir)) {
+ std::string filepath = path.path().string();
+ std::string targetDir = filepath.substr(filepath.rfind("/runtimes/") + 10);
+ if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern)) {
+ if (isDirectory(filepath)) {
+ unusedDir.push_back(filepath);
+ }
+ }
+ }
+ } catch (const bf::filesystem_error& error) {
+ _ERR("Failed to recursive directory: %s", error.what());
+ }
+
+ for (auto& path : unusedDir) {
+ if (!removeAll(path)) {
+ _ERR("Failed to remove of %s", path.c_str());
+ }
+ }
+ unusedDir.clear();
+
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_UPGRADE(xmlDocPtr doc, const char* pkgId)
+{
+ return PKGMGR_PARSER_PLUGIN_INSTALL(doc, pkgId);
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_UNINSTALL(xmlDocPtr doc, const char* pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_REMOVED(xmlDocPtr doc, const char* pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_CLEAN(xmlDocPtr doc, const char* pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_UNDO(xmlDocPtr doc, const char* pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_PRE_INSTALL(const char *pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_PRE_UPGRADE(const char *pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_PRE_UNINSTALL(const char *pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_POST_INSTALL(const char *pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_POST_UPGRADE(const char *pkgId)
+{
+ return 0;
+}
+extern "C" int PKGMGR_PARSER_PLUGIN_POST_UNINSTALL(const char *pkgId)
+{
+ return 0;
+}