Fixed Svace(memory_leak)
[platform/core/dotnet/launcher.git] / NativeLauncher / installer-plugin / prefer_nuget_cache_plugin.cc
index e0c9ffa..da66f24 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2016 Samsung Electronics Co., Ltd All Rights Reserved
+ * Copyright (c) 2019 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.
  */
 
 #include "log.h"
-#include "ni_common.h"
 #include "utils.h"
 #include "db_manager.h"
-
-#ifdef  LOG_TAG
-#undef  LOG_TAG
-#endif
-#define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
+#include "path_manager.h"
+#include "plugin_manager.h"
+#include "tac_common.h"
 
 #include <cstring>
 #include <fstream>
 #include <boost/filesystem.hpp>
 #include <glib.h>
 #include <json/json.h>
-#include <openssl/sha.h>
 #include <pkgmgr-info.h>
 #include <pkgmgr_installer_info.h>
+#include <openssl/sha.h>
+
+#ifdef  LOG_TAG
+#undef  LOG_TAG
+#endif
+#define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
+
+#define __XSTR(x) #x
+#define __STR(x) __XSTR(x)
+static const char* __TAC_DIR = __STR(TAC_DIR);
+#undef __STR
+#undef __XSTR
 
 typedef struct Metadata {
        const char *key;
        const char *value;
 } Metadata;
 
-const std::string mOptUsrDotnet = "/opt/usr/dotnet";
-const std::string mTizenNET = "Tizen.NET";
-const std::string mTizenNETSdk = "Tizen.NET.Sdk";
-const std::string mNETStandardLibrary = "NETStandard.Library";
-const std::string mTacRelease = "TAC.Release";
-const std::string mDepsJson = ".deps.json";
-const std::string mBackup = ".bck";
-const std::string mdValue = "true";
-const std::string mdKey = "http://tizen.org/metadata/prefer_nuget_cache";
-const std::string tacAppListDB = mOptUsrDotnet + "/.TAC.App.list.db";
-
-std::vector<std::string> nugetPackagesAssembliesShaR2R;
+std::vector<std::string> nugetPackagesAssembliesSha;
 std::vector<std::string> tacDB;
 std::vector<std::string> createDirectories;
 std::vector<std::string> updateTac;
 std::string status = "";
-
-bool isCreateDirectory = false;
-bf::path rootPath;
-bf::path execPath;
-bf::path binPath;
-
+std::string rootPath;
+std::string execName;
+std::string binPath;
 static sqlite3 *tac_db = NULL;
 
-int metadataCheck(GList *list)
+bool metadataCheck(GList *list)
 {
        GList *tag = NULL;
        Metadata *mdInfo = NULL;
        tag = g_list_first(list);
        mdInfo = (Metadata*)tag->data;
-       if (mdInfo->key == mdKey && mdInfo->value == mdValue) {
+       if (strcmp(mdInfo->key, TAC_METADATA_KEY) == 0 && strcmp(mdInfo->value, METADATA_VALUE) == 0) {
                _DBG("Prefer nuget cache set TRUE");
-               return 0;
-       } else {
-               return 1;
+               if (initializePluginManager("normal")) {
+                       _ERR("Fail to initialize PluginManager");
+                       return false;
+               }
+               if (initializePathManager(std::string(), std::string(), std::string())) {
+                       _ERR("Fail to initialize PathManger");
+                       return false;
+               }
+               return true;
        }
+       return false;
 }
 
-int getAppType(std::string pkgId)
+bool appTypeCheck(std::string pkgId)
 {
        uid_t uid = 0;
        if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
                _ERR("Failed to get UID");
-               return 0;
+               return false;
        }
 
        pkgmgrinfo_pkginfo_h handle;
        int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
        if (ret != PMINFO_R_OK) {
                _ERR("Failed to get pkg info");
-               return 0;
+               return false;
        }
 
-       bool dotnetExist = false;
+       bool isDotnetAppType = false;
        auto dotnetAppCounter = [] (pkgmgrinfo_appinfo_h handle, void *userData) -> int {
                char* type = nullptr;
                bool* dotnet = static_cast<bool*>(userData);
                if (pkgmgrinfo_appinfo_get_apptype(handle, &type) != PMINFO_R_OK) {
                        _ERR("Failed to get app type : %s", type);
-                       return 0;
+                       return -1;
                }
-               _INFO("App type : %s", type);
                if (strcmp(type, "dotnet") == 0) {
                        *dotnet = true;
                }
                return 0;
        };
 
-       if (pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, dotnetAppCounter, &dotnetExist, uid) != PMINFO_R_OK) {
-               _ERR("Failed to get list of app in pkg : %s", pkgId.c_str());
-               return -1;
-       }
-
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-       return dotnetExist;
-}
-
-int getExecPath(std::string pkgId)
-{
-       uid_t uid = 0;
-       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-               _ERR("Failed to get UID");
-               return 0;
-       }
-
-       pkgmgrinfo_pkginfo_h handle;
-       int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
-       if (ret != PMINFO_R_OK) {
-               _ERR("Failed to get pkg info");
-               return 0;
-       }
-
-       auto dotnetAppCounter = [] (pkgmgrinfo_appinfo_h handle, void *userData) -> int {
-               char* exec = nullptr;
-               if (pkgmgrinfo_appinfo_get_exec(handle, &exec) != PMINFO_R_OK) {
-                       _ERR("Failed to get exec : %s", exec);
-                       return 0;
-               }
-               _INFO("exec : %s", exec);
-               execPath = bf::path(exec);
-               return 0;
-       };
-
-       if (pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, dotnetAppCounter, NULL, uid) != PMINFO_R_OK) {
-               _ERR("Failed to get list of app in pkg : %s", pkgId.c_str());
-               return -1;
-       }
-
-       pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-       return 0;
-}
-
-int getRootPath(std::string pkgId)
-{
-       uid_t uid = 0;
-       if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-               _ERR("Failed to get UID");
-               return 0;
-       }
-
-       pkgmgrinfo_pkginfo_h handle;
-       int ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle);
-       if (ret != PMINFO_R_OK) {
-               _ERR("Failed to get pkg info");
-               return 0;
-       }
-
-       auto dotnetAppCounter = [] (pkgmgrinfo_appinfo_h handle, void *userData) -> int {
-               char* root = nullptr;
-               if (pkgmgrinfo_appinfo_get_root_path(handle, &root) != PMINFO_R_OK) {
-                       _ERR("Failed to get root path : %s", root);
-                       return 0;
-               }
-               _INFO("Root path : %s", root);
-               rootPath = bf::path(root);
-               binPath = root / bf::path("bin");
-               _INFO("Bin path : %s", binPath.c_str());
-               return 0;
-       };
-
-       if (pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, dotnetAppCounter, NULL, uid) != PMINFO_R_OK) {
+       if (pkgmgrinfo_appinfo_get_usr_list(handle, PMINFO_ALL_APP, dotnetAppCounter, &isDotnetAppType, uid) != PMINFO_R_OK) {
                _ERR("Failed to get list of app in pkg : %s", pkgId.c_str());
-               return -1;
+               pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
+               return false;
        }
 
        pkgmgrinfo_pkginfo_destroy_pkginfo(handle);
-       return 0;
+       return isDotnetAppType;
 }
 
