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 std::vector<std::string> nugetPackagesAssembliesSha;
44 std::vector<std::string> tacDB;
45 std::vector<std::string> createDirectories;
46 std::vector<std::string> createLibraries;
47 std::vector<std::string> updateTac;
48 tac_state tacState = TAC_STATE_NONE;
49 static sqlite3 *tac_db = NULL;
50 static sqlite3 *tlc_db = NULL;
51 bool tacPluginInstalled = false;
52 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 (!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))) {
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, std::string tlcDir)
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 bool fileCopied = false;
182 if (!exist(concatPath(tlcDir, fileSha))) {
183 if (!copyFile(library, concatPath(tlcDir, fileSha))) {
184 _ERR("Failed to copy of %s", filename.c_str());
188 createLibraries.push_back(concatPath(tlcDir, fileSha));
190 if (!removeFile(library)) {
191 _ERR("Failed to remove of %s", library.c_str());
193 removeFile(concatPath(tlcDir, fileSha));
197 bs::error_code error;
198 bf::create_symlink(concatPath(tlcDir, fileSha), library, error);
200 _ERR("Failed to create symlink %s file", library.c_str());
201 copyFile(concatPath(tlcDir, fileSha), library);
202 copySmackAndOwnership(getBaseName(library), library);
204 removeFile(concatPath(tlcDir, fileSha));
208 copySmackAndOwnership(getBaseName(library), library, true);
210 char *sql = sqlite3_mprintf("INSERT INTO TLC (PKGID, LIBRARY) VALUES (%Q, %Q);", pkgId.c_str(), fileSha.c_str());
211 if (!insertDB(tlc_db, sql)) {
212 _ERR("Sqlite insert error");
214 copyFile(concatPath(tlcDir, fileSha), library);
215 copySmackAndOwnership(getBaseName(library), library);
217 removeFile(concatPath(tlcDir, fileSha));
225 static void checkDepsJson(std::string rootPath, std::string binPath, std::string execName)
227 for (auto& npAssembly : depsJsonParser(rootPath, execName)) {
228 std::string nuget_package = npAssembly.substr(0, npAssembly.rfind(':'));
229 std::string assembly_name = npAssembly.substr(npAssembly.rfind(':') + 1);
230 tacDB.push_back(nuget_package);
231 std::string buffer = SHA256(concatPath(binPath, assembly_name));
232 nugetPackagesAssembliesSha.push_back(nuget_package + ":" + assembly_name + ":" + buffer);
233 _INFO("Assembly : [%s] / SHA256 : [%s]", assembly_name.c_str(), buffer.c_str());
235 std::sort(tacDB.begin(), tacDB.end());
236 tacDB.erase(unique(tacDB.begin(), tacDB.end()), tacDB.end());
239 int tacInstall(const std::string& pkgId, tac_state state, bool tacForce)
241 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_INSTALL =====]");
242 _INFO("PackageID : %s", pkgId.c_str());
244 // Can be multiple apps in one package
245 if (tacPluginInstalled) {
246 _INFO("TAC plugin already installed");
249 tacPluginInstalled = true;
251 std::string appType = getAppType(pkgId);
252 if (strstr(appType.c_str(), "dotnet") == NULL) {
253 _ERR("App type is not dotnet");
256 std::string execName = getExecName(pkgId);
257 std::string rootPath = getRootPath(pkgId);
258 if (execName.empty() || rootPath.empty()) {
262 std::string binPath = concatPath(rootPath, "bin");
263 std::string metaValue = getMetadataValue(pkgId, TAC_METADATA_KEY);
265 if (metaValue.empty()) {
269 if (metaValue == METADATA_VALUE_TRUE || tacForce) {
270 checkDepsJson(rootPath, binPath, execName);
278 tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
280 _ERR("Sqlite create error. So restore the database.");
281 if (tac_restoreDB() != TAC_ERROR_NONE) {
282 _ERR("Sqlite create error");
285 tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
287 _ERR("Sqlite create error");
291 sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
293 std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
294 if (!createDir(tac_dir)) {
295 _ERR("Cannot create directory: %s", tac_dir.c_str());
298 copySmackAndOwnership(binPath.c_str(), tac_dir.c_str());
300 for (auto& np : tacDB) {
301 std::string tac_name = np.substr(0, np.find('/'));
302 std::string tac_version = np.substr(np.rfind('/') + 1);
303 _INFO("TAC name : %s", tac_name.c_str());
304 _INFO("TAC version : %s", tac_version.c_str());
306 bs::error_code error;
307 std::string tac_version_dir = concatPath(__DOTNET_DIR, np);
308 std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
309 if (!exist(tac_version_dir)) {
310 _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
311 if (!createDir(tac_version_dir)) {
312 _ERR("Cannot create directory: %s", tac_version_dir.c_str());
313 tacState = TAC_STATE_RESTORE;
316 createDirectories.push_back(tac_version_dir);
317 if (!isSymlinkFile(sha256_info)) {
318 createSHA256Info(sha256_info, np);
320 _ERR("Failed to create sha256_info. Symbolic link is detected");
321 tacState = TAC_STATE_RESTORE;
325 if (!exist(sha256_info)) {
326 tacState = TAC_STATE_RESTORE;
330 if (copyAssemblyCreateSymlink(binPath, tac_dir, np, true)) {
331 _ERR("Failed to create symlink");
332 tacState = TAC_STATE_RESTORE;
336 char *sql = sqlite3_mprintf(
337 "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
338 "VALUES (%Q, %Q, %Q, %Q);", pkgId.c_str(), np.c_str(), tac_name.c_str(), tac_version.c_str());
339 if (!insertDB(tac_db, sql)) {
340 _ERR("Sqlite insert error");
342 tacState = TAC_STATE_RESTORE;
347 _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
348 if (!isSymlinkFile(sha256_info)) {
349 if (compareSHA256Info(sha256_info, np)) {
350 if (copyAssemblyCreateSymlink(binPath, tac_dir, np, false)) {
351 _ERR("Failed to create symlink");
352 tacState = TAC_STATE_RESTORE;
356 char *sql = sqlite3_mprintf(
357 "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
358 "VALUES (%Q, %Q, %Q, %Q);", pkgId.c_str(), np.c_str(), tac_name.c_str(), tac_version.c_str());
359 if (!insertDB(tac_db, sql)) {
360 _ERR("Sqlite insert error");
362 tacState = TAC_STATE_RESTORE;
367 _INFO("Different nuget : %s", np.c_str());
371 _ERR("Failed to create sha256_info. Symbolic link is detected");
372 tacState = TAC_STATE_RESTORE;
379 std::string tlcDir = concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR);
380 if (!createDir(tlcDir)) {
381 _ERR("Cannot create directory: %s", tlcDir.c_str());
384 copySmackAndOwnership(__DOTNET_DIR, tlcDir);
386 tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
388 _ERR("Sqlite create error. So restore the database.");
389 if (tlc_restoreDB() != TAC_ERROR_NONE) {
390 _ERR("Sqlite create error");
393 tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
395 _ERR("Sqlite create error");
399 sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL);
401 copyLibraryCreateSymlink(pkgId, getLibrariesInfo(rootPath), tlcDir);
406 static int sqliteCb(void *count, int argc, char **argv, char **colName)
408 int *c = (int*)count;
413 static void tac_updateDB(sqlite3 *sqlite)
415 for (auto& unp : updateTac) {
417 char *sql = sqlite3_mprintf("SELECT COUNT(NUGET) FROM TAC WHERE NUGET = %Q;", unp.c_str());
418 int ret = sqlite3_exec(sqlite, sql, sqliteCb, &count, NULL);
419 if (ret != SQLITE_OK) {
420 _ERR("Sqlite select error");
425 std::string tac_version_dir_prev = concatPath(__DOTNET_DIR, unp);
426 std::string tac_version_dir_backup = tac_version_dir_prev + ".bck";
427 if (!copyDir(tac_version_dir_prev, tac_version_dir_backup)) {
428 _ERR("Failed to copy of %s to %s", tac_version_dir_prev.c_str(), tac_version_dir_backup.c_str());
432 if (!removeAll(tac_version_dir_prev)) {
433 _ERR("Failed to remove of %s", tac_version_dir_prev.c_str());
442 static void tlc_updateDB(sqlite3 *sqlite, std::vector<std::string> updateTlc, std::string tlcDir)
444 for (auto& ulp : updateTlc) {
446 char *sql = sqlite3_mprintf("SELECT COUNT(LIBRARY) FROM TLC WHERE LIBRARY = %Q;", ulp.c_str());
447 int ret = sqlite3_exec(sqlite, sql, sqliteCb, &count, NULL);
448 if (ret != SQLITE_OK) {
449 _ERR("Sqlite select error");
454 std::string library_prev = concatPath(tlcDir, ulp);
455 std::string library_backup = library_prev + ".bck";
456 if (!copyFile(library_prev, library_backup)) {
457 _ERR("Failed to copy of %s", library_prev.c_str());
461 if (!removeFile(library_prev)) {
462 _ERR("Failed to remove of %s", library_prev.c_str());
471 int tacUpgrade(const std::string& pkgId, tac_state state, bool tacForce)
473 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UPGRADE =====]");
474 _INFO("PackageID : %s", pkgId.c_str());
476 // Can be multiple apps in one package
477 if (tacPluginInstalled) {
478 _INFO("TAC plugin already upgraded");
481 tacPluginInstalled = true;
483 std::string appType = getAppType(pkgId);
484 if (strstr(appType.c_str(), "dotnet") == NULL) {
485 _ERR("App type is not dotnet");
488 std::string execName = getExecName(pkgId);
489 std::string rootPath = getRootPath(pkgId);
490 if (execName.empty() || rootPath.empty()) {
494 std::string binPath = concatPath(rootPath, "bin");
495 if (state == TAC_STATE_REMOVED) {
496 _INFO("Skipped to parse of deps.json");
497 } else { //TAC_STATE_UPGRADE
498 std::string metaValue = getMetadataValue(pkgId, TAC_METADATA_KEY);
500 if (metaValue.empty()) {
504 if (metaValue == METADATA_VALUE_TRUE || tacForce) {
505 checkDepsJson(rootPath, binPath, execName);
509 tacState = TAC_STATE_UPGRADE;
510 tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
512 _ERR("Sqlite create error. So restore the database.");
513 if (tac_restoreDB() != TAC_ERROR_NONE) {
514 _ERR("Sqlite create error");
517 tac_db = createDB(TAC_APP_LIST_DB, CREATE_TAC_DB_TABLE);
519 _ERR("Sqlite create error");
523 sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
525 char *sql = sqlite3_mprintf("SELECT * FROM TAC WHERE PKGID = %Q;", pkgId.c_str());
526 updateTac = selectDB(tac_db, sql);
529 bool skipTLC = false;
531 sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId.c_str());
532 if (!deleteDB(tac_db, sql)) {
533 _ERR("Sqlite delete error");
539 tac_updateDB(tac_db);
543 std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
544 if (!createDir(tac_dir)) {
545 _ERR("Cannot create directory: %s", tac_dir.c_str());
548 copySmackAndOwnership(binPath.c_str(), tac_dir.c_str());
550 for (auto& np : tacDB) {
551 std::string tac_name = np.substr(0, np.find('/'));
552 std::string tac_version = np.substr(np.rfind('/') + 1);
553 _INFO("TAC name : %s", tac_name.c_str());
554 _INFO("TAC version : %s", tac_version.c_str());
556 bs::error_code error;
557 std::string tac_version_dir = concatPath(__DOTNET_DIR, np);
558 std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
559 if (!exist(tac_version_dir)) {
560 _INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
561 if (!createDir(tac_version_dir)) {
562 _ERR("Cannot create directory: %s", tac_version_dir.c_str());
563 tacState = TAC_STATE_RESTORE;
566 createDirectories.push_back(tac_version_dir);
567 if (!isSymlinkFile(sha256_info)) {
568 createSHA256Info(sha256_info, np);
570 _ERR("Failed to create sha256_info. Symbolic link is detected");
571 tacState = TAC_STATE_RESTORE;
575 if (!exist(sha256_info)) {
576 tacState = TAC_STATE_RESTORE;
580 if (copyAssemblyCreateSymlink(binPath, tac_dir, np, true)) {
581 _ERR("Failed to create symlink");
582 tacState = TAC_STATE_RESTORE;
587 sql = sqlite3_mprintf(
588 "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = %Q AND NAME = %Q;", pkgId.c_str(), tac_name.c_str());
589 int ret = sqlite3_exec(tac_db, sql, sqliteCb, &count, NULL);
590 if (ret != SQLITE_OK) {
591 _ERR("Sqlite select error");
593 tacState = TAC_STATE_RESTORE;
598 sql = sqlite3_mprintf(
599 "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
600 tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId.c_str(), tac_name.c_str());
601 if (!updateDB(tac_db, sql)) {
602 _ERR("Sqlite update error");
604 tacState = TAC_STATE_RESTORE;
608 } else if (count == 0) {
609 sql = sqlite3_mprintf(
610 "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
611 "VALUES (%Q, %Q, %Q, %Q);", pkgId.c_str(), np.c_str(), tac_name.c_str(), tac_version.c_str());
612 if (!insertDB(tac_db, sql)) {
613 _ERR("Sqlite insert error");
615 tacState = TAC_STATE_RESTORE;
621 _INFO("Exists tac_version_dir [%s]", tac_version_dir.c_str());
622 if (!isSymlinkFile(sha256_info)) {
623 if (compareSHA256Info(sha256_info, np)) {
624 if (copyAssemblyCreateSymlink(binPath, tac_dir, np, false)) {
625 _ERR("Failed to create symlink");
626 tacState = TAC_STATE_RESTORE;
631 char *sql = sqlite3_mprintf(
632 "SELECT COUNT(NUGET) FROM TAC WHERE PKGID = %Q AND NAME = %Q;", pkgId.c_str(), tac_name.c_str());
633 int ret = sqlite3_exec(tac_db, sql, sqliteCb, &count, NULL);
634 if (ret != SQLITE_OK) {
635 _ERR("Sqlite select error");
637 tacState = TAC_STATE_RESTORE;
642 sql = sqlite3_mprintf(
643 "UPDATE TAC SET NAME = %Q, VERSION = %Q, NUGET = %Q WHERE PKGID = %Q AND NAME = %Q;",
644 tac_name.c_str(), tac_version.c_str(), np.c_str(), pkgId.c_str(), tac_name.c_str());
645 if (!updateDB(tac_db, sql)) {
646 _ERR("Sqlite update error");
648 tacState = TAC_STATE_RESTORE;
652 } else if (count == 0) {
653 sql = sqlite3_mprintf(
654 "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
655 "VALUES (%Q, %Q, %Q, %Q);", pkgId.c_str(), np.c_str(), tac_name.c_str(), tac_version.c_str());
656 if (!insertDB(tac_db, sql)) {
657 _ERR("Sqlite insert error");
659 tacState = TAC_STATE_RESTORE;
665 _INFO("Different nuget : %s", np.c_str());
669 _ERR("Failed to create sha256_info. Symbolic link is detected");
670 tacState = TAC_STATE_RESTORE;
675 for (auto& unp : updateTac) {
676 bool isExits = false;
677 for (auto& np : tacDB) {
678 if (!strcmp(unp.c_str(), np.c_str())) {
684 char *sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q AND NUGET = %Q;", pkgId.c_str(), unp.c_str());
685 if (!deleteDB(tac_db, sql)) {
686 _ERR("Sqlite delete error");
688 tacState = TAC_STATE_RESTORE;
694 tac_updateDB(tac_db);
698 std::string tlcDir = concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR);
699 if (!createDir(tlcDir)) {
700 _ERR("Cannot create directory: %s", tlcDir.c_str());
703 copySmackAndOwnership(__DOTNET_DIR, tlcDir);
705 tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
707 _ERR("Sqlite create error. So restore the database.");
708 if (tlc_restoreDB() != TAC_ERROR_NONE) {
709 _ERR("Sqlite create error");
712 tlc_db = createDB(TLC_APP_LIST_DB, CREATE_TLC_DB_TABLE);
714 _ERR("Sqlite create error");
718 sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL);
720 sql = sqlite3_mprintf("SELECT * FROM TLC WHERE PKGID = %Q;", pkgId.c_str());
721 std::vector<std::string> updateTlc = selectDB(tlc_db, sql);
724 sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId.c_str());
725 if (!deleteDB(tlc_db, sql)) {
726 _ERR("Sqlite delete error");
732 std::vector<std::string> librariesInfo;
734 librariesInfo = getLibrariesInfo(rootPath);
737 copyLibraryCreateSymlink(pkgId, librariesInfo, tlcDir);
739 tlc_updateDB(tlc_db, updateTlc, tlcDir);
744 int tacUninstall(const std::string& pkgId, tac_state state)
746 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNINSTALL =====]");
747 _INFO("PackageID : %s", pkgId.c_str());
749 // Can be multiple apps in one package
750 if (tacPluginInstalled) {
751 _INFO("TAC plugin already uninstalled");
754 tacPluginInstalled = true;
757 tac_db = openDB(TAC_APP_LIST_DB);
759 _ERR("Sqlite open error. So restore the database.");
760 if (tac_restoreDB() != TAC_ERROR_NONE) {
761 _ERR("Sqlite open error");
764 tac_db = openDB(TAC_APP_LIST_DB);
766 _ERR("Sqlite open error");
770 sqlite3_exec(tac_db, "BEGIN;", NULL, NULL, NULL);
772 char *sql = sqlite3_mprintf("SELECT * FROM TAC WHERE PKGID = %Q;", pkgId.c_str());
773 updateTac = selectDB(tac_db, sql);
776 sql = sqlite3_mprintf("DELETE FROM TAC WHERE PKGID = %Q;", pkgId.c_str());
778 if (!deleteDB(tac_db, sql)) {
779 _ERR("Sqlite delete error");
781 tacState = TAC_STATE_RESTORE;
786 tac_updateDB(tac_db);
789 tlc_db = openDB(TLC_APP_LIST_DB);
791 _ERR("Sqlite open error. So restore the database.");
792 if (tlc_restoreDB() != TAC_ERROR_NONE) {
793 _ERR("Sqlite open error");
796 tlc_db = openDB(TLC_APP_LIST_DB);
798 _ERR("Sqlite open error");
802 sqlite3_exec(tlc_db, "BEGIN;", NULL, NULL, NULL);
804 sql = sqlite3_mprintf("SELECT * FROM TLC WHERE PKGID = %Q;", pkgId.c_str());
805 std::vector<std::string> updateTlc = selectDB(tlc_db, sql);
808 sql = sqlite3_mprintf("DELETE FROM TLC WHERE PKGID = %Q;", pkgId.c_str());
809 if (!deleteDB(tlc_db, sql)) {
810 _ERR("Sqlite delete error");
816 tlc_updateDB(tlc_db, updateTlc, concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR));
821 int tacRemoved(const std::string& pkgId)
823 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_REMOVED =====]");
824 _INFO("PackageID : %s", pkgId.c_str());
826 return tacUpgrade(pkgId, TAC_STATE_REMOVED);
829 void undoStep(std::string tac)
831 std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
833 for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
834 std::string bck_path = bck.path().string();
835 if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
836 if (!moveFile(bck_path, bck_path.substr(0, bck_path.rfind(".bck")))) {
837 _ERR("Failed to move %s", bck_path.c_str());
842 } catch (const bf::filesystem_error& error) {
843 _ERR("Failed to recursive directory: %s", error.what());
848 auto convert = [](const std::string& path, const std::string& filename) {
849 if (filename.rfind(".bck") != std::string::npos) {
850 if (!moveFile(path, replaceAll(path, ".bck", ""))) {
851 _ERR("Failed to move %s", path.c_str());
856 scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0);
861 for (auto& cd : createDirectories) {
862 if (!removeAll(cd)) {
863 _ERR("Failed to remove of %s", cd.c_str());
867 for (auto& cl : createLibraries) {
868 if (!removeFile(cl)) {
869 _ERR("Failed to remove of %s", cl.c_str());
874 void unInstall_Undo()
876 for (auto& unp : updateTac) {
884 if (!tacDB.empty()) {
885 for (auto& np : tacDB) {
892 int tacUndo(const std::string& pkgId)
894 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_UNDO =====]");
895 _INFO("PackageID : %s", pkgId.c_str());
897 // Can be multiple apps in one package
898 if (tacPluginFinished) {
899 _INFO("TAC plugin already finished(UNDO)");
902 tacPluginFinished = true;
904 if (tacState == TAC_STATE_INSTALL) {
906 } else if (tacState == TAC_STATE_UPGRADE) {
908 } else if (tacState == TAC_STATE_UNINSTALL) {
910 } else if (tacState == TAC_STATE_RESTORE) {
927 void changeOwnershipTAC(std::string current_tac)
929 copySmackAndOwnership(__DOTNET_DIR, current_tac);
931 for (auto& path : bf::recursive_directory_iterator(current_tac))
932 copySmackAndOwnership(__DOTNET_DIR, path.path().string());
933 } catch (const bf::filesystem_error& error) {
934 _ERR("Failed to recursive directory: %s", error.what());
938 void cleanStep(std::string tac)
940 std::string current_tac = concatPath(__DOTNET_DIR, tac.substr(0, tac.find('/')));
942 for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
943 std::string bck_path = bck.path().string();
944 if (bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") != NULL) {
945 if (!removeAll(bck_path)) {
946 _ERR("Failed to remove of %s", bck_path.c_str());
952 bool isExist = false;
953 for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
954 std::string bck_path = bck.path().string();
955 if (exist(bck_path) && bf::is_directory(bck_path) && strstr(bck_path.c_str(), ".bck") == NULL) {
961 if (!removeAll(current_tac)) {
962 _ERR("Failed to remove of %s", current_tac.c_str());
965 } catch (const bf::filesystem_error& error) {
966 _ERR("Failed to recursive directory: %s", error.what());
971 auto convert = [](const std::string& path, const std::string& filename) {
972 if (filename.rfind(".bck") != std::string::npos) {
973 if (!removeFile(path)) {
974 _ERR("Failed to remove of %s", path.c_str());
979 scanFilesInDirectory(concatPath(__DOTNET_DIR, TLC_LIBRARIES_DIR), convert, 0);
984 for (auto& cd : createDirectories) {
985 changeOwnershipTAC(cd);
986 copySmackAndOwnership(__DOTNET_DIR, cd.substr(0, cd.rfind('/')));
989 for (auto& cl : createLibraries) {
990 changeOwnershipTAC(cl);
994 void unInstall_Clean()
996 for (auto& unp : updateTac) {
1004 if (!tacDB.empty()) {
1005 for (auto& np : tacDB) {
1007 changeOwnershipTAC(concatPath(__DOTNET_DIR, np.substr(0, np.find('/'))));
1013 int tacClean(const std::string& pkgId)
1015 if (tacState == TAC_STATE_RESTORE) {
1016 disableTACPackage(pkgId);
1018 std::string rootPath = getRootPath(pkgId);
1019 if (!rootPath.empty()) {
1020 std::string binPath = concatPath(rootPath, "bin");
1021 removeAll(concatPath(binPath, TAC_SYMLINK_SUB_DIR));
1024 std::string runtimesDir = concatPath(rootPath, "bin/runtimes");
1025 if (exist(runtimesDir)) {
1027 sprintf(buffer, "(tizen|linux|unix|base|any)(.\\d.\\d.\\d)?(-%s)?", ARCHITECTURE_IDENTIFIER);
1028 std::regex pattern(buffer);
1031 for (auto& path : bf::recursive_directory_iterator(runtimesDir)) {
1032 std::string symPath = path.path().string();
1033 if (isDirectory(symPath) || !isSymlinkFile(symPath))
1035 std::string targetDir = symPath.substr(symPath.rfind("/runtimes/") + 10);
1036 if (!std::regex_match(targetDir.substr(0, targetDir.find('/')), pattern))
1038 if (symPath.rfind(".so") == std::string::npos)
1040 copyFile(bf::read_symlink(symPath).string(), symPath);
1042 } catch (const bf::filesystem_error& error) {
1043 _ERR("Failed to recursive directory: %s", error.what());
1047 return tacUndo(pkgId);
1050 _DBG("[===== PKGMGR_MDPARSER_PLUGIN_CLEAN =====]");
1051 _INFO("PackageID : %s", pkgId.c_str());
1053 // Can be multiple apps in one package
1054 if (tacPluginFinished) {
1055 _INFO("TAC plugin already finished(CLEAN)");
1058 tacPluginFinished = true;
1060 if (tacState == TAC_STATE_INSTALL) {
1062 } else if (tacState == TAC_STATE_UPGRADE) {
1064 } else if (tacState == TAC_STATE_UNINSTALL) {
1071 copySmackAndOwnership(__DOTNET_DIR, TAC_APP_LIST_DB);
1072 copySmackAndOwnership(__DOTNET_DIR, TAC_APP_LIST_DB + std::string("-journal"));
1078 copySmackAndOwnership(__DOTNET_DIR, TLC_APP_LIST_DB);
1079 copySmackAndOwnership(__DOTNET_DIR, TLC_APP_LIST_DB + std::string("-journal"));