X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Futil%2Futils.cc;h=963cb7f4f4747c806f9d9f25338194bf9e46791e;hb=refs%2Ftags%2Faccepted%2Ftizen%2Funified%2F20221014.123806;hp=90fd0e432a0227703dd89081a641c0fc4fd37b10;hpb=de48021671279d8040bd8baee38bd722db67b800;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index 90fd0e4..963cb7f 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -20,10 +20,11 @@ #include #include #include -#include #include #include #include +#include +#include #include #include @@ -34,6 +35,7 @@ #include #include #include +#include #include "log.h" #include "utils.h" @@ -50,9 +52,7 @@ static bool iCompare(const std::string& a, int aOffset, const std::string& b, in bool isManagedAssembly(const std::string& fileName) { - return (iCompare(fileName, fileName.size()-4, ".dll", 0, 4) || - iCompare(fileName, fileName.size()-4, ".exe", 0, 4)) && - !isNativeImage(fileName); + return iCompare(fileName, fileName.size()-4, ".dll", 0, 4) && !isNativeImage(fileName); } bool isNativeImage(const std::string& fileName) @@ -99,34 +99,21 @@ std::string getRootPath(const std::string& pkgId) { int ret = 0; char *path = 0; - uid_t uid = 0; std::string rootPath; - if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { - _ERR("Failed to get UID"); + pkgmgrinfo_pkginfo_h pkg_handle; + ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { return rootPath; } - pkgmgrinfo_pkginfo_h handle; - if (uid == 0) { - ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &handle); - if (ret != PMINFO_R_OK) { - return rootPath; - } - } else { - ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, &handle); - if (ret != PMINFO_R_OK) { - return rootPath; - } - } - - ret = pkgmgrinfo_pkginfo_get_root_path(handle, &path); + ret = pkgmgrinfo_pkginfo_get_root_path(pkg_handle, &path); if (ret != PMINFO_R_OK) { - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); return rootPath; } rootPath = path; - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); return rootPath; } @@ -138,10 +125,11 @@ std::string getExecName(const std::string& pkgId) std::string execName; pkgmgrinfo_pkginfo_h pkg_handle; - int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle); - if (ret != PMINFO_R_OK) { + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { return execName; } + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); if (ret != PMINFO_R_OK) { pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); @@ -149,11 +137,12 @@ std::string getExecName(const std::string& pkgId) } pkgmgrinfo_appinfo_h app_handle; - ret = pkgmgrinfo_appinfo_get_appinfo(appId, &app_handle); - if (ret != PMINFO_R_OK) { + ret = pkgmgrGetAppInfo(appId, &app_handle); + if (ret != 0) { pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); return execName; } + ret = pkgmgrinfo_appinfo_get_exec(app_handle, &exec); if (ret != PMINFO_R_OK) { pkgmgrinfo_appinfo_destroy_appinfo(app_handle); @@ -175,10 +164,11 @@ std::string getAppType(const std::string& pkgId) std::string appType; pkgmgrinfo_pkginfo_h pkg_handle; - int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle); - if (ret != PMINFO_R_OK) { + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { return appType; } + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); if (ret != PMINFO_R_OK) { pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); @@ -186,11 +176,12 @@ std::string getAppType(const std::string& pkgId) } pkgmgrinfo_appinfo_h app_handle; - ret = pkgmgrinfo_appinfo_get_appinfo(appId, &app_handle); - if (ret != PMINFO_R_OK) { + ret = pkgmgrGetAppInfo(appId, &app_handle); + if (ret != 0) { pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); return appType; } + ret = pkgmgrinfo_appinfo_get_apptype(app_handle, &type); if (ret != PMINFO_R_OK) { pkgmgrinfo_appinfo_destroy_appinfo(app_handle); @@ -212,10 +203,11 @@ std::string getMetadataValue(const std::string& pkgId, const std::string& key) std::string metadataValue; pkgmgrinfo_pkginfo_h pkg_handle; - int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle); - if (ret != PMINFO_R_OK) { + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { return metadataValue; } + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); if (ret != PMINFO_R_OK) { pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); @@ -223,11 +215,12 @@ std::string getMetadataValue(const std::string& pkgId, const std::string& key) } pkgmgrinfo_appinfo_h app_handle; - ret = pkgmgrinfo_appinfo_get_appinfo(appId, &app_handle); - if (ret != PMINFO_R_OK) { + ret = pkgmgrGetAppInfo(appId, &app_handle); + if (ret != 0) { pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); return metadataValue; } + ret = pkgmgrinfo_appinfo_get_metadata_value(app_handle, key.c_str(), &value); if (ret != PMINFO_R_OK) { pkgmgrinfo_appinfo_destroy_appinfo(app_handle); @@ -242,6 +235,35 @@ std::string getMetadataValue(const std::string& pkgId, const std::string& key) return metadataValue; } +bool isReadOnlyArea(const std::string& path) +{ + FILE *f = NULL; + struct mntent *m = NULL; + + // "/opt/usr" is mounted to "RW" only + if (path.find("/opt/usr") != std::string::npos) { + return false; + } + + // check whether "/" is mounted to RO or not + f = setmntent("/proc/mounts", "r"); + if (!f) { + // return true for fail case to generate NI files under RW area. + return true; + } + + while((m = getmntent(f))) { + if (m->mnt_dir != NULL && strcmp(m->mnt_dir, "/") == 0 && + m->mnt_opts != NULL && strstr(m->mnt_opts, "ro,") != NULL) { + endmntent(f); + return true; + } + } + endmntent(f); + return false; + +} + std::string getBaseName(const std::string& path) { auto pos = path.find_last_of(PATH_SEPARATOR); @@ -266,23 +288,33 @@ std::string replaceAll(const std::string& str, const std::string& pattern, const return result; } +std::string changeExtension(const std::string& path, const std::string& from, const std::string& to) +{ + return path.substr(0, path.rfind(from)) + to; +} + bool isFile(const std::string& path) { struct stat sb; return lstat(path.c_str(), &sb) == 0; } -bool isDirectory(const std::string& path) +bool isSymlinkFile(const std::string& path) { struct stat sb; - if (stat(path.c_str(), &sb) != 0) { + if (lstat(path.c_str(), &sb) != 0) { return false; } - if (sb.st_mode & S_IFDIR) { - return true; - } else { + return (sb.st_mode & S_IFMT) == S_IFLNK; +} + +bool isDirectory(const std::string& path) +{ + struct stat sb; + if (stat(path.c_str(), &sb) != 0) { return false; } + return (sb.st_mode & S_IFMT) == S_IFDIR; } std::string getAssemblyNameFromPath(const std::string& path) @@ -385,29 +417,32 @@ void copySmackAndOwnership(const std::string& fromPath, const std::string& toPat // change smack label for symbolic link. if (smack_lgetlabel(fromPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { if (smack_lsetlabel(toPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { - fprintf(stderr, "Fail to set smack label\n"); + _SERR("Fail to set smack label"); } free(label); } - // change owner and groups for symbolic link. - if (!stat(fromPath.c_str(), &info)) { + // change owner and groupsfor symbolic link. + // change mode is skipped for symlink because permission of symlink file is meaningless. + if (!lstat(fromPath.c_str(), &info)) { if (lchown(toPath.c_str(), info.st_uid, info.st_gid) == -1) - fprintf(stderr, "Failed to change owner and group name\n"); + _SERR("Failed to change owner and group name"); } } else { // change smack label if (smack_getlabel(fromPath.c_str(), &label, SMACK_LABEL_ACCESS) == 0) { if (smack_setlabel(toPath.c_str(), label, SMACK_LABEL_ACCESS) < 0) { - fprintf(stderr, "Fail to set smack label\n"); + _SERR("Fail to set smack label"); } free(label); } - // change owner and groups for generated ni file. + // change owner, groups and mode for generated ni file. if (!stat(fromPath.c_str(), &info)) { if (chown(toPath.c_str(), info.st_uid, info.st_gid) == -1) - fprintf(stderr, "Failed to change owner and group name\n"); + _SERR("Failed to change owner and group name"); + if (chmod(toPath.c_str(), info.st_mode) == -1) + _SERR("Failed to change mode"); } } } @@ -454,11 +489,16 @@ static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permis static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) { - if (!bf::exists(path)) { + if (!exist(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(); + bs::error_code error; + bf::perms permissions = bf::status(path, error).permissions(); + if (error) { + _ERR("Failed to copy ownership and permissions : %s", error.message().c_str()); + return false; + } struct stat stats; if (stat(path.c_str(), &stats) != 0) { return false; @@ -470,9 +510,21 @@ static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& pa return true; } +bool exist(const bf::path& path) +{ + bs::error_code error; + int ret = bf::exists(path, error); + if (error) { + if ((error.value() != bs::errc::success) && (error.value() != bs::errc::no_such_file_or_directory)) { + _ERR("Failed to check %s exists : %s", path.c_str(), error.message().c_str()); + } + } + return ret; +} + bool createDir(const bf::path& path) { - if (bf::exists(path)) { + if (exist(path)) { return true; } bs::error_code error; @@ -488,11 +540,11 @@ 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)) { + if (!exist(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)) { + if (!exist(path2)) { // Create the destination directory if (!createDir(path2)) { _ERR("Unable to create destination directory %s", path2.c_str()); @@ -516,12 +568,12 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) } // Iterate through the source directory - for (bf::directory_iterator file(path1); file != bf::directory_iterator(); ++file) { - try { + try { + for (bf::directory_iterator file(path1); file != bf::directory_iterator(); ++file) { 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)) { + if (bf::is_symlink(bf::symlink_status(current))) { + if ((flags & (FS_MERGE_SKIP | FS_MERGE_OVERWRITE)) && exist(target)) { continue; } bs::error_code error; @@ -536,7 +588,7 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) return false; } } else { - if ((flags & FS_MERGE_SKIP) && bf::exists(target)) { + if ((flags & FS_MERGE_SKIP) && exist(target)) { continue; } bf::path destination = target; @@ -558,18 +610,19 @@ bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) bf::rename(destination, target); } } - } catch (const bf::filesystem_error& error) { - _ERR("Failed to copy directory: %s", error.what()); - return false; } + } 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)) { + if (!exist(path1)) { return false; } bf::copy_file(path1, path2, bf::copy_option::overwrite_if_exists, error); @@ -582,7 +635,7 @@ bool copyFile(const bf::path& path1, const bf::path& path2) bool moveFile(const bf::path& path1, const bf::path& path2) { - if (!bf::exists(path1) || bf::exists(path2)) { + if (!exist(path1) || exist(path2)) { return false; } bs::error_code error; @@ -605,7 +658,7 @@ bool moveFile(const bf::path& path1, const bf::path& path2) bool removeFile(const bf::path& path) { - if (!bf::exists(path)) { + if (!exist(path)) { return true; } bs::error_code error; @@ -619,7 +672,7 @@ bool removeFile(const bf::path& path) bool removeAll(const bf::path& path) { - if (!exists(path)) { + if (!exist(path)) { return true; } bs::error_code error; @@ -651,3 +704,150 @@ std::string getFileName(const std::string& path) size_t index = ret.find_last_of(PATH_SEPARATOR); return index == std::string::npos ? ret : ret.substr(index + 1); } + +std::string SHA256(const std::string& path) +{ + std::string output = ""; + FILE *file = fopen(path.c_str(), "rb"); + if (!file) { + return output; + } + + unsigned char hash[SHA256_DIGEST_LENGTH]; + SHA256_CTX sha256; + SHA256_Init(&sha256); + int bytesRead = 0; + const int bufSize = 32768; + char *buffer = (char*)malloc(bufSize); + if (!buffer) { + fclose(file); + return output; + } + + while ((bytesRead = fread(buffer, 1, bufSize, file))) { + SHA256_Update(&sha256, buffer, bytesRead); + } + SHA256_Final(hash, &sha256); + + std::stringstream ss; + for (int i = 0; i < SHA256_DIGEST_LENGTH; i++) { + ss << std::hex << std::setw(2) << std::setfill('0') << (int)hash[i]; + } + output = ss.str(); + + fclose(file); + free(buffer); + + return output; +} + +int pkgmgrGetPkgInfo(const std::string& pkgId, pkgmgrinfo_pkginfo_h* handle) +{ + uid_t uid = 0; + int ret = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + ret = pkgmgrinfo_pkginfo_get_usr_pkginfo(pkgId.c_str(), uid, handle); + if (ret != PMINFO_R_OK) { + _ERR("Failed to get pkginfo (%d)", ret); + return -1; + } + + return 0; +} + +int pkgmgrGetAppInfo(const std::string& appId, pkgmgrinfo_appinfo_h* handle) +{ + uid_t uid = 0; + int ret = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + ret = pkgmgrinfo_appinfo_get_usr_appinfo(appId.c_str(), uid, handle); + if (ret != PMINFO_R_OK) { + _ERR("Failed to get appinfo (%d)", ret); + return -1; + } + + return 0; +} + +int pkgmgrMDFilterForeach(pkgmgrinfo_appinfo_metadata_filter_h handle, + pkgmgrinfo_app_list_cb app_cb, + void *user_data) +{ + uid_t uid = 0; + int ret = 0; + + if (pkgmgr_installer_info_get_target_uid(&uid) < 0) { + _ERR("Failed to get UID"); + return -1; + } + + + ret = pkgmgrinfo_appinfo_usr_metadata_filter_foreach(handle, app_cb, user_data, uid); + if (ret != PMINFO_R_OK) { + _ERR("Failed to execute the metadata filter query (%d)", ret); + return -1; + } + + return 0; +} + +void printHWClockLog(const char* format, ...) +{ + char buf[1024] = {0,}; + va_list ap; + + va_start(ap, format); + vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + + prctl(PR_TASK_PERF_USER_TRACE, buf, strlen(buf)); +} + +const char* getNCDBStartupHook() +{ + return "/home/owner/share/tmp/sdk_tools/netcoredbg/ncdbhook.dll"; +} + +bool isNCDBStartupHookProvided() +{ + char *env = nullptr; + env = getenv("DOTNET_STARTUP_HOOKS"); + if (env == nullptr) + return false; + + // Note, `DOTNET_STARTUP_HOOKS` env could provide list of dlls with ':' delimiter, + // for example: "/path1/name1.dll:/path2/name2.dll" + while (*env != '\0') + { + const char *ncdbCur = getNCDBStartupHook(); + while (*ncdbCur != '\0' && *env != '\0' && *env != ':') + { + if (*ncdbCur != *env) + break; + + ncdbCur++; + env++; + + if (*ncdbCur == '\0' && (*env == '\0' || *env == ':')) + return true; + } + while (*env != '\0' && *env != ':') + { + env++; + } + if (*env == ':') + env++; + } + + return false; +}