X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=NativeLauncher%2Futil%2Futils.cc;h=9f34fb4e922d0e663952cc3f190adbffbe8a5f1e;hb=9ab4547491e1bc0ba0564581a9390ed63b09348e;hp=f399b2c2022e1b6fd5174fa66896d678673579d0;hpb=5373d256e77414acb8872443f536002215bf674a;p=platform%2Fcore%2Fdotnet%2Flauncher.git diff --git a/NativeLauncher/util/utils.cc b/NativeLauncher/util/utils.cc index f399b2c..9f34fb4 100644 --- a/NativeLauncher/util/utils.cc +++ b/NativeLauncher/util/utils.cc @@ -20,11 +20,15 @@ #include #include #include -#include #include #include #include +#include +#include + +#include + #include #include #include @@ -34,6 +38,7 @@ #include #include #include +#include #include "log.h" #include "utils.h" @@ -50,9 +55,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) @@ -60,23 +63,6 @@ bool isNativeImage(const std::string& fileName) return iCompare(fileName, fileName.size()-7, ".ni", 0, 3); } -bool cmdOptionExists(char** begin, char** end, const std::string& option) -{ - return std::find(begin, end, option) != end; -} - -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 ""; -} - std::string concatPath(const std::string& path1, const std::string& path2) { std::string path(path1); @@ -112,109 +98,173 @@ std::string getAbsolutePath(const std::string& path) return absPath; } -int getRootPath(const std::string& pkgId, std::string& rootPath) +std::string getRootPath(const std::string& pkgId) { 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; - } + std::string rootPath; - 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; - } + pkgmgrinfo_pkginfo_h pkg_handle; + ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { + 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); - return -1; + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return rootPath; } rootPath = path; - pkgmgrinfo_pkginfo_destroy_pkginfo(handle); - return 0; + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + + return rootPath; } -int getExecName(const std::string& pkgId, std::string& execName) +std::string getExecName(const std::string& pkgId) { char *exec = NULL; char *appId = 0; + std::string execName; pkgmgrinfo_pkginfo_h pkg_handle; - int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle); - if (ret != PMINFO_R_OK) { - return -1; + 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); - return -1; + return execName; } 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 -1; + return execName; } + 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; + return execName; } execName = std::string(exec).substr(std::string(exec).rfind('/') + 1); pkgmgrinfo_appinfo_destroy_appinfo(app_handle); pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); - return 0; + + return execName; } -int getMetadataValue(const std::string& pkgId, const std::string& metadataKey, std::string& metadataValue) +std::string getAppType(const std::string& pkgId) { - char *value = NULL; char *appId = 0; + char *type = 0; + std::string appType; pkgmgrinfo_pkginfo_h pkg_handle; - int ret = pkgmgrinfo_pkginfo_get_pkginfo(pkgId.c_str(), &pkg_handle); - if (ret != PMINFO_R_OK) { - return -1; + 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); - return -1; + return appType; } pkgmgrinfo_appinfo_h app_handle; - ret = pkgmgrinfo_appinfo_get_appinfo(appId, &app_handle); + 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); pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); - return -1; + return appType; + } + appType = type; + + pkgmgrinfo_appinfo_destroy_appinfo(app_handle); + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + + return appType; +} + +std::string getMetadataValue(const std::string& pkgId, const std::string& key) +{ + char *value = NULL; + char *appId = 0; + std::string metadataValue; + + pkgmgrinfo_pkginfo_h pkg_handle; + int ret = pkgmgrGetPkgInfo(pkgId, &pkg_handle); + if (ret != 0) { + return metadataValue; } - ret = pkgmgrinfo_appinfo_get_metadata_value(app_handle, metadataKey.c_str(), &value); + + ret = pkgmgrinfo_pkginfo_get_mainappid(pkg_handle, &appId); + if (ret != PMINFO_R_OK) { + pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); + return metadataValue; + } + + pkgmgrinfo_appinfo_h app_handle; + 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); pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); - //Does not return error because the metadata key may not exist. - return 0; + return metadataValue; } metadataValue = std::string(value); pkgmgrinfo_appinfo_destroy_appinfo(app_handle); pkgmgrinfo_pkginfo_destroy_pkginfo(pkg_handle); - return 0; + + 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) @@ -241,33 +291,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 stat(path.c_str(), &sb) == 0; + 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) { - return false; - } else if (sb.st_mode & S_IFDIR) { - return true; - } else { + if (lstat(path.c_str(), &sb) != 0) { return false; } + return (sb.st_mode & S_IFMT) == S_IFLNK; } -uintptr_t getFileSize(const std::string& path) +bool isDirectory(const std::string& path) { struct stat sb; - - if (stat(path.c_str(), &sb) == 0) { - return sb.st_size; + if (stat(path.c_str(), &sb) != 0) { + return false; } - - return 0; + return (sb.st_mode & S_IFMT) == S_IFDIR; } std::string getAssemblyNameFromPath(const std::string& path) @@ -284,7 +334,8 @@ std::string getAssemblyNameFromPath(const std::string& path) return ret; } -void addAssembliesFromDirectories(const std::vector& directories, std::string& list) { +void addAssembliesFromDirectories(const std::vector& directories, std::string& list) +{ std::vector assems; std::unordered_map assemPaths; @@ -323,9 +374,6 @@ void scanFilesInDirectory(const std::string& directory, FileReader reader, unsig struct dirent* entry; bool isDir; - if (strstr(directory.c_str(), TAC_SYMLINK_SUB_DIR) != NULL) - return; - dir = opendir(directory.c_str()); if (dir == nullptr) @@ -341,14 +389,12 @@ void scanFilesInDirectory(const std::string& directory, FileReader reader, unsig case DT_DIR: isDir = true; break; + // symlink is added to the list even if there is no original file. + // It used to remove broken symlinks related to TAC case DT_LNK: + break; 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; + continue; default: continue; } @@ -374,34 +420,38 @@ 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"); } } } -static bool setOwnership(const bf::path& path, uid_t uid, gid_t gid) { +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()); @@ -416,7 +466,8 @@ static bool setOwnership(const bf::path& path, uid_t uid, gid_t gid) { return true; } -static bool setDirPermissions(const bf::path& path, bf::perms permissions) { +static bool setDirPermissions(const bf::path& path, bf::perms permissions) +{ bs::error_code error; bf::permissions(path, permissions, error); if (error) { @@ -426,7 +477,8 @@ static bool setDirPermissions(const bf::path& path, bf::perms permissions) { return true; } -static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permissions, uid_t uid, gid_t gid) { +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; @@ -438,12 +490,18 @@ static bool setDirOwnershipAndPermissions(const bf::path& path, bf::perms permis return true; } -static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) { - if (!bf::exists(path)) { +static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& path2) +{ + 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; @@ -455,8 +513,21 @@ static bool copyOwnershipAndPermissions(const bf::path& path, const bf::path& pa return true; } -bool createDir(const bf::path& path) { - if (bf::exists(path)) { +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 (exist(path)) { return true; } bs::error_code error; @@ -468,14 +539,15 @@ bool createDir(const bf::path& path) { return true; } -bool copyDir(const bf::path& path1, const bf::path& path2, FSFlag flags) { +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()); @@ -499,12 +571,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; @@ -519,7 +591,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; @@ -541,17 +613,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) { +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); @@ -562,8 +636,9 @@ bool copyFile(const bf::path& path1, const bf::path& path2) { return true; } -bool moveFile(const bf::path& path1, const bf::path& path2) { - if (!bf::exists(path1) || bf::exists(path2)) { +bool moveFile(const bf::path& path1, const bf::path& path2) +{ + if (!exist(path1) || exist(path2)) { return false; } bs::error_code error; @@ -584,8 +659,9 @@ bool moveFile(const bf::path& path1, const bf::path& path2) { return true; } -bool removeFile(const bf::path& path) { - if (!bf::exists(path)) { +bool removeFile(const bf::path& path) +{ + if (!exist(path)) { return true; } bs::error_code error; @@ -597,8 +673,9 @@ bool removeFile(const bf::path& path) { return true; } -bool removeAll(const bf::path& path) { - if (!exists(path)) { +bool removeAll(const bf::path& path) +{ + if (!exist(path)) { return true; } bs::error_code error; @@ -630,3 +707,182 @@ 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) +{ + int bytesRead = 0; + const int bufSize = 32768; + + unsigned int digest_len = 0; + unsigned char* digest = NULL; + + std::stringstream ss; + EVP_MD_CTX *mdctx = NULL; + std::string output = ""; + + FILE *file = fopen(path.c_str(), "rb"); + if (!file) { + return output; + } + + char *buffer = (char*)malloc(bufSize); + if (!buffer) { + goto cleanup4; + } + + mdctx = EVP_MD_CTX_new(); + if (mdctx == NULL) { + _ERR("Message Digest Context creation NULL"); + goto cleanup3; + } + + digest = (unsigned char*)OPENSSL_malloc(EVP_MD_size(EVP_sha256())); + if (!digest) { + _ERR("Memory Allocation for SHA256 failed"); + goto cleanup2; + } + + if (!EVP_DigestInit_ex(mdctx, EVP_sha256(), NULL)) { + _ERR("Message Digest init failed"); + goto cleanup1; + } + + while ((bytesRead = fread(buffer, 1, bufSize, file))) { + if (!EVP_DigestUpdate(mdctx, buffer, bytesRead)) { + _ERR("Message Digest update failed"); + goto cleanup1; + } + } + + if (!EVP_DigestFinal_ex(mdctx, digest, &digest_len)) { + _ERR("Message Digest Finalization falied"); + goto cleanup1; + } + + for (unsigned int i = 0; i < digest_len; i++) { + ss << std::hex << std::setw(2) << std::setfill('0') << (int)digest[i]; + } + output = ss.str(); + +cleanup1: + EVP_MD_CTX_free(mdctx); +cleanup2: + OPENSSL_free(digest); +cleanup3: + free(buffer); +cleanup4: + fclose(file); + + 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; +}