SET(NI_COMMON "ni_common")
SET(${NI_COMMON}_SOURCE_FILES
tool/ni_common.cc
+ tool/tac_common.cc
)
ADD_LIBRARY(${NI_COMMON} SHARED ${${NI_COMMON}_SOURCE_FILES})
SET_TARGET_PROPERTIES(${NI_COMMON} PROPERTIES COMPILE_FLAGS "-fPIC")
SET_TARGET_PROPERTIES(${TPATOOL} PROPERTIES COMPILE_FLAGS "-fPIE")
TARGET_LINK_LIBRARIES(${TPATOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL})
-SET(TACTOOL "tactool")
-SET(${TACTOOL}_SOURCE_FILES
- tool/tactool.cc
+SET(DOTNETTOOL "dotnettool")
+SET(${DOTNETTOOL}_SOURCE_FILES
+ tool/dotnettool.cc
)
-ADD_EXECUTABLE(${TACTOOL} ${${TACTOOL}_SOURCE_FILES})
-SET_TARGET_PROPERTIES(${TACTOOL} PROPERTIES COMPILE_FLAGS "-fPIE")
-TARGET_LINK_LIBRARIES(${TACTOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON})
+ADD_EXECUTABLE(${DOTNETTOOL} ${${DOTNETTOOL}_SOURCE_FILES})
+SET_TARGET_PROPERTIES(${DOTNETTOOL} PROPERTIES COMPILE_FLAGS "-fPIE")
+TARGET_LINK_LIBRARIES(${DOTNETTOOL} ${${PROJECT_NAME}_LDFLAGS} "-pie" ${DOTNET_LAUNCHER_UTIL} ${NI_COMMON})
#SET(INSTALLER_PLUGIN "ui-application")
#SET(${INSTALLER_PLUGIN}_SOURCE_FILES
INSTALL(TARGETS ${NI_COMMON} DESTINATION ${LIBDIR})
INSTALL(TARGETS ${NITOOL} DESTINATION ${BINDIR})
INSTALL(TARGETS ${TPATOOL} DESTINATION ${BINDIR})
-INSTALL(TARGETS ${TACTOOL} DESTINATION ${BINDIR})
+INSTALL(TARGETS ${DOTNETTOOL} DESTINATION ${BINDIR})
#INSTALL(TARGETS ${INSTALLER_PLUGIN} DESTINATION ${INSTALL_PLUGIN_DIR})
INSTALL(TARGETS ${PREFER_DOTNET_AOT_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
INSTALL(TARGETS ${PREFER_NUGET_CACHE_PLUGIN} DESTINATION ${INSTALL_MDPLUGIN_DIR})
INSTALL(FILES inc/coreclr_host.h DESTINATION ${INCLUDEDIR})
INSTALL(FILES inc/dotnet_launcher_plugin.h DESTINATION ${INCLUDEDIR})
INSTALL(FILES inc/ni_common.h DESTINATION ${INCLUDEDIR})
+INSTALL(FILES inc/tac_common.h DESTINATION ${INCLUDEDIR})
INSTALL(FILES ../dotnet-launcher.pc DESTINATION ${LIBDIR}/pkgconfig)
INSTALL(FILES dotnet-launcher.info DESTINATION /usr/share/parser-plugins)
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#ifndef __TAC_COMMON_H__
+#define __TAC_COMMON_H__
+
+#include <functional>
+
+typedef enum {
+ TAC_ERROR_NONE = 0,
+ TAC_ERROR_INVALID_PARAMETER = -1,
+ TAC_ERROR_ALREADY_EXIST = -2,
+ TAC_ERROR_NO_SUCH_FILE = -3,
+ TAC_ERROR_INVALID_PACKAGE = -4,
+ TAC_ERROR_NOT_SUPPORTED = -5,
+ TAC_ERROR_UNKNOWN = -9
+} tac_error_e;
+
+/**
+ * @brief restore database of TAC
+ * @return tac_error_e
+ */
+tac_error_e restoreTACDB();
+
+/**
+ * @brief remove a symbolic link file, the native images of TAC for specific package.
+ * @param[i] pkgId package ID
+ * @return tac_error_e
+ */
+tac_error_e resetTACPackage(const std::string& pkgId);
+
+/**
+ * @brief creates a symbolic link file, the native image of TAC for specific package.
+ * @param[i] pkgId package ID
+ * @return tac_error_e
+ */
+tac_error_e createTACPackage(const std::string& pkgId);
+
+/**
+ * @brief regenerate native image of TAC for all shared assembly.
+ * @return tac_error_e
+ */
+tac_error_e regenerateTAC();
+
+/**
+ * @brief disable tac feature.
+ * @param[i] pkgId package ID
+ * @return tac_error_e
+ */
+tac_error_e disableTACPackage(const std::string& pkgId);
+
+/**
+ * @brief enable tac feature.
+ * @param[i] pkgId package ID
+ * @return tac_error_e
+ */
+tac_error_e enableTACPackage(const std::string& pkgId);
+
+#endif /* __TAC_COMMON_H__ */
FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS = (1 << 3)
};
+/**
+ * @brief an iterator to the begin element in the range that compares equal to option
+ * @param[in] begin element
+ * @param[in] end elment
+ * return return true when elements match
+ */
bool cmdOptionExists(char** begin, char** end, const std::string& option);
/**
int getRootPath(std::string pkgId, std::string& rootPath);
/**
+ * @brief get exec name
+ * @param[in] package id
+ * @param[out] exec name
+ */
+int getExecName(std::string pkgId, std::string& execName);
+
+/**
+ * @brief get metadata value
+ * @param[in] package id
+ * @param[in] metadata key
+ * @param[out] metadata value
+ */
+int getMetadataValue(std::string pkgId, std::string metadataKey, std::string& metadataValue);
+
+/**
* @brief split path with ":" delimiter and put that in the vector
* @param[in] source path
* @param[out] string vector
void scanFilesInDir(const std::string& directory, FileReader reader, unsigned int depth);
/**
+ * @brief update assembly file info.
+ * @param[in] get path
+ * @param[in] set path
+ * @param[in] symbolic link
+ */
+void updateAssemblyInfo(const std::string& getPath, const std::string& setPath, bool isSymlink = false);
+
+/**
* @brief create the new directory.
* @param[in] source path
* @return return true when the directory was created.
bool createDir(const bf::path& path);
/**
- * @brief update assembly file info.
- * @param[in] get path
- * @param[in] set path
- */
-void updateAssemblyInfo(const std::string& getPath, const std::string& setPath);
-
-/**
* @brief copy the directory.
* @param[in] path to the source directory
* @param[in] path to the target directory
return -1;
}
- if (createNiUnderPkgRoot(pkgId, false) != 0) {
+ if (createNiUnderPkgRoot(pkgId, false) != NI_ERROR_NONE) {
_ERR("Failed to get root path from [%s]", pkgId);
return -1;
} else {
std::string pkgRoot;
if (getRootPath(pkgId, pkgRoot) < 0) {
- fprintf(stderr, "Failed to get root path from [%s]\n", pkgId);
- return -1;
+ _ERR("Failed to get root path from [%s]", pkgId);
+ return 0;
}
std::string binDir = concatPath(pkgRoot, "bin");
uid_t uid = 0;
if (pkgmgr_installer_info_get_target_uid(&uid) < 0) {
_ERR("Failed to get UID");
- return -1;
+ return 0;
}
- for (auto& symlinkAssembly : bf::recursive_directory_iterator(bf::path(tacDir))) {
+ for (auto& symlinkAssembly : bf::recursive_directory_iterator(tacDir)) {
std::string symPath = symlinkAssembly.path().string();
if (!isNativeImage(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, false) != NI_ERROR_NONE) {
- _ERR("Failed to create NI file [%s]\n", originPath.c_str());
+ _ERR("Failed to create NI file [%s]", originPath.c_str());
return -1;
}
}
std::string setNiPath = symPath.substr(0, symPath.rfind(".dll")) + ".ni.dll";
if (!bf::exists(setNiPath)) {
bf::create_symlink(originNiPath, setNiPath);
- fprintf(stderr, "%s symbolic link file generated successfully.\n", setNiPath.c_str());
+ _ERR("%s symbolic link file generated successfully.", setNiPath.c_str());
if (lchown(setNiPath.c_str(), uid, 0)) {
_ERR("Failed to change owner of: %s", setNiPath.c_str());
return -1;
bool isCreateDirectory = false;
static sqlite3 *tac_db = NULL;
-int metadataCheck(GList *list)
+bool metadataCheck(GList *list)
{
GList *tag = NULL;
Metadata *mdInfo = NULL;
NiCommonOption option = {std::string(), std::string(), std::string()};
if (initNICommon(&option) < 0) {
_ERR("Fail to initialize NI Common");
- return -1;
+ return false;
}
- return 0;
- } else {
- return -1;
+ return true;
}
+ return false;
}
-int appTypeCheck(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 isDotnetAppType = false;
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;
}
if (strcmp(type, "dotnet") == 0) {
*dotnet = true;
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 isDotnetAppType;
}
-int getExecName(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;
- }
- execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
- 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 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];
char *buffer = (char*)malloc(bufSize);
if (!buffer) {
fclose(file);
- return -1;
+ return;
}
while ((bytesRead = fread(buffer, 1, bufSize, file))) {
fclose(file);
free(buffer);
- return 0;
}
int depsJsonParser()
std::string error;
if (ifs.is_open()) {
if (!Json::parseFromStream(reader, ifs, &root, &error)) {
- _INFO("Failed to parse of deps.json");
+ _ERR("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()];
+ const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()];
for (auto& nuget : nugetPackages.getMemberNames()) {
if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) != NULL ||
strstr(nuget.c_str(), TIZEN_DOTNET_SDK_NUGET) != NULL ||
_INFO("Nuget package : %s", nuget.c_str());
for (auto& assembly : assemblies.getMemberNames()) {
std::string assembly_name = assembly.substr(assembly.rfind('/') + 1);
- char buffer[65];
+ char buffer[65] = {0};
SHA256(concatPath(binPath, assembly_name), buffer);
nugetPackagesAssembliesShaR2R.push_back(nuget + "/" + assembly_name + "/" + buffer + "/" + r2r);
_INFO("Assembly / SHA256 : %s / %s", assembly_name.c_str(), buffer);
return 0;
}
-int createSymlink(bf::path tac_version_dir, std::string np)
+int createSymlink(std::string tac_version_dir, std::string np)
{
- bs::error_code error;
uid_t uid = 0;
+ std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
+ if (!createDir(tac_dir)) {
+ _INFO("Cannot create directory: %s", tac_dir.c_str());
+ return -1;
+ }
+
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);
if (!strcmp(nuget_package.c_str(), np.c_str())) {
if (bf::exists(concatPath(binPath, assembly))) {
if (isCreateDirectory) {
- if (!copyFile(concatPath(binPath, assembly), tac_version_dir / assembly)) {
+ if (!copyFile(concatPath(binPath, assembly), concatPath(tac_version_dir, assembly))) {
_ERR("Failed to move of %s", assembly.c_str());
return -1;
}
_ERR("Failed to get UID");
return -1;
}
- std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
- bf::create_symlink(tac_version_dir / assembly, concatPath(tac_dir, assembly), error);
- if (error) {
- _ERR("Failed to create symlink");
- return -1;
- }
+ bf::create_symlink(concatPath(tac_version_dir, assembly), concatPath(tac_dir, assembly));
if (lchown(concatPath(tac_dir, assembly).c_str(), uid, 0)) {
_ERR("Failed to change owner of: %s", concatPath(tac_dir, assembly).c_str());
return -1;
}
- }
- }
- }
- 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);
- if (bf::exists(concatPath(binPath, assembly))) {
- if (!removeFile(concatPath(binPath, assembly))) {
- _ERR("Failed to remove of %s", assembly.c_str());
- return -1;
+ if (!removeFile(concatPath(binPath, assembly))) {
+ _ERR("Failed to remove of %s", assembly.c_str());
+ return -1;
+ }
}
}
}
_INFO("App type is not dotnet");
return 0;
}
- if (getExecName(std::string(pkgId)) < 0) {
+ if (getExecName(std::string(pkgId), execName) < 0) {
return 0;
}
if (getRootPath(std::string(pkgId), rootPath) < 0) {
} else {
binPath = concatPath(rootPath, "bin");
}
- if (!metadataCheck(list)) {
- if (depsJsonParser()) {
+ if (metadataCheck(list)) {
+ if (depsJsonParser() < 0) {
return 0;
}
}
tac_db = dbCreate(TAC_APP_LIST_DB);
if (tac_db) {
if (!dbOpen(tac_db, TAC_APP_LIST_DB)) {
+ _ERR("Sqlite open error");
return 0;
}
} else {
_ERR("Not exist .deps.json file");
return 0;
}
- std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
- if (!bf::exists(tac_dir)) {
- if (!createDir(tac_dir)) {
- _INFO("Cannot create directory: %s", tac_dir.c_str());
- return 0;
- }
- }
for (auto& np : tacDB) {
std::string tac_name = np.substr(0, np.find('/'));
_INFO("TAC name : %s", tac_name.c_str());
_INFO("TAC version : %s", tac_version.c_str());
- bf::path tac_version_dir = concatPath(__TAC_DIR, np);
+ std::string tac_version_dir = concatPath(__TAC_DIR, np);
+ std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
isCreateDirectory = false;
if (!bf::exists(tac_version_dir)) {
_INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
return 0;
}
isCreateDirectory = true;
- createDirectories.push_back(tac_version_dir.string());
- std::string sha256_info = (tac_version_dir / TAC_SHA_256_INFO).string();
+ createDirectories.push_back(tac_version_dir);
std::ofstream ofs(sha256_info, std::ios::app);
int assembly_count = 0;
for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
ofs << assembly_count << std::endl;
ofs.close();
- if (createSymlink(tac_version_dir, np)) {
+ if (createSymlink(tac_version_dir, np) < 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 + "');";
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 / TAC_SHA_256_INFO).string();
std::ifstream ifs(sha256_info);
std::string get_str;
if (ifs.is_open()) {
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;
+ if (createSymlink(tac_version_dir, np) < 0) {
+ _ERR("Failed to create symlink");
+ return -1;
}
std::string sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
"VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
_INFO("Different : %s", tac_name.c_str());
}
}
- }
- if (removeOriginalAssembly()) {
- return 0;
+ if (!bf::exists(sha256_info)) {
+ if(!removeAll(tac_version_dir)) {
+ _ERR("Failed to remove of %s", tac_version_dir.c_str());
+ }
+ }
}
return 0;
}
int updateTacDB(const char *pkgId)
{
for (auto& unp : updateTac) {
- char *error = 0;
int ret;
- int count = 0;
+ int count = -1;
if (tac_db) {
if (!dbOpen(tac_db, TAC_APP_LIST_DB)) {
- return 0;
+ _ERR("Sqlite open error");
+ return -1;
}
} else {
_ERR("Sqlite create error");
- return 0;
+ return -1;
}
std::string sql = "SELECT COUNT(NUGET) FROM TAC WHERE NUGET = '" + unp + "';";
- ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, &error);
+ ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, NULL);
if (ret != SQLITE_OK) {
- _ERR("SQL error: %s", error);
- sqlite3_free(error);
+ _ERR("Sqlite select error");
+ return -1;
}
- if (count < 1) {
- bf::path tac_version_dir_prev = concatPath(__TAC_DIR, unp);
- bf::path tac_version_dir_backup = concatPath(__TAC_DIR, unp) + ".bck";
+ 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());
return -1;
_INFO("App type is not dotnet");
return 0;
}
- if (getExecName(std::string(pkgId)) < 0) {
+ if (getExecName(std::string(pkgId), execName) < 0) {
return 0;
}
if (getRootPath(std::string(pkgId), rootPath) < 0) {
if (!strcmp("removed", status.c_str())) {
_INFO("Skipped to parse of deps.json");
} else {
- if (!metadataCheck(list)) {
- if (depsJsonParser()) {
+ if (metadataCheck(list)) {
+ if (depsJsonParser() < 0) {
return 0;
}
}
tac_db = dbCreate(TAC_APP_LIST_DB);
if (tac_db) {
if (!dbOpen(tac_db, TAC_APP_LIST_DB)) {
+ _ERR("Sqlite open error");
return 0;
}
} else {
if (tacDB.empty()) {
sql = "DELETE FROM TAC WHERE PKGID = '" + std::string(pkgId) + "';";
dbDelete(tac_db, TAC_APP_LIST_DB, sql);
- if (updateTacDB(pkgId)) {
- return 0;
+ if (updateTacDB(pkgId) < 0) {
+ return -1;
}
} else {
- std::string tac_dir = concatPath(binPath, TAC_SYMLINK_SUB_DIR);
- if (!bf::exists(tac_dir)) {
- if (!createDir(tac_dir)) {
- _INFO("Cannot create directory: %s", tac_dir.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 = concatPath(__TAC_DIR, np);
+ std::string tac_version_dir = concatPath(__TAC_DIR, np);
+ std::string sha256_info = concatPath(tac_version_dir, TAC_SHA_256_INFO);
isCreateDirectory = false;
if (!bf::exists(tac_version_dir)) {
_INFO("Create tac_version_dir [%s]", tac_version_dir.c_str());
return 0;
}
isCreateDirectory = true;
- createDirectories.push_back(tac_version_dir.string());
- std::string sha256_info = (tac_version_dir / TAC_SHA_256_INFO).string();
+ createDirectories.push_back(tac_version_dir);
std::ofstream ofs2(sha256_info, std::ios::app);
int assembly_count = 0;
for (auto& npAssemblyShaR2R : nugetPackagesAssembliesShaR2R) {
}
ofs2 << assembly_count << std::endl;
ofs2.close();
- if (createSymlink(tac_version_dir, np)) {
- return 0;
+ if (createSymlink(tac_version_dir, np) < 0) {
+ _ERR("Failed to create symlink");
+ return -1;
}
- char *error = 0;
- int count = 0;
+ int count = -1;
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 ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, NULL);
if (ret != SQLITE_OK) {
- _ERR("SQL error: %s", error);
- sqlite3_free(error);
+ _ERR("Sqlite select error");
+ return -1;
}
-
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, TAC_APP_LIST_DB, sql);
- } else {
+ } else if (count == 0) {
sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
"VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
dbInsert(tac_db, TAC_APP_LIST_DB, sql);
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 / TAC_SHA_256_INFO).string();
std::ifstream ifs2(sha256_info);
std::string get_str;
if (ifs2.is_open()) {
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;
+ if (createSymlink(tac_version_dir, np) < 0) {
+ _ERR("Failed to create symlink");
+ return -1;
}
- char *error = 0;
- int count = 0;
+ int count = -1;
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);
+ int ret = sqlite3_exec(tac_db, sql.c_str(), sqliteCb, &count, NULL);
if (ret != SQLITE_OK) {
- _ERR("SQL error: %s", error);
- sqlite3_free(error);
+ _ERR("Sqlite select error");
+ return -1;
}
-
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, TAC_APP_LIST_DB, sql);
- } else {
+ } else if (count == 0) {
sql = "INSERT INTO TAC (PKGID, NUGET, NAME, VERSION) " \
"VALUES ('" + std::string(pkgId) + "', '" + np + "', '" + tac_name + "', '" + tac_version + "');";
dbInsert(tac_db, TAC_APP_LIST_DB, sql);
_INFO("Different : %s", tac_name.c_str());
}
}
+ if (!bf::exists(sha256_info)) {
+ if(!removeAll(tac_version_dir)) {
+ _ERR("Failed to remove of %s", tac_version_dir.c_str());
+ }
+ }
}
for (auto& unp : updateTac) {
bool isExits = false;
dbDelete(tac_db, TAC_APP_LIST_DB, sql);
}
}
-
- if (removeOriginalAssembly()) {
- return 0;
- }
- if (updateTacDB(pkgId)) {
- return 0;
+ if (updateTacDB(pkgId) < 0) {
+ return -1;
}
}
return 0;
tac_db = dbCreate(TAC_APP_LIST_DB);
if (tac_db) {
if (!dbOpen(tac_db, TAC_APP_LIST_DB)) {
+ _ERR("Sqlite open error");
return 0;
}
} else {
sql = "DELETE FROM TAC WHERE PKGID = '" + std::string(pkgId) + "';";
dbDelete(tac_db, TAC_APP_LIST_DB, sql);
- if (updateTacDB(pkgId)) {
- return 0;
+ if (updateTacDB(pkgId) < 0) {
+ return -1;
}
return 0;
}
status = "removed";
- PKGMGR_MDPARSER_PLUGIN_UPGRADE(pkgId, appId, list);
- return 0;
-}
-
-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(__TAC_DIR) / unp.substr(0, unp.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(), ".bck") != NULL) {
- if (!removeAll(bck.path().string())) {
- _ERR("Failed to remove of %s", bck.path().c_str());
- return 0;
- }
- break;
+ std::string current_tac = concatPath(__TAC_DIR, tac.substr(0, tac.find('/')));
+ for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
+ if (bf::is_directory(bck.path()) && strstr(bck.path().c_str(), ".bck") != NULL) {
+ if (!removeAll(bck.path().string())) {
+ _ERR("Failed to remove of %s", bck.path().c_str());
}
+ 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(), ".bck") == NULL) {
- exist_directory_name.push_back(bck.path().string());
- 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(), ".bck") == NULL) {
+ isExist = true;
+ 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();
+ }
+ if (!isExist) {
+ if (!removeAll(current_tac)) {
+ _ERR("Failed to remove of %s", current_tac.c_str());
}
}
- return 0;
}
-int update_Clean()
+void install_Clean()
+{
+ return;
+}
+
+void unInstall_Clean()
+{
+ for (auto& unp : updateTac) {
+ cleanStep(unp);
+ }
+}
+
+void update_Clean()
{
if (!tacDB.empty()) {
for (auto& np : tacDB) {
- bf::path current_tac = bf::path(__TAC_DIR) / 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(), ".bck") != 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(), ".bck") == 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);
return 0;
}
-int install_Undo()
+void undoStep(std::string tac)
+{
+ std::string current_tac = concatPath(__TAC_DIR, tac.substr(0, tac.find('/')));
+ for (auto& bck : bf::recursive_directory_iterator(current_tac)) {
+ if (bf::is_directory(bck.path()) && strstr(bck.path().c_str(), ".bck") != NULL) {
+ if (!moveFile(bck.path(), bck.path().string().substr(0, bck.path().string().rfind(".bck")))) {
+ _ERR("Failed to move %s to %s",
+ bck.path().c_str(), bck.path().string().substr(0, bck.path().string().rfind(".bck")).c_str());
+ }
+ break;
+ }
+ }
+}
+
+void 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 unInstall_Undo()
{
for (auto& unp : updateTac) {
- for (auto& bck : bf::recursive_directory_iterator(bf::path(__TAC_DIR) / unp.substr(0, unp.find('/')))) {
- if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), ".bck") != NULL) {
- if (!moveFile(bck.path(), bck.path().string().substr(0, bck.path().string().rfind(".bck")))) {
- _ERR("Failed to move %s to %s",
- bck.path().c_str(), bck.path().string().substr(0, bck.path().string().rfind(".bck")).c_str());
- return 0;
- }
- break;
- }
- }
+ undoStep(unp);
}
- return 0;
}
-int update_Undo()
+void update_Undo()
{
- for (auto& cd : createDirectories) {
- if (!removeAll(cd)) {
- _ERR("Failed to remove of %s", cd.c_str());
- return 0;
- }
- }
+ install_Undo();
if (!tacDB.empty()) {
for (auto& np : tacDB) {
- for (auto& bck : bf::recursive_directory_iterator(bf::path(__TAC_DIR) / np.substr(0, np.find('/')))) {
- if (bf::exists(bck.path()) && bf::is_directory(bck.path()) && strstr(bck.path().c_str(), ".bck") != NULL) {
- if (!moveFile(bck.path(), bck.path().string().substr(0, bck.path().string().rfind(".bck")))) {
- _ERR("Failed to move %s to %s",
- bck.path().c_str(), bck.path().string().substr(0, bck.path().string().rfind(".bck")).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);
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include "log.h"
+#include "utils.h"
+#include "db_manager.h"
+#include "ni_common.h"
+#include "tac_common.h"
+
+#include <algorithm>
+#include <cstdio>
+#include <cstring>
+#include <fstream>
+#include <vector>
+
+#include <pkgmgr-info.h>
+#include <pkgmgr_installer_info.h>
+
+#ifdef LOG_TAG
+#undef LOG_TAG
+#endif
+#define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
+
+std::vector<std::string> getCmdArgs(char** begin, char** end)
+{
+ std::vector<std::string> list;
+ for (char** itr = begin+1; itr != end; itr++) {
+ if (strncmp(*itr, "--", 2) != 0) {
+ list.push_back(*itr);
+ }
+ }
+ return list;
+}
+
+static void help(const char *argv0)
+{
+ const char* helpDesc =
+ "Usage: %s [args] <root paths or pkg name>\n"
+ " --help - Display this screen\n"
+ " --ni-system - Create NI under System DLLs\n"
+ " --ni-dll - Create NI for DLL\n"
+ " --ni-pkg - Create NI for package\n"
+ " --ni-pkg-dll - Create NI for DLL in package\n"
+ " --ni-dir - Create NI for directory\n"
+ " --r2r - Use ready-to-run option (default: FNV)\n"
+ " (This option should be used with other options)\n"
+ " --ni-reset-system - Remove System NI files\n"
+ " --ni-reset-pkg - Remove App NI files\n"
+ " --ni-regen-all-app - Re-generate All App NI files\n"
+ " --tac-regen-all - Re-generate All TAC files\n"
+ " --tac-restore-db - Restore TAC Database\n"
+ " --tac-disable-pkg - Disable TAC for package\n"
+ " --tac-enable-pkg - Enable TAC for package\n"
+ "\n"
+ "Example:\n"
+ "1. Create native image for dlls and exes under platform directories\n"
+ " # %s --ni-system\n"
+ "2. Create native image for dll\n"
+ " # %s --ni-dll /usr/bin/Tizen.Runtime.dll\n"
+ "3. Create native image under the package's bin and lib directory\n"
+ " # %s --ni-pkg org.tizen.FormsGallery\n"
+ "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
+ " # %s --r2r --ni-regen-all-app\n\n";
+ printf(helpDesc, argv0, argv0, argv0, argv0, argv0);
+}
+
+int main(int argc, char* argv[])
+{
+ bool pkgMode = false;
+ bool dllMode = false;
+ bool dirMode = false;
+ bool rmPkgMode = false;
+ bool enableR2R = false;
+ bool pkgDllMode = false;
+ bool disableTacMode = false;
+ bool enableTacMode = false;
+
+ bool doGenUniqueBaseSystem = true;
+
+ NiCommonOption option = {std::string(), std::string(), std::string()};
+ if (initNICommon(&option) != NI_ERROR_NONE) {
+ fprintf(stderr, "Fail to initialize NI Common\n");
+ return -1;
+ }
+
+ if (cmdOptionExists(argv, argv+argc, "--r2r")) {
+ enableR2R = true;
+ }
+
+ if (cmdOptionExists(argv, argv+argc, "--help")) {
+ help(argv[0]);
+ return 0;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-system")) {
+ createNiPlatform(enableR2R, doGenUniqueBaseSystem);
+ return 0;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-dll")) {
+ dllMode = true;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg")) {
+ pkgMode = true;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-dir")) {
+ dirMode = true;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-system")) {
+ removeNiPlatform();
+ return 0;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-reset-pkg")) {
+ rmPkgMode = true;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-pkg-dll")) {
+ pkgDllMode = true;
+ } else if (cmdOptionExists(argv, argv+argc, "--ni-regen-all-app")) {
+ regenerateAppNI(enableR2R);
+ return 0;
+ } else if (cmdOptionExists(argv, argv+argc, "--tac-regen-all")) {
+ regenerateTAC();
+ return 0;
+ } else if (cmdOptionExists(argv, argv+argc, "--tac-restore-db")) {
+ restoreTACDB();
+ return 0;
+ } else if (cmdOptionExists(argv, argv+argc, "--tac-disable-pkg")) {
+ disableTacMode = true;
+ } else if (cmdOptionExists(argv, argv+argc, "--tac-enable-pkg")) {
+ enableTacMode = true;
+ } else {
+ help(argv[0]);
+ return 0;
+ }
+
+ std::vector<std::string> args = getCmdArgs(argv, argv+argc);
+
+ if (args.size() < 1) {
+ if (pkgMode || rmPkgMode || disableTacMode || enableTacMode) {
+ fprintf(stderr, "Package name is missed\n");
+ } else if (dllMode) {
+ fprintf(stderr, "DLL path is missed\n");
+ }
+ help(argv[0]);
+ return 1;
+ } else if (args.size() < 2) {
+ if (pkgDllMode) {
+ fprintf(stderr, "Package name or DLL path is missed\n");
+ help(argv[0]);
+ return 1;
+ }
+ }
+
+ if (pkgMode) {
+ for (const std::string pkg : args) {
+ // if there is AOTed dlls under package root, that is skiped.
+ int ret = createNiUnderPkgRoot(pkg, enableR2R);
+ if (ret == NI_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+ return -1;
+ } else if (ret != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
+ return -1;
+ }
+ ret = createTACPackage(pkg);
+ if (ret == TAC_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+ return -1;
+ } else if (ret != TAC_ERROR_NONE) {
+ fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkg.c_str());
+ return -1;
+ }
+ }
+ } else if (pkgDllMode) {
+ int ret = createNiDllUnderPkgRoot(args[0], args[1], enableR2R);
+ if (ret == NI_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", args[0].c_str());
+ return -1;
+ } else if (ret == NI_ERROR_ALREADY_EXIST) {
+ // skip for already exist case
+ return -1;
+ } else if (ret != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
+ return -1;
+ }
+ } else if (rmPkgMode) {
+ for (const std::string pkg : args) {
+ int ret = removeNiUnderPkgRoot(pkg);
+ if (ret == NI_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+ return -1;
+ } else if (ret != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to remove dlls for given package [%s]\n", pkg.c_str());
+ return -1;
+ }
+ ret = resetTACPackage(pkg);
+ if (ret == TAC_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+ return -1;
+ } else if (ret != TAC_ERROR_NONE) {
+ fprintf(stderr, "Failed to remove symlink for given package [%s]\n", pkg.c_str());
+ return -1;
+ }
+ }
+ } else if (dllMode) {
+ // donot return error code for generation failure.
+ // we have to run crossgen for all input dlls.
+ for (const std::string dll : args) {
+ int ret = createNiDll(dll, enableR2R, doGenUniqueBaseSystem);
+ if (ret == NI_ERROR_ALREADY_EXIST) {
+ // skip for already exist case
+ } else if (ret != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to generate NI file [%s]\n", dll.c_str());
+ }
+ }
+ } else if (dirMode) {
+ createNiUnderDirs(args.data(), args.size(), enableR2R, doGenUniqueBaseSystem);
+ } else if (disableTacMode) {
+ for (const std::string pkg : args) {
+ int ret = disableTACPackage(pkg);
+ if (ret == TAC_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+ return -1;
+ } else if (ret != TAC_ERROR_NONE) {
+ fprintf(stderr, "Failed to disable tac [%s]\n", pkg.c_str());
+ return -1;
+ }
+ }
+ } else if (enableTacMode) {
+ for (const std::string pkg : args) {
+ int ret = enableTACPackage(pkg);
+ if (ret == TAC_ERROR_INVALID_PACKAGE) {
+ fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
+ return -1;
+ } else if (ret != TAC_ERROR_NONE) {
+ fprintf(stderr, "Failed to enable tac [%s]\n", pkg.c_str());
+ return -1;
+ }
+ }
+ }
+ return 0;
+}
#include <string.h>
#include "ni_common.h"
+#include "tac_common.h"
#include "path_manager.h"
#include "plugin_manager.h"
return -1;
}
- if (removeNiUnderPkgRoot(pkgId) != 0) {
+ if (removeNiUnderPkgRoot(pkgId) != NI_ERROR_NONE) {
fprintf(stderr, "Failed to remove previous dlls from [%s]\n", pkgId);
return -1;
}
+ if (resetTACPackage(pkgId) != TAC_ERROR_NONE) {
+ fprintf(stderr, "Failed to remove symlink for given package [%s]\n", pkgId);
+ return -1;
+ }
+
// Regenerate ni files with R2R mode forcibiliy. (there is no way to now which option is used)
- if (createNiUnderPkgRoot(pkgId, *enableR2R) != 0) {
- fprintf(stderr, "Failed to get root path from [%s]\n", pkgId);
+ if (createNiUnderPkgRoot(pkgId, *enableR2R) != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to generate NI file [%s]\n", pkgId);
return -1;
} else {
fprintf(stderr, "Complete make application to native image\n");
}
+ if (createTACPackage(pkgId) != TAC_ERROR_NONE) {
+ fprintf(stderr, "Failed to generate symbolic link file [%s]\n", pkgId);
+ return -1;
+ }else {
+ fprintf(stderr, "Complete make symbolic link file to tac\n");
+ }
+
return 0;
}
ni_error_e createNiUnderPkgRoot(const std::string& pkgId, bool enableR2R)
{
std::string pkgRoot;
- if (getRootPath(pkgId, pkgRoot) != NI_ERROR_NONE) {
- fprintf(stderr, "Failed to get root path from [%s]\n", pkgId.c_str());
+ if (getRootPath(pkgId, pkgRoot) < 0) {
return NI_ERROR_INVALID_PACKAGE;
}
{
std::string pkgRoot;
if (getRootPath(pkgId, pkgRoot) < 0) {
- fprintf(stderr, "Failed to get root path from [%s]\n", pkgId.c_str());
return NI_ERROR_INVALID_PACKAGE;
}
std::string binDir = concatPath(pkgRoot, "bin");
std::string libDir = concatPath(pkgRoot, "lib");
- std::string appTAC = concatPath(binDir, ".TAC.Release");
- std::string paths = binDir + ":" + libDir + ":" + appTAC;
-
- return crossgen(dllPath, paths, enableR2R, 0, true);
+ std::string tacDir = concatPath(binDir, TAC_SYMLINK_SUB_DIR);
+ std::string paths = binDir + ":" + libDir + ":" + tacDir;
+
+ if (bf::is_symlink(dllPath)) {
+ if (bf::exists(tacDir)) {
+ if (!isNativeImage(dllPath)) {
+ std::string originPath = bf::read_symlink(dllPath).string();
+ std::string originNiPath = originPath.substr(0, originPath.rfind(".dll")) + ".ni.dll";
+ if (!bf::exists(originNiPath)) {
+ if(createNiDll(originPath, false, false) != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to create NI file [%s]\n", originPath.c_str());
+ return NI_ERROR_UNKNOWN;
+ }
+ }
+ std::string setNiPath = dllPath.substr(0, dllPath.rfind(".dll")) + ".ni.dll";
+ if (!bf::exists(setNiPath)) {
+ bf::create_symlink(originNiPath, setNiPath);
+ fprintf(stderr, "%s symbolic link file generated successfully.\n", setNiPath.c_str());
+ updateAssemblyInfo(tacDir.c_str(), setNiPath.c_str(), true);
+ }
+ }
+ }
+ return NI_ERROR_NONE;
+ } else {
+ return crossgen(dllPath, paths, enableR2R, 0, true);
+ }
}
void removeNiPlatform()
{
std::string pkgRoot;
if (getRootPath(pkgId, pkgRoot) < 0) {
- fprintf(stderr, "Failed to get root path from [%s]\n", pkgId.c_str());
return NI_ERROR_INVALID_PACKAGE;
}
static void help(const char *argv0)
{
const char* helpDesc =
- "Usage: %s [args] <root paths or pkg name>\n"
- " --help - Display this screen\n"
- " --system - Create NI under System DLLs\n"
- " --dll - Create NI for DLL\n"
- " --pkg - Create NI for package\n"
- " --dir - Create NI for directory\n"
- " --r2r - Use ready-to-run option (default: FNV)\n"
- " (This option should be used with other options)\n"
- " --reset-system - Remove System NI files\n"
- " --reset-pkg - Remove App NI files\n"
- " --regen-all-app - Re-generate All App NI files\n"
- "\n"
+ "%s is deprecated. Please use dotnettool instead.\n"
"Example:\n"
- "1. Create native image for dlls and exes under platform directories\n"
- " # %s --system\n"
- "2. Create native image for dll\n"
- " # %s --dll /usr/bin/Tizen.Runtime.dll\n"
- "3. Create native image under the package's bin and lib directory\n"
- " # %s --pkg org.tizen.FormsGallery\n"
- "4. Regenerate native images for all installed .net packages with ready-to-run option\n"
- " # %s --r2r --regen-all-app\n\n";
- printf(helpDesc, argv0, argv0, argv0, argv0, argv0);
+ " # dotnettool --help\n\n";
+ printf(helpDesc, argv0);
}
int main(int argc, char* argv[])
fprintf(stderr, "Failed to get root path from [%s]\n", pkg.c_str());
return -1;
} else if (ret != NI_ERROR_NONE) {
- fprintf(stderr, "Failed to generate NI file [%s]\n", args[1].c_str());
+ fprintf(stderr, "Failed to generate NI file [%s]\n", pkg.c_str());
return -1;
}
}
--- /dev/null
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an AS IS BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <fstream>
+#include <pkgmgr-info.h>
+#include <pkgmgr_installer_info.h>
+#include <json/json.h>
+
+#include "log.h"
+#include "utils.h"
+#include "ni_common.h"
+#include "tac_common.h"
+#include "db_manager.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
+
+static sqlite3 *tac_db = NULL;
+std::vector<std::string> restoreNuget;
+std::vector<std::string> enableNuget;
+
+void cleanupDirectory()
+{
+ std::vector<std::string> removeNuget;
+ for (auto& nuget : bf::recursive_directory_iterator(__TAC_DIR)) {
+ bool isExist = false;
+ for (auto& restore : restoreNuget) {
+ if (!bf::is_directory(nuget.path())) {
+ isExist = true;
+ }
+ if (strstr(nuget.path().c_str(), restore.c_str()) != NULL) {
+ isExist = true;
+ break;
+ }
+ }
+ if (!isExist) {
+ removeNuget.push_back(nuget.path().string());
+ }
+ }
+
+ for (auto& rm : removeNuget) {
+ if (!removeAll(rm)) {
+ _ERR("Failed to remove of %s", rm.c_str());
+ }
+ }
+ removeNuget.clear();
+}
+
+void depsJsonParser(std::string pkgId, std::string depsJsonPath, std::string execName, bool isRestore)
+{
+ std::ifstream ifs(depsJsonPath);
+ 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;
+ }
+ const Json::Value runtimeTargetName = root["runtimeTarget"]["name"];
+ const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()];
+ for (auto& nuget : nugetPackages.getMemberNames()) {
+ 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) {
+ continue;
+ } else {
+ const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"];
+ if (assemblies != Json::nullValue) {
+ const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"];
+ bool isDependency = false;
+ for (auto& dependency : dependencies.getMemberNames()) {
+ if (strstr(dependency.c_str(), TIZEN_DOTNET_NUGET) != NULL ||
+ strstr(dependency.c_str(), NET_STANDARD_LIBRARY_NUGET) != NULL) {
+ continue;
+ } else {
+ isDependency = true;
+ }
+ }
+ if (!isDependency) {
+ _INFO("PackageId : [%s] / Nuget package : [%s]", pkgId.c_str(), nuget.c_str());
+ 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 ('" + pkgId + "', '" + nuget + "', '" + name + "', '" + version + "');";
+ if (isRestore) {
+ if (tac_db) {
+ dbInsert(tac_db, TAC_APP_LIST_RESTORE_DB, sql);
+ restoreNuget.push_back(concatPath(__TAC_DIR, name));
+ }
+ } else {
+ std::string nugetPath = concatPath(__TAC_DIR, nuget);
+ if (bf::exists(nugetPath)) {
+ for (auto& assembly : assemblies.getMemberNames()) {
+ std::string assemblyName = assembly.substr(assembly.rfind('/') + 1);
+ std::string originPath = concatPath(nugetPath, assemblyName);
+ if (bf::exists(originPath)) {
+ enableNuget.push_back(originPath);
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+ ifs.close();
+ }
+}
+
+// callback function of "pkgmgrinfo_appinfo_metadata_filter_foreach"
+static int 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");
+ return -1;
+ }
+
+ ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
+ if (ret != PMINFO_R_OK) {
+ fprintf(stderr, "Failed to get root path\n");
+ return -1;
+ }
+ rootPath = root;
+
+ ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
+ if (ret != PMINFO_R_OK) {
+ fprintf(stderr, "Failed to get exec name\n");
+ return -1;
+ }
+ execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
+
+ std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json";
+ std::string depsJsonPath = concatPath(rootPath, depsJsonName);
+ if (bf::exists(depsJsonPath)) {
+ depsJsonParser(pkgId, depsJsonPath, execName, true);
+ }
+ return 0;
+}
+
+tac_error_e restoreTACDB()
+{
+ if (!removeFile(TAC_APP_LIST_RESTORE_DB)) {
+ fprintf(stderr, "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());
+ 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 {
+ return TAC_ERROR_UNKNOWN;
+ }
+
+ 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);
+ 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");
+ 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);
+ tac_db = NULL;
+ }
+
+ if (!copyFile(TAC_APP_LIST_RESTORE_DB, TAC_APP_LIST_DB)) {
+ fprintf(stderr, "Failed to move 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);
+ return TAC_ERROR_UNKNOWN;
+ }
+
+ std::string dbJournal = TAC_APP_LIST_DB + std::string("-journal");
+ if (!copyFile(dbRestoreJournal, dbJournal)) {
+ fprintf(stderr, "Failed to move of %s", dbJournal.c_str());
+ return TAC_ERROR_UNKNOWN;
+ }
+ if (!removeFile(dbRestoreJournal)) {
+ fprintf(stderr, "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<std::string> 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)
+{
+ 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();
+ if (bf::is_symlink(symPath)) {
+ if (!isNativeImage(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, false) != NI_ERROR_NONE) {
+ fprintf(stderr, "Failed to create NI file [%s]\n", originPath.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());
+ return TAC_ERROR_UNKNOWN;
+ }
+ }
+ }
+ }
+ }
+ }
+ 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, 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)) {
+ 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 pkgRoot;
+ if (getRootPath(pkgId, pkgRoot) < 0) {
+ return TAC_ERROR_INVALID_PACKAGE;
+ }
+
+ std::string execName;
+ if (getExecName(pkgId, execName) < 0) {
+ return TAC_ERROR_INVALID_PACKAGE;
+ }
+
+ std::string metaValue;
+ if (getMetadataValue(pkgId, TAC_METADATA_KEY, metaValue) < 0) {
+ return TAC_ERROR_INVALID_PACKAGE;
+ }
+
+ if (!strcmp(metaValue.c_str(), "true")) {
+ 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)) {
+ if (!createDir(tacDir)) {
+ fprintf(stderr, "Cannot create directory: %s\n", tacDir.c_str());
+ return TAC_ERROR_UNKNOWN;
+ }
+ updateAssemblyInfo(binDir.c_str(), tacDir.c_str());
+
+ std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json";
+ std::string depsJsonPath = concatPath(pkgRoot, depsJsonName);
+ if (bf::exists(depsJsonPath)) {
+ depsJsonParser(pkgId, depsJsonPath, execName, false);
+ }
+
+ for (auto& originPath : enableNuget) {
+ if (bf::exists(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);
+
+ if (!removeFile(concatPath(binNIDir, NIFileName))) {
+ fprintf(stderr, "Failed to remove of %s\n", 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);
+
+ if (!removeFile(concatPath(binDir, fileName))) {
+ fprintf(stderr, "Failed to remove of %s\n", concatPath(binDir, fileName).c_str());
+ return TAC_ERROR_UNKNOWN;
+ }
+ }
+ }
+ if (enableNuget.empty()) {
+ if (!removeAll(tacDir)) {
+ _ERR("Failed to remove of %s", tacDir.c_str());
+ }
+ }
+ }
+ } else {
+ fprintf(stderr, "The metadata key is missing or the metadata value is false of [%s]\n", pkgId.c_str());
+ }
+ return TAC_ERROR_NONE;
+}
+++ /dev/null
-/*
- * 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.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an AS IS BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "log.h"
-#include "utils.h"
-#include "db_manager.h"
-
-#include <algorithm>
-#include <cstdio>
-#include <cstring>
-#include <fstream>
-#include <vector>
-
-#include <json/json.h>
-#include <pkgmgr-info.h>
-#include <pkgmgr_installer_info.h>
-
-#ifdef LOG_TAG
-#undef LOG_TAG
-#endif
-#define LOG_TAG "DOTNET_INSTALLER_PLUGIN"
-
-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 mDepsJson = ".deps.json";
-const std::string tacAppListDB = mOptUsrDotnet + "/.TAC.App.list.db";
-const std::string tacAppListDBJournal = mOptUsrDotnet + "/.TAC.App.list.db-journal";
-const std::string tacAppListRestoreDB = mOptUsrDotnet + "/.TAC.App.list.restore.db";
-const std::string tacAppListRestoreDBJournal = mOptUsrDotnet + "/.TAC.App.list.restore.db-journal";
-const std::string mdKey = "http://tizen.org/metadata/prefer_nuget_cache";
-const std::string mdValue = "true";
-
-static sqlite3 *tac_db = NULL;
-std::vector<std::string> restoreNuget;
-
-static void help(const char *argv0)
-{
- const char* helpDesc =
- "Usage: %s [args] <root paths or pkg name>\n"
- " --help - Display this screen\n"
- " --restore-db - Restore TAC Database\n"
- "\n";
- printf(helpDesc, argv0, argv0, argv0, argv0, argv0);
-}
-
-void cleanupDirectory()
-{
- std::vector<std::string> removeNuget;
- for (auto& nuget : bf::recursive_directory_iterator(bf::path(mOptUsrDotnet))) {
- bool isExist = false;
- for (auto& restore : restoreNuget) {
- if (!bf::is_directory(nuget.path())) {
- isExist = true;
- }
- if (strstr(nuget.path().c_str(), restore.c_str()) != NULL) {
- isExist = true;
- break;
- }
- }
- if (!isExist) {
- removeNuget.push_back(nuget.path().string());
- }
- }
-
- for (auto& rm : removeNuget) {
- if (bf::exists(rm)) {
- if (!removeAll(rm)) {
- _ERR("Failed to remove of %s", rm.c_str());
- }
- }
- }
- removeNuget.clear();
-}
-
-void restoreTACDB(std::string pkgId, std::string depsJsonPath, std::string execName)
-{
- std::ifstream ifs(depsJsonPath);
- 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;
- }
- 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(), (execName.substr(0, execName.find(".Tizen."))).c_str()) != NULL ||
- strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).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"];
- bool isDependency = false;
- for (auto& dependency : dependencies.getMemberNames()) {
- if (strstr(dependency.c_str(), mTizenNET.c_str()) != NULL ||
- strstr(dependency.c_str(), mNETStandardLibrary.c_str()) != NULL) {
- continue;
- } else {
- isDependency = true;
- }
- }
- if (!isDependency) {
- _INFO("PackageId : [%s] / Nuget package : [%s]", pkgId.c_str(), nuget.c_str());
- 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 ('" + pkgId + "', '" + nuget + "', '" + name + "', '" + version + "');";
- dbInsert(tac_db, tacAppListRestoreDB, sql);
- restoreNuget.push_back(mOptUsrDotnet + "/" + name);
- }
- }
- }
- }
- ifs.close();
- }
-}
-
-static int restoreDBCb(pkgmgrinfo_appinfo_h handle, void *userData)
-{
- int ret = 0;
- char *pkgId = NULL;
- char *root = NULL;
- char *exec = NULL;
- std::string rootPath;
- std::string execName;
-
- ret = pkgmgrinfo_appinfo_get_pkgid(handle, &pkgId);
- if (ret != PMINFO_R_OK) {
- fprintf(stderr, "Failed to get pkgid\n");
- return -1;
- }
-
- ret = pkgmgrinfo_appinfo_get_root_path(handle, &root);
- if (ret != PMINFO_R_OK) {
- fprintf(stderr, "Failed to get root path\n");
- return -1;
- }
- rootPath = root;
-
- ret = pkgmgrinfo_appinfo_get_exec(handle, &exec);
- if (ret != PMINFO_R_OK) {
- fprintf(stderr, "Failed to get exec name\n");
- return -1;
- }
- execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
-
- std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + mDepsJson;
- std::string depsJsonPath = rootPath + "/" + depsJsonName;
- if (bf::exists(depsJsonPath)) {
- restoreTACDB(pkgId, depsJsonPath, execName);
- }
- return 0;
-}
-
-int restoreDB()
-{
- if (bf::exists(tacAppListRestoreDB)) {
- if (!removeFile(tacAppListRestoreDB)) {
- _ERR("Failed to remove of %s", tacAppListRestoreDB.c_str());
- return -1;
- }
- }
- if (bf::exists(tacAppListRestoreDBJournal)) {
- if (!removeFile(tacAppListRestoreDBJournal)) {
- _ERR("Failed to remove of %s", tacAppListRestoreDBJournal.c_str());
- return -1;
- }
- }
-
- tac_db = dbCreate(tacAppListRestoreDB);
- if (tac_db) {
- if (!dbOpen(tac_db, tacAppListRestoreDB)) {
- return 0;
- }
- } else {
- return 0;
- }
-
- int ret = 0;
- pkgmgrinfo_appinfo_metadata_filter_h handle;
-
- ret = pkgmgrinfo_appinfo_metadata_filter_create(&handle);
- if (ret != PMINFO_R_OK) {
- return -1;
- }
-
- ret = pkgmgrinfo_appinfo_metadata_filter_add(handle, mdKey.c_str(), mdValue.c_str());
- if (ret != PMINFO_R_OK) {
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
- }
-
- ret = pkgmgrinfo_appinfo_metadata_filter_foreach(handle, restoreDBCb, NULL);
- if (ret != PMINFO_R_OK) {
- fprintf(stderr, "Failed pkgmgrinfo_appinfo_metadata_filter_foreach\n");
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
- return -1;
- }
- pkgmgrinfo_appinfo_metadata_filter_destroy(handle);
-
- if (tac_db) {
- dbClose(tac_db);
- tac_db = NULL;
- }
-
- if (bf::exists(tacAppListRestoreDB)) {
- if (!copyFile(tacAppListRestoreDB, tacAppListDB)) {
- _ERR("Failed to move of %s", tacAppListDB.c_str());
- return -1;
- }
- if (!removeFile(tacAppListRestoreDB)) {
- _ERR("Failed to remove of %s", tacAppListRestoreDB.c_str());
- return -1;
- }
- }
-
- if (bf::exists(tacAppListRestoreDBJournal)) {
- if (!copyFile(tacAppListRestoreDBJournal, tacAppListDBJournal)) {
- _ERR("Failed to move of %s", tacAppListDBJournal.c_str());
- return -1;
- }
- if (!removeFile(tacAppListRestoreDBJournal)) {
- _ERR("Failed to remove of %s", tacAppListRestoreDBJournal.c_str());
- return -1;
- }
- }
-
- cleanupDirectory();
- return 0;
-}
-
-// step 1. Remove original DB
-// step 2. Parsing the .deps.json for all apps
-// step 3. Create new DB
-// step 4. Cleanup unnecessary TAC directory
-int main(int argc, char* argv[])
-{
- if (cmdOptionExists(argv, argv + argc, "--help")) {
- help(argv[0]);
- } else if (cmdOptionExists(argv, argv + argc, "--restore-db")) {
- restoreDB();
- } else {
- help(argv[0]);
- }
- return 0;
-}
return 0;
}
+int getExecName(std::string pkgId, std::string& execName)
+{
+ char *exec = NULL;
+ char *appId = 0;
+
+ pkgmgrinfo_pkginfo_h pkg_handle;
+ int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle);
+ if (ret != PMINFO_R_OK) {
+ return -1;
+ }
+ ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return -1;
+ }
+
+ pkgmgrinfo_appinfo_h app_handle;
+ ret = pkgmgrinfo_appinfo_get_appinfo(appId, &app_handle);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return -1;
+ }
+ ret = pkgmgrinfo_appinfo_get_exec(app_handle, &exec);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return -1;
+ }
+ execName = std::string(exec).substr(std::string(exec).rfind('/') + 1);
+
+ pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return 0;
+}
+
+int getMetadataValue(std::string pkgId, std::string metadataKey, std::string& metadataValue)
+{
+ char *value = NULL;
+ char *appId = 0;
+
+ pkgmgrinfo_pkginfo_h pkg_handle;
+ int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle);
+ if (ret != PMINFO_R_OK) {
+ return -1;
+ }
+ ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return -1;
+ }
+
+ pkgmgrinfo_appinfo_h app_handle;
+ ret = pkgmgrinfo_appinfo_get_appinfo(appId, &app_handle);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return -1;
+ }
+ ret = pkgmgrinfo_appinfo_get_metadata_value(app_handle, metadataKey.c_str(), &value);
+ if (ret != PMINFO_R_OK) {
+ pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ //Does not return error because the metadata key may not exist.
+ return 0;
+ }
+ metadataValue = std::string(value);
+
+ pkgmgrinfo_appinfo_destroy_appinfo(app_handle);
+ pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle);
+ return 0;
+}
+
std::string baseName(const std::string& path)
{
auto pos = path.find_last_of(PATH_SEPARATOR);
bool isDir;
if (strstr(directory.c_str(), TAC_SYMLINK_SUB_DIR) != NULL)
- return; // skip nitool --regen-all-app (--r2r)
+ return;
dir = opendir(directory.c_str());
closedir(dir);
}
-void updateAssemblyInfo(const std::string& getPath, const std::string& setPath)
+void updateAssemblyInfo(const std::string& getPath, const std::string& setPath, bool isSymlink)
{
char* label = NULL;
+ struct stat info;
- // change smack label
- if (smack_getlabel(getPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) {
- if (smack_setlabel(setPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) {
- fprintf(stderr, "Fail to set smack label\n");
+ if (isSymlink) {
+ // change smack label for symbolic link.
+ if (smack_lgetlabel(getPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) {
+ if (smack_lsetlabel(setPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) {
+ fprintf(stderr, "Fail to set smack label\n");
+ }
+ free(label);
}
- free(label);
- }
- // change owner and groups for generated ni file.
- struct stat info;
- if (!stat(getPath.c_str(), &info)) {
- if (chown(setPath.c_str(), info.st_uid, info.st_gid) == -1)
- fprintf(stderr, "Failed to change owner and group name\n");
+ // change owner and groups for symbolic link.
+ if (!stat(getPath.c_str(), &info)) {
+ if (lchown(setPath.c_str(), info.st_uid, info.st_gid) == -1)
+ fprintf(stderr, "Failed to change owner and group name\n");
+ }
+ } else {
+ // change smack label
+ if (smack_getlabel(getPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) {
+ if (smack_setlabel(setPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) {
+ fprintf(stderr, "Fail to set smack label\n");
+ }
+ free(label);
+ }
+
+ // change owner and groups for generated ni file.
+ if (!stat(getPath.c_str(), &info)) {
+ if (chown(setPath.c_str(), info.st_uid, info.st_gid) == -1)
+ fprintf(stderr, "Failed to change owner and group name\n");
+ }
}
}
bool copyFile(const bf::path& path1, const bf::path& path2) {
bs::error_code error;
+ if (!bf::exists(path1)) {
+ return false;
+ }
bf::copy_file(path1, path2, bf::copy_option::overwrite_if_exists, error);
if (error) {
_ERR("copy file %s due to error [%s]", path1.c_str(), error.message().c_str());
}
bool moveFile(const bf::path& path1, const bf::path& path2) {
- if (bf::exists(path2)) {
+ if (!bf::exists(path1) || bf::exists(path2)) {
return false;
}
bs::error_code error;
%post
mkdir -p /opt/etc/skel/.dotnet
chsmack -t -a User::App::Shared /opt/etc/skel/.dotnet
-%{_bindir}/nitool --dll %{_runtime_dir}/System.Private.CoreLib.dll
chsmack -a _ %{_system_base_addr_file}
+%{_bindir}/dotnettool --ni-dll %{_runtime_dir}/System.Private.CoreLib.dll
%files
%manifest dotnet-launcher.manifest
%{_native_lib_dir}/libsqlite3.so
%{_bindir}/nitool
%{_bindir}/tpatool
-%{_bindir}/tactool
+%{_bindir}/dotnettool
%{_install_mdplugin_dir}/libprefer_nuget_cache_plugin.so
%{_install_mdplugin_dir}/libprefer_dotnet_aot_plugin.so
%{_bindir}/dotnet-launcher
%manifest dotnet-launcher.manifest
%defattr(-,root,root,-)
%{_includedir}/ni_common.h
+%{_includedir}/tac_common.h
%{_includedir}/dotnet_launcher_plugin.h
%{_includedir}/coreclr_host.h
%{_libdir}/libdotnet_launcher_util.so