2 * Copyright (c) 2022 Samsung Electronics Co., Ltd All Rights Reserved
4 * Licensed under the Apache License, Version 2.0 (the License);
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an AS IS BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
19 #include "db_manager.h"
20 #include "tac_common.h"
21 #include "tac_installer.h"
28 #include <boost/filesystem.hpp>
29 #include <json/json.h>
30 #include <pkgmgr-info.h>
35 #define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
38 #define __STR(x) __XSTR(x)
39 static const char* __DOTNET_DIR = __STR(DOTNET_DIR);
43 static std::vector<std::string> nugetPackagesAssembliesSha;
44 static std::vector<std::string> tacDB;
45 static std::vector<std::string> createDirectories;
46 static std::vector<std::string> createLibraries;
47 static std::vector<std::string> updateTac;
48 static tac_state tacState = TAC_STATE_NONE;
49 static sqlite3 *tac_db = NULL;
50 static sqlite3 *tlc_db = NULL;
51 static bool tacPluginInstalled = false;
52 static bool tacPluginFinished = false;
54 static void createSHA256Info(std::string sha256Info, std::string nugetPackage)
56 std::ofstream ofs(sha256Info, std::ios::app);
57 int assembly_count = 0;
58 for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
59 std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
60 std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
61 std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
62 std::string sha = npAssemblySha.substr(npAssemblySha.rfind(':') + 1);
63 if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) {
64 ofs << assembly << ":" << sha << std::endl;
68 ofs << assembly_count << std::endl;
72 static bool compareSHA256Info(std::string sha256Info, std::string nugetPackage)
74 int compare_count = 0;
75 int assembly_count = 0;
76 std::string sha256_count = "0";
77 for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
78 std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
79 std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
80 std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
81 std::string sha = npAssemblySha.substr(npAssemblySha.rfind(':') + 1);
82 if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) {
84 std::ifstream ifs(sha256Info);
87 while (getline(ifs, get_str)) {
88 if (!strcmp(get_str.c_str(), (assembly + ":" + sha).c_str())) {
91 sha256_count = get_str;
97 if (!strcmp(std::to_string(assembly_count).c_str(), std::to_string(compare_count).c_str()) &&
98 !strcmp(std::to_string(assembly_count).c_str(), sha256_count.c_str())) {
99 _INFO("Same nuget : %s", nugetPackage.c_str());
105 static bool copyAssemblyCreateSymlink(std::string binPath, std::string tacDir, std::string nugetPackage, bool isCreateTacDir)
107 std::string binNiPath = concatPath(binPath, APP_NI_SUB_DIR);
108 std::string tac_version_dir = concatPath(__DOTNET_DIR, nugetPackage);
109 bool nuget_restoration = false;
110 for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
111 std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
112 std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
113 std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
114 if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) {
115 if (exist(concatPath(binPath, assembly))) {
116 std::string niFile = changeExtension(assembly, ".dll", ".ni.dll");
117 bs::error_code error;
118 if (isCreateTacDir) {
119 if (!copyFile(concatPath(binPath, assembly), concatPath(tac_version_dir, assembly))) {
120 _ERR("Failed to copy of %s", assembly.c_str());
121 nuget_restoration = true;
124 if (exist(binNiPath) && !copyFile(concatPath(binNiPath, niFile), concatPath(tac_version_dir, niFile))) {
125 _ERR("Failed to copy of %s", niFile.c_str());
128 bf::create_symlink(concatPath(tac_version_dir, assembly), concatPath(tacDir, assembly), error);
130 _ERR("Failed to create symlink %s file", concatPath(tacDir, assembly).c_str());
131 nuget_restoration = true;
134 if (exist(concatPath(tac_version_dir, niFile)) && exist(binNiPath)) {
135 bf::create_symlink(concatPath(tac_version_dir, niFile), concatPath(tacDir, niFile), error);
137 _ERR("Failed to create symlink %s file", concatPath(tacDir, niFile).c_str());
141 copySmackAndOwnership(tacDir, concatPath(tacDir, assembly), true);
143 if (!removeFile(concatPath(binPath, assembly))) {
144 _ERR("Failed to remove of %s", assembly.c_str());
145 nuget_restoration = true;
148 if (!removeFile(concatPath(binNiPath, niFile))) {
149 _ERR("Failed to remove of %s", niFile.c_str());
155 if (nuget_restoration) {
156 for (auto& npAssemblySha : nugetPackagesAssembliesSha) {
157 std::string nuget_package_assembly = npAssemblySha.substr(0, npAssemblySha.rfind(':'));
158 std::string nuget_package = nuget_package_assembly.substr(0, nuget_package_assembly.rfind(':'));
159 std::string assembly = nuget_package_assembly.substr(nuget_package_assembly.rfind(':') + 1);
160 if (!strcmp(nuget_package.c_str(), nugetPackage.c_str())) {
161 copyFile(concatPath(tac_version_dir, assembly), concatPath(binPath, assembly));
162 copySmackAndOwnership(binPath, concatPath(binPath, assembly));
163 removeFile(concatPath(tacDir, assembly));
168 return nuget_restoration;
171 static void copyLibraryCreateSymlink(const std::string pkgId, std::vector<std::string> LibrariesInfo)
173 if (LibrariesInfo.empty()) {
177 for (auto& librarySha : LibrariesInfo) {
178 std::string library = librarySha.substr(0, librarySha.find(':'));
179 std::string filename = library.substr(library.rfind('/') + 1);
180 std::string fileSha = filename + ".." + librarySha.substr(librarySha.find(':') + 1);
181 std::string shaPath = concatPath(TLC_LIBRARIES_DIR, fileSha);
182 bool fileCopied = false;
183 if (!exist(shaPath)) {
184 if (!copyFile(library, shaPath)) {
185 _ERR("Failed to copy of %s", filename.c_str());
189 createLibraries.push_back(shaPath);
191 if (!removeFile(library)) {
192 _ERR("Failed to remove of %s", library.c_str());
198 bs::error_code error;
199 bf::create_symlink(shaPath, library, error);
201 _ERR("Failed to create symlink %s file", library.c_str());
202 copyFile(shaPath, library);
203 copySmackAndOwnership(getBaseName(library), library);
209 copySmackAndOwnership(getBaseName(library), library, true);
211 char *sql = sqlite3_mprintf("INSERT INTO TLC (PKGID, LIBRARY) VALUES (%Q, %Q);", pkgId.c_str(), fileSha.c_str());
212 if (!insertDB(tlc_db, sql)) {
213 _ERR("Sqlite insert error");
215 copyFile(shaPath, library);
216 copySmackAndOwnership(getBaseName(library), library);
226 static void checkDepsJson(std::string rootPath, std::string binPath, std::string execName)
228 for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
229 std::string nuget_package = npAssembly.substr(0, npAssembly.rfind(':'));
230 std::string assembly_name = npAssembly.substr(npAssembly.rfind(':') + 1);
231 tacDB.push_back(nuget_package);
232 std::string buffer = SHA256(concatPath(binPath, assembly_name));
233 nugetPackagesAssembliesSha.push_back(nuget_package + ":" + assembly_name + ":" + buffer);
234 _INFO("Assembly : [%s] / SHA256 : [%s]", assembly_name.c_str(), buffer.c_str());
236 std::sort(tacDB.begin(), tacDB.end());
237 tacDB.erase(unique(tacDB.begin(), tacDB.end()), tacDB.end());
240 static int tac_createDB()
242 tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
244 _ERR("Sqlite create error. So restore the database.");
245 if (tac_restoreDB() != TAC_ERROR_NONE) {
246 _ERR("Sqlite create error");
249 tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
251 _ERR("Sqlite create error");
255 sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
259 static int tac_openDB()
261 tac_db = openDB(TAC_APP_LIST_DB);
263 _ERR("Sqlite open error. So restore the database.");
264 if (tac_restoreDB() != TAC_ERROR_NONE) {
265 _ERR("Sqlite open error");
268 tac_db = openDB(TAC_APP_LIST_DB);
270 _ERR("Sqlite open error");
274 sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
278 static int tac_insertDB(const std::string& pkgId, const std::string& np, const std::string& tac_name, const std::string& tac_version)
280 char *sql = sqlite3_mprintf(
281 "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
282 "VALUES (%Q, %Q, %Q, %Q);", pkgId.c_str(), np.c_str(), tac_name.c_str(), tac_version.c_str());
283 if (!insertDB(tac_db, sql)) {
284 _ERR("Sqlite insert error");
292 static int sqliteCb(void *count, int argc, char **argv, char **colName)
294 int *c = (int*)count;
299 static int tac_countDB(const std::string& pkgId, const std::string& tac_name, int& count)
301 char *sql = sqlite3_mprintf(
302 "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = %Q AND NAME = %Q;", pkgId.c_str(), tac_name.c_str());
303 if (sqlite3_exec(tac_db, sql, sqliteCb, &count, NULL) != SQLITE_OK) {
304 _ERR("Sqlite select error");
312 static void tac_selectDB(const std::string& pkgId)
314 char *sql = sqlite3_mprintf("SELECT * FROM TAC WHERE PKGID = %Q;", pkgId.c_str());
315 updateTac = selectDB(tac_db, sql);
319 static int tac_updateDB(const std::string& pkgId, const std::string& np, const std::string& tac_name, const std::string& tac_version)
321 char *sql = sqlite3_mprintf(
322 "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
323 tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId.c_str(), tac_name.c_str());
324 if (!updateDB(tac_db, sql)) {
325 _ERR("Sqlite update error");
333 static void tacUpdateDB(sqlite3 *sqlite)
335 for (auto& unp : updateTac) {
337 char *sql = sqlite3_mprintf("SELECT COUNT(NUGET) FROM TAC WHERE NUGET = %Q;", unp.c_str());
338 if (sqlite3_exec(sqlite, sql, sqliteCb, &count, NULL) != SQLITE_OK) {
339 _ERR("Sqlite select error");
345 std::string tac_version_dir_prev = concatPath(__DOTNET_DIR, unp);
346 std::string tac_version_dir_backup = tac_version_dir_prev + ".bck";
347 if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) {
348 _ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str());
352 if (!removeAll(tac_version_dir_prev)) {
353 _ERR("Failed to remove of %s", tac_version_dir_prev.c_str());
362 static int tac_deleteDB(const std::string& pkgId, const std::string& unp = "")
366 sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId.c_str());
368 sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q AND NUGET = %Q;", pkgId.c_str(), unp.c_str());
370 if (!deleteDB(tac_db, sql)) {
371 _ERR("Sqlite delete error");
379 static int tlc_createDB()
381 if (!createDir(TLC_LIBRARIES_DIR)) {
382 _ERR("Cannot create directory: %s", TLC_LIBRARIES_DIR);
385 copySmackAndOwnership(__DOTNET_DIR, TLC_LIBRARIES_DIR);
387 tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
389 _ERR("Sqlite create error. So restore the database.");
390 if (tlc_restoreDB() != TAC_ERROR_NONE) {
391 _ERR("Sqlite create error");
394 tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
396 _ERR("Sqlite create error");
400 sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL);
404 static int tlc_openDB()
406 tlc_db = openDB(TLC_APP_LIST_DB);
408 _ERR("Sqlite open error. So restore the database.");
409 if (tlc_restoreDB() != TAC_ERROR_NONE) {
410 _ERR("Sqlite open error");
413 tlc_db = openDB(TLC_APP_LIST_DB);
415 _ERR("Sqlite open error");
419 sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL);
423 static void tlcUpdateDB(sqlite3 *sqlite, std::vector<std::string> updateTlc)
425 for (auto& ulp : updateTlc) {
427 char *sql = sqlite3_mprintf("SELECT COUNT(LIBRARY) FROM TLC WHERE LIBRARY = %Q;", ulp.c_str());
428 if (sqlite3_exec(sqlite, sql, sqliteCb, &count, NULL) != SQLITE_OK) {
429 _ERR("Sqlite select error");
434 std::string library_prev = concatPath(TLC_LIBRARIES_DIR, ulp);
435 std::string library_backup = library_prev + ".bck";
436 if (!copyFile(library_prev, library_backup)) {
437 _ERR("Failed to copy of %s", library_prev.c_str());
441 if (!removeFile(library_prev)) {
442 _ERR("Failed to remove of %s", library_prev.c_str());
451 static int tlc_deleteDB(const std::string& pkgId)
453 char *sql = sqlite3_mprintf("SELECT * FROM TLC WHERE PKGID = %Q;", pkgId.c_str());
454 std::vector<std::string> updateTlc = selectDB(tlc_db, sql);
457 sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId.c_str());
458 if (!deleteDB(tlc_db, sql)) {
459 _ERR("Sqlite delete error");
465 tlcUpdateDB(tlc_db, updateTlc);
469 static int generateTAC(const std::string& pkgId, const std::string& binPath)
471 std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
472 if (!createDir(tac_dir)) {
473 _ERR("Cannot create directory: %s", tac_dir.c_str());
477 copySmackAndOwnership(binPath.c_str(), tac_dir.c_str());
479 for (auto& np : tacDB) {
480 std::string tac_name = np.substr(0, np.find('/'));
481 std::string tac_version = np.substr(np.rfind('/') + 1);
482 _INFO("TAC name : %s", tac_name.c_str());
483 _INFO("TAC version : %s", tac_version.c_str());
485 bs::error_code error;
486 std::string tac_version_dir = concatPath(__DOTNET_DIR, np);
487 std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
488 bool isCreateTacDir = false;
489 if (!exist(tac_version_dir)) {
490 _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
492 if (!createDir(tac_version_dir)) {
493 _ERR("Cannot create directory: %s", tac_version_dir.c_str());
494 tacState = TAC_STATE_RESTORE;
497 createDirectories.push_back(tac_version_dir);
499 if (isSymlinkFile(sha256_info)) {
500 _ERR("Failed to create sha256_info. Symbolic link is detected");
501 tacState = TAC_STATE_RESTORE;
505 createSHA256Info(sha256_info, np);
507 if (!exist(sha256_info)) {
508 tacState = TAC_STATE_RESTORE;
512 isCreateTacDir = true;
514 _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
516 if (isSymlinkFile(sha256_info)) {
517 _ERR("Failed to create sha256_info. Symbolic link is detected");
518 tacState = TAC_STATE_RESTORE;
522 if (!compareSHA256Info(sha256_info, np)) {
523 _INFO("Different nuget : %s", np.c_str());
527 isCreateTacDir = false;
530 if (copyAssemblyCreateSymlink(binPath, tac_dir, np, isCreateTacDir)) {
531 _ERR("Failed to create symlink");
532 tacState = TAC_STATE_RESTORE;
536 if (tacState == TAC_STATE_INSTALL) {
537 if (tac_insertDB(pkgId, np, tac_name, tac_version) != 0) {
538 tacState = TAC_STATE_RESTORE;
541 } else if (tacState == TAC_STATE_UPGRADE) {
543 if (tac_countDB(pkgId, tac_name, count) != 0) {
544 tacState = TAC_STATE_RESTORE;
548 if (tac_updateDB(pkgId, np, tac_name, tac_version) != 0) {
549 tacState = TAC_STATE_RESTORE;
552 } else if (count == 0) {
553 if (tac_insertDB(pkgId, np, tac_name, tac_version) != 0) {
554 tacState = TAC_STATE_RESTORE;
563 int tacInstall(const std::string& pkgId, tac_state state, bool tacForce)
565 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_INSTALL =====]");
566 _INFO("PackageID : %s", pkgId.c_str());
568 // Can be multiple apps in one package
569 if (tacPluginInstalled) {
570 _INFO("TAC plugin already installed");
573 tacPluginInstalled = true;
575 std::string appType = getAppType(pkgId);
576 if (strstr(appType.c_str(), "dotnet") == NULL) {
577 _ERR("App type is not dotnet");
580 std::string execName = getExecName(pkgId);
581 std::string rootPath = getRootPath(pkgId);
582 if (execName.empty() || rootPath.empty()) {
586 std::string binPath = concatPath(rootPath, "bin");
587 if (exist(concatPath(binPath, PRE_COMPILED_PACKAGE_FILE))) {
588 _INFO("The %s is a Pre-Compiled package. So, skip the TAC", pkgId.c_str());
592 std::string metaValue = getMetadataValue(pkgId, TAC_METADATA_KEY);
594 if (metaValue.empty()) {
598 if (metaValue == METADATA_VALUE_TRUE || tacForce) {
599 checkDepsJson(rootPath, binPath, execName);
607 if (tac_createDB() != 0) {
611 if (generateTAC(pkgId, binPath) != 0) {
616 if (tlc_createDB() != 0) {
620 copyLibraryCreateSymlink(pkgId, getLibrariesInfo(rootPath));
625 int tacUpgrade(const std::string& pkgId, tac_state state, bool tacForce)
627 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UPGRADE =====]");
628 _INFO("PackageID : %s", pkgId.c_str());
630 // Can be multiple apps in one package
631 if (tacPluginInstalled) {
632 _INFO("TAC plugin already upgraded");
635 tacPluginInstalled = true;
637 std::string appType = getAppType(pkgId);
638 if (strstr(appType.c_str(), "dotnet") == NULL) {
639 _ERR("App type is not dotnet");
642 std::string execName = getExecName(pkgId);
643 std::string rootPath = getRootPath(pkgId);
644 if (execName.empty() || rootPath.empty()) {
648 std::string binPath = concatPath(rootPath, "bin");
649 if (exist(concatPath(binPath, PRE_COMPILED_PACKAGE_FILE))) {
650 _INFO("The %s is a Pre-Compiled package. So, skip the TAC", pkgId.c_str());
651 state = TAC_STATE_REMOVED;
654 if (state == TAC_STATE_REMOVED) {
655 _INFO("Skipped to parse of deps.json");
656 } else { //TAC_STATE_UPGRADE
657 std::string metaValue = getMetadataValue(pkgId, TAC_METADATA_KEY);
659 if (metaValue.empty()) {
663 if (metaValue == METADATA_VALUE_TRUE || tacForce) {
664 checkDepsJson(rootPath, binPath, execName);
668 tacState = TAC_STATE_UPGRADE;
669 if (tac_createDB() != 0) {
675 bool skipTLC = false;
677 if (tac_deleteDB(pkgId) != 0) {
684 if (generateTAC(pkgId, binPath) != 0) {
688 for (auto& unp : updateTac) {
689 bool isExits = false;
690 for (auto& np : tacDB) {
691 if (!strcmp(unp.c_str(), np.c_str())) {
697 if (tac_deleteDB(pkgId, unp) != 0) {
698 tacState = TAC_STATE_RESTORE;
707 if (tlc_createDB() != 0) {
711 if (tlc_deleteDB(pkgId) != 0) {
715 copyLibraryCreateSymlink(pkgId, skipTLC ? std::vector<std::string>() : getLibrariesInfo(rootPath));
720 int tacUninstall(const std::string& pkgId, tac_state state)
722 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNINSTALL =====]");
723 _INFO("PackageID : %s", pkgId.c_str());
725 // Can be multiple apps in one package
726 if (tacPluginInstalled) {
727 _INFO("TAC plugin already uninstalled");
730 tacPluginInstalled = true;
733 if (tac_openDB() != 0) {
739 if (tac_deleteDB(pkgId) != 0) {
740 tacState = TAC_STATE_RESTORE;
746 if (tlc_openDB() != 0) {
750 return tlc_deleteDB(pkgId);
753 int tacRemoved(const std::string& pkgId)
755 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_REMOVED =====]");
756 _INFO("PackageID : %s", pkgId.c_str());
758 return tacUpgrade(pkgId, TAC_STATE_REMOVED);
761 void undoStep(std::string tac)
763 std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
765 for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
766 std::string bck_path = bck.path().string();
767 if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
768 if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) {
769 _ERR("Failed to move %s", bck_path.c_str());
774 } catch (const bf::filesystem_error& error) {
775 _ERR("Failed to recursive directory: %s", error.what());
780 auto convert = [](const std::string& path, const std::string& filename) {
781 if (filename.rfind(".bck") != std::string::npos) {
782 if (!moveFile(path, replaceAll(path, ".bck", ""))) {
783 _ERR("Failed to move %s", path.c_str());
788 scanFilesInDirectory(TLC_LIBRARIES_DIR, convert, 0);
793 for (auto& cd : createDirectories) {
794 if (!removeAll(cd)) {
795 _ERR("Failed to remove of %s", cd.c_str());
799 for (auto& cl : createLibraries) {
800 if (!removeFile(cl)) {
801 _ERR("Failed to remove of %s", cl.c_str());
806 void unInstall_Undo()
808 for (auto& unp : updateTac) {
816 if (!tacDB.empty()) {
817 for (auto& np : tacDB) {
824 int tacUndo(const std::string& pkgId)
826 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
827 _INFO("PackageID : %s", pkgId.c_str());
829 // Can be multiple apps in one package
830 if (tacPluginFinished) {
831 _INFO("TAC plugin already finished(UNDO)");
834 tacPluginFinished = true;
836 if (tacState == TAC_STATE_INSTALL) {
838 } else if (tacState == TAC_STATE_UPGRADE) {
840 } else if (tacState == TAC_STATE_UNINSTALL) {
842 } else if (tacState == TAC_STATE_RESTORE) {
859 void changeOwnershipTAC(std::string current_tac)
861 copySmackAndOwnership(__DOTNET_DIR, current_tac);
863 for (auto& path : bf::recursive_directory_iterator(current_tac))
864 copySmackAndOwnership(__DOTNET_DIR, path.path().string());
865 } catch (const bf::filesystem_error& error) {
866 _ERR("Failed to recursive directory: %s", error.what());
870 void cleanStep(std::string tac)
872 std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
874 for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
875 std::string bck_path = bck.path().string();
876 if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
877 if (!removeAll(bck_path)) {
878 _ERR("Failed to remove of %s", bck_path.c_str());
884 bool isExist = false;
885 for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
886 std::string bck_path = bck.path().string();
887 if (exist(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) {
893 if (!removeAll(current_tac)) {
894 _ERR("Failed to remove of %s", current_tac.c_str());
897 } catch (const bf::filesystem_error& error) {
898 _ERR("Failed to recursive directory: %s", error.what());
903 auto convert = [](const std::string& path, const std::string& filename) {
904 if (filename.rfind(".bck") != std::string::npos) {
905 if (!removeFile(path)) {
906 _ERR("Failed to remove of %s", path.c_str());
911 scanFilesInDirectory(TLC_LIBRARIES_DIR, convert, 0);
916 for (auto& cd : createDirectories) {
917 changeOwnershipTAC(cd);
918 copySmackAndOwnership(__DOTNET_DIR, cd.substr(0, cd.rfind('/')));
921 for (auto& cl : createLibraries) {
922 copySmackAndOwnership(__DOTNET_DIR, cl);
926 void unInstall_Clean()
928 for (auto& unp : updateTac) {
936 if (!tacDB.empty()) {
937 for (auto& np : tacDB) {
939 changeOwnershipTAC(concatPath(__DOTNET_DIR, np.substr(0, np.find('/'))));
945 int tacClean(const std::string& pkgId)
947 if (tacState == TAC_STATE_RESTORE) {
948 disableTACPackage(pkgId);
950 std::string rootPath = getRootPath(pkgId);
951 if (!rootPath.empty()) {
952 std::string binPath = concatPath(rootPath, "bin");
953 removeAll(concatPath(binPath, TAC_SYMLINK_SUB_DIR));
956 std::string runtimesDir = concatPath(rootPath, "bin/runtimes");
957 if (exist(runtimesDir)) {
959 sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER);
960 std::regex pattern(buffer);
963 for (auto& path : bf::recursive_directory_iterator(runtimesDir)) {
964 std::string symPath = path.path().string();
965 if (isDirectory(symPath) || !isSymlinkFile(symPath))
967 std::string targetDir = symPath.substr(symPath.rfind("/runtimes/") + 10);
968 if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern))
970 if (symPath.rfind(".so") == std::string::npos)
972 copyFile(bf::read_symlink(symPath).string(), symPath);
974 } catch (const bf::filesystem_error& error) {
975 _ERR("Failed to recursive directory: %s", error.what());
979 return tacUndo(pkgId);
982 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]");
983 _INFO("PackageID : %s", pkgId.c_str());
985 // Can be multiple apps in one package
986 if (tacPluginFinished) {
987 _INFO("TAC plugin already finished(CLEAN)");
990 tacPluginFinished = true;
992 if (tacState == TAC_STATE_INSTALL) {
994 } else if (tacState == TAC_STATE_UPGRADE) {
996 } else if (tacState == TAC_STATE_UNINSTALL) {
1003 copySmackAndOwnership(__DOTNET_DIR, TAC_APP_LIST_DB);
1004 copySmackAndOwnership(__DOTNET_DIR, TAC_APP_LIST_DB + std::string("-journal"));
1010 copySmackAndOwnership(__DOTNET_DIR, TLC_APP_LIST_DB);
1011 copySmackAndOwnership(__DOTNET_DIR, TLC_APP_LIST_DB + std::string("-journal"));