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 &param)
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 &param)
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