-int SHA256(std::string path, char outputBuffer[65])
+void SHA256(std::string path, char outputBuffer[65])
 {
        FILE *file = fopen(path.c_str(), "rb");
        if (!file) {
-               return -1;
+               return;
        }
 
        unsigned char hash[SHA256_DIGEST_LENGTH];
@@ -204,7 +133,7 @@ int SHA256(std::string path, char outputBuffer[65])
        char *buffer = (char*)malloc(bufSize);
        if (!buffer) {
                fclose(file);
-               return -1;
+               return;
        }
 
        while ((bytesRead = fread(buffer, 1, bufSize, file))) {
@@ -212,122 +141,99 @@ int SHA256(std::string path, char outputBuffer[65])
        }
        SHA256_Final(hash, &sha256);
        for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) {
-               sprintf(outputBuffer + (i * 2), "%02x", hash[i]);
+               snprintf(outputBuffer + (i * 2), 3, "%02x", hash[i]);
        }
        outputBuffer[64] = 0;
 
        fclose(file);
        free(buffer);
-       return 0;
 }
 
-int depsJsonParser()
+void createSHA256Info(std::string sha256_info, std::string np)
 {
-       std::string exec_name = execPath.filename().string();
-       std::string deps_json_name = exec_name.substr(0, exec_name.rfind(".dll")) + mDepsJson;
-       if (bf::exists(rootPath / deps_json_name)) {
-               std::string deps_json_path = (rootPath / deps_json_name).string();
-               std::ifstream ifs(deps_json_path);
-               Json::CharReaderBuilder reader;
-               Json::Value root;
-               std::string error;
-               if (ifs.is_open()) {
-                       if (!Json::parseFromStream(reader, ifs, &root, &error)) {
-                               _INFO("Failed to parse of deps.json");
-                               ifs.close();
-                               return -1;
-                       }
-                       const Json::Value runtimeTargetName = root["runtimeTarget"]["name"];
-                       std::string runtimeTarget_name = runtimeTargetName.asString();
-                       const Json::Value nugetPackages = root["targets"][runtimeTarget_name.c_str()];
-                       for (auto& nuget : nugetPackages.getMemberNames()) {
-                               if (strstr(nuget.c_str(), mTizenNET.c_str()) != NULL ||
-                                       strstr(nuget.c_str(), mTizenNETSdk.c_str()) != NULL ||
-                                       strstr(nuget.c_str(), exec_name.c_str()) != NULL ||
-                                       strstr(nuget.c_str(), (exec_name.substr(0, exec_name.find('.'))).c_str()) != NULL) {
-                                       continue;
-                               } else {
-                                       const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"];
-                                       if (assemblies != Json::nullValue) {
-                                               const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"];
-                                               std::string r2r = "";
-                                               for (auto& dependency : dependencies.getMemberNames()) {
-                                                       if (strstr(dependency.c_str(), mTizenNET.c_str()) != NULL ||
-                                                               strstr(dependency.c_str(), mNETStandardLibrary.c_str()) != NULL) {
-                                                               continue;
-                                                       } else {
-                                                               r2r = "--r2r";
-                                                       }
-                                               }
-                                               if (strcmp(r2r.c_str(), "--r2r")) {
-                                                       tacDB.push_back(nuget);
-                                                       _INFO("Nuget package : %s", nuget.c_str());
-                                                       for (auto& assembly : assemblies.getMemberNames()) {
-                                                               std::string assembly_name = assembly.substr(assembly.rfind('/') + 1);
-                                                               char buffer[65];
-                                                               SHA256((binPath / assembly_name).string(), buffer);
-                                                               nugetPackagesAssembliesShaR2R.push_back(nuget + "/" + assembly_name + "/" + buffer + "/" + r2r);
-                                                               _INFO("Assembly / SHA256 : %s / %s", assembly_name.c_str(), buffer);
-                                                       }
-                                               }
+       std::ofstream ofs(sha256_info, std::ios::app);
+       int assembly_count = 0;
+       for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+               std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
+               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
+               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
+               std::string sha = npAssemblySha.substr(npAssemblySha.rfind(':') + 1);
+               if (!strcmp(nuget_package.c_str(), np.c_str())) {
+                       ofs << assembly << ":" << sha << std::endl;
+                       assembly_count++;
+               }
+       }
+       ofs << assembly_count << std::endl;
+       ofs.close();
+}
+
+int compareSHA256Info(std::string sha256_info, std::string np)
+{
+       int compare_count = 0;
+       int assembly_count = 0;
+       std::string sha256_count = "0";
+       for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+               std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
+               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
+               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
+               std::string sha = npAssemblySha.substr(npAssemblySha.rfind(':') + 1);
+               if (!strcmp(nuget_package.c_str(), np.c_str())) {
+                       assembly_count++;
+                       std::ifstream ifs(sha256_info);
+                       std::string get_str;
+                       if (ifs.is_open()) {
+                               while (getline(ifs, get_str)) {
+                                       if (!strcmp(get_str.c_str(), (assembly + ":" + sha).c_str())) {
+                                               compare_count++;
                                        }
+                                       sha256_count = get_str;
                                }
+                               ifs.close();
                        }
-                       ifs.close();
                }
        }
+       if (!strcmp(std::to_string(assembly_count).c_str(), std::to_string(compare_count).c_str()) &&
+               !strcmp(std::to_string(assembly_count).c_str(), sha256_count.c_str())) {
+               _INFO("Same nuget : %s", np.c_str());
+               return 1;
+       }
        return 0;
 }
 
-int createSymlink(bf::path tac_version_dir, std::string np)
+int copyNCreateSymlink(std::string tac_version_dir, std::string np, bool is_create_tac_dir)
 {
-       bs::error_code error;
-       uid_t uid = 0;
-       for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
-               std::string nuget_package_assembly_sha = npAssemblyShaR2R.substr(0, npAssemblyShaR2R.rfind('/'));
-               std::string sha = nuget_package_assembly_sha.substr(nuget_package_assembly_sha.rfind('/') + 1);
-               std::string nuget_package_assembly = nuget_package_assembly_sha.substr(0, nuget_package_assembly_sha.rfind('/'));
-               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/'));
-               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind('/') + 1);
-               std::string r2r = npAssemblyShaR2R.substr(npAssemblyShaR2R.rfind('/') + 1);
-               std::string ni_assembly = assembly.substr(0, assembly.rfind(".dll")) + ".ni.dll";
+       uid_t g_uid = 0;
+       gid_t g_gid = 0;
+       if (pkgmgr_installer_info_get_target_uid(&g_uid) < 0) {
+               _ERR("Failed to get UID");
+               return -1;
+       }
+
+       std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
+       if (!createDir(tac_dir)) {
+               _ERR("Cannot create directory: %s", tac_dir.c_str());
+               return -1;
+       }
+
+       for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
+               std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
+               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
+               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
                if (!strcmp(nuget_package.c_str(), np.c_str())) {
-                       if (bf::exists(binPath / assembly)) {
-                               if (isCreateDirectory) {
-                                       std::string command = "nitool --dll " + binPath.string() + "/" + assembly + " " + r2r;
-                                       if (system(command.c_str()) != 0) {
-                                               _ERR("Failed to create ni dll [%s]", command.c_str());
+                       if (bf::exists(concatPath(binPath, assembly))) {
+                               if (is_create_tac_dir) {
+                                       if (!copyFile(concatPath(binPath, assembly), concatPath(tac_version_dir, assembly))) {
+                                               _ERR("Failed to copy of %s", assembly.c_str());
                                                return -1;
                                        }
-                                       if (!copyFile(binPath / ni_assembly, tac_version_dir / ni_assembly)) {
-                                               _ERR("Failed to move of %s", ni_assembly.c_str());
-                                               return -1;
-                                       }
-                                       if (!copyFile(binPath / assembly, tac_version_dir / assembly)) {
-                                               _ERR("Failed to move of %s", assembly.c_str());
-                                               return -1;
-                                       }
-                               }
-                               if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
-                                       _ERR("Failed to get UID");
-                                       return -1;
-                               }
-                               bf::create_symlink(tac_version_dir / ni_assembly, binPath / mTacRelease / ni_assembly, error);
-                               if (error) {
-                                       _ERR("Failed to create symlink");
-                                       return -1;
-                               }
-                               bf::create_symlink(tac_version_dir / assembly, binPath / mTacRelease / assembly, error);
-                               if (error) {
-                                       _ERR("Failed to create symlink");
-                                       return -1;
                                }
-                               if (lchown((binPath / mTacRelease / ni_assembly).c_str(), uid, 0)) {
-                                       _ERR("Failed to change owner of: %s", (binPath / mTacRelease / ni_assembly).c_str());
+                               bf::create_symlink(concatPath(tac_version_dir, assembly), concatPath(tac_dir, assembly));
+                               if (lchown(concatPath(tac_dir, assembly).c_str(), g_uid, g_gid)) {
+                                       _ERR("Failed to change owner of: %s", concatPath(tac_dir, assembly).c_str());
                                        return -1;
                                }
-                               if (lchown((binPath / mTacRelease / assembly).c_str(), uid, 0)) {
-                                       _ERR("Failed to change owner of: %s", (binPath / mTacRelease / assembly).c_str());
+                               if (!removeFile(concatPath(binPath, assembly))) {
+                                       _ERR("Failed to remove of %s", assembly.c_str());
                                        return -1;
                                }
                        }
@@ -336,29 +242,18 @@ int createSymlink(bf::path tac_version_dir, std::string np)
        return 0;
 }
 
-int removeOriginalAssembly() {
-       for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
-               std::string nuget_package_assembly_sha = npAssemblyShaR2R.substr(0, npAssemblyShaR2R.rfind('/'));
-               std::string sha = nuget_package_assembly_sha.substr(nuget_package_assembly_sha.rfind('/') + 1);
-               std::string nuget_package_assembly = nuget_package_assembly_sha.substr(0, nuget_package_assembly_sha.rfind('/'));
-               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/'));
-               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind('/') + 1);
-               std::string r2r = npAssemblyShaR2R.substr(npAssemblyShaR2R.rfind('/') + 1);
-               std::string ni_assembly = assembly.substr(0, assembly.rfind(".dll")) + ".ni.dll";
-               if (bf::exists(binPath / assembly)) {
-                       if (!removeFile(binPath / assembly)) {
-                               _ERR("Failed to remove of %s", assembly.c_str());
-                               return -1;
-                       }
-               }
-               if (bf::exists(binPath / ni_assembly)) {
-                       if (!removeFile(binPath / ni_assembly)) {
-                               _ERR("Failed to remove of %s", ni_assembly.c_str());
-                               return -1;
-                       }
-               }
-       }
-       return 0;
+void depsJsonCheck() {
+       for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) {
+               std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':'));
+               std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1);
+               tacDB.push_back(nugetPackage);
+               char buffer[65] = {0};
+               SHA256(concatPath(binPath, assemblyName), buffer);
+               nugetPackagesAssembliesSha.push_back(nugetPackage + ":" + assemblyName + ":" + buffer);
+               _INFO("Assembly : [%s] / SHA256 : [%s]", assemblyName.c_str(), buffer);
+       }
+       std::sort(tacDB.begin(), tacDB.end());
+       tacDB.erase(unique(tacDB.begin(), tacDB.end()), tacDB.end());
 }
 
 extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *appId, GList *list)
@@ -366,43 +261,33 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_INSTALL =====]");
        _INFO("PackageID : %s", pkgId);
 
