X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Ftool%2Ftac_common.cc;h=94ff4392ad1ce638d8bfe6acf33c10a23c1d85e9;hb=33b4aa2fcbb716d081fc13ac6855fc53bd343532;hp=1f9c76b2e61d4152bfc9e35d9679c712ec577b19;hpb=46e0e046275cc61bef04da504a094c47f34f6310;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/tool/tac_common.cc b/NativeLauncher/tool/tac_common.cc index 1f9c76b..94ff439 100644 --- a/NativeLauncher/tool/tac_common.cc +++ b/NativeLauncher/tool/tac_common.cc @@ -15,15 +15,15 @@ */ #include +#include #include #include #include "log.h" #include "utils.h" -#include "ni_common.h" #include "tac_common.h" #include "db_manager.h" -#include "path_manager.h" +#include "r2r_checker.h" #ifdef LOG_TAG #undef LOG_TAG @@ -32,74 +32,90 @@ #define __XSTR(x) #x #define __STR(x) __XSTR(x) -static const char* __TAC_DIR = __STR(TAC_DIR); +static const char* __DOTNET_DIR = __STR(DOTNET_DIR); +static const char* __READ_ONLY_APP_UPDATE_DIR = __STR(READ_ONLY_APP_UPDATE_DIR); #undef __STR #undef __XSTR static sqlite3 *tac_db = NULL; -std::vector restoreNuget; +static sqlite3 *tlc_db = NULL; +static std::vector restore_nuget; +static std::vector restore_library; -void cleanupDirectory() +static void cleanupDirectory() { std::vector removeNuget; - for (auto& nuget : bf::recursive_directory_iterator(__TAC_DIR)) { - bool isExist = false; - std::string nugetPath = nuget.path().string(); - for (auto& restore : restoreNuget) { - if (!bf::is_directory(nugetPath)) { - isExist = true; + try { + for (auto& nuget : bf::recursive_directory_iterator(__DOTNET_DIR)) { + std::string nugetPath = nuget.path().string(); + if (!bf::is_directory(nugetPath) || + nugetPath.find(TLC_LIBRARIES_DIR) != std::string::npos || + nugetPath.find(__READ_ONLY_APP_UPDATE_DIR) != std::string::npos) { + continue; } - if (strstr(nugetPath.c_str(), restore.c_str()) != NULL) { - isExist = true; - break; + + bool isExist = false; + for (auto& restore : restore_nuget) { + if (nugetPath == restore || nugetPath == getBaseName(restore)) { + isExist = true; + break; + } + } + if (!isExist) { + removeNuget.push_back(nugetPath); } } - if (!isExist) { - removeNuget.push_back(nugetPath); - } - } - for (auto& rm : removeNuget) { - if (!removeAll(rm)) { - _ERR("Failed to remove of %s", rm.c_str()); + for (auto& rm : removeNuget) { + if (!removeAll(rm)) { + _SERR("Failed to remove of %s", rm.c_str()); + } } + removeNuget.clear(); + } catch (const bf::filesystem_error& error) { + _SERR("Failed to recursive directory: %s", error.what()); + return; } - removeNuget.clear(); } // callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach" -static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) +static int tac_restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) { char *pkgId = NULL; char *root = NULL; char *exec = NULL; - std::string rootPath; - std::string execName; int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId); if (ret != PMINFO_R_OK) { - fprintf(stderr, "Failed to get pkgid\n"); + _SERR("Failed to get pkgid"); return -1; } ret = pkgmgrinfo_appinfo_get_root_path(handle, &root); if (ret != PMINFO_R_OK) { - fprintf(stderr, "Failed to get root path\n"); + _SERR("Failed to get root path"); return -1; } - rootPath = root; + std::string rootPath = std::string(root); ret = pkgmgrinfo_appinfo_get_exec(handle, &exec); if (ret != PMINFO_R_OK) { - fprintf(stderr, "Failed to get exec name\n"); + _SERR("Failed to get exec name"); return -1; } - execName = std::string(exec).substr(std::string(exec).rfind('/') + 1); + std::string execName = std::string(exec).substr(std::string(exec).rfind('/') + 1); + + enableTACPackage(std::string(pkgId)); std::vector parserData; - for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) { + std::string binDir = concatPath(rootPath, "bin"); + std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); + for (auto& npAssembly : depsJsonParser(rootPath, execName)) { std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':')); - parserData.push_back(nugetPackage); + std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1); + if (exist(tacDir) && exist(concatPath(tacDir, assemblyName))) { + parserData.push_back(nugetPackage); + } } std::sort(parserData.begin(), parserData.end()); parserData.erase(unique(parserData.begin(), parserData.end()), parserData.end()); @@ -108,42 +124,38 @@ static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) if (tac_db) { std::string name = nuget.substr(0, nuget.find('/')); std::string version = nuget.substr(nuget.rfind('/') + 1); - std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ - "VALUES ('" + std::string(pkgId) + "', '" + nuget + "', '" + name + "', '" + version + "');"; - dbInsert(tac_db, TAC_APP_LIST_RESTORE_DB, sql); - restoreNuget.push_back(concatPath(__TAC_DIR, name)); + char *sql = sqlite3_mprintf( + "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \ + "VALUES (%Q, %Q, %Q, %Q);", pkgId, nuget.c_str(), name.c_str(), version.c_str()); + insertDB(tac_db, sql); + restore_nuget.push_back(concatPath(__DOTNET_DIR, nuget)); + sqlite3_free(sql); } } parserData.clear(); + return 0; } -tac_error_e restoreTACDB() +tac_error_e tac_restoreDB() { if (!removeFile(TAC_APP_LIST_RESTORE_DB)) { - fprintf(stderr, "Failed to remove of %s", TAC_APP_LIST_RESTORE_DB); + _SERR("Failed to remove of %s", TAC_APP_LIST_RESTORE_DB); return TAC_ERROR_UNKNOWN; } std::string dbRestoreJournal = TAC_APP_LIST_RESTORE_DB + std::string("-journal"); if (!removeFile(dbRestoreJournal)) { - fprintf(stderr, "Failed to remove of %s", dbRestoreJournal.c_str()); + _SERR("Failed to remove of %s", dbRestoreJournal.c_str()); return TAC_ERROR_UNKNOWN; } - if (initializePathManager(std::string(), std::string(), std::string())) { - fprintf(stderr, "Fail to initialize PathManger"); - return TAC_ERROR_UNKNOWN; - } - - tac_db = dbCreate(TAC_APP_LIST_RESTORE_DB); - if (tac_db) { - if (!dbOpen(tac_db, TAC_APP_LIST_RESTORE_DB)) { - return TAC_ERROR_UNKNOWN; - } - } else { + tac_db = createDB(TAC_APP_LIST_RESTORE_DB, CREATE_TAC_DB_TABLE); + if (!tac_db) { + _SERR("Sqlite create error"); return TAC_ERROR_UNKNOWN; } + sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL); pkgmgrinfo_appinfo_metadata_filter_h handle; int ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle); @@ -151,262 +163,373 @@ tac_error_e restoreTACDB() return TAC_ERROR_UNKNOWN; } - ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE); + ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE_TRUE); if (ret != PMINFO_R_OK) { pkgmgrinfo_appinfo_metadata_filter_destroy(handle); return TAC_ERROR_UNKNOWN; } - ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, restoreDBCb, NULL); - if (ret != PMINFO_R_OK) { - fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n"); + ret = pkgmgrMDFilterForeach(handle, tac_restoreDBCb, NULL); + if (ret != 0) { pkgmgrinfo_appinfo_metadata_filter_destroy(handle); return TAC_ERROR_UNKNOWN; } - fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n"); pkgmgrinfo_appinfo_metadata_filter_destroy(handle); if (tac_db) { - dbClose(tac_db); + closeDB(tac_db); tac_db = NULL; } if (!copyFile(TAC_APP_LIST_RESTORE_DB, TAC_APP_LIST_DB)) { - fprintf(stderr, "Failed to copy of %s", TAC_APP_LIST_DB); + _SERR("Failed to copy of %s", TAC_APP_LIST_DB); return TAC_ERROR_UNKNOWN; } if (!removeFile(TAC_APP_LIST_RESTORE_DB)) { - fprintf(stderr, "Failed to remove of %s", TAC_APP_LIST_RESTORE_DB); + _SERR("Failed to remove of %s", TAC_APP_LIST_RESTORE_DB); return TAC_ERROR_UNKNOWN; } std::string dbJournal = TAC_APP_LIST_DB + std::string("-journal"); if (!copyFile(dbRestoreJournal, dbJournal)) { - fprintf(stderr, "Failed to copy of %s", dbJournal.c_str()); + _SERR("Failed to copy of %s", dbJournal.c_str()); return TAC_ERROR_UNKNOWN; } if (!removeFile(dbRestoreJournal)) { - fprintf(stderr, "Failed to remove of %s", dbRestoreJournal.c_str()); + _SERR("Failed to remove of %s", dbRestoreJournal.c_str()); return TAC_ERROR_UNKNOWN; } cleanupDirectory(); - return TAC_ERROR_NONE; -} -tac_error_e resetTACPackage(const std::string& pkgId) -{ - std::string pkgRoot; - if (getRootPath(pkgId, pkgRoot) < 0) { - return TAC_ERROR_INVALID_PACKAGE; - } - - std::vector tacNativeImage; - std::string binDir = concatPath(pkgRoot, "bin"); - std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); - if (bf::exists(tacDir)) { - for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) { - std::string symPath = symlinkAssembly.path().string(); - if (bf::is_symlink(symPath)) { - if (isNativeImage(symPath)) { - tacNativeImage.push_back(symPath); - } - } - } - for (auto& path : tacNativeImage) { - if (!removeFile(path)) { - fprintf(stderr, "Failed to remove of %s", path.c_str()); - return TAC_ERROR_UNKNOWN; - } - } - } - tacNativeImage.clear(); return TAC_ERROR_NONE; } -tac_error_e createTACPackage(const std::string& pkgId) +tac_error_e disableTACPackage(const std::string& pkgId) { - std::string pkgRoot; - if (getRootPath(pkgId, pkgRoot) < 0) { + std::string rootPath = getRootPath(pkgId); + if (rootPath.empty()) { + _SERR("Failed to get root path from [%s]", pkgId.c_str()); return TAC_ERROR_INVALID_PACKAGE; } - std::string binDir = concatPath(pkgRoot, "bin"); + std::string binDir = concatPath(rootPath, "bin"); std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR); - if (bf::exists(tacDir)) { - for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) { - std::string symPath = symlinkAssembly.path().string(); - if (bf::is_symlink(symPath)) { - if (!isNativeImage(symPath)) { + if (exist(tacDir)) { + try { + for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) { + std::string symPath = symlinkAssembly.path().string(); + std::string fileName = symlinkAssembly.path().filename().string(); + if (isSymlinkFile(symPath)) { std::string originPath = bf::read_symlink(symPath).string(); - std::string originNiPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll"; - if (!bf::exists(originNiPath)) { - if(createNiDll(originPath, false) != NI_ERROR_NONE) { - fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str()); + if (!isR2RImage(symPath)) { + std::string dllPath = concatPath(binDir, fileName); + if (!copyFile(originPath, dllPath)) { + _SERR("Failed to copy of %s", dllPath.c_str()); return TAC_ERROR_UNKNOWN; } - } - std::string symNIPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll"; - if (!bf::exists(symNIPath)) { - bf::create_symlink(originNiPath, symNIPath); - fprintf(stderr, "%s symbolic link file generated successfully.\n", symNIPath.c_str()); - updateAssemblyInfo(tacDir.c_str(), symNIPath.c_str(), true); - - std::string NIFileName = symNIPath.substr(symNIPath.rfind('/') + 1); - if (!removeFile(concatPath(binNIDir, NIFileName))) { - fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, NIFileName).c_str()); + copySmackAndOwnership(binDir.c_str(), concatPath(binDir, fileName).c_str()); + } else { + std::string niPath = concatPath(binNIDir, fileName); + if (!copyFile(originPath, niPath)) { + _SERR("Failed to copy of %s", niPath.c_str()); return TAC_ERROR_UNKNOWN; } + copySmackAndOwnership(binDir.c_str(), niPath.c_str()); } } } - } - } - return TAC_ERROR_NONE; -} - -tac_error_e regenerateTAC() -{ - const std::string tacDir[] = {__TAC_DIR}; - removeNiUnderDirs(tacDir, 1); - - auto convert = [](const std::string& path, std::string name) { - if (strstr(path.c_str(), TAC_APP_LIST_DB) != NULL || - strstr(path.c_str(), TAC_APP_LIST_RESTORE_DB) != NULL || - strstr(path.c_str(), TAC_SHA_256_INFO) != NULL) - return; - if(createNiDll(path, false) != NI_ERROR_NONE) { - fprintf(stderr, "Failed to create NI file [%s]\n", path.c_str()); - return; - } - }; - scanFilesInDir(tacDir[0], convert, -1); - return TAC_ERROR_NONE; -} - -tac_error_e disableTACPackage(const std::string& pkgId) -{ - std::string pkgRoot; - if (getRootPath(pkgId, pkgRoot) < 0) { - return TAC_ERROR_INVALID_PACKAGE; - } - - std::string binDir = concatPath(pkgRoot, "bin"); - std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); - std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR); - if (bf::exists(tacDir)) { - for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) { - std::string symPath = symlinkAssembly.path().string(); - std::string fileName = symlinkAssembly.path().filename().string(); - if (bf::is_symlink(symPath)) { - std::string originPath = bf::read_symlink(symPath).string(); - if (!isNativeImage(symPath)) { - if (!copyFile(originPath, concatPath(binDir, fileName))) { - fprintf(stderr, "Failed to copy of %s\n", concatPath(binDir, fileName).c_str()); - return TAC_ERROR_UNKNOWN; - } - updateAssemblyInfo(binDir.c_str(), concatPath(binDir, fileName).c_str()); - } else { - if (!copyFile(originPath, concatPath(binNIDir, fileName))) { - fprintf(stderr, "Failed to copy of %s\n", concatPath(binNIDir, fileName).c_str()); - return TAC_ERROR_UNKNOWN; - } - updateAssemblyInfo(binDir.c_str(), concatPath(binNIDir, fileName).c_str()); - } + if (!removeAll(tacDir)) { + _SERR("Failed to remove of %s", tacDir.c_str()); + return TAC_ERROR_UNKNOWN; } + } catch (const bf::filesystem_error& error) { + _SERR("Failed to recursive directory: %s", error.what()); + return TAC_ERROR_UNKNOWN; } } - if (!removeAll(tacDir)) { - fprintf(stderr, "Failed to remove of %s\n", tacDir.c_str()); - return TAC_ERROR_UNKNOWN; - } return TAC_ERROR_NONE; } tac_error_e enableTACPackage(const std::string& pkgId) { - std::string rootPath; - if (getRootPath(pkgId, rootPath) < 0) { + std::string rootPath = getRootPath(pkgId); + if (rootPath.empty()) { + _SERR("Failed to get root path from [%s]", pkgId.c_str()); return TAC_ERROR_INVALID_PACKAGE; } - std::string execName; - if (getExecName(pkgId, execName) < 0) { - return TAC_ERROR_INVALID_PACKAGE; + std::string binDir = concatPath(rootPath, "bin"); + if (exist(concatPath(binDir, PRE_COMPILED_PACKAGE_FILE))) { + _INFO("The %s is a Pre-Compiled package. So, skip the TAC", pkgId.c_str()); + return TAC_ERROR_NONE; } - std::string metaValue; - if (getMetadataValue(pkgId, TAC_METADATA_KEY, metaValue) < 0) { + std::string execName = getExecName(pkgId); + if (execName.empty()) { + _SERR("Failed to get exec name from [%s]", pkgId.c_str()); return TAC_ERROR_INVALID_PACKAGE; } - if (initializePathManager(std::string(), std::string(), std::string())) { - fprintf(stderr, "Fail to initialize PathManger"); - return TAC_ERROR_UNKNOWN; + std::string metaValue = getMetadataValue(pkgId, TAC_METADATA_KEY); + if (metaValue.empty()) { + _SERR("Failed to get metadata from [%s]", pkgId.c_str()); + return TAC_ERROR_INVALID_PACKAGE; } - if (!strcmp(metaValue.c_str(), "true")) { + if (!strcmp(metaValue.c_str(), METADATA_VALUE_TRUE)) { std::string binDir = concatPath(rootPath, "bin"); std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR); std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR); - if (!bf::exists(tacDir)) { + if (!exist(tacDir)) { if (!createDir(tacDir)) { - fprintf(stderr, "Cannot create directory: %s\n", tacDir.c_str()); + _SERR("Cannot create directory: %s", tacDir.c_str()); return TAC_ERROR_UNKNOWN; } - updateAssemblyInfo(binDir.c_str(), tacDir.c_str()); + copySmackAndOwnership(binDir.c_str(), tacDir.c_str()); std::vector enableNuget; - for (auto& npAssembly : depsJsonParser(rootPath, execName, getTPA())) { + for (auto& npAssembly : depsJsonParser(rootPath, execName)) { std::string nugetPackage = npAssembly.substr(0, npAssembly.rfind(':')); std::string assemblyName = npAssembly.substr(npAssembly.rfind(':') + 1); - std::string nugetPath = concatPath(__TAC_DIR, nugetPackage); - if (bf::exists(nugetPath)) { + std::string nugetPath = concatPath(__DOTNET_DIR, nugetPackage); + if (exist(nugetPath)) { std::string originPath = concatPath(nugetPath, assemblyName); - if (bf::exists(originPath)) { + if (exist(originPath)) { enableNuget.push_back(originPath); } } } + bs::error_code error; for (auto& originPath : enableNuget) { - if (bf::exists(originPath)) { + if (exist(originPath)) { std::string fileName = originPath.substr(originPath.rfind('/') + 1); - std::string NIFileName = fileName.substr(0, fileName.rfind(".dll")) + ".ni.dll"; - if (bf::exists(binNIDir)) { - std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll"; - if (bf::exists(originNIPath)) { - bf::create_symlink(originNIPath, concatPath(tacDir, NIFileName)); - fprintf(stderr, "%s symbolic link file generated successfully.\n", concatPath(tacDir, NIFileName).c_str()); - updateAssemblyInfo(tacDir.c_str(), concatPath(tacDir, NIFileName).c_str(), true); + std::string NIFileName = changeExtension(fileName, "dll", "ni.dll"); + if (exist(binNIDir)) { + std::string originNIPath = changeExtension(originPath, "dll", "ni.dll"); + if (exist(originNIPath)) { + bf::create_symlink(originNIPath, concatPath(tacDir, NIFileName), error); + if (error) { + _SERR("Failed to create symlink %s file", concatPath(tacDir, NIFileName).c_str()); + return TAC_ERROR_UNKNOWN; + } + _SOUT("%s symbolic link file generated successfully.", concatPath(tacDir, NIFileName).c_str()); + copySmackAndOwnership(tacDir.c_str(), concatPath(tacDir, NIFileName).c_str(), true); if (!removeFile(concatPath(binNIDir, NIFileName))) { - fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, NIFileName).c_str()); + _SERR("Failed to remove of %s", concatPath(binNIDir, NIFileName).c_str()); return TAC_ERROR_UNKNOWN; } } } - bf::create_symlink(originPath, concatPath(tacDir, fileName)); - fprintf(stderr, "%s symbolic link file generated successfully.\n", concatPath(tacDir, fileName).c_str()); - updateAssemblyInfo(tacDir.c_str(), concatPath(tacDir, fileName).c_str(), true); + bf::create_symlink(originPath, concatPath(tacDir, fileName), error); + if (error) { + _SERR("Failed to create symlink %s file", concatPath(tacDir, fileName).c_str()); + return TAC_ERROR_UNKNOWN; + } + _SOUT("%s symbolic link file generated successfully.", concatPath(tacDir, fileName).c_str()); + copySmackAndOwnership(tacDir.c_str(), concatPath(tacDir, fileName).c_str(), true); if (!removeFile(concatPath(binDir, fileName))) { - fprintf(stderr, "Failed to remove of %s\n", concatPath(binDir, fileName).c_str()); + _SERR("Failed to remove of %s", concatPath(binDir, fileName).c_str()); return TAC_ERROR_UNKNOWN; } } } if (enableNuget.empty()) { if (!removeAll(tacDir)) { - _ERR("Failed to remove of %s", tacDir.c_str()); + _SERR("Failed to remove of %s", tacDir.c_str()); } } enableNuget.clear(); } } else { - fprintf(stderr, "The metadata key is missing or the metadata value is false of [%s]\n", pkgId.c_str()); + _SERR("The metadata key is missing or the metadata value is false of [%s]", pkgId.c_str()); } return TAC_ERROR_NONE; } + +//Parser the .deps.json file to get nuget information. +std::vector depsJsonParser(const std::string& rootPath, const std::string& execName) +{ + std::vector parserData; + std::string depsJsonName = changeExtension(execName, "dll", "deps.json"); + std::string depsJsonPath = concatPath(rootPath, depsJsonName); + try { + if (exist(depsJsonPath)) { + std::ifstream ifs(depsJsonPath); + Json::CharReaderBuilder reader; + Json::Value root; + std::string error; + if (ifs.is_open()) { + if (!Json::parseFromStream(reader, ifs, &root, &error)) { + _ERR("Failed to parse of deps.json"); + ifs.close(); + return parserData; + } + const Json::Value runtimeTargetName = root["runtimeTarget"]["name"]; + const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()]; + for (auto& nuget : nugetPackages.getMemberNames()) { + //Skip the nuget package related to Tizen + if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) == NULL && + strstr(nuget.c_str(), TIZEN_DOTNET_SDK_NUGET) == NULL && + strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) == NULL && + strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) == NULL) { + const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"]; + if (assemblies != Json::nullValue) { + // handle assembly even though that is included in the TPA. + for (auto& assembly : assemblies.getMemberNames()) { + std::string assemblyName = assembly.substr(assembly.rfind('/') + 1); + parserData.push_back(nuget + ":" + assemblyName); + _INFO("Nuget : [%s] / Assembly : [%s]", nuget.c_str(), assemblyName.c_str()); + } + } + } + } + ifs.close(); + } + } + } catch (const Json::Exception& error) { + _ERR("Failed to parse Json: %s", error.what()); + } + return parserData; +} + +std::vector getLibrariesInfo(const std::string& rootPath) +{ + std::vector LibrariesInfo; + std::string binDir = concatPath(rootPath, "bin"); + if (!exist(binDir)) + return LibrariesInfo; + + auto convert = [&LibrariesInfo](const std::string& filepath, const std::string& filename) { + if (filename.find(".so", filename.size() - 3) != std::string::npos || filepath.rfind(".so.") != std::string::npos) { + std::string buffer = SHA256(filepath); + LibrariesInfo.push_back(filepath + ":" + buffer); + _INFO("Library : [%s] / SHA256 : [%s]", filename.c_str(), buffer.c_str()); + } + }; + scanFilesInDirectory(binDir, convert, -1); + + return LibrariesInfo; +} + +// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach" +static int tlc_restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData) +{ + char *pkgId = NULL; + char *root = NULL; + std::string rootPath; + + int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId); + if (ret != PMINFO_R_OK) { + _SERR("Failed to get pkgid"); + return -1; + } + + ret = pkgmgrinfo_appinfo_get_root_path(handle, &root); + if (ret != PMINFO_R_OK) { + _SERR("Failed to get root path"); + return -1; + } + rootPath = std::string(root); + + for (auto& librarySha : getLibrariesInfo(rootPath)) { + std::string library = librarySha.substr(0, librarySha.find(':')); + if (exist(library)) { + std::string fileSha = library.substr(library.rfind('/') + 1) + ".." + librarySha.substr(librarySha.find(':') + 1); + char *sql = sqlite3_mprintf("INSERT INTO TLC (PKGID, LIBRARY) VALUES (%Q, %Q);", pkgId, fileSha.c_str()); + insertDB(tlc_db, sql); + restore_library.push_back(fileSha); + sqlite3_free(sql); + } + } + return 0; +} + +tac_error_e tlc_restoreDB() +{ + if (!removeFile(TLC_APP_LIST_RESTORE_DB)) { + _SERR("Failed to remove of %s", TLC_APP_LIST_RESTORE_DB); + return TAC_ERROR_UNKNOWN; + } + + std::string dbRestoreJournal = TLC_APP_LIST_RESTORE_DB + std::string("-journal"); + if (!removeFile(dbRestoreJournal)) { + _SERR("Failed to remove of %s", dbRestoreJournal.c_str()); + return TAC_ERROR_UNKNOWN; + } + + tlc_db = createDB(TLC_APP_LIST_RESTORE_DB, CREATE_TLC_DB_TABLE); + if (!tlc_db) { + _SERR("Sqlite create error"); + return TAC_ERROR_UNKNOWN; + } + sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL); + + pkgmgrinfo_appinfo_metadata_filter_h handle; + int ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle); + if (ret != PMINFO_R_OK) { + return TAC_ERROR_UNKNOWN; + } + + ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE_TRUE); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_appinfo_metadata_filter_destroy(handle); + return TAC_ERROR_UNKNOWN; + } + + ret = pkgmgrMDFilterForeach(handle, tlc_restoreDBCb, NULL); + if (ret != 0) { + pkgmgrinfo_appinfo_metadata_filter_destroy(handle); + return TAC_ERROR_UNKNOWN; + } + + pkgmgrinfo_appinfo_metadata_filter_destroy(handle); + + if (tlc_db) { + closeDB(tlc_db); + tlc_db = NULL; + } + + if (!copyFile(TLC_APP_LIST_RESTORE_DB, TLC_APP_LIST_DB)) { + _SERR("Failed to copy of %s", TLC_APP_LIST_DB); + return TAC_ERROR_UNKNOWN; + } + if (!removeFile(TLC_APP_LIST_RESTORE_DB)) { + _SERR("Failed to remove of %s", TLC_APP_LIST_RESTORE_DB); + return TAC_ERROR_UNKNOWN; + } + + std::string dbJournal = TLC_APP_LIST_DB + std::string("-journal"); + if (!copyFile(dbRestoreJournal, dbJournal)) { + _SERR("Failed to copy of %s", dbJournal.c_str()); + return TAC_ERROR_UNKNOWN; + } + if (!removeFile(dbRestoreJournal)) { + _SERR("Failed to remove of %s", dbRestoreJournal.c_str()); + return TAC_ERROR_UNKNOWN; + } + + auto convert = [](const std::string& path, const std::string& filename) { + bool isExist = false; + for (auto& library : restore_library) { + if (!strcmp(filename.c_str(), library.c_str())) { + isExist = true; + break; + } + } + if (!isExist) { + if (!removeFile(path)) { + _ERR("Failed to remove of %s", path.c_str()); + } + } + }; + + scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0); + + return TAC_ERROR_NONE; +}