1600cc4afSopenharmony_ci/* 2600cc4afSopenharmony_ci * Copyright (c) 2021-2024 Huawei Device Co., Ltd. 3600cc4afSopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License"); 4600cc4afSopenharmony_ci * you may not use this file except in compliance with the License. 5600cc4afSopenharmony_ci * You may obtain a copy of the License at 6600cc4afSopenharmony_ci * 7600cc4afSopenharmony_ci * http://www.apache.org/licenses/LICENSE-2.0 8600cc4afSopenharmony_ci * 9600cc4afSopenharmony_ci * Unless required by applicable law or agreed to in writing, software 10600cc4afSopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS, 11600cc4afSopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12600cc4afSopenharmony_ci * See the License for the specific language governing permissions and 13600cc4afSopenharmony_ci * limitations under the License. 14600cc4afSopenharmony_ci */ 15600cc4afSopenharmony_ci 16600cc4afSopenharmony_ci#include "bundle_util.h" 17600cc4afSopenharmony_ci 18600cc4afSopenharmony_ci#include <cinttypes> 19600cc4afSopenharmony_ci#include <dirent.h> 20600cc4afSopenharmony_ci#include <fcntl.h> 21600cc4afSopenharmony_ci#include <fstream> 22600cc4afSopenharmony_ci#include <sstream> 23600cc4afSopenharmony_ci#include <sys/sendfile.h> 24600cc4afSopenharmony_ci#include <sys/statfs.h> 25600cc4afSopenharmony_ci 26600cc4afSopenharmony_ci#include "bundle_service_constants.h" 27600cc4afSopenharmony_ci#ifdef CONFIG_POLOCY_ENABLE 28600cc4afSopenharmony_ci#include "config_policy_utils.h" 29600cc4afSopenharmony_ci#endif 30600cc4afSopenharmony_ci#include "directory_ex.h" 31600cc4afSopenharmony_ci#include "hitrace_meter.h" 32600cc4afSopenharmony_ci#include "installd_client.h" 33600cc4afSopenharmony_ci#include "ipc_skeleton.h" 34600cc4afSopenharmony_ci#include "parameter.h" 35600cc4afSopenharmony_ci#include "string_ex.h" 36600cc4afSopenharmony_ci#ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED 37600cc4afSopenharmony_ci#include "type_descriptor.h" 38600cc4afSopenharmony_ci#include "utd_client.h" 39600cc4afSopenharmony_ci#endif 40600cc4afSopenharmony_ci 41600cc4afSopenharmony_cinamespace OHOS { 42600cc4afSopenharmony_cinamespace AppExecFwk { 43600cc4afSopenharmony_cinamespace { 44600cc4afSopenharmony_ciconst std::string::size_type EXPECT_SPLIT_SIZE = 2; 45600cc4afSopenharmony_ciconstexpr char UUID_SEPARATOR = '-'; 46600cc4afSopenharmony_ciconstexpr size_t ORIGIN_STRING_LENGTH = 32; 47600cc4afSopenharmony_ciconst std::vector<int32_t> SEPARATOR_POSITIONS { 8, 13, 18, 23}; 48600cc4afSopenharmony_ciconstexpr int64_t HALF_GB = 1024 * 1024 * 512; // 0.5GB 49600cc4afSopenharmony_ciconstexpr int8_t SPACE_NEED_DOUBLE = 2; 50600cc4afSopenharmony_ciconstexpr uint16_t UUID_LENGTH_MAX = 512; 51600cc4afSopenharmony_cistatic std::string g_deviceUdid; 52600cc4afSopenharmony_cistatic std::mutex g_mutex; 53600cc4afSopenharmony_ci// hmdfs and sharefs config 54600cc4afSopenharmony_ciconstexpr const char* BUNDLE_ID_FILE = "appid"; 55600cc4afSopenharmony_ci// single max hap size 56600cc4afSopenharmony_ciconstexpr int64_t ONE_GB = 1024 * 1024 * 1024; 57600cc4afSopenharmony_ciconstexpr int64_t MAX_HAP_SIZE = ONE_GB * 4; // 4GB 58600cc4afSopenharmony_ciconstexpr const char* ABC_FILE_PATH = "abc_files"; 59600cc4afSopenharmony_ciconstexpr const char* PGO_FILE_PATH = "pgo_files"; 60600cc4afSopenharmony_ci#ifdef CONFIG_POLOCY_ENABLE 61600cc4afSopenharmony_ciconst char* NO_DISABLING_CONFIG_PATH = "/etc/ability_runtime/resident_process_in_extreme_memory.json"; 62600cc4afSopenharmony_ci#endif 63600cc4afSopenharmony_ciconst char* NO_DISABLING_CONFIG_PATH_DEFAULT = 64600cc4afSopenharmony_ci "/system/etc/ability_runtime/resident_process_in_extreme_memory.json"; 65600cc4afSopenharmony_ciconst std::string EMPTY_STRING = ""; 66600cc4afSopenharmony_ciconstexpr int64_t DISK_REMAINING_SIZE_LIMIT = 1024 * 1024 * 10; // 10M 67600cc4afSopenharmony_ci} 68600cc4afSopenharmony_ci 69600cc4afSopenharmony_cistd::mutex BundleUtil::g_mutex; 70600cc4afSopenharmony_ci 71600cc4afSopenharmony_ciErrCode BundleUtil::CheckFilePath(const std::string &bundlePath, std::string &realPath) 72600cc4afSopenharmony_ci{ 73600cc4afSopenharmony_ci if (!CheckFileName(bundlePath)) { 74600cc4afSopenharmony_ci APP_LOGE("bundle file path invalid"); 75600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID; 76600cc4afSopenharmony_ci } 77600cc4afSopenharmony_ci if (!CheckFileType(bundlePath, ServiceConstants::INSTALL_FILE_SUFFIX) && 78600cc4afSopenharmony_ci !CheckFileType(bundlePath, ServiceConstants::HSP_FILE_SUFFIX) && 79600cc4afSopenharmony_ci !CheckFileType(bundlePath, ServiceConstants::QUICK_FIX_FILE_SUFFIX) && 80600cc4afSopenharmony_ci !CheckFileType(bundlePath, ServiceConstants::CODE_SIGNATURE_FILE_SUFFIX)) { 81600cc4afSopenharmony_ci APP_LOGE("file is not hap, hsp, hqf or sig"); 82600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_INVALID_HAP_NAME; 83600cc4afSopenharmony_ci } 84600cc4afSopenharmony_ci if (!PathToRealPath(bundlePath, realPath)) { 85600cc4afSopenharmony_ci APP_LOGE("file is not real path"); 86600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID; 87600cc4afSopenharmony_ci } 88600cc4afSopenharmony_ci if (access(realPath.c_str(), F_OK) != 0) { 89600cc4afSopenharmony_ci APP_LOGE("not access the bundle file path: %{public}s, errno:%{public}d", realPath.c_str(), errno); 90600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_INVALID_BUNDLE_FILE; 91600cc4afSopenharmony_ci } 92600cc4afSopenharmony_ci if (!CheckFileSize(realPath, MAX_HAP_SIZE)) { 93600cc4afSopenharmony_ci APP_LOGE("file size larger than max hap size Max size is: %{public}" PRId64, MAX_HAP_SIZE); 94600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_INVALID_HAP_SIZE; 95600cc4afSopenharmony_ci } 96600cc4afSopenharmony_ci return ERR_OK; 97600cc4afSopenharmony_ci} 98600cc4afSopenharmony_ci 99600cc4afSopenharmony_ciErrCode BundleUtil::CheckFilePath(const std::vector<std::string> &bundlePaths, std::vector<std::string> &realPaths) 100600cc4afSopenharmony_ci{ 101600cc4afSopenharmony_ci HITRACE_METER_NAME(HITRACE_TAG_APP, __PRETTY_FUNCTION__); 102600cc4afSopenharmony_ci // there are three cases for bundlePaths: 103600cc4afSopenharmony_ci // 1. one bundle direction in the bundlePaths, some hap files under this bundle direction. 104600cc4afSopenharmony_ci // 2. one hap direction in the bundlePaths. 105600cc4afSopenharmony_ci // 3. some hap file directions in the bundlePaths. 106600cc4afSopenharmony_ci APP_LOGD("check file path"); 107600cc4afSopenharmony_ci if (bundlePaths.empty()) { 108600cc4afSopenharmony_ci APP_LOGE("bundle file paths invalid"); 109600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID; 110600cc4afSopenharmony_ci } 111600cc4afSopenharmony_ci ErrCode ret = ERR_OK; 112600cc4afSopenharmony_ci 113600cc4afSopenharmony_ci if (bundlePaths.size() == 1) { 114600cc4afSopenharmony_ci struct stat s; 115600cc4afSopenharmony_ci std::string bundlePath = bundlePaths.front(); 116600cc4afSopenharmony_ci if (stat(bundlePath.c_str(), &s) == 0) { 117600cc4afSopenharmony_ci std::string realPath = ""; 118600cc4afSopenharmony_ci // it is a direction 119600cc4afSopenharmony_ci if ((s.st_mode & S_IFDIR) && !GetHapFilesFromBundlePath(bundlePath, realPaths)) { 120600cc4afSopenharmony_ci APP_LOGE("GetHapFilesFromBundlePath failed with bundlePath:%{public}s", bundlePaths.front().c_str()); 121600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID; 122600cc4afSopenharmony_ci } 123600cc4afSopenharmony_ci // it is a file 124600cc4afSopenharmony_ci if ((s.st_mode & S_IFREG) && (ret = CheckFilePath(bundlePaths.front(), realPath)) == ERR_OK) { 125600cc4afSopenharmony_ci realPaths.emplace_back(realPath); 126600cc4afSopenharmony_ci } 127600cc4afSopenharmony_ci return ret; 128600cc4afSopenharmony_ci } else { 129600cc4afSopenharmony_ci APP_LOGE("bundlePath not existed with :%{public}s", bundlePaths.front().c_str()); 130600cc4afSopenharmony_ci return ERR_APPEXECFWK_INSTALL_FILE_PATH_INVALID; 131600cc4afSopenharmony_ci } 132600cc4afSopenharmony_ci } else { 133600cc4afSopenharmony_ci for (const std::string& bundlePath : bundlePaths) { 134600cc4afSopenharmony_ci std::string realPath = ""; 135600cc4afSopenharmony_ci ret = CheckFilePath(bundlePath, realPath); 136600cc4afSopenharmony_ci if (ret != ERR_OK) { 137600cc4afSopenharmony_ci return ret; 138600cc4afSopenharmony_ci } 139600cc4afSopenharmony_ci realPaths.emplace_back(realPath); 140600cc4afSopenharmony_ci } 141600cc4afSopenharmony_ci } 142600cc4afSopenharmony_ci APP_LOGD("finish check file path"); 143600cc4afSopenharmony_ci return ret; 144600cc4afSopenharmony_ci} 145600cc4afSopenharmony_ci 146600cc4afSopenharmony_cibool BundleUtil::CheckFileType(const std::string &fileName, const std::string &extensionName) 147600cc4afSopenharmony_ci{ 148600cc4afSopenharmony_ci APP_LOGD("path is %{public}s, support suffix is %{public}s", fileName.c_str(), extensionName.c_str()); 149600cc4afSopenharmony_ci if (!CheckFileName(fileName)) { 150600cc4afSopenharmony_ci return false; 151600cc4afSopenharmony_ci } 152600cc4afSopenharmony_ci 153600cc4afSopenharmony_ci auto position = fileName.rfind('.'); 154600cc4afSopenharmony_ci if (position == std::string::npos) { 155600cc4afSopenharmony_ci APP_LOGE("filename no extension name"); 156600cc4afSopenharmony_ci return false; 157600cc4afSopenharmony_ci } 158600cc4afSopenharmony_ci 159600cc4afSopenharmony_ci std::string suffixStr = fileName.substr(position); 160600cc4afSopenharmony_ci return LowerStr(suffixStr) == extensionName; 161600cc4afSopenharmony_ci} 162600cc4afSopenharmony_ci 163600cc4afSopenharmony_cibool BundleUtil::CheckFileName(const std::string &fileName) 164600cc4afSopenharmony_ci{ 165600cc4afSopenharmony_ci if (fileName.empty()) { 166600cc4afSopenharmony_ci APP_LOGE("the file name is empty"); 167600cc4afSopenharmony_ci return false; 168600cc4afSopenharmony_ci } 169600cc4afSopenharmony_ci if (fileName.size() > ServiceConstants::PATH_MAX_SIZE) { 170600cc4afSopenharmony_ci APP_LOGE("bundle file path length %{public}zu too long", fileName.size()); 171600cc4afSopenharmony_ci return false; 172600cc4afSopenharmony_ci } 173600cc4afSopenharmony_ci return true; 174600cc4afSopenharmony_ci} 175600cc4afSopenharmony_ci 176600cc4afSopenharmony_cibool BundleUtil::CheckFileSize(const std::string &bundlePath, const int64_t fileSize) 177600cc4afSopenharmony_ci{ 178600cc4afSopenharmony_ci APP_LOGD("fileSize is %{public}" PRId64, fileSize); 179600cc4afSopenharmony_ci struct stat fileInfo = { 0 }; 180600cc4afSopenharmony_ci if (stat(bundlePath.c_str(), &fileInfo) != 0) { 181600cc4afSopenharmony_ci APP_LOGE("call stat error:%{public}d", errno); 182600cc4afSopenharmony_ci return false; 183600cc4afSopenharmony_ci } 184600cc4afSopenharmony_ci if (fileInfo.st_size > fileSize) { 185600cc4afSopenharmony_ci return false; 186600cc4afSopenharmony_ci } 187600cc4afSopenharmony_ci return true; 188600cc4afSopenharmony_ci} 189600cc4afSopenharmony_ci 190600cc4afSopenharmony_cibool BundleUtil::CheckSystemSize(const std::string &bundlePath, const std::string &diskPath) 191600cc4afSopenharmony_ci{ 192600cc4afSopenharmony_ci struct statfs diskInfo = { 0 }; 193600cc4afSopenharmony_ci if (statfs(diskPath.c_str(), &diskInfo) != 0) { 194600cc4afSopenharmony_ci APP_LOGE("call statfs error:%{public}d", errno); 195600cc4afSopenharmony_ci return false; 196600cc4afSopenharmony_ci } 197600cc4afSopenharmony_ci int64_t freeSize = static_cast<int64_t>(diskInfo.f_bavail * diskInfo.f_bsize); 198600cc4afSopenharmony_ci APP_LOGD("left free size in the disk path is %{public}" PRId64, freeSize); 199600cc4afSopenharmony_ci struct stat fileInfo = { 0 }; 200600cc4afSopenharmony_ci if (stat(bundlePath.c_str(), &fileInfo) != 0) { 201600cc4afSopenharmony_ci APP_LOGE("call stat error:%{public}d", errno); 202600cc4afSopenharmony_ci return false; 203600cc4afSopenharmony_ci } 204600cc4afSopenharmony_ci if (std::max(fileInfo.st_size * SPACE_NEED_DOUBLE, HALF_GB) > freeSize) { 205600cc4afSopenharmony_ci return false; 206600cc4afSopenharmony_ci } 207600cc4afSopenharmony_ci return true; 208600cc4afSopenharmony_ci} 209600cc4afSopenharmony_ci 210600cc4afSopenharmony_cibool BundleUtil::CheckSystemFreeSize(const std::string &path, int64_t size) 211600cc4afSopenharmony_ci{ 212600cc4afSopenharmony_ci struct statfs diskInfo = { 0 }; 213600cc4afSopenharmony_ci if (statfs(path.c_str(), &diskInfo) != 0) { 214600cc4afSopenharmony_ci APP_LOGE("call statfs error:%{public}d", errno); 215600cc4afSopenharmony_ci return false; 216600cc4afSopenharmony_ci } 217600cc4afSopenharmony_ci int64_t freeSize = static_cast<int64_t>(diskInfo.f_bavail * diskInfo.f_bsize); 218600cc4afSopenharmony_ci return freeSize >= size; 219600cc4afSopenharmony_ci} 220600cc4afSopenharmony_ci 221600cc4afSopenharmony_cibool BundleUtil::CheckSystemSizeAndHisysEvent(const std::string &path, const std::string &fileName) 222600cc4afSopenharmony_ci{ 223600cc4afSopenharmony_ci struct statfs diskInfo = { 0 }; 224600cc4afSopenharmony_ci if (statfs(path.c_str(), &diskInfo) != 0) { 225600cc4afSopenharmony_ci APP_LOGE("call statfs error:%{public}d", errno); 226600cc4afSopenharmony_ci return false; 227600cc4afSopenharmony_ci } 228600cc4afSopenharmony_ci int64_t freeSize = static_cast<int64_t>(diskInfo.f_bavail * diskInfo.f_bsize); 229600cc4afSopenharmony_ci return freeSize < DISK_REMAINING_SIZE_LIMIT; 230600cc4afSopenharmony_ci} 231600cc4afSopenharmony_ci 232600cc4afSopenharmony_cibool BundleUtil::GetHapFilesFromBundlePath(const std::string& currentBundlePath, std::vector<std::string>& hapFileList) 233600cc4afSopenharmony_ci{ 234600cc4afSopenharmony_ci APP_LOGD("GetHapFilesFromBundlePath with path is %{public}s", currentBundlePath.c_str()); 235600cc4afSopenharmony_ci if (currentBundlePath.empty()) { 236600cc4afSopenharmony_ci return false; 237600cc4afSopenharmony_ci } 238600cc4afSopenharmony_ci DIR* dir = opendir(currentBundlePath.c_str()); 239600cc4afSopenharmony_ci if (dir == nullptr) { 240600cc4afSopenharmony_ci char errMsg[256] = {0}; 241600cc4afSopenharmony_ci strerror_r(errno, errMsg, sizeof(errMsg)); 242600cc4afSopenharmony_ci APP_LOGE("GetHapFilesFromBundlePath open bundle dir:%{public}s failed due to %{public}s, errno:%{public}d", 243600cc4afSopenharmony_ci currentBundlePath.c_str(), errMsg, errno); 244600cc4afSopenharmony_ci return false; 245600cc4afSopenharmony_ci } 246600cc4afSopenharmony_ci std::string bundlePath = currentBundlePath; 247600cc4afSopenharmony_ci if (bundlePath.back() != ServiceConstants::FILE_SEPARATOR_CHAR) { 248600cc4afSopenharmony_ci bundlePath.append(ServiceConstants::PATH_SEPARATOR); 249600cc4afSopenharmony_ci } 250600cc4afSopenharmony_ci struct dirent *entry = nullptr; 251600cc4afSopenharmony_ci while ((entry = readdir(dir)) != nullptr) { 252600cc4afSopenharmony_ci if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) { 253600cc4afSopenharmony_ci continue; 254600cc4afSopenharmony_ci } 255600cc4afSopenharmony_ci const std::string hapFilePath = bundlePath + entry->d_name; 256600cc4afSopenharmony_ci std::string realPath = ""; 257600cc4afSopenharmony_ci if (CheckFilePath(hapFilePath, realPath) != ERR_OK) { 258600cc4afSopenharmony_ci APP_LOGE("find invalid hap path %{public}s", hapFilePath.c_str()); 259600cc4afSopenharmony_ci closedir(dir); 260600cc4afSopenharmony_ci return false; 261600cc4afSopenharmony_ci } 262600cc4afSopenharmony_ci hapFileList.emplace_back(realPath); 263600cc4afSopenharmony_ci APP_LOGD("find hap path %{public}s", realPath.c_str()); 264600cc4afSopenharmony_ci 265600cc4afSopenharmony_ci if (!hapFileList.empty() && (hapFileList.size() > ServiceConstants::MAX_HAP_NUMBER)) { 266600cc4afSopenharmony_ci APP_LOGE("reach the max hap number 128, stop to add more"); 267600cc4afSopenharmony_ci closedir(dir); 268600cc4afSopenharmony_ci return false; 269600cc4afSopenharmony_ci } 270600cc4afSopenharmony_ci } 271600cc4afSopenharmony_ci APP_LOGI("hap number: %{public}zu", hapFileList.size()); 272600cc4afSopenharmony_ci closedir(dir); 273600cc4afSopenharmony_ci return true; 274600cc4afSopenharmony_ci} 275600cc4afSopenharmony_ci 276600cc4afSopenharmony_ciint64_t BundleUtil::GetCurrentTime() 277600cc4afSopenharmony_ci{ 278600cc4afSopenharmony_ci int64_t time = 279600cc4afSopenharmony_ci std::chrono::duration_cast<std::chrono::seconds>(std::chrono::system_clock::now().time_since_epoch()) 280600cc4afSopenharmony_ci .count(); 281600cc4afSopenharmony_ci APP_LOGD("the current time in seconds is %{public}" PRId64, time); 282600cc4afSopenharmony_ci return time; 283600cc4afSopenharmony_ci} 284600cc4afSopenharmony_ci 285600cc4afSopenharmony_ciint64_t BundleUtil::GetCurrentTimeMs() 286600cc4afSopenharmony_ci{ 287600cc4afSopenharmony_ci int64_t time = 288600cc4afSopenharmony_ci std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()) 289600cc4afSopenharmony_ci .count(); 290600cc4afSopenharmony_ci APP_LOGD("the current time in milliseconds is %{public}" PRId64, time); 291600cc4afSopenharmony_ci return time; 292600cc4afSopenharmony_ci} 293600cc4afSopenharmony_ci 294600cc4afSopenharmony_ciint64_t BundleUtil::GetCurrentTimeNs() 295600cc4afSopenharmony_ci{ 296600cc4afSopenharmony_ci int64_t time = 297600cc4afSopenharmony_ci std::chrono::duration_cast<std::chrono::nanoseconds>(std::chrono::system_clock::now().time_since_epoch()) 298600cc4afSopenharmony_ci .count(); 299600cc4afSopenharmony_ci APP_LOGD("the current time in nanoseconds is %{public}" PRId64, time); 300600cc4afSopenharmony_ci return time; 301600cc4afSopenharmony_ci} 302600cc4afSopenharmony_ci 303600cc4afSopenharmony_civoid BundleUtil::DeviceAndNameToKey( 304600cc4afSopenharmony_ci const std::string &deviceId, const std::string &bundleName, std::string &key) 305600cc4afSopenharmony_ci{ 306600cc4afSopenharmony_ci key.append(deviceId); 307600cc4afSopenharmony_ci key.append(Constants::FILE_UNDERLINE); 308600cc4afSopenharmony_ci key.append(bundleName); 309600cc4afSopenharmony_ci APP_LOGD("bundleName = %{public}s", bundleName.c_str()); 310600cc4afSopenharmony_ci} 311600cc4afSopenharmony_ci 312600cc4afSopenharmony_cibool BundleUtil::KeyToDeviceAndName( 313600cc4afSopenharmony_ci const std::string &key, std::string &deviceId, std::string &bundleName) 314600cc4afSopenharmony_ci{ 315600cc4afSopenharmony_ci bool ret = false; 316600cc4afSopenharmony_ci std::vector<std::string> splitStrs; 317600cc4afSopenharmony_ci OHOS::SplitStr(key, Constants::FILE_UNDERLINE, splitStrs); 318600cc4afSopenharmony_ci // the expect split size should be 2. 319600cc4afSopenharmony_ci // key rule is <deviceId>_<bundleName> 320600cc4afSopenharmony_ci if (splitStrs.size() == EXPECT_SPLIT_SIZE) { 321600cc4afSopenharmony_ci deviceId = splitStrs[0]; 322600cc4afSopenharmony_ci bundleName = splitStrs[1]; 323600cc4afSopenharmony_ci ret = true; 324600cc4afSopenharmony_ci } 325600cc4afSopenharmony_ci APP_LOGD("bundleName = %{public}s", bundleName.c_str()); 326600cc4afSopenharmony_ci return ret; 327600cc4afSopenharmony_ci} 328600cc4afSopenharmony_ci 329600cc4afSopenharmony_ciint32_t BundleUtil::GetUserIdByCallingUid() 330600cc4afSopenharmony_ci{ 331600cc4afSopenharmony_ci int32_t uid = IPCSkeleton::GetCallingUid(); 332600cc4afSopenharmony_ci APP_LOGD("get calling uid(%{public}d)", uid); 333600cc4afSopenharmony_ci return GetUserIdByUid(uid); 334600cc4afSopenharmony_ci} 335600cc4afSopenharmony_ci 336600cc4afSopenharmony_ciint32_t BundleUtil::GetUserIdByUid(int32_t uid) 337600cc4afSopenharmony_ci{ 338600cc4afSopenharmony_ci if (uid <= Constants::INVALID_UID) { 339600cc4afSopenharmony_ci APP_LOGE("uid illegal: %{public}d", uid); 340600cc4afSopenharmony_ci return Constants::INVALID_USERID; 341600cc4afSopenharmony_ci } 342600cc4afSopenharmony_ci 343600cc4afSopenharmony_ci return uid / Constants::BASE_USER_RANGE; 344600cc4afSopenharmony_ci} 345600cc4afSopenharmony_ci 346600cc4afSopenharmony_civoid BundleUtil::MakeFsConfig(const std::string &bundleName, int32_t bundleId, const std::string &configPath) 347600cc4afSopenharmony_ci{ 348600cc4afSopenharmony_ci std::string bundleDir = configPath + ServiceConstants::PATH_SEPARATOR + bundleName; 349600cc4afSopenharmony_ci if (access(bundleDir.c_str(), F_OK) != 0) { 350600cc4afSopenharmony_ci APP_LOGD("fail to access error:%{public}d", errno); 351600cc4afSopenharmony_ci if (mkdir(bundleDir.c_str(), S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH) != 0) { 352600cc4afSopenharmony_ci APP_LOGE("make bundle dir error:%{public}d", errno); 353600cc4afSopenharmony_ci return; 354600cc4afSopenharmony_ci } 355600cc4afSopenharmony_ci } 356600cc4afSopenharmony_ci 357600cc4afSopenharmony_ci std::string realBundleDir; 358600cc4afSopenharmony_ci if (!PathToRealPath(bundleDir, realBundleDir)) { 359600cc4afSopenharmony_ci APP_LOGE("bundleIdFile is not real path"); 360600cc4afSopenharmony_ci return; 361600cc4afSopenharmony_ci } 362600cc4afSopenharmony_ci 363600cc4afSopenharmony_ci realBundleDir += (std::string(ServiceConstants::PATH_SEPARATOR) + BUNDLE_ID_FILE); 364600cc4afSopenharmony_ci 365600cc4afSopenharmony_ci int32_t bundleIdFd = open(realBundleDir.c_str(), O_WRONLY | O_TRUNC); 366600cc4afSopenharmony_ci if (bundleIdFd > 0) { 367600cc4afSopenharmony_ci std::string bundleIdStr = std::to_string(bundleId); 368600cc4afSopenharmony_ci if (write(bundleIdFd, bundleIdStr.c_str(), bundleIdStr.size()) < 0) { 369600cc4afSopenharmony_ci APP_LOGE("write bundleId error:%{public}d", errno); 370600cc4afSopenharmony_ci } 371600cc4afSopenharmony_ci } 372600cc4afSopenharmony_ci close(bundleIdFd); 373600cc4afSopenharmony_ci} 374600cc4afSopenharmony_ci 375600cc4afSopenharmony_civoid BundleUtil::RemoveFsConfig(const std::string &bundleName, const std::string &configPath) 376600cc4afSopenharmony_ci{ 377600cc4afSopenharmony_ci std::string bundleDir = configPath + ServiceConstants::PATH_SEPARATOR + bundleName; 378600cc4afSopenharmony_ci std::string realBundleDir; 379600cc4afSopenharmony_ci if (!PathToRealPath(bundleDir, realBundleDir)) { 380600cc4afSopenharmony_ci APP_LOGE("bundleDir is not real path"); 381600cc4afSopenharmony_ci return; 382600cc4afSopenharmony_ci } 383600cc4afSopenharmony_ci if (rmdir(realBundleDir.c_str()) != 0) { 384600cc4afSopenharmony_ci APP_LOGE("remove hmdfs bundle dir error:%{public}d", errno); 385600cc4afSopenharmony_ci } 386600cc4afSopenharmony_ci} 387600cc4afSopenharmony_ci 388600cc4afSopenharmony_cistd::string BundleUtil::CreateTempDir(const std::string &tempDir) 389600cc4afSopenharmony_ci{ 390600cc4afSopenharmony_ci if (!OHOS::ForceCreateDirectory(tempDir)) { 391600cc4afSopenharmony_ci APP_LOGE("mkdir %{public}s failed", tempDir.c_str()); 392600cc4afSopenharmony_ci return ""; 393600cc4afSopenharmony_ci } 394600cc4afSopenharmony_ci if (chown(tempDir.c_str(), Constants::FOUNDATION_UID, ServiceConstants::BMS_GID) != 0) { 395600cc4afSopenharmony_ci APP_LOGE("fail to change %{public}s ownership errno:%{public}d", tempDir.c_str(), errno); 396600cc4afSopenharmony_ci return ""; 397600cc4afSopenharmony_ci } 398600cc4afSopenharmony_ci mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 399600cc4afSopenharmony_ci if (!OHOS::ChangeModeFile(tempDir, mode)) { 400600cc4afSopenharmony_ci APP_LOGE("change mode failed, temp install dir : %{public}s", tempDir.c_str()); 401600cc4afSopenharmony_ci return ""; 402600cc4afSopenharmony_ci } 403600cc4afSopenharmony_ci return tempDir; 404600cc4afSopenharmony_ci} 405600cc4afSopenharmony_ci 406600cc4afSopenharmony_cistd::string BundleUtil::CreateInstallTempDir(uint32_t installerId, const DirType &type) 407600cc4afSopenharmony_ci{ 408600cc4afSopenharmony_ci std::time_t curTime = std::time(0); 409600cc4afSopenharmony_ci std::string tempDir = ServiceConstants::HAP_COPY_PATH; 410600cc4afSopenharmony_ci std::string pathseparator = ServiceConstants::PATH_SEPARATOR; 411600cc4afSopenharmony_ci if (type == DirType::STREAM_INSTALL_DIR) { 412600cc4afSopenharmony_ci tempDir += pathseparator + ServiceConstants::STREAM_INSTALL_PATH; 413600cc4afSopenharmony_ci } else if (type == DirType::QUICK_FIX_DIR) { 414600cc4afSopenharmony_ci tempDir += pathseparator + ServiceConstants::QUICK_FIX_PATH; 415600cc4afSopenharmony_ci } else if (type == DirType::SIG_FILE_DIR) { 416600cc4afSopenharmony_ci tempDir += pathseparator + ServiceConstants::SIGNATURE_FILE_PATH; 417600cc4afSopenharmony_ci } else if (type == DirType::PGO_FILE_DIR) { 418600cc4afSopenharmony_ci tempDir += pathseparator + PGO_FILE_PATH; 419600cc4afSopenharmony_ci } else if (type == DirType::ABC_FILE_DIR) { 420600cc4afSopenharmony_ci tempDir += pathseparator + ABC_FILE_PATH; 421600cc4afSopenharmony_ci } else if (type == DirType::EXT_RESOURCE_FILE_DIR) { 422600cc4afSopenharmony_ci tempDir += pathseparator + ServiceConstants::EXT_RESOURCE_FILE_PATH; 423600cc4afSopenharmony_ci } else { 424600cc4afSopenharmony_ci return ""; 425600cc4afSopenharmony_ci } 426600cc4afSopenharmony_ci 427600cc4afSopenharmony_ci if (CreateTempDir(tempDir).empty()) { 428600cc4afSopenharmony_ci APP_LOGE("create tempDir failed"); 429600cc4afSopenharmony_ci return ""; 430600cc4afSopenharmony_ci } 431600cc4afSopenharmony_ci 432600cc4afSopenharmony_ci tempDir += ServiceConstants::PATH_SEPARATOR + std::to_string(curTime) + 433600cc4afSopenharmony_ci std::to_string(installerId) + ServiceConstants::PATH_SEPARATOR; 434600cc4afSopenharmony_ci return CreateTempDir(tempDir); 435600cc4afSopenharmony_ci} 436600cc4afSopenharmony_ci 437600cc4afSopenharmony_cistd::string BundleUtil::CreateSharedBundleTempDir(uint32_t installerId, uint32_t index) 438600cc4afSopenharmony_ci{ 439600cc4afSopenharmony_ci std::time_t curTime = std::time(0); 440600cc4afSopenharmony_ci std::string tempDir = ServiceConstants::HAP_COPY_PATH; 441600cc4afSopenharmony_ci tempDir += std::string(ServiceConstants::PATH_SEPARATOR) + ServiceConstants::STREAM_INSTALL_PATH; 442600cc4afSopenharmony_ci tempDir += ServiceConstants::PATH_SEPARATOR + std::to_string(curTime) + std::to_string(installerId) 443600cc4afSopenharmony_ci + Constants::FILE_UNDERLINE + std::to_string(index)+ ServiceConstants::PATH_SEPARATOR; 444600cc4afSopenharmony_ci return CreateTempDir(tempDir); 445600cc4afSopenharmony_ci} 446600cc4afSopenharmony_ci 447600cc4afSopenharmony_ciint32_t BundleUtil::CreateFileDescriptor(const std::string &bundlePath, long long offset) 448600cc4afSopenharmony_ci{ 449600cc4afSopenharmony_ci int fd = -1; 450600cc4afSopenharmony_ci if (bundlePath.length() > ServiceConstants::PATH_MAX_SIZE) { 451600cc4afSopenharmony_ci APP_LOGE("the length of the bundlePath exceeds maximum limitation"); 452600cc4afSopenharmony_ci return fd; 453600cc4afSopenharmony_ci } 454600cc4afSopenharmony_ci if ((fd = open(bundlePath.c_str(), O_CREAT | O_RDWR, S_IRUSR | S_IWUSR)) < 0) { 455600cc4afSopenharmony_ci APP_LOGE("open bundlePath %{public}s failed errno:%{public}d", bundlePath.c_str(), errno); 456600cc4afSopenharmony_ci return fd; 457600cc4afSopenharmony_ci } 458600cc4afSopenharmony_ci if (offset > 0) { 459600cc4afSopenharmony_ci lseek(fd, offset, SEEK_SET); 460600cc4afSopenharmony_ci } 461600cc4afSopenharmony_ci return fd; 462600cc4afSopenharmony_ci} 463600cc4afSopenharmony_ci 464600cc4afSopenharmony_ciint32_t BundleUtil::CreateFileDescriptorForReadOnly(const std::string &bundlePath, long long offset) 465600cc4afSopenharmony_ci{ 466600cc4afSopenharmony_ci int fd = -1; 467600cc4afSopenharmony_ci if (bundlePath.length() > ServiceConstants::PATH_MAX_SIZE) { 468600cc4afSopenharmony_ci APP_LOGE("the length of the bundlePath exceeds maximum limitation"); 469600cc4afSopenharmony_ci return fd; 470600cc4afSopenharmony_ci } 471600cc4afSopenharmony_ci std::string realPath; 472600cc4afSopenharmony_ci if (!PathToRealPath(bundlePath, realPath)) { 473600cc4afSopenharmony_ci APP_LOGE("file is not real path"); 474600cc4afSopenharmony_ci return fd; 475600cc4afSopenharmony_ci } 476600cc4afSopenharmony_ci 477600cc4afSopenharmony_ci if ((fd = open(realPath.c_str(), O_RDONLY)) < 0) { 478600cc4afSopenharmony_ci APP_LOGE("open bundlePath %{public}s failed errno:%{public}d", realPath.c_str(), errno); 479600cc4afSopenharmony_ci return fd; 480600cc4afSopenharmony_ci } 481600cc4afSopenharmony_ci if (offset > 0) { 482600cc4afSopenharmony_ci lseek(fd, offset, SEEK_SET); 483600cc4afSopenharmony_ci } 484600cc4afSopenharmony_ci return fd; 485600cc4afSopenharmony_ci} 486600cc4afSopenharmony_ci 487600cc4afSopenharmony_civoid BundleUtil::CloseFileDescriptor(std::vector<int32_t> &fdVec) 488600cc4afSopenharmony_ci{ 489600cc4afSopenharmony_ci for_each(fdVec.begin(), fdVec.end(), [](const auto &fd) { 490600cc4afSopenharmony_ci if (fd > 0) { 491600cc4afSopenharmony_ci close(fd); 492600cc4afSopenharmony_ci } 493600cc4afSopenharmony_ci }); 494600cc4afSopenharmony_ci fdVec.clear(); 495600cc4afSopenharmony_ci} 496600cc4afSopenharmony_ci 497600cc4afSopenharmony_cibool BundleUtil::IsExistFile(const std::string &path) 498600cc4afSopenharmony_ci{ 499600cc4afSopenharmony_ci if (path.empty()) { 500600cc4afSopenharmony_ci return false; 501600cc4afSopenharmony_ci } 502600cc4afSopenharmony_ci 503600cc4afSopenharmony_ci struct stat buf = {}; 504600cc4afSopenharmony_ci if (stat(path.c_str(), &buf) != 0) { 505600cc4afSopenharmony_ci APP_LOGE("fail stat errno:%{public}d", errno); 506600cc4afSopenharmony_ci return false; 507600cc4afSopenharmony_ci } 508600cc4afSopenharmony_ci 509600cc4afSopenharmony_ci return S_ISREG(buf.st_mode); 510600cc4afSopenharmony_ci} 511600cc4afSopenharmony_ci 512600cc4afSopenharmony_cibool BundleUtil::IsExistFileNoLog(const std::string &path) 513600cc4afSopenharmony_ci{ 514600cc4afSopenharmony_ci if (path.empty()) { 515600cc4afSopenharmony_ci return false; 516600cc4afSopenharmony_ci } 517600cc4afSopenharmony_ci 518600cc4afSopenharmony_ci struct stat buf = {}; 519600cc4afSopenharmony_ci if (stat(path.c_str(), &buf) != 0) { 520600cc4afSopenharmony_ci return false; 521600cc4afSopenharmony_ci } 522600cc4afSopenharmony_ci 523600cc4afSopenharmony_ci return S_ISREG(buf.st_mode); 524600cc4afSopenharmony_ci} 525600cc4afSopenharmony_ci 526600cc4afSopenharmony_cibool BundleUtil::IsExistDir(const std::string &path) 527600cc4afSopenharmony_ci{ 528600cc4afSopenharmony_ci if (path.empty()) { 529600cc4afSopenharmony_ci return false; 530600cc4afSopenharmony_ci } 531600cc4afSopenharmony_ci 532600cc4afSopenharmony_ci struct stat buf = {}; 533600cc4afSopenharmony_ci if (stat(path.c_str(), &buf) != 0) { 534600cc4afSopenharmony_ci APP_LOGE("fail stat errno:%{public}d", errno); 535600cc4afSopenharmony_ci return false; 536600cc4afSopenharmony_ci } 537600cc4afSopenharmony_ci 538600cc4afSopenharmony_ci return S_ISDIR(buf.st_mode); 539600cc4afSopenharmony_ci} 540600cc4afSopenharmony_ci 541600cc4afSopenharmony_cibool BundleUtil::IsExistDirNoLog(const std::string &path) 542600cc4afSopenharmony_ci{ 543600cc4afSopenharmony_ci if (path.empty()) { 544600cc4afSopenharmony_ci return false; 545600cc4afSopenharmony_ci } 546600cc4afSopenharmony_ci 547600cc4afSopenharmony_ci struct stat buf = {}; 548600cc4afSopenharmony_ci if (stat(path.c_str(), &buf) != 0) { 549600cc4afSopenharmony_ci return false; 550600cc4afSopenharmony_ci } 551600cc4afSopenharmony_ci 552600cc4afSopenharmony_ci return S_ISDIR(buf.st_mode); 553600cc4afSopenharmony_ci} 554600cc4afSopenharmony_ci 555600cc4afSopenharmony_ciint64_t BundleUtil::CalculateFileSize(const std::string &bundlePath) 556600cc4afSopenharmony_ci{ 557600cc4afSopenharmony_ci struct stat fileInfo = { 0 }; 558600cc4afSopenharmony_ci if (stat(bundlePath.c_str(), &fileInfo) != 0) { 559600cc4afSopenharmony_ci APP_LOGE("call stat error:%{public}d", errno); 560600cc4afSopenharmony_ci return 0; 561600cc4afSopenharmony_ci } 562600cc4afSopenharmony_ci 563600cc4afSopenharmony_ci return static_cast<int64_t>(fileInfo.st_size); 564600cc4afSopenharmony_ci} 565600cc4afSopenharmony_ci 566600cc4afSopenharmony_cibool BundleUtil::RenameFile(const std::string &oldPath, const std::string &newPath) 567600cc4afSopenharmony_ci{ 568600cc4afSopenharmony_ci if (oldPath.empty() || newPath.empty()) { 569600cc4afSopenharmony_ci APP_LOGE("oldPath or newPath is empty"); 570600cc4afSopenharmony_ci return false; 571600cc4afSopenharmony_ci } 572600cc4afSopenharmony_ci 573600cc4afSopenharmony_ci if (!DeleteDir(newPath)) { 574600cc4afSopenharmony_ci APP_LOGE("delete newPath failed"); 575600cc4afSopenharmony_ci return false; 576600cc4afSopenharmony_ci } 577600cc4afSopenharmony_ci 578600cc4afSopenharmony_ci return rename(oldPath.c_str(), newPath.c_str()) == 0; 579600cc4afSopenharmony_ci} 580600cc4afSopenharmony_ci 581600cc4afSopenharmony_cibool BundleUtil::DeleteDir(const std::string &path) 582600cc4afSopenharmony_ci{ 583600cc4afSopenharmony_ci if (IsExistFile(path)) { 584600cc4afSopenharmony_ci return OHOS::RemoveFile(path); 585600cc4afSopenharmony_ci } 586600cc4afSopenharmony_ci 587600cc4afSopenharmony_ci if (IsExistDir(path)) { 588600cc4afSopenharmony_ci return OHOS::ForceRemoveDirectory(path); 589600cc4afSopenharmony_ci } 590600cc4afSopenharmony_ci 591600cc4afSopenharmony_ci return true; 592600cc4afSopenharmony_ci} 593600cc4afSopenharmony_ci 594600cc4afSopenharmony_cibool BundleUtil::IsUtd(const std::string ¶m) 595600cc4afSopenharmony_ci{ 596600cc4afSopenharmony_ci#ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED 597600cc4afSopenharmony_ci bool isUtd = false; 598600cc4afSopenharmony_ci auto ret = UDMF::UtdClient::GetInstance().IsUtd(param, isUtd); 599600cc4afSopenharmony_ci return ret == ERR_OK && isUtd; 600600cc4afSopenharmony_ci#else 601600cc4afSopenharmony_ci return false; 602600cc4afSopenharmony_ci#endif 603600cc4afSopenharmony_ci} 604600cc4afSopenharmony_ci 605600cc4afSopenharmony_cibool BundleUtil::IsSpecificUtd(const std::string ¶m) 606600cc4afSopenharmony_ci{ 607600cc4afSopenharmony_ci if (!IsUtd(param)) { 608600cc4afSopenharmony_ci return false; 609600cc4afSopenharmony_ci } 610600cc4afSopenharmony_ci#ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED 611600cc4afSopenharmony_ci std::shared_ptr<UDMF::TypeDescriptor> typeDescriptor; 612600cc4afSopenharmony_ci auto ret = UDMF::UtdClient::GetInstance().GetTypeDescriptor(param, typeDescriptor); 613600cc4afSopenharmony_ci if (ret != ERR_OK || typeDescriptor == nullptr) { 614600cc4afSopenharmony_ci return false; 615600cc4afSopenharmony_ci } 616600cc4afSopenharmony_ci std::vector<std::string> mimeTypes = typeDescriptor->GetMimeTypes(); 617600cc4afSopenharmony_ci std::vector<std::string> filenameExtensions = typeDescriptor->GetFilenameExtensions(); 618600cc4afSopenharmony_ci return !mimeTypes.empty() || !filenameExtensions.empty(); 619600cc4afSopenharmony_ci#else 620600cc4afSopenharmony_ci return false; 621600cc4afSopenharmony_ci#endif 622600cc4afSopenharmony_ci} 623600cc4afSopenharmony_ci 624600cc4afSopenharmony_cistd::vector<std::string> BundleUtil::GetUtdVectorByMimeType(const std::string &mimeType) 625600cc4afSopenharmony_ci{ 626600cc4afSopenharmony_ci#ifdef BUNDLE_FRAMEWORK_UDMF_ENABLED 627600cc4afSopenharmony_ci std::vector<std::string> utdVector; 628600cc4afSopenharmony_ci auto ret = UDMF::UtdClient::GetInstance().GetUniformDataTypesByMIMEType(mimeType, utdVector); 629600cc4afSopenharmony_ci if (ret != ERR_OK || utdVector.empty()) { 630600cc4afSopenharmony_ci return {}; 631600cc4afSopenharmony_ci } 632600cc4afSopenharmony_ci return utdVector; 633600cc4afSopenharmony_ci#else 634600cc4afSopenharmony_ci return {}; 635600cc4afSopenharmony_ci#endif 636600cc4afSopenharmony_ci} 637600cc4afSopenharmony_ci 638600cc4afSopenharmony_cistd::string BundleUtil::GetBoolStrVal(bool val) 639600cc4afSopenharmony_ci{ 640600cc4afSopenharmony_ci return val ? "true" : "false"; 641600cc4afSopenharmony_ci} 642600cc4afSopenharmony_ci 643600cc4afSopenharmony_cibool BundleUtil::CopyFile( 644600cc4afSopenharmony_ci const std::string &sourceFile, const std::string &destinationFile) 645600cc4afSopenharmony_ci{ 646600cc4afSopenharmony_ci if (sourceFile.empty() || destinationFile.empty()) { 647600cc4afSopenharmony_ci APP_LOGE("Copy file failed due to sourceFile or destinationFile is empty"); 648600cc4afSopenharmony_ci return false; 649600cc4afSopenharmony_ci } 650600cc4afSopenharmony_ci 651600cc4afSopenharmony_ci std::ifstream in(sourceFile); 652600cc4afSopenharmony_ci if (!in.is_open()) { 653600cc4afSopenharmony_ci APP_LOGE("Copy file failed due to open sourceFile failed errno:%{public}d", errno); 654600cc4afSopenharmony_ci return false; 655600cc4afSopenharmony_ci } 656600cc4afSopenharmony_ci 657600cc4afSopenharmony_ci std::ofstream out(destinationFile); 658600cc4afSopenharmony_ci if (!out.is_open()) { 659600cc4afSopenharmony_ci APP_LOGE("Copy file failed due to open destinationFile failed errno:%{public}d", errno); 660600cc4afSopenharmony_ci in.close(); 661600cc4afSopenharmony_ci return false; 662600cc4afSopenharmony_ci } 663600cc4afSopenharmony_ci 664600cc4afSopenharmony_ci out << in.rdbuf(); 665600cc4afSopenharmony_ci in.close(); 666600cc4afSopenharmony_ci out.close(); 667600cc4afSopenharmony_ci return true; 668600cc4afSopenharmony_ci} 669600cc4afSopenharmony_ci 670600cc4afSopenharmony_cibool BundleUtil::CopyFileFast(const std::string &sourcePath, const std::string &destPath) 671600cc4afSopenharmony_ci{ 672600cc4afSopenharmony_ci APP_LOGI("sourcePath : %{public}s, destPath : %{public}s", sourcePath.c_str(), destPath.c_str()); 673600cc4afSopenharmony_ci if (sourcePath.empty() || destPath.empty()) { 674600cc4afSopenharmony_ci APP_LOGE("invalid path"); 675600cc4afSopenharmony_ci return false; 676600cc4afSopenharmony_ci } 677600cc4afSopenharmony_ci 678600cc4afSopenharmony_ci int32_t sourceFd = open(sourcePath.c_str(), O_RDONLY); 679600cc4afSopenharmony_ci if (sourceFd == -1) { 680600cc4afSopenharmony_ci APP_LOGE("sourcePath open failed, errno : %{public}d", errno); 681600cc4afSopenharmony_ci return CopyFile(sourcePath, destPath); 682600cc4afSopenharmony_ci } 683600cc4afSopenharmony_ci 684600cc4afSopenharmony_ci struct stat sourceStat; 685600cc4afSopenharmony_ci if (fstat(sourceFd, &sourceStat) == -1) { 686600cc4afSopenharmony_ci APP_LOGE("fstat failed, errno : %{public}d", errno); 687600cc4afSopenharmony_ci close(sourceFd); 688600cc4afSopenharmony_ci return CopyFile(sourcePath, destPath); 689600cc4afSopenharmony_ci } 690600cc4afSopenharmony_ci if (sourceStat.st_size < 0) { 691600cc4afSopenharmony_ci APP_LOGE("invalid st_size"); 692600cc4afSopenharmony_ci close(sourceFd); 693600cc4afSopenharmony_ci return CopyFile(sourcePath, destPath); 694600cc4afSopenharmony_ci } 695600cc4afSopenharmony_ci 696600cc4afSopenharmony_ci int32_t destFd = open( 697600cc4afSopenharmony_ci destPath.c_str(), O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); 698600cc4afSopenharmony_ci if (destFd == -1) { 699600cc4afSopenharmony_ci APP_LOGE("destPath open failed, errno : %{public}d", errno); 700600cc4afSopenharmony_ci close(sourceFd); 701600cc4afSopenharmony_ci return CopyFile(sourcePath, destPath); 702600cc4afSopenharmony_ci } 703600cc4afSopenharmony_ci 704600cc4afSopenharmony_ci size_t buffer = 524288; // 0.5M 705600cc4afSopenharmony_ci size_t transferCount = 0; 706600cc4afSopenharmony_ci ssize_t singleTransfer = 0; 707600cc4afSopenharmony_ci while ((singleTransfer = sendfile(destFd, sourceFd, nullptr, buffer)) > 0) { 708600cc4afSopenharmony_ci transferCount += static_cast<size_t>(singleTransfer); 709600cc4afSopenharmony_ci } 710600cc4afSopenharmony_ci 711600cc4afSopenharmony_ci if (singleTransfer == -1 || transferCount != static_cast<size_t>(sourceStat.st_size)) { 712600cc4afSopenharmony_ci APP_LOGE("sendfile failed, errno : %{public}d, send count : %{public}zu , file size : %{public}zu", 713600cc4afSopenharmony_ci errno, transferCount, static_cast<size_t>(sourceStat.st_size)); 714600cc4afSopenharmony_ci close(sourceFd); 715600cc4afSopenharmony_ci close(destFd); 716600cc4afSopenharmony_ci return CopyFile(sourcePath, destPath); 717600cc4afSopenharmony_ci } 718600cc4afSopenharmony_ci 719600cc4afSopenharmony_ci close(sourceFd); 720600cc4afSopenharmony_ci close(destFd); 721600cc4afSopenharmony_ci APP_LOGD("sendfile success"); 722600cc4afSopenharmony_ci return true; 723600cc4afSopenharmony_ci} 724600cc4afSopenharmony_ci 725600cc4afSopenharmony_ciResource BundleUtil::GetResource(const std::string &bundleName, const std::string &moduleName, uint32_t resId) 726600cc4afSopenharmony_ci{ 727600cc4afSopenharmony_ci Resource resource; 728600cc4afSopenharmony_ci resource.bundleName = bundleName; 729600cc4afSopenharmony_ci resource.moduleName = moduleName; 730600cc4afSopenharmony_ci resource.id = resId; 731600cc4afSopenharmony_ci return resource; 732600cc4afSopenharmony_ci} 733600cc4afSopenharmony_ci 734600cc4afSopenharmony_cibool BundleUtil::CreateDir(const std::string &dir) 735600cc4afSopenharmony_ci{ 736600cc4afSopenharmony_ci if (dir.empty()) { 737600cc4afSopenharmony_ci APP_LOGE("path is empty"); 738600cc4afSopenharmony_ci return false; 739600cc4afSopenharmony_ci } 740600cc4afSopenharmony_ci 741600cc4afSopenharmony_ci if (IsExistFile(dir)) { 742600cc4afSopenharmony_ci return true; 743600cc4afSopenharmony_ci } 744600cc4afSopenharmony_ci 745600cc4afSopenharmony_ci if (!OHOS::ForceCreateDirectory(dir)) { 746600cc4afSopenharmony_ci APP_LOGE("mkdir %{public}s failed", dir.c_str()); 747600cc4afSopenharmony_ci return false; 748600cc4afSopenharmony_ci } 749600cc4afSopenharmony_ci 750600cc4afSopenharmony_ci if (chown(dir.c_str(), Constants::FOUNDATION_UID, ServiceConstants::BMS_GID) != 0) { 751600cc4afSopenharmony_ci APP_LOGE("fail change %{public}s ownership, errno:%{public}d", dir.c_str(), errno); 752600cc4afSopenharmony_ci return false; 753600cc4afSopenharmony_ci } 754600cc4afSopenharmony_ci 755600cc4afSopenharmony_ci mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 756600cc4afSopenharmony_ci if (!OHOS::ChangeModeFile(dir, mode)) { 757600cc4afSopenharmony_ci APP_LOGE("change mode failed, temp install dir : %{public}s", dir.c_str()); 758600cc4afSopenharmony_ci return false; 759600cc4afSopenharmony_ci } 760600cc4afSopenharmony_ci return true; 761600cc4afSopenharmony_ci} 762600cc4afSopenharmony_ci 763600cc4afSopenharmony_cibool BundleUtil::RevertToRealPath(const std::string &sandBoxPath, const std::string &bundleName, std::string &realPath) 764600cc4afSopenharmony_ci{ 765600cc4afSopenharmony_ci if (sandBoxPath.empty() || bundleName.empty() || 766600cc4afSopenharmony_ci sandBoxPath.find(ServiceConstants::SANDBOX_DATA_PATH) == std::string::npos) { 767600cc4afSopenharmony_ci APP_LOGE("input sandboxPath or bundleName invalid"); 768600cc4afSopenharmony_ci return false; 769600cc4afSopenharmony_ci } 770600cc4afSopenharmony_ci 771600cc4afSopenharmony_ci realPath = sandBoxPath; 772600cc4afSopenharmony_ci std::string relaDataPath = std::string(ServiceConstants::REAL_DATA_PATH) + ServiceConstants::PATH_SEPARATOR 773600cc4afSopenharmony_ci + std::to_string(BundleUtil::GetUserIdByCallingUid()) + ServiceConstants::BASE + bundleName; 774600cc4afSopenharmony_ci realPath.replace(realPath.find(ServiceConstants::SANDBOX_DATA_PATH), 775600cc4afSopenharmony_ci std::string(ServiceConstants::SANDBOX_DATA_PATH).size(), relaDataPath); 776600cc4afSopenharmony_ci return true; 777600cc4afSopenharmony_ci} 778600cc4afSopenharmony_ci 779600cc4afSopenharmony_cibool BundleUtil::StartWith(const std::string &source, const std::string &prefix) 780600cc4afSopenharmony_ci{ 781600cc4afSopenharmony_ci if (source.empty() || prefix.empty()) { 782600cc4afSopenharmony_ci return false; 783600cc4afSopenharmony_ci } 784600cc4afSopenharmony_ci 785600cc4afSopenharmony_ci return source.find(prefix) == 0; 786600cc4afSopenharmony_ci} 787600cc4afSopenharmony_ci 788600cc4afSopenharmony_cibool BundleUtil::EndWith(const std::string &source, const std::string &suffix) 789600cc4afSopenharmony_ci{ 790600cc4afSopenharmony_ci if (source.empty() || suffix.empty()) { 791600cc4afSopenharmony_ci return false; 792600cc4afSopenharmony_ci } 793600cc4afSopenharmony_ci 794600cc4afSopenharmony_ci auto position = source.rfind(suffix); 795600cc4afSopenharmony_ci if (position == std::string::npos) { 796600cc4afSopenharmony_ci return false; 797600cc4afSopenharmony_ci } 798600cc4afSopenharmony_ci 799600cc4afSopenharmony_ci std::string suffixStr = source.substr(position); 800600cc4afSopenharmony_ci return suffixStr == suffix; 801600cc4afSopenharmony_ci} 802600cc4afSopenharmony_ci 803600cc4afSopenharmony_ciint64_t BundleUtil::GetFileSize(const std::string &filePath) 804600cc4afSopenharmony_ci{ 805600cc4afSopenharmony_ci struct stat fileInfo = { 0 }; 806600cc4afSopenharmony_ci if (stat(filePath.c_str(), &fileInfo) != 0) { 807600cc4afSopenharmony_ci APP_LOGE("call stat error:%{public}d", errno); 808600cc4afSopenharmony_ci return 0; 809600cc4afSopenharmony_ci } 810600cc4afSopenharmony_ci return fileInfo.st_size; 811600cc4afSopenharmony_ci} 812600cc4afSopenharmony_ci 813600cc4afSopenharmony_cistd::string BundleUtil::CopyFileToSecurityDir(const std::string &filePath, const DirType &dirType, 814600cc4afSopenharmony_ci std::vector<std::string> &toDeletePaths) 815600cc4afSopenharmony_ci{ 816600cc4afSopenharmony_ci APP_LOGD("the original dir is %{public}s", filePath.c_str()); 817600cc4afSopenharmony_ci std::string destination = ""; 818600cc4afSopenharmony_ci std::string subStr = ""; 819600cc4afSopenharmony_ci destination.append(ServiceConstants::HAP_COPY_PATH).append(ServiceConstants::PATH_SEPARATOR); 820600cc4afSopenharmony_ci if (dirType == DirType::STREAM_INSTALL_DIR) { 821600cc4afSopenharmony_ci subStr = ServiceConstants::STREAM_INSTALL_PATH; 822600cc4afSopenharmony_ci destination.append(ServiceConstants::SECURITY_STREAM_INSTALL_PATH); 823600cc4afSopenharmony_ci mode_t mode = S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH; 824600cc4afSopenharmony_ci if (InstalldClient::GetInstance()->Mkdir( 825600cc4afSopenharmony_ci destination, mode, Constants::FOUNDATION_UID, ServiceConstants::BMS_GID) != ERR_OK) { 826600cc4afSopenharmony_ci APP_LOGW("installd mkdir %{private}s failed", destination.c_str()); 827600cc4afSopenharmony_ci } 828600cc4afSopenharmony_ci } 829600cc4afSopenharmony_ci if (dirType == DirType::SIG_FILE_DIR) { 830600cc4afSopenharmony_ci subStr = ServiceConstants::SIGNATURE_FILE_PATH; 831600cc4afSopenharmony_ci destination.append(ServiceConstants::SECURITY_SIGNATURE_FILE_PATH); 832600cc4afSopenharmony_ci } 833600cc4afSopenharmony_ci destination.append(ServiceConstants::PATH_SEPARATOR).append(std::to_string(GetCurrentTimeNs())); 834600cc4afSopenharmony_ci destination = CreateTempDir(destination); 835600cc4afSopenharmony_ci auto pos = filePath.find(subStr); 836600cc4afSopenharmony_ci if (pos == std::string::npos) { // this circumstance could not be considered laterly 837600cc4afSopenharmony_ci auto lastPathSeperator = filePath.rfind(ServiceConstants::PATH_SEPARATOR); 838600cc4afSopenharmony_ci if ((lastPathSeperator != std::string::npos) && (lastPathSeperator != filePath.length() - 1)) { 839600cc4afSopenharmony_ci toDeletePaths.emplace_back(destination); 840600cc4afSopenharmony_ci destination.append(filePath.substr(lastPathSeperator)); 841600cc4afSopenharmony_ci } 842600cc4afSopenharmony_ci } else { 843600cc4afSopenharmony_ci auto secondLastPathSep = filePath.find(ServiceConstants::PATH_SEPARATOR, pos); 844600cc4afSopenharmony_ci if ((secondLastPathSep == std::string::npos) || (secondLastPathSep == filePath.length() - 1)) { 845600cc4afSopenharmony_ci return ""; 846600cc4afSopenharmony_ci } 847600cc4afSopenharmony_ci auto thirdLastPathSep = 848600cc4afSopenharmony_ci filePath.find(ServiceConstants::PATH_SEPARATOR, secondLastPathSep + 1); 849600cc4afSopenharmony_ci if ((thirdLastPathSep == std::string::npos) || (thirdLastPathSep == filePath.length() - 1)) { 850600cc4afSopenharmony_ci return ""; 851600cc4afSopenharmony_ci } 852600cc4afSopenharmony_ci toDeletePaths.emplace_back(destination); 853600cc4afSopenharmony_ci std::string innerSubstr = 854600cc4afSopenharmony_ci filePath.substr(secondLastPathSep, thirdLastPathSep - secondLastPathSep + 1); 855600cc4afSopenharmony_ci destination = CreateTempDir(destination.append(innerSubstr)); 856600cc4afSopenharmony_ci destination.append(filePath.substr(thirdLastPathSep + 1)); 857600cc4afSopenharmony_ci } 858600cc4afSopenharmony_ci APP_LOGD("the destination dir is %{public}s", destination.c_str()); 859600cc4afSopenharmony_ci if (destination.empty()) { 860600cc4afSopenharmony_ci return ""; 861600cc4afSopenharmony_ci } 862600cc4afSopenharmony_ci if (!CopyFileFast(filePath, destination)) { 863600cc4afSopenharmony_ci APP_LOGE("copy file from %{public}s to %{public}s failed", filePath.c_str(), destination.c_str()); 864600cc4afSopenharmony_ci return ""; 865600cc4afSopenharmony_ci } 866600cc4afSopenharmony_ci return destination; 867600cc4afSopenharmony_ci} 868600cc4afSopenharmony_ci 869600cc4afSopenharmony_civoid BundleUtil::DeleteTempDirs(const std::vector<std::string> &tempDirs) 870600cc4afSopenharmony_ci{ 871600cc4afSopenharmony_ci for (const auto &tempDir : tempDirs) { 872600cc4afSopenharmony_ci APP_LOGD("the temp hap dir %{public}s needs to be deleted", tempDir.c_str()); 873600cc4afSopenharmony_ci BundleUtil::DeleteDir(tempDir); 874600cc4afSopenharmony_ci } 875600cc4afSopenharmony_ci} 876600cc4afSopenharmony_ci 877600cc4afSopenharmony_cistd::string BundleUtil::GetHexHash(const std::string &s) 878600cc4afSopenharmony_ci{ 879600cc4afSopenharmony_ci std::hash<std::string> hasher; 880600cc4afSopenharmony_ci size_t hash = hasher(s); 881600cc4afSopenharmony_ci 882600cc4afSopenharmony_ci std::stringstream ss; 883600cc4afSopenharmony_ci ss << std::hex << hash; 884600cc4afSopenharmony_ci 885600cc4afSopenharmony_ci std::string hash_str = ss.str(); 886600cc4afSopenharmony_ci return hash_str; 887600cc4afSopenharmony_ci} 888600cc4afSopenharmony_ci 889600cc4afSopenharmony_civoid BundleUtil::RecursiveHash(std::string& s) 890600cc4afSopenharmony_ci{ 891600cc4afSopenharmony_ci if (s.size() >= ORIGIN_STRING_LENGTH) { 892600cc4afSopenharmony_ci s = s.substr(s.size() - ORIGIN_STRING_LENGTH); 893600cc4afSopenharmony_ci return; 894600cc4afSopenharmony_ci } 895600cc4afSopenharmony_ci std::string hash = GetHexHash(s); 896600cc4afSopenharmony_ci s += hash; 897600cc4afSopenharmony_ci RecursiveHash(s); 898600cc4afSopenharmony_ci} 899600cc4afSopenharmony_ci 900600cc4afSopenharmony_cistd::string BundleUtil::GenerateUuid() 901600cc4afSopenharmony_ci{ 902600cc4afSopenharmony_ci std::lock_guard<std::mutex> lock(g_mutex); 903600cc4afSopenharmony_ci auto currentTime = std::chrono::system_clock::now(); 904600cc4afSopenharmony_ci auto timestampNanoseconds = 905600cc4afSopenharmony_ci std::chrono::duration_cast<std::chrono::nanoseconds>(currentTime.time_since_epoch()).count(); 906600cc4afSopenharmony_ci 907600cc4afSopenharmony_ci // convert nanosecond timestamps to string 908600cc4afSopenharmony_ci std::string s = std::to_string(timestampNanoseconds); 909600cc4afSopenharmony_ci std::string timeStr = GetHexHash(s); 910600cc4afSopenharmony_ci 911600cc4afSopenharmony_ci char deviceId[UUID_LENGTH_MAX] = { 0 }; 912600cc4afSopenharmony_ci auto ret = GetDevUdid(deviceId, UUID_LENGTH_MAX); 913600cc4afSopenharmony_ci std::string deviceUdid; 914600cc4afSopenharmony_ci std::string deviceStr; 915600cc4afSopenharmony_ci if (ret != 0) { 916600cc4afSopenharmony_ci APP_LOGW("GetDevUdid failed"); 917600cc4afSopenharmony_ci } else { 918600cc4afSopenharmony_ci deviceUdid = std::string{ deviceId }; 919600cc4afSopenharmony_ci deviceStr = GetHexHash(deviceUdid); 920600cc4afSopenharmony_ci } 921600cc4afSopenharmony_ci 922600cc4afSopenharmony_ci std::string uuid = timeStr + deviceStr; 923600cc4afSopenharmony_ci RecursiveHash(uuid); 924600cc4afSopenharmony_ci 925600cc4afSopenharmony_ci for (int32_t index : SEPARATOR_POSITIONS) { 926600cc4afSopenharmony_ci uuid.insert(index, 1, UUID_SEPARATOR); 927600cc4afSopenharmony_ci } 928600cc4afSopenharmony_ci return uuid; 929600cc4afSopenharmony_ci} 930600cc4afSopenharmony_ci 931600cc4afSopenharmony_cistd::string BundleUtil::GenerateUuidByKey(const std::string &key) 932600cc4afSopenharmony_ci{ 933600cc4afSopenharmony_ci std::string keyHash = GetHexHash(key); 934600cc4afSopenharmony_ci 935600cc4afSopenharmony_ci char deviceId[UUID_LENGTH_MAX] = { 0 }; 936600cc4afSopenharmony_ci auto ret = GetDevUdid(deviceId, UUID_LENGTH_MAX); 937600cc4afSopenharmony_ci std::string deviceUdid; 938600cc4afSopenharmony_ci std::string deviceStr; 939600cc4afSopenharmony_ci if (ret != 0) { 940600cc4afSopenharmony_ci APP_LOGW("GetDevUdid failed"); 941600cc4afSopenharmony_ci } else { 942600cc4afSopenharmony_ci deviceUdid = std::string{ deviceId }; 943600cc4afSopenharmony_ci deviceStr = GetHexHash(deviceUdid); 944600cc4afSopenharmony_ci } 945600cc4afSopenharmony_ci 946600cc4afSopenharmony_ci std::string uuid = keyHash + deviceStr; 947600cc4afSopenharmony_ci RecursiveHash(uuid); 948600cc4afSopenharmony_ci 949600cc4afSopenharmony_ci for (int32_t index : SEPARATOR_POSITIONS) { 950600cc4afSopenharmony_ci uuid.insert(index, 1, UUID_SEPARATOR); 951600cc4afSopenharmony_ci } 952600cc4afSopenharmony_ci return uuid; 953600cc4afSopenharmony_ci} 954600cc4afSopenharmony_ci 955600cc4afSopenharmony_cistd::string BundleUtil::ExtractGroupIdByDevelopId(const std::string &developerId) 956600cc4afSopenharmony_ci{ 957600cc4afSopenharmony_ci std::string::size_type dot_position = developerId.find('.'); 958600cc4afSopenharmony_ci if (dot_position == std::string::npos) { 959600cc4afSopenharmony_ci // If cannot find '.' , the input string is developerId, return developerId 960600cc4afSopenharmony_ci return developerId; 961600cc4afSopenharmony_ci } 962600cc4afSopenharmony_ci if (dot_position == 0) { 963600cc4afSopenharmony_ci // if'.' In the first place, then groupId is empty, return developerId 964600cc4afSopenharmony_ci return developerId.substr(1); 965600cc4afSopenharmony_ci } 966600cc4afSopenharmony_ci // If '.' If it is not the first place, there is a groupId, and the groupId is returned 967600cc4afSopenharmony_ci return developerId.substr(0, dot_position); 968600cc4afSopenharmony_ci} 969600cc4afSopenharmony_ci 970600cc4afSopenharmony_cistd::string BundleUtil::ToString(const std::vector<std::string> &vector) 971600cc4afSopenharmony_ci{ 972600cc4afSopenharmony_ci std::string ret; 973600cc4afSopenharmony_ci for (const std::string &item : vector) { 974600cc4afSopenharmony_ci ret.append(item).append(","); 975600cc4afSopenharmony_ci } 976600cc4afSopenharmony_ci return ret; 977600cc4afSopenharmony_ci} 978600cc4afSopenharmony_ci 979600cc4afSopenharmony_cistd::string BundleUtil::GetNoDisablingConfigPath() 980600cc4afSopenharmony_ci{ 981600cc4afSopenharmony_ci#ifdef CONFIG_POLOCY_ENABLE 982600cc4afSopenharmony_ci char buf[MAX_PATH_LEN] = { 0 }; 983600cc4afSopenharmony_ci char *configPath = GetOneCfgFile(NO_DISABLING_CONFIG_PATH, buf, MAX_PATH_LEN); 984600cc4afSopenharmony_ci if (configPath == nullptr || configPath[0] == '\0' || strlen(configPath) > MAX_PATH_LEN) { 985600cc4afSopenharmony_ci return NO_DISABLING_CONFIG_PATH_DEFAULT; 986600cc4afSopenharmony_ci } 987600cc4afSopenharmony_ci return configPath; 988600cc4afSopenharmony_ci#else 989600cc4afSopenharmony_ci return NO_DISABLING_CONFIG_PATH_DEFAULT; 990600cc4afSopenharmony_ci#endif 991600cc4afSopenharmony_ci} 992600cc4afSopenharmony_ci} // namespace AppExecFwk 993600cc4afSopenharmony_ci} // namespace OHOS 994