-       if (!getAppType(std::string(pkgId))) {
+       if (!appTypeCheck(std::string(pkgId))) {
                _INFO("App type is not dotnet");
                return 0;
        }
-       if (getExecPath(std::string(pkgId))) {
+       if (getExecName(std::string(pkgId), execName) < 0) {
                return 0;
        }
-       if (getRootPath(std::string(pkgId))) {
+       if (getRootPath(std::string(pkgId), rootPath) < 0) {
                return 0;
+       } else {
+               binPath = concatPath(rootPath, "bin");
        }
-       if (!metadataCheck(list)) {
-               if (depsJsonParser()) {
-                       return 0;
-               }
+       if (metadataCheck(list)) {
+               depsJsonCheck();
        }
 
        status = "install";
-       tac_db = dbCreate(tacAppListDB);
-       if (tac_db) {
-               if (!dbOpen(tac_db, tacAppListDB)) {
-                       return 0;
-               }
-       } else {
+       tac_db = dbCreate(TAC_APP_LIST_DB);
+       if (!tac_db) {
                _ERR("Sqlite create error");
                return 0;
        }
 
        if (tacDB.empty()) {
-               _ERR("Not exist .deps.json file");
+               _INFO("Not exist .deps.json file");
                return 0;
        }
-       if (!bf::exists(binPath / mTacRelease)) {
-               if (!createDir(binPath / mTacRelease)) {
-                       _INFO("Cannot create directory: %s", (binPath / mTacRelease).c_str());
-                       return 0;
-               }
-       }
 
        for (auto& np : tacDB) {
                std::string tac_name = np.substr(0, np.find('/'));
@@ -410,127 +295,95 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_INSTALL(const char *pkgId, const char *app
                _INFO("TAC name : %s", tac_name.c_str());
                _INFO("TAC version : %s", tac_version.c_str());
 
-               bf::path tac_version_dir = bf::path(mOptUsrDotnet) / np;
-               isCreateDirectory = false;
+               std::string tac_version_dir = concatPath(__TAC_DIR, np);
+               std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
                if (!bf::exists(tac_version_dir)) {
                        _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
                        if (!createDir(tac_version_dir)) {
                                _ERR("Cannot create directory: %s", tac_version_dir.c_str());
                                return 0;
                        }
-                       isCreateDirectory = true;
-                       createDirectories.push_back(tac_version_dir.string());
-                       std::string sha256_info = (tac_version_dir / bf::path("SHA256.info")).string();
-                       std::ofstream ofs(sha256_info, std::ios::app);
-                       int assembly_count = 0;
-                       for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
-                               std::string nuget_package_assembly_sha = npAssemblyShaR2R.substr(0, npAssemblyShaR2R.rfind('/'));
-                               std::string sha = nuget_package_assembly_sha.substr(nuget_package_assembly_sha.rfind('/') + 1);
-                               std::string nuget_package_assembly = nuget_package_assembly_sha.substr(0, nuget_package_assembly_sha.rfind('/'));
-                               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/'));
-                               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind('/') + 1);
-                               std::string r2r = npAssemblyShaR2R.substr(npAssemblyShaR2R.rfind('/') + 1);
-                               if (!strcmp(nuget_package.c_str(), np.c_str())) {
-                                       ofs << assembly << ";" << sha << std::endl;
-                                       assembly_count++;
-                               }
+                       createDirectories.push_back(tac_version_dir);
+                       if (!bf::is_symlink(sha256_info)) {
+                               createSHA256Info(sha256_info, np);
+                       } else {
+                               _ERR("Failed to create sha256_info. Symbolic link is detected");
+                               return -1;
                        }
-                       ofs << assembly_count << std::endl;
-                       ofs.close();
 
-                       if (createSymlink(tac_version_dir, np)) {
+                       if (copyNCreateSymlink(tac_version_dir, np, true) < 0) {
                                _ERR("Failed to create symlink");
-                               return 0;
+                               return -1;
                        }
-                       std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
-                                       "VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
-                       dbInsert(tac_db, tacAppListDB, sql);
+
+                       char *sql = sqlite3_mprintf(
+                               "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
+                               "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
+                       dbInsert(tac_db, TAC_APP_LIST_DB, sql);
+                       sqlite3_free(sql);
                } else {
                        _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
-                       int compare_count = 0;
-                       int assembly_count = 0;
-                       std::string sha256_count = "0";
-                       for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
-                               std::string nuget_package_assembly_sha = npAssemblyShaR2R.substr(0, npAssemblyShaR2R.rfind('/'));
-                               std::string sha = nuget_package_assembly_sha.substr(nuget_package_assembly_sha.rfind('/') + 1);
-                               std::string nuget_package_assembly = nuget_package_assembly_sha.substr(0, nuget_package_assembly_sha.rfind('/'));
-                               std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/'));
-                               std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind('/') + 1);
-                               std::string r2r = npAssemblyShaR2R.substr(npAssemblyShaR2R.rfind('/') + 1);
-                               if (!strcmp(nuget_package.c_str(), np.c_str())) {
-                                       assembly_count++;
-                                       std::string sha256_info = (tac_version_dir / bf::path("SHA256.info")).string();
-                                       std::ifstream ifs(sha256_info);
-                                       std::string get_str;
-                                       if (ifs.is_open()) {
-                                               while (getline(ifs, get_str)) {
-                                                       if (!strcmp(get_str.c_str(), (assembly + ";" + sha).c_str())) {
-                                                               compare_count++;
-                                                       }
-                                                       sha256_count = get_str;
-                                               }
-                                               ifs.close();
+                       if (!bf::is_symlink(sha256_info)) {
+                               if (compareSHA256Info(sha256_info, np)) {
+                                       if (copyNCreateSymlink(tac_version_dir, np, false) < 0) {
+                                               _ERR("Failed to create symlink");
+                                               return -1;
                                        }
+
+                                       char *sql = sqlite3_mprintf(
+                                               "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
+                                               "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
+                                       dbInsert(tac_db, TAC_APP_LIST_DB, sql);
+                                       sqlite3_free(sql);
+                               } else {
+                                       _INFO("Different nuget : %s", np.c_str());
                                }
-                       }
-                       if (!strcmp(std::to_string(assembly_count).c_str(), std::to_string(compare_count).c_str()) &&
-                               !strcmp(std::to_string(assembly_count).c_str(), sha256_count.c_str())) {
-                               _INFO("Same : %s", tac_name.c_str());
-                               if (createSymlink(tac_version_dir, np)) {
-                                       return 0;
-                               }
-                               std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
-                                               "VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
-                               dbInsert(tac_db, tacAppListDB, sql);
                        } else {
-                               _INFO("Different : %s", tac_name.c_str());
+                               _ERR("Failed to create sha256_info. Symbolic link is detected");
+                               return -1;
+                       }
+               }
+               if (!bf::exists(sha256_info)) {
+                       if(!removeAll(tac_version_dir)) {
+                               _ERR("Failed to remove of %s", tac_version_dir.c_str());
                        }
                }
-       }
-       if (removeOriginalAssembly()) {
-               return 0;
        }
        return 0;
 }
 
-static int sqliteCb(void *count, int argc, char **argv, char **azColName) {
+static int sqliteCb(void *count, int argc, char **argv, char **colName) {
        int *c = (int*)count;
        *c = atoi(argv[0]);
        return 0;
 }
 
-int updateTacDB(const char *pkgId)
+int updateTacDB(sqlite3 *sqlite)
 {
        for (auto& unp : updateTac) {
-               char *error = 0;
-               int ret;
-               int count = 0;
-               if (tac_db) {
-                       if (!dbOpen(tac_db, tacAppListDB)) {
-                               return 0;
-                       }
-               } else {
-                       _ERR("Sqlite create error");
-                       return 0;
-               }
-               std::string sql = "SELECT COUNT(NUGET) FROM TAC WHERE NUGET = '" + unp + "';";
-               ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, &error);
+               int count = -1;
+               char *sql = sqlite3_mprintf("SELECT COUNT(NUGET) FROM TAC WHERE NUGET = %Q;", unp.c_str());
+               int ret = sqlite3_exec(sqlite, sql, sqliteCb, &count, NULL);
                if (ret != SQLITE_OK) {
-                       _ERR("SQL error: %s", error);
-                       sqlite3_free(error);
+                       _ERR("Sqlite select error");
+                       sqlite3_free(sql);
+                       return -1;
                }
-               if (count < 1) {
-                       bf::path tac_version_dir_prev = bf::path(mOptUsrDotnet) / unp;
-                       bf::path tac_version_dir_backup = bf::path(mOptUsrDotnet) / (unp + mBackup);
+               if (count == 0) {
+                       std::string tac_version_dir_prev = concatPath(__TAC_DIR, unp);
+                       std::string tac_version_dir_backup = tac_version_dir_prev + ".bck";
                        if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) {
                                _ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str());
+                               sqlite3_free(sql);
                                return -1;
                        }
                        if (!removeAll(tac_version_dir_prev)) {
                                _ERR("Failed to remove of %s", tac_version_dir_prev.c_str());
+                               sqlite3_free(sql);
                                return -1;
                        }
                }
+               sqlite3_free(sql);
        }
        return 0;
 }
@@ -540,163 +393,138 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UPGRADE =====]");
        _INFO("PackageID : %s", pkgId);
 
-       if (!getAppType(std::string(pkgId))) {
+       if (!appTypeCheck(std::string(pkgId))) {
                _INFO("App type is not dotnet");
                return 0;
        }
-       if (getExecPath(std::string(pkgId))) {
+       if (getExecName(std::string(pkgId), execName) < 0) {
                return 0;
        }
-       if (getRootPath(std::string(pkgId))) {
+       if (getRootPath(std::string(pkgId), rootPath) < 0) {
                return 0;
+       } else {
+               binPath = concatPath(rootPath, "bin");
        }
        if (!strcmp("removed", status.c_str())) {
                _INFO("Skipped to parse of deps.json");
        } else {
-               if (!metadataCheck(list)) {
-                       if (depsJsonParser()) {
-                               return 0;
-                       }
+               if (metadataCheck(list)) {
+                       depsJsonCheck();
                }
        }
 
        status = "update";
-       tac_db = dbCreate(tacAppListDB);
-       if (tac_db) {
-               if (!dbOpen(tac_db, tacAppListDB)) {
-                       return 0;
-               }
-       } else {
-               _ERR("Sqlite create error");
+       tac_db = dbCreate(TAC_APP_LIST_DB);
+       if (!tac_db) {
+               _ERR("Sqlite open error");
                return 0;
        }
 
-       std::string sql = "SELECT * FROM TAC WHERE PKGID = '" + std::string(pkgId) + "';";
-       updateTac = dbSelect(tac_db, tacAppListDB, sql);
+       char *sql = sqlite3_mprintf("SELECT * FROM TAC WHERE PKGID = %Q;", pkgId);
+       updateTac = dbSelect(tac_db, TAC_APP_LIST_DB, sql);
+       sqlite3_free(sql);
 
        if (tacDB.empty()) {
-               sql = "DELETE FROM TAC WHERE PKGID = '" + std::string(pkgId) + "';";
-               dbDelete(tac_db, tacAppListDB, sql);
-               if (updateTacDB(pkgId)) {
-                       return 0;
+               sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId);
+               dbDelete(tac_db, TAC_APP_LIST_DB, sql);
+               sqlite3_free(sql);
+               if (updateTacDB(tac_db) < 0) {
+                       return -1;
                }
        } else {
-               if (!bf::exists(binPath / mTacRelease)) {
-                       if (!createDir(binPath / mTacRelease)) {
-                               _INFO("Cannot create directory: %s", (binPath / mTacRelease).c_str());
-                               return 0;
-                       }
-               }
-
                for (auto& np : tacDB) {
                        std::string tac_name = np.substr(0, np.find('/'));
                        std::string tac_version = np.substr(np.rfind('/') + 1);
                        _INFO("TAC name : %s", tac_name.c_str());
                        _INFO("TAC version : %s", tac_version.c_str());
 
-                       bf::path tac_version_dir = bf::path(mOptUsrDotnet) / np;
-                       isCreateDirectory = false;
+                       std::string tac_version_dir = concatPath(__TAC_DIR, np);
+                       std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
                        if (!bf::exists(tac_version_dir)) {
                                _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
                                if (!createDir(tac_version_dir)) {
                                        _ERR("Cannot create directory: %s", tac_version_dir.c_str());
                                        return 0;
                                }
-                               isCreateDirectory = true;
-                               createDirectories.push_back(tac_version_dir.string());
-                               std::string sha256_info = (tac_version_dir / bf::path("SHA256.info")).string();
-                               std::ofstream ofs2(sha256_info, std::ios::app);
-                               int assembly_count = 0;
-                               for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
-                                       std::string nuget_package_assembly_sha = npAssemblyShaR2R.substr(0, npAssemblyShaR2R.rfind('/'));
-                                       std::string sha = nuget_package_assembly_sha.substr(nuget_package_assembly_sha.rfind('/') + 1);
-                                       std::string nuget_package_assembly = nuget_package_assembly_sha.substr(0, nuget_package_assembly_sha.rfind('/'));
-                                       std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/'));
-                                       std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind('/') + 1);
-                                       std::string r2r = npAssemblyShaR2R.substr(npAssemblyShaR2R.rfind('/') + 1);
-                                       if (!strcmp(nuget_package.c_str(), np.c_str())) {
-                                               ofs2 << assembly << ";" << sha << std::endl;
-                                               assembly_count++;
-                                       }
+                               createDirectories.push_back(tac_version_dir);
+                               if (!bf::is_symlink(sha256_info)) {
+                                       createSHA256Info(sha256_info, np);
+                               } else {
+                                       _ERR("Failed to create sha256_info. Symbolic link is detected");
+                                       return -1;
                                }
-                               ofs2 << assembly_count << std::endl;
-                               ofs2.close();
-                               if (createSymlink(tac_version_dir, np)) {
-                                       return 0;
+
+                               if (copyNCreateSymlink(tac_version_dir, np, true) < 0) {
+                                       _ERR("Failed to create symlink");
+                                       return -1;
                                }
 
-                               char *error = 0;
-                               int count = 0;
-                               sql = "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = '" + std::string(pkgId) + "' AND NAME = '" + tac_name + "';";
-                               int ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, &error);
+                               int count = -1;
+                               sql = sqlite3_mprintf(
+                                               "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = %Q AND NAME = %Q;", pkgId, tac_name.c_str());
+                               int ret = sqlite3_exec(tac_db, sql, sqliteCb, &count, NULL);
                                if (ret != SQLITE_OK) {
-                                       _ERR("SQL error: %s", error);
-                                       sqlite3_free(error);
+                                       _ERR("Sqlite select error");
+                                       sqlite3_free(sql);
+                                       return -1;
                                }
-
+                               sqlite3_free(sql);
                                if (count == 1) {
-                                       sql = "UPDATE TAC SET NAME = '" + tac_name + "', VERSION = '" + tac_version + "', NUGET = '" + np + "' WHERE PKGID = '" + std::string(pkgId) + "' AND NAME = '" + tac_name + "';";
-                                       dbUpdate(tac_db, tacAppListDB, sql);
-                               } else {
-                                       sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
-                                               "VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
-                                       dbInsert(tac_db, tacAppListDB, sql);
+                                       sql = sqlite3_mprintf(
+                                               "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
+                                               tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId, tac_name.c_str());
+                                       dbUpdate(tac_db, TAC_APP_LIST_DB, sql);
+                                       sqlite3_free(sql);
+                               } else if (count == 0) {
+                                       sql = sqlite3_mprintf(
+                                               "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
+                                               "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
+                                       dbInsert(tac_db, TAC_APP_LIST_DB, sql);
+                                       sqlite3_free(sql);
                                }
                        } else {
                                _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
-                               int compare_count = 0;
-                               int assembly_count = 0;
-                               std::string sha256_count = "0";
-                               for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
-                                       std::string nuget_package_assembly_sha = npAssemblyShaR2R.substr(0, npAssemblyShaR2R.rfind('/'));
-                                       std::string sha = nuget_package_assembly_sha.substr(nuget_package_assembly_sha.rfind('/') + 1);
-                                       std::string nuget_package_assembly = nuget_package_assembly_sha.substr(0, nuget_package_assembly_sha.rfind('/'));
-                                       std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind('/'));
-                                       std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind('/') + 1);
-                                       std::string r2r = npAssemblyShaR2R.substr(npAssemblyShaR2R.rfind('/') + 1);
-                                       if (!strcmp(nuget_package.c_str(), np.c_str())) {
-                                               assembly_count++;
-                                               std::string sha256_info = (tac_version_dir / bf::path("SHA256.info")).string();
-                                               std::ifstream ifs2(sha256_info);
-                                               std::string get_str;
-                                               if (ifs2.is_open()) {
-                                                       while (getline(ifs2, get_str)) {
-                                                               if (!strcmp(get_str.c_str(), (assembly + ";" + sha).c_str())) {
-                                                                       compare_count++;
-                                                               }
-                                                               sha256_count = get_str;
-                                                       }
-                                                       ifs2.close();
+                               if (!bf::is_symlink(sha256_info)) {
+                                       if (compareSHA256Info(sha256_info, np)) {
+                                               if (copyNCreateSymlink(tac_version_dir, np, false) < 0) {
+                                                       _ERR("Failed to create symlink");
+                                                       return -1;
                                                }
-                                       }
-                               }
 
-                               if (!strcmp(std::to_string(assembly_count).c_str(), std::to_string(compare_count).c_str()) &&
-                                       !strcmp(std::to_string(assembly_count).c_str(), sha256_count.c_str())) {
-                                       _INFO("Same : %s", tac_name.c_str());
-                                       if (createSymlink(tac_version_dir, np)) {
-                                               return 0;
-                                       }
-
-                                       char *error = 0;
-                                       int count = 0;
-                                       std::string sql = "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = '" + std::string(pkgId) + "' AND NAME = '" + tac_name + "';";
-                                       int ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, &error);
-                                       if (ret != SQLITE_OK) {
-                                               _ERR("SQL error: %s", error);
-                                               sqlite3_free(error);
-                                       }
-
-                                       if (count == 1) {
-                                               sql = "UPDATE TAC SET NAME = '" + tac_name + "', VERSION = '" + tac_version + "', NUGET = '" + np + "' WHERE PKGID = '" + std::string(pkgId) + "' AND NAME = '" + tac_name + "';";
-                                               dbUpdate(tac_db, tacAppListDB, sql);
+                                               int count = -1;
+                                               char *sql = sqlite3_mprintf(
+                                                       "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = %Q AND NAME = %Q;", pkgId, tac_name.c_str());
+                                               int ret = sqlite3_exec(tac_db, sql, sqliteCb, &count, NULL);
+                                               if (ret != SQLITE_OK) {
+                                                       _ERR("Sqlite select error");
+                                                       sqlite3_free(sql);
+                                                       return -1;
+                                               }
+                                               sqlite3_free(sql);
+                                               if (count == 1) {
+                                                       sql = sqlite3_mprintf(
+                                                               "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
+                                                               tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId, tac_name.c_str());
+                                                       dbUpdate(tac_db, TAC_APP_LIST_DB, sql);
+                                                       sqlite3_free(sql);
+                                               } else if (count == 0) {
+                                                       sql = sqlite3_mprintf(
+                                                               "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
+                                                               "VALUES (%Q, %Q, %Q, %Q);", pkgId, np.c_str(), tac_name.c_str(), tac_version.c_str());
+                                                       dbInsert(tac_db, TAC_APP_LIST_DB, sql);
+                                                       sqlite3_free(sql);
+                                               }
                                        } else {
-                                               sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
-                                                       "VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
-                                               dbInsert(tac_db, tacAppListDB, sql);
+                                               _INFO("Different nuget : %s", np.c_str());
                                        }
                                } else {
-                                       _INFO("Different : %s", tac_name.c_str());
+                                       _ERR("Failed to create sha256_info. Symbolic link is detected");
+                                       return -1;
+                               }
+                       }
+                       if (!bf::exists(sha256_info)) {
+                               if(!removeAll(tac_version_dir)) {
+                                       _ERR("Failed to remove of %s", tac_version_dir.c_str());
                                }
                        }
                }
@@ -708,18 +536,14 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UPGRADE(const char *pkgId, const char *app
                                        break;
                                }
                        }
-
                        if (!isExits) {
-                               std::string sql = "DELETE FROM TAC WHERE PKGID = '" + std::string(pkgId) + "' AND NUGET = '" + unp + "';";
-                               dbDelete(tac_db, tacAppListDB, sql);
+                               char *sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q AND NUGET = %Q;", pkgId, unp.c_str());
+                               dbDelete(tac_db, TAC_APP_LIST_DB, sql);
+                               sqlite3_free(sql);
                        }
                }
-
-               if (removeOriginalAssembly()) {
-                       return 0;
-               }
-               if (updateTacDB(pkgId)) {
-                       return 0;
+               if (updateTacDB(tac_db) < 0) {
+                       return -1;
                }
        }
        return 0;
@@ -731,24 +555,22 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a
        _INFO("PackageID : %s", pkgId);
 
        status = "uninstall";
-       tac_db = dbCreate(tacAppListDB);
-       if (tac_db) {
-               if (!dbOpen(tac_db, tacAppListDB)) {
-                       return 0;
-               }
-       } else {
-               _ERR("Sqlite create error");
+       tac_db = dbOpen(TAC_APP_LIST_DB);
+       if (!tac_db) {
+               _ERR("Sqlite open error");
                return 0;
        }
 
-       std::string sql = "SELECT * FROM TAC WHERE PKGID = '" + std::string(pkgId) + "';";
-       updateTac = dbSelect(tac_db, tacAppListDB, sql);
+       char *sql = sqlite3_mprintf("SELECT * FROM TAC WHERE PKGID = %Q;", pkgId);
+       updateTac = dbSelect(tac_db, TAC_APP_LIST_DB, sql);
+       sqlite3_free(sql);
 
-       sql = "DELETE FROM TAC WHERE PKGID = '" + std::string(pkgId) + "';";
-       dbDelete(tac_db, tacAppListDB, sql);
+       sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId);
+       dbDelete(tac_db, TAC_APP_LIST_DB, sql);
+       sqlite3_free(sql);
 
-       if (updateTacDB(pkgId)) {
-               return 0;
+       if (updateTacDB(tac_db) < 0) {
+               return -1;
        }
        return 0;
 }
@@ -756,87 +578,72 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_UNINSTALL(const char *pkgId, const char *a
 extern "C" int PKGMGR_MDPARSER_PLUGIN_REMOVED(const char *pkgId, const char *appId, GList *list)
 {
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_REMOVED =====]");
-       status = "removed";
+       _INFO("PackageID : %s", pkgId);
 
-       PKGMGR_MDPARSER_PLUGIN_UPGRADE(pkgId, appId, list);
-       return 0;
-}
+       status = "removed";
 
-int install_Clean()
-{
-       return 0;
+       return PKGMGR_MDPARSER_PLUGIN_UPGRADE(pkgId, appId, list);
 }
 
-int unInstall_Clean()
+void cleanStep(std::string tac)
 {
-       for (auto& unp : updateTac) {
-               bf::path current_tac = bf::path(mOptUsrDotnet) / unp.substr(0, unp.find('/'));
-               std::vector<std::string> exist_directory_name;
+       std::string current_tac = concatPath(__TAC_DIR, tac.substr(0, tac.find('/')));
+       try {
                for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
-                       if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), mBackup.c_str()) != NULL) {
-                               if (!removeAll(bck.path().string())) {
-                                       _ERR("Failed to remove of %s", bck.path().c_str());
-                                       return 0;
+                       std::string bck_path = bck.path().string();
+                       if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
+                               if (!removeAll(bck_path)) {
+                                       _ERR("Failed to remove of %s", bck_path.c_str());
                                }
                                break;
                        }
                }
+
+               bool isExist = false;
                for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
-                       if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), mBackup.c_str()) == NULL) {
-                               exist_directory_name.push_back(bck.path().string());
+                       std::string bck_path = bck.path().string();
+                       if (bf::exists(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) {
+                               isExist = true;
                                break;
                        }
                }
-               if (exist_directory_name.empty()) {
+               if (!isExist) {
                        if (!removeAll(current_tac)) {
                                _ERR("Failed to remove of %s", current_tac.c_str());
-                               return 0;
                        }
-               } else {
-                       exist_directory_name.clear();
                }
+       } catch (const bf::filesystem_error& error) {
+               _ERR("Failed to recursive directory: %s", error.what());
+               return;
+       }
+}
+
+void install_Clean()
+{
+       return;
+}
+
+void unInstall_Clean()
+{
+       for (auto& unp : updateTac) {
+               cleanStep(unp);
        }
-       return 0;
 }
 
-int update_Clean()
+void update_Clean()
 {
        if (!tacDB.empty()) {
                for (auto& np : tacDB) {
-                       bf::path current_tac = bf::path(mOptUsrDotnet) / np.substr(0, np.find('/'));
-                       std::vector<std::string> exist_directory_name;
-                       for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
-                               if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), mBackup.c_str()) != NULL) {
-                                       if (!removeAll(bck.path().string())) {
-                                               _ERR("Failed to remove of %s", bck.path().c_str());
-                                               return 0;
-                                       }
-                                       break;
-                               }
-                       }
-                       for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
-                               if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), mBackup.c_str()) == NULL) {
-                                       exist_directory_name.push_back(bck.path().string());
-                                       break;
-                               }
-                       }
-                       if (exist_directory_name.empty()) {
-                               if (!removeAll(current_tac)) {
-                                       _ERR("Failed to remove of %s", current_tac.c_str());
-                                       return 0;
-                               }
-                       } else {
-                               exist_directory_name.clear();
-                       }
+                       cleanStep(np);
                }
        }
        unInstall_Clean();
