2 * Copyright (c) 2019 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.
18 #include <pkgmgr-info.h>
19 #include <pkgmgr_installer_info.h>
20 #include <json/json.h>
24 #include "ni_common.h"
25 #include "tac_common.h"
26 #include "db_manager.h"
27 #include "path_manager.h"
32 #define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
35 #define __STR(x) __XSTR(x)
36 static const char* __TAC_DIR = __STR(TAC_DIR);
40 static sqlite3 *tac_db = NULL;
41 std::vector<std::string> restoreNuget;
42 std::vector<std::string> enableNuget;
44 void cleanupDirectory()
46 std::vector<std::string> removeNuget;
47 for (auto& nuget : bf::recursive_directory_iterator(__TAC_DIR)) {
49 for (auto& restore : restoreNuget) {
50 if (!bf::is_directory(nuget.path())) {
53 if (strstr(nuget.path().c_str(), restore.c_str()) != NULL) {
59 removeNuget.push_back(nuget.path().string());
63 for (auto& rm : removeNuget) {
65 _ERR("Failed to remove of %s", rm.c_str());
71 // callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
72 static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
80 int ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
81 if (ret != PMINFO_R_OK) {
82 fprintf(stderr, "Failed to get pkgid\n");
86 ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
87 if (ret != PMINFO_R_OK) {
88 fprintf(stderr, "Failed to get root path\n");
93 ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
94 if (ret != PMINFO_R_OK) {
95 fprintf(stderr, "Failed to get exec name\n");
98 execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
100 restoreNuget = depsJsonParser(pkgId, rootPath, execName, getTPA(), true, tac_db);
104 tac_error_e restoreTACDB()
106 if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
107 fprintf(stderr, "Failed to remove of %s", TAC_APP_LIST_RESTORE_DB);
108 return TAC_ERROR_UNKNOWN;
111 std::string dbRestoreJournal = TAC_APP_LIST_RESTORE_DB + std::string("-journal");
112 if (!removeFile(dbRestoreJournal)) {
113 fprintf(stderr, "Failed to remove of %s", dbRestoreJournal.c_str());
114 return TAC_ERROR_UNKNOWN;
117 if (initializePathManager(std::string(), std::string(), std::string())) {
118 fprintf(stderr, "Fail to initialize PathManger");
119 return TAC_ERROR_UNKNOWN;
122 tac_db = dbCreate(TAC_APP_LIST_RESTORE_DB);
124 if (!dbOpen(tac_db, TAC_APP_LIST_RESTORE_DB)) {
125 return TAC_ERROR_UNKNOWN;
128 return TAC_ERROR_UNKNOWN;
131 pkgmgrinfo_appinfo_metadata_filter_h handle;
132 int ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
133 if (ret != PMINFO_R_OK) {
134 return TAC_ERROR_UNKNOWN;
137 ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, TAC_METADATA_KEY, METADATA_VALUE);
138 if (ret != PMINFO_R_OK) {
139 pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
140 return TAC_ERROR_UNKNOWN;
143 ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, restoreDBCb, NULL);
144 if (ret != PMINFO_R_OK) {
145 fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
146 pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
147 return TAC_ERROR_UNKNOWN;
149 fprintf(stderr, "Success pkgmgrinfo_appinfo_metadata_filter_foreach\n");
151 pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
158 if (!copyFile(TAC_APP_LIST_RESTORE_DB, TAC_APP_LIST_DB)) {
159 fprintf(stderr, "Failed to copy of %s", TAC_APP_LIST_DB);
160 return TAC_ERROR_UNKNOWN;
162 if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
163 fprintf(stderr, "Failed to remove of %s", TAC_APP_LIST_RESTORE_DB);
164 return TAC_ERROR_UNKNOWN;
167 std::string dbJournal = TAC_APP_LIST_DB + std::string("-journal");
168 if (!copyFile(dbRestoreJournal, dbJournal)) {
169 fprintf(stderr, "Failed to copy of %s", dbJournal.c_str());
170 return TAC_ERROR_UNKNOWN;
172 if (!removeFile(dbRestoreJournal)) {
173 fprintf(stderr, "Failed to remove of %s", dbRestoreJournal.c_str());
174 return TAC_ERROR_UNKNOWN;
178 return TAC_ERROR_NONE;
181 tac_error_e resetTACPackage(const std::string& pkgId)
184 if (getRootPath(pkgId, pkgRoot) < 0) {
185 return TAC_ERROR_INVALID_PACKAGE;
188 std::vector<std::string> tacNativeImage;
189 std::string binDir = concatPath(pkgRoot, "bin");
190 std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
191 if (bf::exists(tacDir)) {
192 for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
193 std::string symPath = symlinkAssembly.path().string();
194 if (bf::is_symlink(symPath)) {
195 if (isNativeImage(symPath)) {
196 tacNativeImage.push_back(symPath);
200 for (auto& path : tacNativeImage) {
201 if (!removeFile(path)) {
202 fprintf(stderr, "Failed to remove of %s", path.c_str());
203 return TAC_ERROR_UNKNOWN;
207 tacNativeImage.clear();
208 return TAC_ERROR_NONE;
211 tac_error_e createTACPackage(const std::string& pkgId)
214 if (getRootPath(pkgId, pkgRoot) < 0) {
215 return TAC_ERROR_INVALID_PACKAGE;
218 std::string binDir = concatPath(pkgRoot, "bin");
219 std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
220 std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
221 if (bf::exists(tacDir)) {
222 for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
223 std::string symPath = symlinkAssembly.path().string();
224 if (bf::is_symlink(symPath)) {
225 if (!isNativeImage(symPath)) {
226 std::string originPath = bf::read_symlink(symPath).string();
227 std::string originNiPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
228 if (!bf::exists(originNiPath)) {
229 if(createNiDll(originPath, false) != NI_ERROR_NONE) {
230 fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str());
231 return TAC_ERROR_UNKNOWN;
234 std::string symNIPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll";
235 if (!bf::exists(symNIPath)) {
236 bf::create_symlink(originNiPath, symNIPath);
237 fprintf(stderr, "%s symbolic link file generated successfully.\n", symNIPath.c_str());
238 updateAssemblyInfo(tacDir.c_str(), symNIPath.c_str(), true);
240 std::string NIFileName = symNIPath.substr(symNIPath.rfind('/') + 1);
241 if (!removeFile(concatPath(binNIDir, NIFileName))) {
242 fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, NIFileName).c_str());
243 return TAC_ERROR_UNKNOWN;
250 return TAC_ERROR_NONE;
253 tac_error_e regenerateTAC()
255 const std::string tacDir[] = {__TAC_DIR};
256 removeNiUnderDirs(tacDir, 1);
258 auto convert = [](const std::string& path, std::string name) {
259 if (strstr(path.c_str(), TAC_APP_LIST_DB) != NULL ||
260 strstr(path.c_str(), TAC_APP_LIST_RESTORE_DB) != NULL ||
261 strstr(path.c_str(), TAC_SHA_256_INFO) != NULL)
263 if(createNiDll(path, false) != NI_ERROR_NONE) {
264 fprintf(stderr, "Failed to create NI file [%s]\n", path.c_str());
268 scanFilesInDir(tacDir[0], convert, -1);
269 return TAC_ERROR_NONE;
272 tac_error_e disableTACPackage(const std::string& pkgId)
275 if (getRootPath(pkgId, pkgRoot) < 0) {
276 return TAC_ERROR_INVALID_PACKAGE;
279 std::string binDir = concatPath(pkgRoot, "bin");
280 std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
281 std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
282 if (bf::exists(tacDir)) {
283 for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
284 std::string symPath = symlinkAssembly.path().string();
285 std::string fileName = symlinkAssembly.path().filename().string();
286 if (bf::is_symlink(symPath)) {
287 std::string originPath = bf::read_symlink(symPath).string();
288 if (!isNativeImage(symPath)) {
289 if (!copyFile(originPath, concatPath(binDir, fileName))) {
290 fprintf(stderr, "Failed to copy of %s\n", concatPath(binDir, fileName).c_str());
291 return TAC_ERROR_UNKNOWN;
293 updateAssemblyInfo(binDir.c_str(), concatPath(binDir, fileName).c_str());
295 if (!copyFile(originPath, concatPath(binNIDir, fileName))) {
296 fprintf(stderr, "Failed to copy of %s\n", concatPath(binNIDir, fileName).c_str());
297 return TAC_ERROR_UNKNOWN;
299 updateAssemblyInfo(binDir.c_str(), concatPath(binNIDir, fileName).c_str());
304 if (!removeAll(tacDir)) {
305 fprintf(stderr, "Failed to remove of %s\n", tacDir.c_str());
306 return TAC_ERROR_UNKNOWN;
308 return TAC_ERROR_NONE;
311 tac_error_e enableTACPackage(const std::string& pkgId)
313 std::string rootPath;
314 if (getRootPath(pkgId, rootPath) < 0) {
315 return TAC_ERROR_INVALID_PACKAGE;
318 std::string execName;
319 if (getExecName(pkgId, execName) < 0) {
320 return TAC_ERROR_INVALID_PACKAGE;
323 std::string metaValue;
324 if (getMetadataValue(pkgId, TAC_METADATA_KEY, metaValue) < 0) {
325 return TAC_ERROR_INVALID_PACKAGE;
328 if (initializePathManager(std::string(), std::string(), std::string())) {
329 fprintf(stderr, "Fail to initialize PathManger");
330 return TAC_ERROR_UNKNOWN;
333 if (!strcmp(metaValue.c_str(), "true")) {
334 std::string binDir = concatPath(rootPath, "bin");
335 std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
336 std::string binNIDir = concatPath(binDir, APP_NI_SUB_DIR);
337 if (!bf::exists(tacDir)) {
338 if (!createDir(tacDir)) {
339 fprintf(stderr, "Cannot create directory: %s\n", tacDir.c_str());
340 return TAC_ERROR_UNKNOWN;
342 updateAssemblyInfo(binDir.c_str(), tacDir.c_str());
344 enableNuget = depsJsonParser(pkgId, rootPath, execName, getTPA(), true);
346 for (auto& originPath : enableNuget) {
347 if (bf::exists(originPath)) {
348 std::string fileName = originPath.substr(originPath.rfind('/') + 1);
349 std::string NIFileName = fileName.substr(0, fileName.rfind(".dll")) + ".ni.dll";
350 if (bf::exists(binNIDir)) {
351 std::string originNIPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
352 if (bf::exists(originNIPath)) {
353 bf::create_symlink(originNIPath, concatPath(tacDir, NIFileName));
354 fprintf(stderr, "%s symbolic link file generated successfully.\n", concatPath(tacDir, NIFileName).c_str());
355 updateAssemblyInfo(tacDir.c_str(), concatPath(tacDir, NIFileName).c_str(), true);
357 if (!removeFile(concatPath(binNIDir, NIFileName))) {
358 fprintf(stderr, "Failed to remove of %s\n", concatPath(binNIDir, NIFileName).c_str());
359 return TAC_ERROR_UNKNOWN;
363 bf::create_symlink(originPath, concatPath(tacDir, fileName));
364 fprintf(stderr, "%s symbolic link file generated successfully.\n", concatPath(tacDir, fileName).c_str());
365 updateAssemblyInfo(tacDir.c_str(), concatPath(tacDir, fileName).c_str(), true);
367 if (!removeFile(concatPath(binDir, fileName))) {
368 fprintf(stderr, "Failed to remove of %s\n", concatPath(binDir, fileName).c_str());
369 return TAC_ERROR_UNKNOWN;
373 if (enableNuget.empty()) {
374 if (!removeAll(tacDir)) {
375 _ERR("Failed to remove of %s", tacDir.c_str());
380 fprintf(stderr, "The metadata key is missing or the metadata value is false of [%s]\n", pkgId.c_str());
382 return TAC_ERROR_NONE;