X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Futil%2Futils.cc;h=3d5a5f6cde17aac9ad316b3b14895477fbf81c5b;hb=42e47e57b40b9e5365a97b9eea194ab63bb7a031;hp=75dbcec72c130bd79e9606e8662242174e2ebec4;hpb=85937f2de4f6650255b4d42c7b13499caaa152ec;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc old mode 100755 new mode 100644 index 75dbcec..3d5a5f6 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -14,12 +14,16 @@ * limitations under the License. */ - #include +#include #include #include #include #include +#include +#include +#include +#include #include #include @@ -27,317 +31,660 @@ #include #include #include +#include #include +#include +#include "log.h" #include "utils.h" +#include "path_manager.h" -bool ICompare(const std::string& a, const std::string& b) +static bool iCompare(const std::string& a, int aOffset, const std::string& b, int bOffset, int length) { - return a.length() == b.length() && - std::equal(b.begin(), b.end(), a.begin(), - [](unsigned char a, unsigned char b) - { return std::tolower(a) == std::tolower(b); }); + return static_cast(a.length()) - length >= aOffset && + static_cast(b.length()) - length >= bOffset && + std::equal(b.begin() + bOffset, b.begin() + bOffset + length, a.begin() + aOffset, + [](unsigned char a, unsigned char b) + { return std::tolower(a) == std::tolower(b); }); } -bool ICompare(const std::string& a, int a_offset, const std::string& b, int b_offset, int length) +bool isManagedAssembly(const std::string& fileName) { - return static_cast(a.length()) - length >= a_offset && - static_cast(b.length()) - length >= b_offset && - std::equal(b.begin() + b_offset, b.begin() + b_offset + length, a.begin() + a_offset, - [](unsigned char a, unsigned char b) - { return std::tolower(a) == std::tolower(b); }); + return (iCompare(fileName, fileName.size()-4, ".dll", 0, 4) || + iCompare(fileName, fileName.size()-4, ".exe", 0, 4)) && + !isNativeImage(fileName); } -bool IsManagedAssembly(const std::string& filename) +bool isNativeImage(const std::string& fileName) { - return ICompare(filename, filename.size()-4, ".dll", 0, 4) || - ICompare(filename, filename.size()-4, ".exe", 0, 4); + return iCompare(fileName, fileName.size()-7, ".ni", 0, 3); } -bool IsNativeImage(const std::string& filename) +bool cmdOptionExists(char** begin, char** end, const std::string& option) { - return ICompare(filename, filename.size()-7, ".ni", 0, 3); + return std::find(begin, end, option) != end; } -std::string ReadSelfPath() +std::string readSelfPath() { - char buff[PATH_MAX]; - ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1); - if (len != -1) { - buff[len] = '\0'; - return std::string(buff); - } - - return ""; + char buff[PATH_MAX]; + ssize_t len = ::readlink("/proc/self/exe", buff, sizeof(buff)-1); + if (len != -1) { + buff[len] = '\0'; + return std::string(buff); + } + + return ""; } -std::string ConcatPath(const std::string& path1, const std::string& path2) +std::string concatPath(const std::string& path1, const std::string& path2) { - std::string path(path1); - if (path.back() == PATH_SEPARATOR) - { - path.append(path2); - } - else - { - path += PATH_SEPARATOR; - path.append(path2); - } - - return path; + std::string path(path1); + if (path.back() == PATH_SEPARATOR) { + path.append(path2); + } else { + path += PATH_SEPARATOR; + path.append(path2); + } + + return path; } -void AppendPath(std::string& path1, const std::string& path2) +void splitPath(const std::string& path, std::vector& out) { - if (path1.back() == PATH_SEPARATOR) - { - path1.append(path2); - } - else - { - path1 += PATH_SEPARATOR; - path1.append(path2); - } + std::istringstream ss(path); + std::string token; + + while (std::getline(ss, token, ':')) { + out.push_back(token); + } } -std::string AbsolutePath(const std::string& path) +std::string absolutePath(const std::string& path) { - std::string absPath; + std::string absPath; + char realPath[PATH_MAX]; + if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0') + absPath.assign(realPath); - char realPath[PATH_MAX]; - if (realpath(path.c_str(), realPath) != nullptr && realPath[0] != '\0') - { - absPath.assign(realPath); - } + return absPath; +} - return absPath; +int getRootPath(std::string pkgId, std::string& rootPath) +{ + int ret = 0; + char *path = 0; + uid_t uid = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + pkgmgrinfo_pkginfo_h handle; + if (uid == 0) { + ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); + if (ret != PMINFO_R_OK) { + return -1; + } + } else { + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle); + if (ret != PMINFO_R_OK) { + return -1; + } + } + + ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return -1; + } + rootPath = path; + pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + return 0; } -std::string Basename(const std::string& path) +int getExecName(std::string pkgId, std::string& execName) { - auto pos = path.find_last_of(PATH_SEPARATOR); - if (pos != std::string::npos) - { - return path.substr(0, pos); - } - else - { - return std::string("."); - } - return path; + 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; } -bool EndWithIgnoreCase(const std::string& str1, const std::string& str2, std::string& filename) +int getMetadataValue(std::string pkgId, std::string metadataKey, std::string& metadataValue) { - std::string::size_type len1 = str1.length(); - std::string::size_type len2 = str2.length(); - if (len2 > len1) return false; - - int i = 0; - bool result = std::all_of(str1.cend() - len2, str1.end(), - [&i, &str2] (char x) { - return std::tolower(x) == std::tolower(str2[i++]); - }); - if (result) - { - filename = str1.substr(0, len1 - len2); - } - return result; + 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; } -bool FileNotExist(const std::string& path) +std::string baseName(const std::string& path) { - struct stat sb; - return stat(path.c_str(), &sb) != 0; + auto pos = path.find_last_of(PATH_SEPARATOR); + if (pos != std::string::npos) + return path.substr(0, pos); + else + return std::string("."); + return path; } -static bool ExtCheckAndGetFileNameIfExist(const std::string& dir, const std::string& ext, struct dirent* entry, std::string& filename) +std::string replaceAll(const std::string &str, const std::string &pattern, const std::string &replace) { - std::string fname(entry->d_name); - if (fname.length() < ext.length() || - fname.compare(fname.length() - ext.length(), ext.length(), ext) != 0) - { - return false; - } - std::string fullname = ConcatPath(dir, entry->d_name); - switch (entry->d_type) - { - case DT_REG: break; - case DT_LNK: - case DT_UNKNOWN: - if (FileNotExist(fullname)) - { - return false; - } - default: - return false; - } - - filename = fullname; - - return true; + std::string result = str; + std::string::size_type pos = 0; + std::string::size_type offset = 0; + + while ((pos = result.find(pattern, offset)) != std::string::npos) { + result.replace(result.begin() + pos, result.begin() + pos + pattern.size(), replace); + offset = pos + replace.size(); + } + + return result; } -std::string StripNIDLL(const std::string& path) +bool isFileExist(const std::string& path) { - std::string npath(path); - if (path.size() < 5) return npath; - if (!strncasecmp(path.c_str() + path.size() - 4, ".dll", 4)) - { - npath = path.substr(0, path.size()-4); - }else if (!strncasecmp(path.c_str() + path.size() - 4, ".exe", 4)) - { - npath = path.substr(0, path.size()-4); - } - if (!strncasecmp(npath.c_str() + npath.size() - 3, ".ni", 3)) - { - return npath.substr(0, npath.size()-3); - } - return npath; + struct stat sb; + return stat(path.c_str(), &sb) == 0; } -std::string JoinStrings(const std::vector& strings, const char* const delimeter) +uintptr_t getFileSize(const std::string& path) { - switch (strings.size()) - { - case 0: - return ""; - case 1: - return strings[0]; - default: - std::ostringstream os; - std::copy(strings.begin(), strings.end()-1, std::ostream_iterator(os, delimeter)); - os << *strings.rbegin(); - return os.str(); - } + struct stat sb; + + if (stat(path.c_str(), &sb) == 0) { + return sb.st_size; + } + + return 0; } -struct AssemblyFile +std::string stripNiDLL(const std::string& path) { - std::string noext; - std::string ext; -}; + std::string niPath(path); + if (path.size() < 5) return niPath; + if (!strncasecmp(path.c_str() + path.size() - 4, ".dll", 4)) + niPath = path.substr(0, path.size()-4); + else if (!strncasecmp(path.c_str() + path.size() - 4, ".exe", 4)) + niPath = path.substr(0, path.size()-4); -bool operator == (const AssemblyFile& lhs, const AssemblyFile& rhs) + if (!strncasecmp(niPath.c_str() + niPath.size() - 3, ".ni", 3)) + return niPath.substr(0, niPath.size()-3); + + return niPath; +} + +void assembliesInDirectory(const std::vector& directories, std::string& tpaList) { - return lhs.noext == rhs.noext && lhs.ext == rhs.ext; + std::map assemblyList; + std::map tmpList; + + auto reader = [&assemblyList, &tmpList] (const std::string& path, const char* name) { + if (isManagedAssembly(path) || isNativeImage(path)) { + std::string dllName = stripNiDLL(name); + std::pair::iterator, bool> ret; + ret = tmpList.insert(std::pair(dllName, path)); + if (ret.second == false) { + if (isNativeImage(path)) + tmpList[dllName] = path; + } + } + }; + + for (auto directory : directories) { + scanFilesInDir(directory.c_str(), reader, 1); + // merge scaned dll list to tpa list. + // if the dll is already exist in the list, that is skipped. + assemblyList.insert(tmpList.begin(), tmpList.end()); + } + + std::map::iterator it; + for (it = assemblyList.begin(); it != assemblyList.end(); it++) + tpaList += it->second + ':'; + + if (tpaList.back() == ':') + tpaList.pop_back(); } -namespace std +void scanFilesInDir(const std::string& directory, FileReader reader, unsigned int depth) { - template<> - struct hash - { - std::size_t operator () (const AssemblyFile& f) const - { - const std::size_t h1 = std::hash{}(f.noext); - const std::size_t h2 = std::hash{}(f.ext); - - return h1 ^ (h2 << 1); - } - }; + DIR *dir; + struct dirent* entry; + bool isDir; + + if (strstr(directory.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) + return; + + dir = opendir(directory.c_str()); + + if (dir == nullptr) + return; + + std::vector innerDirectories; + + while ((entry = readdir(dir)) != nullptr) { + isDir = false; + std::string path = concatPath(directory, entry->d_name); + switch (entry->d_type) { + case DT_REG: break; + case DT_DIR: + isDir = true; + break; + case DT_LNK: + case DT_UNKNOWN: + struct stat sb; + if (stat(path.c_str(), &sb) == -1) + continue; + + if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode)) + break; + default: + continue; + } + if (!isDir) + reader(path, entry->d_name); + else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) + innerDirectories.push_back(path); + } + + if (depth != 0) + for (auto& d : innerDirectories) + scanFilesInDir(d.c_str(), reader, depth - 1); + + closedir(dir); } -void AssembliesInDirectory(const std::vector& directories, std::string& tpaList) +void updateAssemblyInfo(const std::string& getPath, const std::string& setPath, bool isSymlink) { - std::map assemblyList; - std::map tmpList; - - auto reader = [&assemblyList, &tmpList] (const char* path, const char* name) - { - std::string _path(path); - if (IsManagedAssembly(_path)) - { - std::string dll_name = StripNIDLL(name); - std::pair::iterator, bool> ret; - ret = tmpList.insert(std::pair(dll_name, _path)); - if (ret.second == false) - { - if (IsNativeImage(_path)) - { - tmpList[dll_name] = _path; - } - } - } - }; - - for (auto directory : directories) - { - ScanFilesInDir(directory.c_str(), reader, 1); - // merge scaned dll list to tpa list. - // if the dll is already exist in the list, that is skipped. - assemblyList.insert(tmpList.begin(), tmpList.end()); - } - - std::map::iterator it; - for (it = assemblyList.begin(); it != assemblyList.end(); it++) - { - tpaList += it->second + ':'; - } - if (tpaList.back() == ':') - { - tpaList.pop_back(); - } + char* label = NULL; + struct stat info; + + 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); + } + + // 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"); + } + } +} + +static bool setOwnership(const bf::path& path, uid_t uid, gid_t gid) { + int fd = open(path.c_str(), O_RDONLY); + if (fd < 0) { + _ERR("Can't open directory: %s", path.c_str()); + return false; + } + int ret = fchown(fd, uid, gid); + close(fd); + if (ret != 0) { + _ERR("Failed to change owner of: %s", path.c_str()); + return false; + } + return true; +} + +static bool setDirPermissions(const bf::path& path, bf::perms permissions) { + bs::error_code error; + bf::permissions(path, permissions, error); + if (error) { + _ERR("Failed to set permissions for directory: %s, %s", path.c_str(), error.message().c_str()); + return false; + } + return true; +} + +static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permissions, uid_t uid, gid_t gid) { + if (!setOwnership(path, uid, gid)) { + _ERR("Failed to change owner: %s, (uid: %d, gid: %d)", path.c_str(), uid, gid); + return false; + } + if (!setDirPermissions(path, permissions)) { + _ERR("Failed to change permission: %s, (%d)", path.c_str(), permissions); + return false; + } + return true; +} + +static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) { + if (!bf::exists(path)) { + _ERR("Failed to copy ownership and permissions from %s to %s", path.c_str(), path2.c_str()); + return false; + } + bf::perms permissions = bf::status(path).permissions(); + struct stat stats; + if (stat(path.c_str(), &stats) != 0) { + return false; + } + if (!setDirOwnershipAndPermissions(path2, permissions, stats.st_uid, stats.st_gid)) { + _ERR("Failed to copy ownership and permissions from %s to %s", path.c_str(), path2.c_str()); + return false; + } + return true; +} + +bool createDir(const bf::path& path) { + if (bf::exists(path)) { + return true; + } + bs::error_code error; + bf::create_directories(path, error); + if (error) { + _ERR("Failed to create directory: %s", error.message().c_str()); + return false; + } + return true; +} + +bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { + try { + // Check whether the function call is valid + if (!bf::exists(path1) || !bf::is_directory(path1)) { + _ERR("Source directory %s does not exist or is not a directory", path1.c_str()); + return false; + } + if (!bf::exists(path2)) { + // Create the destination directory + if (!createDir(path2)) { + _ERR("Unable to create destination directory %s", path2.c_str()); + return false; + } + if (flags & FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS) { + copyOwnershipAndPermissions(path1, path2); + } + } else { + if (!(flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE))) { + _ERR("Destination directory %s already exists", path2.c_str()); + return false; + } + if (flags & (FS_MERGE_OVERWRITE | FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS)) { + copyOwnershipAndPermissions(path1, path2); + } + } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to copy directory: %s", error.what()); + return false; + } + + // Iterate through the source directory + for (bf::directory_iterator file(path1); file != bf::directory_iterator(); ++file) { + try { + bf::path current(file->path()); + bf::path target = path2 / current.filename(); + if (bf::is_symlink(symlink_status(current))) { + if ((flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE)) && bf::exists(target)) { + continue; + } + bs::error_code error; + bf::copy_symlink(current, target, error); + if (error) { + _ERR("Failed to copy symlink: %s, %s", current.c_str(), error.message().c_str()); + return false; + } + } else if (bf::is_directory(current)) { + // Found directory: Recursion + if (!copyDir(current, target, flags)) { + return false; + } + } else { + if ((flags & FS_MERGE_SKIP) && bf::exists(target)) { + continue; + } + bf::path destination = target; + if (flags & FS_COMMIT_COPY_FILE) { + destination = bf::unique_path(target.parent_path() / "%%%%-%%%%-%%%%-%%%%"); + } + if (flags & FS_MERGE_OVERWRITE) { + bf::copy_file(current, destination, bf::copy_option::overwrite_if_exists); + } else { + bf::copy_file(current, destination); + } + if (flags & FS_PRESERVE_OWNERSHIP_AND_PERMISSIONS) { + copyOwnershipAndPermissions(current, destination); + } + if (flags & FS_COMMIT_COPY_FILE) { + if (flags & FS_MERGE_OVERWRITE) { + bf::remove(target); + } + bf::rename(destination, target); + } + } + } catch (const bf::filesystem_error& error) { + _ERR("Failed to copy directory: %s", error.what()); + return false; + } + } + return true; +} + +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()); + return false; + } + return true; +} + +bool moveFile(const bf::path& path1, const bf::path& path2) { + if (!bf::exists(path1) || bf::exists(path2)) { + return false; + } + bs::error_code error; + bf::rename(path1, path2, error); + if (error) { + _ERR("Cannot move file: %s. Will copy/remove... with error [%s]", path1.c_str(), error.message().c_str()); + bf::copy_file(path1, path2, bf::copy_option::overwrite_if_exists, error); + if (error) { + _ERR("Cannot copy file %s due to error [%s]", path1.c_str(), error.message().c_str()); + return false; + } + bf::remove_all(path1, error); + if (error) { + _ERR("Cannot remove old file when coping: %s with error [%s]", path1.c_str(), error.message().c_str()); + return false; + } + } + return true; +} + +bool removeFile(const bf::path& path) { + if (!bf::exists(path)) { + return true; + } + bs::error_code error; + bf::remove(path, error); + if (error) { + _ERR("Cannot remove: %s, %s", path.c_str(), error.message().c_str()); + return false; + } + return true; +} + +bool removeAll(const bf::path& path) { + if (!exists(path)) { + return true; + } + bs::error_code error; + bf::remove_all(path, error); + if (error) { + _ERR("Cannot remove: %s, %s", path.c_str(), error.message().c_str()); + return false; + } + return true; } -void ScanFilesInDir(const char* directory, FileReader reader, unsigned int depth) +//Parser the .deps.json file to get nuget information. +std::vector depsJsonParser(std::string rootPath, std::string execName, std::string tpaList) { - DIR *dir; - struct dirent* entry; - bool isDir; - - dir = opendir(directory); - - if (dir == nullptr) - { - //_ERR("Can not open directory : %s", directory); - return; - } - - std::vector innerDirectories; - - while ((entry = readdir(dir)) != nullptr) - { - isDir = false; - std::string path = ConcatPath(directory, entry->d_name); - switch (entry->d_type) - { - case DT_REG: break; - case DT_DIR: - isDir = true; - break; - case DT_LNK: - case DT_UNKNOWN: - struct stat sb; - if (stat(path.c_str(), &sb) == -1) - { - continue; - } - - if (S_ISREG(sb.st_mode) || S_ISDIR(sb.st_mode)) - { - break; - } - default: - continue; - } - if (!isDir) - { - reader(path.c_str(), entry->d_name); - } - else if (depth > 1 && strcmp(entry->d_name, ".") && strcmp(entry->d_name, "..")) - { - innerDirectories.push_back(path); - } - } - - if (depth != 0) - { - for (auto& d : innerDirectories) - { - ScanFilesInDir(d.c_str(), reader, depth-1); - } - } - - closedir(dir); + std::vector tpaAssemblies; + splitPath(tpaList, tpaAssemblies); + + std::vector parserData; + std::string depsJsonName = execName.substr(0, execName.rfind(".dll")) + ".deps.json"; + std::string depsJsonPath = concatPath(rootPath, depsJsonName); + if (bf::exists(depsJsonPath)) { + std::ifstream ifs(depsJsonPath); + Json::CharReaderBuilder reader; + Json::Value root; + std::string error; + if (ifs.is_open()) { + if (!Json::parseFromStream(reader, ifs, &root, &error)) { + _ERR("Failed to parse of deps.json"); + ifs.close(); + tpaAssemblies.clear(); + return parserData; + } + const Json::Value runtimeTargetName = root["runtimeTarget"]["name"]; + const Json::Value nugetPackages = root["targets"][runtimeTargetName.asString().c_str()]; + std::vector appDependencies; + for (auto& nuget : nugetPackages.getMemberNames()) { + if (strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) != NULL || + strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) != NULL) { + const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"]; + if (assemblies != Json::nullValue) { + const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"]; + for (auto& dependency : dependencies.getMemberNames()) { + appDependencies.push_back(dependency); + } + } + } + } + for (auto& nuget : nugetPackages.getMemberNames()) { + //Skip the nuget package related to Tizen + if (strstr(nuget.c_str(), TIZEN_DOTNET_NUGET) == NULL && + strstr(nuget.c_str(), TIZEN_DOTNET_SDK_NUGET) == NULL && + strstr(nuget.c_str(), (execName.substr(0, execName.find(".Tizen."))).c_str()) == NULL && + strstr(nuget.c_str(), (execName.substr(0, execName.find(".dll"))).c_str()) == NULL) { + const Json::Value assemblies = nugetPackages[nuget.c_str()]["runtime"]; + if (assemblies != Json::nullValue) { + const Json::Value dependencies = nugetPackages[nuget.c_str()]["dependencies"]; + bool hasDependency = false; + for (auto& dependency : dependencies.getMemberNames()) { + //Skip the nugget package that is dependent on another nuget package + if (strstr(dependency.c_str(), TIZEN_DOTNET_NUGET) == NULL && + strstr(dependency.c_str(), NET_STANDARD_LIBRARY_NUGET) == NULL) { + hasDependency = true; + for (auto& ad : appDependencies) { + if (!strcmp(ad.c_str(), dependency.c_str())) { + hasDependency = true; + break; + } else { + hasDependency = false; + } + } + } + } + if (!hasDependency) { + bool isExistTpaAssembly = false; + for (auto& assembly : assemblies.getMemberNames()) { + std::string assemblyName = assembly.substr(assembly.rfind('/') + 1); + //Skip the assembly present in the TPA list + for (auto& tpa : tpaAssemblies) { + if (!strcmp(replaceAll(tpa, ".ni.dll", ".dll").c_str(), assembly.c_str())) { + isExistTpaAssembly = true; + break; + } + } + if (isExistTpaAssembly) break; + } + if (!isExistTpaAssembly) { + for (auto& assembly : assemblies.getMemberNames()) { + std::string assemblyName = assembly.substr(assembly.rfind('/') + 1); + parserData.push_back(nuget + ":" + assemblyName); + _INFO("Nuget : [%s] / Assembly : [%s]", nuget.c_str(), assemblyName.c_str()); + } + } + } + } + } + } + appDependencies.clear(); + ifs.close(); + } + } + tpaAssemblies.clear(); + return parserData; } \ No newline at end of file