-       return 0;
 }
 
 extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId, GList *list)
 {
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]");
+       _INFO("PackageID : %s", pkgId);
 
        if (tac_db) {
                dbClose(tac_db);
@@ -852,63 +659,56 @@ extern "C" int PKGMGR_MDPARSER_PLUGIN_CLEAN(const char *pkgId, const char *appId
        return 0;
 }
 
-int install_Undo()
-{
-       for (auto& cd : createDirectories) {
-               if (!removeAll(cd)) {
-                       _ERR("Failed to remove of %s", cd.c_str());
-                       return 0;
-               }
-       }
-       return 0;
-}
-
-int unInstall_Undo()
+void undoStep(std::string tac)
 {
-       for (auto& unp : updateTac) {
-               for (auto& bck : bf::recursive_directory_iterator(bf::path(mOptUsrDotnet) / unp.substr(0, unp.find('/')))) {
-                       if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), mBackup.c_str()) != NULL) {
-                               if (!moveFile(bck.path(), bck.path().string().substr(0, bck.path().string().rfind(mBackup.c_str())), FSFlag::FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS)) {
-                                       _ERR("Failed to move %s to %s",
-                                               bck.path().c_str(), bck.path().string().substr(0, bck.path().string().rfind(mBackup.c_str())).c_str());
-                                       return 0;
+       std::string current_tac = concatPath(__TAC_DIR, tac.substr(0, tac.find('/')));
+       try {
+               for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
+                       std::string bck_path = bck.path().string();
+                       if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
+                               if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) {
+                                       _ERR("Failed to move %s", bck_path.c_str());
                                }
                                break;
                        }
                }
+       } catch (const bf::filesystem_error& error) {
+               _ERR("Failed to recursive directory: %s", error.what());
+               return;
        }
-       return 0;
 }
 
-int update_Undo()
+void install_Undo()
 {
        for (auto& cd : createDirectories) {
                if (!removeAll(cd)) {
                        _ERR("Failed to remove of %s", cd.c_str());
-                       return 0;
                }
        }
+}
+
+void unInstall_Undo()
+{
+       for (auto& unp : updateTac) {
+               undoStep(unp);
+       }
+}
+
+void update_Undo()
+{
+       install_Undo();
        if (!tacDB.empty()) {
                for (auto& np : tacDB) {
-                       for (auto& bck : bf::recursive_directory_iterator(bf::path(mOptUsrDotnet) / np.substr(0, np.find('/')))) {
-                               if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), mBackup.c_str()) != NULL) {
-                                       if (!moveFile(bck.path(), bck.path().string().substr(0, bck.path().string().rfind(mBackup.c_str())), FSFlag::FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS)) {
-                                               _ERR("Failed to move %s to %s",
-                                                       bck.path().c_str(), bck.path().string().substr(0, bck.path().string().rfind(mBackup.c_str())).c_str());
-                                               return 0;
-                                       }
-                                       break;
-                               }
-                       }
+                       undoStep(np);
                }
        }
        unInstall_Undo();
-       return 0;
 }
 
 extern "C" int PKGMGR_MDPARSER_PLUGIN_UNDO(const char *pkgId, const char *appId, GList *list)
 {
        _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
+       _INFO("PackageID : %s", pkgId);
 
        if (tac_db) {
                dbRollback(tac_db);