169570cc8Sopenharmony_ci/*
269570cc8Sopenharmony_ci * Copyright (c) 2024 Huawei Device Co., Ltd.
369570cc8Sopenharmony_ci * Licensed under the Apache License, Version 2.0 (the "License");
469570cc8Sopenharmony_ci * you may not use this file except in compliance with the License.
569570cc8Sopenharmony_ci * You may obtain a copy of the License at
669570cc8Sopenharmony_ci *
769570cc8Sopenharmony_ci *     http://www.apache.org/licenses/LICENSE-2.0
869570cc8Sopenharmony_ci *
969570cc8Sopenharmony_ci * Unless required by applicable law or agreed to in writing, software
1069570cc8Sopenharmony_ci * distributed under the License is distributed on an "AS IS" BASIS,
1169570cc8Sopenharmony_ci * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
1269570cc8Sopenharmony_ci * See the License for the specific language governing permissions and
1369570cc8Sopenharmony_ci * limitations under the License.
1469570cc8Sopenharmony_ci */
1569570cc8Sopenharmony_ci
1669570cc8Sopenharmony_ci#include <stdio.h>
1769570cc8Sopenharmony_ci#include <stdlib.h>
1869570cc8Sopenharmony_ci#include <string.h>
1969570cc8Sopenharmony_ci#include <dirent.h>
2069570cc8Sopenharmony_ci#include <unistd.h>
2169570cc8Sopenharmony_ci#include <sys/stat.h>
2269570cc8Sopenharmony_ci#include <ctype.h>
2369570cc8Sopenharmony_ci#include <errno.h>
2469570cc8Sopenharmony_ci#include <getopt.h>
2569570cc8Sopenharmony_ci
2669570cc8Sopenharmony_ci#include "policycoreutils.h"
2769570cc8Sopenharmony_ci#ifdef CODE_SIGNATURE_ENABLE
2869570cc8Sopenharmony_ci#include "code_sign_utils_in_c.h"
2969570cc8Sopenharmony_ci#endif
3069570cc8Sopenharmony_ci#include "hnp_installer.h"
3169570cc8Sopenharmony_ci
3269570cc8Sopenharmony_ci#ifdef __cplusplus
3369570cc8Sopenharmony_ciextern "C" {
3469570cc8Sopenharmony_ci#endif
3569570cc8Sopenharmony_ci
3669570cc8Sopenharmony_cistatic int HnpInstallerUidGet(const char *uidIn, int *uidOut)
3769570cc8Sopenharmony_ci{
3869570cc8Sopenharmony_ci    int index;
3969570cc8Sopenharmony_ci
4069570cc8Sopenharmony_ci    for (index = 0; uidIn[index] != '\0'; index++) {
4169570cc8Sopenharmony_ci        if (!isdigit(uidIn[index])) {
4269570cc8Sopenharmony_ci            return HNP_ERRNO_INSTALLER_ARGV_UID_INVALID;
4369570cc8Sopenharmony_ci        }
4469570cc8Sopenharmony_ci    }
4569570cc8Sopenharmony_ci
4669570cc8Sopenharmony_ci    *uidOut = atoi(uidIn); // 转化为10进制
4769570cc8Sopenharmony_ci    return 0;
4869570cc8Sopenharmony_ci}
4969570cc8Sopenharmony_ci
5069570cc8Sopenharmony_cistatic int HnpGenerateSoftLinkAllByJson(const char *installPath, const char *dstPath, HnpCfgInfo *hnpCfg)
5169570cc8Sopenharmony_ci{
5269570cc8Sopenharmony_ci    char srcFile[MAX_FILE_PATH_LEN];
5369570cc8Sopenharmony_ci    char dstFile[MAX_FILE_PATH_LEN];
5469570cc8Sopenharmony_ci    NativeBinLink *currentLink = hnpCfg->links;
5569570cc8Sopenharmony_ci    char *fileNameTmp;
5669570cc8Sopenharmony_ci
5769570cc8Sopenharmony_ci    if (access(dstPath, F_OK) != 0) {
5869570cc8Sopenharmony_ci        int ret = mkdir(dstPath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
5969570cc8Sopenharmony_ci        if ((ret != 0) && (errno != EEXIST)) {
6069570cc8Sopenharmony_ci            HNP_LOGE("mkdir [%{public}s] unsuccess, ret=%{public}d, errno:%{public}d", dstPath, ret, errno);
6169570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_MKDIR_PATH_FAILED;
6269570cc8Sopenharmony_ci        }
6369570cc8Sopenharmony_ci    }
6469570cc8Sopenharmony_ci
6569570cc8Sopenharmony_ci    for (unsigned int i = 0; i < hnpCfg->linkNum; i++) {
6669570cc8Sopenharmony_ci        if (strstr(currentLink->source, "../") || strstr(currentLink->target, "../")) {
6769570cc8Sopenharmony_ci            HNP_LOGE("hnp json link source[%{public}s],target[%{public}s],does not allow the use of ../",
6869570cc8Sopenharmony_ci                currentLink->source, currentLink->target);
6969570cc8Sopenharmony_ci            return HNP_ERRNO_INSTALLER_GET_HNP_PATH_FAILED;
7069570cc8Sopenharmony_ci        }
7169570cc8Sopenharmony_ci        int ret = sprintf_s(srcFile, MAX_FILE_PATH_LEN, "%s/%s", installPath, currentLink->source);
7269570cc8Sopenharmony_ci        char *fileName;
7369570cc8Sopenharmony_ci        if (ret < 0) {
7469570cc8Sopenharmony_ci            HNP_LOGE("sprintf install bin src file unsuccess.");
7569570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
7669570cc8Sopenharmony_ci        }
7769570cc8Sopenharmony_ci        /* 如果target为空则使用源二进制名称 */
7869570cc8Sopenharmony_ci        if (strcmp(currentLink->target, "") == 0) {
7969570cc8Sopenharmony_ci            fileNameTmp = currentLink->source;
8069570cc8Sopenharmony_ci        } else {
8169570cc8Sopenharmony_ci            fileNameTmp = currentLink->target;
8269570cc8Sopenharmony_ci        }
8369570cc8Sopenharmony_ci        fileName = strrchr(fileNameTmp, DIR_SPLIT_SYMBOL);
8469570cc8Sopenharmony_ci        if (fileName == NULL) {
8569570cc8Sopenharmony_ci            fileName = fileNameTmp;
8669570cc8Sopenharmony_ci        } else {
8769570cc8Sopenharmony_ci            fileName++;
8869570cc8Sopenharmony_ci        }
8969570cc8Sopenharmony_ci        ret = sprintf_s(dstFile, MAX_FILE_PATH_LEN, "%s/%s", dstPath, fileName);
9069570cc8Sopenharmony_ci        if (ret < 0) {
9169570cc8Sopenharmony_ci            HNP_LOGE("sprintf install bin dst file unsuccess.");
9269570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
9369570cc8Sopenharmony_ci        }
9469570cc8Sopenharmony_ci        /* 生成软链接 */
9569570cc8Sopenharmony_ci        ret = HnpSymlink(srcFile, dstFile);
9669570cc8Sopenharmony_ci        if (ret != 0) {
9769570cc8Sopenharmony_ci            return ret;
9869570cc8Sopenharmony_ci        }
9969570cc8Sopenharmony_ci
10069570cc8Sopenharmony_ci        currentLink++;
10169570cc8Sopenharmony_ci    }
10269570cc8Sopenharmony_ci
10369570cc8Sopenharmony_ci    return 0;
10469570cc8Sopenharmony_ci}
10569570cc8Sopenharmony_ci
10669570cc8Sopenharmony_cistatic int HnpGenerateSoftLinkAll(const char *installPath, const char *dstPath)
10769570cc8Sopenharmony_ci{
10869570cc8Sopenharmony_ci    char srcPath[MAX_FILE_PATH_LEN];
10969570cc8Sopenharmony_ci    char srcFile[MAX_FILE_PATH_LEN];
11069570cc8Sopenharmony_ci    char dstFile[MAX_FILE_PATH_LEN];
11169570cc8Sopenharmony_ci    int ret;
11269570cc8Sopenharmony_ci    DIR *dir;
11369570cc8Sopenharmony_ci    struct dirent *entry;
11469570cc8Sopenharmony_ci
11569570cc8Sopenharmony_ci    ret = sprintf_s(srcPath, MAX_FILE_PATH_LEN, "%s/bin", installPath);
11669570cc8Sopenharmony_ci    if (ret < 0) {
11769570cc8Sopenharmony_ci        HNP_LOGE("sprintf install bin path unsuccess.");
11869570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
11969570cc8Sopenharmony_ci    }
12069570cc8Sopenharmony_ci
12169570cc8Sopenharmony_ci    if ((dir = opendir(srcPath)) == NULL) {
12269570cc8Sopenharmony_ci        HNP_LOGI("soft link bin file:%{public}s not exist", srcPath);
12369570cc8Sopenharmony_ci        return 0;
12469570cc8Sopenharmony_ci    }
12569570cc8Sopenharmony_ci
12669570cc8Sopenharmony_ci    if (access(dstPath, F_OK) != 0) {
12769570cc8Sopenharmony_ci        ret = mkdir(dstPath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
12869570cc8Sopenharmony_ci        if ((ret != 0) && (errno != EEXIST)) {
12969570cc8Sopenharmony_ci            closedir(dir);
13069570cc8Sopenharmony_ci            HNP_LOGE("mkdir [%{public}s] unsuccess, ret=%{public}d, errno:%{public}d", dstPath, ret, errno);
13169570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_MKDIR_PATH_FAILED;
13269570cc8Sopenharmony_ci        }
13369570cc8Sopenharmony_ci    }
13469570cc8Sopenharmony_ci
13569570cc8Sopenharmony_ci    while (((entry = readdir(dir)) != NULL)) {
13669570cc8Sopenharmony_ci        /* 非二进制文件跳过 */
13769570cc8Sopenharmony_ci        if (entry->d_type != DT_REG) {
13869570cc8Sopenharmony_ci            continue;
13969570cc8Sopenharmony_ci        }
14069570cc8Sopenharmony_ci        ret = sprintf_s(srcFile, MAX_FILE_PATH_LEN, "%s/%s", srcPath, entry->d_name);
14169570cc8Sopenharmony_ci        if (ret < 0) {
14269570cc8Sopenharmony_ci            closedir(dir);
14369570cc8Sopenharmony_ci            HNP_LOGE("sprintf install bin src file unsuccess.");
14469570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
14569570cc8Sopenharmony_ci        }
14669570cc8Sopenharmony_ci
14769570cc8Sopenharmony_ci        ret = sprintf_s(dstFile, MAX_FILE_PATH_LEN, "%s/%s", dstPath, entry->d_name);
14869570cc8Sopenharmony_ci        if (ret < 0) {
14969570cc8Sopenharmony_ci            closedir(dir);
15069570cc8Sopenharmony_ci            HNP_LOGE("sprintf install bin dst file unsuccess.");
15169570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
15269570cc8Sopenharmony_ci        }
15369570cc8Sopenharmony_ci        /* 生成软链接 */
15469570cc8Sopenharmony_ci        ret = HnpSymlink(srcFile, dstFile);
15569570cc8Sopenharmony_ci        if (ret != 0) {
15669570cc8Sopenharmony_ci            closedir(dir);
15769570cc8Sopenharmony_ci            return ret;
15869570cc8Sopenharmony_ci        }
15969570cc8Sopenharmony_ci    }
16069570cc8Sopenharmony_ci
16169570cc8Sopenharmony_ci    closedir(dir);
16269570cc8Sopenharmony_ci    return 0;
16369570cc8Sopenharmony_ci}
16469570cc8Sopenharmony_ci
16569570cc8Sopenharmony_cistatic int HnpGenerateSoftLink(const char *installPath, const char *hnpBasePath, HnpCfgInfo *hnpCfg)
16669570cc8Sopenharmony_ci{
16769570cc8Sopenharmony_ci    int ret = 0;
16869570cc8Sopenharmony_ci    char binPath[MAX_FILE_PATH_LEN];
16969570cc8Sopenharmony_ci
17069570cc8Sopenharmony_ci    ret = sprintf_s(binPath, MAX_FILE_PATH_LEN, "%s/bin", hnpBasePath);
17169570cc8Sopenharmony_ci    if (ret < 0) {
17269570cc8Sopenharmony_ci        HNP_LOGE("sprintf install bin path unsuccess.");
17369570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
17469570cc8Sopenharmony_ci    }
17569570cc8Sopenharmony_ci
17669570cc8Sopenharmony_ci    if (hnpCfg->linkNum == 0) {
17769570cc8Sopenharmony_ci        ret = HnpGenerateSoftLinkAll(installPath, binPath);
17869570cc8Sopenharmony_ci    } else {
17969570cc8Sopenharmony_ci        ret = HnpGenerateSoftLinkAllByJson(installPath, binPath, hnpCfg);
18069570cc8Sopenharmony_ci    }
18169570cc8Sopenharmony_ci
18269570cc8Sopenharmony_ci    return ret;
18369570cc8Sopenharmony_ci}
18469570cc8Sopenharmony_ci
18569570cc8Sopenharmony_cistatic int HnpInstall(const char *hnpFile, HnpInstallInfo *hnpInfo, HnpCfgInfo *hnpCfg,
18669570cc8Sopenharmony_ci    HnpSignMapInfo *hnpSignMapInfos, int *count)
18769570cc8Sopenharmony_ci{
18869570cc8Sopenharmony_ci    int ret;
18969570cc8Sopenharmony_ci
19069570cc8Sopenharmony_ci    /* 解压hnp文件 */
19169570cc8Sopenharmony_ci    ret = HnpUnZip(hnpFile, hnpInfo->hnpVersionPath, hnpInfo->hnpSignKeyPrefix, hnpSignMapInfos, count);
19269570cc8Sopenharmony_ci    if (ret != 0) {
19369570cc8Sopenharmony_ci        return ret; /* 内部已打印日志 */
19469570cc8Sopenharmony_ci    }
19569570cc8Sopenharmony_ci
19669570cc8Sopenharmony_ci    /* 生成软链 */
19769570cc8Sopenharmony_ci    return HnpGenerateSoftLink(hnpInfo->hnpVersionPath, hnpInfo->hnpBasePath, hnpCfg);
19869570cc8Sopenharmony_ci}
19969570cc8Sopenharmony_ci
20069570cc8Sopenharmony_ci/**
20169570cc8Sopenharmony_ci * 卸载公共hnp.
20269570cc8Sopenharmony_ci *
20369570cc8Sopenharmony_ci * @param packageName hap名称.
20469570cc8Sopenharmony_ci * @param name  hnp名称
20569570cc8Sopenharmony_ci * @param version 版本号.
20669570cc8Sopenharmony_ci * @param uid 用户id.
20769570cc8Sopenharmony_ci * @param isInstallVersion 是否卸载安装版本.
20869570cc8Sopenharmony_ci *
20969570cc8Sopenharmony_ci * @return 0:success;other means failure.
21069570cc8Sopenharmony_ci */
21169570cc8Sopenharmony_cistatic int HnpUnInstallPublicHnp(const char* packageName, const char *name, const char *version, int uid,
21269570cc8Sopenharmony_ci    bool isInstallVersion)
21369570cc8Sopenharmony_ci{
21469570cc8Sopenharmony_ci    int ret;
21569570cc8Sopenharmony_ci    char hnpNamePath[MAX_FILE_PATH_LEN];
21669570cc8Sopenharmony_ci    char hnpVersionPath[MAX_FILE_PATH_LEN];
21769570cc8Sopenharmony_ci    char sandboxPath[MAX_FILE_PATH_LEN];
21869570cc8Sopenharmony_ci
21969570cc8Sopenharmony_ci    if (sprintf_s(hnpNamePath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d/hnppublic/%s.org", uid, name) < 0) {
22069570cc8Sopenharmony_ci        HNP_LOGE("hnp uninstall name path sprintf unsuccess,uid:%{public}d,name:%{public}s", uid, name);
22169570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
22269570cc8Sopenharmony_ci    }
22369570cc8Sopenharmony_ci
22469570cc8Sopenharmony_ci    if (sprintf_s(hnpVersionPath, MAX_FILE_PATH_LEN, "%s/%s_%s", hnpNamePath, name, version) < 0) {
22569570cc8Sopenharmony_ci        HNP_LOGE("hnp uninstall sprintf version path unsuccess.");
22669570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
22769570cc8Sopenharmony_ci    }
22869570cc8Sopenharmony_ci
22969570cc8Sopenharmony_ci    if (sprintf_s(sandboxPath, MAX_FILE_PATH_LEN, HNP_SANDBOX_BASE_PATH"/%s.org", name) < 0) {
23069570cc8Sopenharmony_ci        HNP_LOGE("sprintf unstall base path unsuccess.");
23169570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
23269570cc8Sopenharmony_ci    }
23369570cc8Sopenharmony_ci
23469570cc8Sopenharmony_ci    ret = HnpProcessRunCheck(sandboxPath);
23569570cc8Sopenharmony_ci    if (ret != 0) {
23669570cc8Sopenharmony_ci        return ret;
23769570cc8Sopenharmony_ci    }
23869570cc8Sopenharmony_ci
23969570cc8Sopenharmony_ci    if (!isInstallVersion) {
24069570cc8Sopenharmony_ci        ret = HnpPackageInfoHnpDelete(packageName, name, version);
24169570cc8Sopenharmony_ci        if (ret != 0) {
24269570cc8Sopenharmony_ci            return ret;
24369570cc8Sopenharmony_ci        }
24469570cc8Sopenharmony_ci    }
24569570cc8Sopenharmony_ci
24669570cc8Sopenharmony_ci    ret = HnpDeleteFolder(hnpVersionPath);
24769570cc8Sopenharmony_ci    if (ret != 0) {
24869570cc8Sopenharmony_ci        return ret;
24969570cc8Sopenharmony_ci    }
25069570cc8Sopenharmony_ci
25169570cc8Sopenharmony_ci    if (HnpPathFileCount(hnpNamePath) == 0) {
25269570cc8Sopenharmony_ci        return HnpDeleteFolder(hnpNamePath);
25369570cc8Sopenharmony_ci    }
25469570cc8Sopenharmony_ci
25569570cc8Sopenharmony_ci    return 0;
25669570cc8Sopenharmony_ci}
25769570cc8Sopenharmony_ci
25869570cc8Sopenharmony_cistatic int HnpNativeUnInstall(HnpPackageInfo *packageInfo, int uid, const char *packageName)
25969570cc8Sopenharmony_ci{
26069570cc8Sopenharmony_ci    int ret = 0;
26169570cc8Sopenharmony_ci
26269570cc8Sopenharmony_ci    HNP_LOGI("hnp uninstall start now! name=%{public}s,version=[%{public}s,%{public}s],uid=%{public}d,"
26369570cc8Sopenharmony_ci        "package=%{public}s", packageInfo->name, packageInfo->currentVersion, packageInfo->installVersion, uid,
26469570cc8Sopenharmony_ci        packageName);
26569570cc8Sopenharmony_ci
26669570cc8Sopenharmony_ci    if (!packageInfo->hnpExist) {
26769570cc8Sopenharmony_ci        ret = HnpUnInstallPublicHnp(packageName, packageInfo->name, packageInfo->currentVersion, uid, false);
26869570cc8Sopenharmony_ci        if (ret != 0) {
26969570cc8Sopenharmony_ci            return ret;
27069570cc8Sopenharmony_ci        }
27169570cc8Sopenharmony_ci    }
27269570cc8Sopenharmony_ci
27369570cc8Sopenharmony_ci    if (strcmp(packageInfo->installVersion, "none") != 0 &&
27469570cc8Sopenharmony_ci        strcmp(packageInfo->currentVersion, packageInfo->installVersion) != 0) {
27569570cc8Sopenharmony_ci        ret = HnpUnInstallPublicHnp(packageName, packageInfo->name, packageInfo->installVersion, uid, true);
27669570cc8Sopenharmony_ci        if (ret != 0) {
27769570cc8Sopenharmony_ci            return ret;
27869570cc8Sopenharmony_ci        }
27969570cc8Sopenharmony_ci    }
28069570cc8Sopenharmony_ci    HNP_LOGI("hnp uninstall end! ret=%{public}d", ret);
28169570cc8Sopenharmony_ci
28269570cc8Sopenharmony_ci    return 0;
28369570cc8Sopenharmony_ci}
28469570cc8Sopenharmony_ci
28569570cc8Sopenharmony_cistatic int HnpUnInstall(int uid, const char *packageName)
28669570cc8Sopenharmony_ci{
28769570cc8Sopenharmony_ci    HnpPackageInfo *packageInfo = NULL;
28869570cc8Sopenharmony_ci    int count = 0;
28969570cc8Sopenharmony_ci    char privatePath[MAX_FILE_PATH_LEN];
29069570cc8Sopenharmony_ci    char dstPath[MAX_FILE_PATH_LEN];
29169570cc8Sopenharmony_ci
29269570cc8Sopenharmony_ci    /* 拼接卸载路径 */
29369570cc8Sopenharmony_ci    if (sprintf_s(dstPath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d", uid) < 0) {
29469570cc8Sopenharmony_ci        HNP_LOGE("hnp install sprintf unsuccess, uid:%{public}d", uid);
29569570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
29669570cc8Sopenharmony_ci    }
29769570cc8Sopenharmony_ci
29869570cc8Sopenharmony_ci    /* 验证卸载路径是否存在 */
29969570cc8Sopenharmony_ci    if (access(dstPath, F_OK) != 0) {
30069570cc8Sopenharmony_ci        HNP_LOGE("hnp uninstall uid path[%{public}s] is not exist", dstPath);
30169570cc8Sopenharmony_ci        return HNP_ERRNO_UNINSTALLER_HNP_PATH_NOT_EXIST;
30269570cc8Sopenharmony_ci    }
30369570cc8Sopenharmony_ci
30469570cc8Sopenharmony_ci    int ret = HnpPackageInfoGet(packageName, &packageInfo, &count);
30569570cc8Sopenharmony_ci    if (ret != 0) {
30669570cc8Sopenharmony_ci        return ret;
30769570cc8Sopenharmony_ci    }
30869570cc8Sopenharmony_ci
30969570cc8Sopenharmony_ci    /* 卸载公有native */
31069570cc8Sopenharmony_ci    for (int i = 0; i < count; i++) {
31169570cc8Sopenharmony_ci        ret = HnpNativeUnInstall(&packageInfo[i], uid, packageName);
31269570cc8Sopenharmony_ci        if (ret != 0) {
31369570cc8Sopenharmony_ci            free(packageInfo);
31469570cc8Sopenharmony_ci            return ret;
31569570cc8Sopenharmony_ci        }
31669570cc8Sopenharmony_ci    }
31769570cc8Sopenharmony_ci    free(packageInfo);
31869570cc8Sopenharmony_ci
31969570cc8Sopenharmony_ci    ret = HnpPackageInfoDelete(packageName);
32069570cc8Sopenharmony_ci    if (ret != 0) {
32169570cc8Sopenharmony_ci        return ret;
32269570cc8Sopenharmony_ci    }
32369570cc8Sopenharmony_ci
32469570cc8Sopenharmony_ci    if (sprintf_s(privatePath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d/hnp/%s", uid, packageName) < 0) {
32569570cc8Sopenharmony_ci        HNP_LOGE("hnp uninstall private path sprintf unsuccess, uid:%{public}d,package name[%{public}s]", uid,
32669570cc8Sopenharmony_ci            packageName);
32769570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
32869570cc8Sopenharmony_ci    }
32969570cc8Sopenharmony_ci
33069570cc8Sopenharmony_ci    (void)HnpDeleteFolder(privatePath);
33169570cc8Sopenharmony_ci
33269570cc8Sopenharmony_ci    return 0;
33369570cc8Sopenharmony_ci}
33469570cc8Sopenharmony_ci
33569570cc8Sopenharmony_cistatic int HnpInstallForceCheck(HnpCfgInfo *hnpCfgInfo, HnpInstallInfo *hnpInfo)
33669570cc8Sopenharmony_ci{
33769570cc8Sopenharmony_ci    int ret = 0;
33869570cc8Sopenharmony_ci
33969570cc8Sopenharmony_ci    /* 判断安装目录是否存在,存在判断是否是强制安装,如果是则走卸载流程,否则返回错误 */
34069570cc8Sopenharmony_ci    if (access(hnpInfo->hnpSoftwarePath, F_OK) == 0) {
34169570cc8Sopenharmony_ci        if (hnpInfo->hapInstallInfo->isForce == false) {
34269570cc8Sopenharmony_ci            HNP_LOGE("hnp install path[%{public}s] exist, but force is false", hnpInfo->hnpSoftwarePath);
34369570cc8Sopenharmony_ci            return HNP_ERRNO_INSTALLER_PATH_IS_EXIST;
34469570cc8Sopenharmony_ci        }
34569570cc8Sopenharmony_ci        if (hnpInfo->isPublic == false) {
34669570cc8Sopenharmony_ci            if (HnpDeleteFolder(hnpInfo->hnpSoftwarePath) != 0) {
34769570cc8Sopenharmony_ci                return ret;
34869570cc8Sopenharmony_ci            }
34969570cc8Sopenharmony_ci        }
35069570cc8Sopenharmony_ci    }
35169570cc8Sopenharmony_ci
35269570cc8Sopenharmony_ci    ret = HnpCreateFolder(hnpInfo->hnpVersionPath);
35369570cc8Sopenharmony_ci    if (ret != 0) {
35469570cc8Sopenharmony_ci        return HnpDeleteFolder(hnpInfo->hnpVersionPath);
35569570cc8Sopenharmony_ci    }
35669570cc8Sopenharmony_ci    return ret;
35769570cc8Sopenharmony_ci}
35869570cc8Sopenharmony_ci
35969570cc8Sopenharmony_cistatic int HnpInstallPathGet(HnpCfgInfo *hnpCfgInfo, HnpInstallInfo *hnpInfo)
36069570cc8Sopenharmony_ci{
36169570cc8Sopenharmony_ci    int ret;
36269570cc8Sopenharmony_ci
36369570cc8Sopenharmony_ci    /* 拼接安装路径 */
36469570cc8Sopenharmony_ci    ret = sprintf_s(hnpInfo->hnpSoftwarePath, MAX_FILE_PATH_LEN, "%s/%s.org", hnpInfo->hnpBasePath,
36569570cc8Sopenharmony_ci        hnpCfgInfo->name);
36669570cc8Sopenharmony_ci    if (ret < 0) {
36769570cc8Sopenharmony_ci        HNP_LOGE("hnp install sprintf hnp base path unsuccess.");
36869570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
36969570cc8Sopenharmony_ci    }
37069570cc8Sopenharmony_ci
37169570cc8Sopenharmony_ci    /* 拼接安装路径 */
37269570cc8Sopenharmony_ci    ret = sprintf_s(hnpInfo->hnpVersionPath, MAX_FILE_PATH_LEN, "%s/%s_%s", hnpInfo->hnpSoftwarePath,
37369570cc8Sopenharmony_ci        hnpCfgInfo->name, hnpCfgInfo->version);
37469570cc8Sopenharmony_ci    if (ret < 0) {
37569570cc8Sopenharmony_ci        HNP_LOGE("hnp install sprintf install path unsuccess.");
37669570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
37769570cc8Sopenharmony_ci    }
37869570cc8Sopenharmony_ci
37969570cc8Sopenharmony_ci    return 0;
38069570cc8Sopenharmony_ci}
38169570cc8Sopenharmony_ci
38269570cc8Sopenharmony_cistatic int HnpPublicDealAfterInstall(HnpInstallInfo *hnpInfo, HnpCfgInfo *hnpCfg)
38369570cc8Sopenharmony_ci{
38469570cc8Sopenharmony_ci    char *version = HnpCurrentVersionUninstallCheck(hnpCfg->name);
38569570cc8Sopenharmony_ci    if (version == NULL) {
38669570cc8Sopenharmony_ci        version = HnpCurrentVersionGet(hnpCfg->name);
38769570cc8Sopenharmony_ci        if (version != NULL) {
38869570cc8Sopenharmony_ci            HnpUnInstallPublicHnp(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg->name, version,
38969570cc8Sopenharmony_ci                hnpInfo->hapInstallInfo->uid, true);
39069570cc8Sopenharmony_ci        }
39169570cc8Sopenharmony_ci    }
39269570cc8Sopenharmony_ci    if (version != NULL) {
39369570cc8Sopenharmony_ci        free(version);
39469570cc8Sopenharmony_ci    }
39569570cc8Sopenharmony_ci    hnpCfg->isInstall = true;
39669570cc8Sopenharmony_ci
39769570cc8Sopenharmony_ci    return HnpInstallInfoJsonWrite(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg);
39869570cc8Sopenharmony_ci}
39969570cc8Sopenharmony_ci
40069570cc8Sopenharmony_cistatic int HnpReadAndInstall(char *srcFile, HnpInstallInfo *hnpInfo, HnpSignMapInfo *hnpSignMapInfos, int *count)
40169570cc8Sopenharmony_ci{
40269570cc8Sopenharmony_ci    int ret;
40369570cc8Sopenharmony_ci    HnpCfgInfo hnpCfg = {0};
40469570cc8Sopenharmony_ci
40569570cc8Sopenharmony_ci    HNP_LOGI("hnp install start now! src file=%{public}s, dst path=%{public}s", srcFile, hnpInfo->hnpBasePath);
40669570cc8Sopenharmony_ci    /* 从hnp zip获取cfg信息 */
40769570cc8Sopenharmony_ci    ret = HnpCfgGetFromZip(srcFile, &hnpCfg);
40869570cc8Sopenharmony_ci    if (ret != 0) {
40969570cc8Sopenharmony_ci        return ret;
41069570cc8Sopenharmony_ci    }
41169570cc8Sopenharmony_ci
41269570cc8Sopenharmony_ci    ret = HnpInstallPathGet(&hnpCfg, hnpInfo);
41369570cc8Sopenharmony_ci    if (ret != 0) {
41469570cc8Sopenharmony_ci        // 释放软链接占用的内存
41569570cc8Sopenharmony_ci        if (hnpCfg.links != NULL) {
41669570cc8Sopenharmony_ci            free(hnpCfg.links);
41769570cc8Sopenharmony_ci        }
41869570cc8Sopenharmony_ci        return ret;
41969570cc8Sopenharmony_ci    }
42069570cc8Sopenharmony_ci
42169570cc8Sopenharmony_ci    /* 存在对应版本的公有hnp包跳过安装 */
42269570cc8Sopenharmony_ci    if (access(hnpInfo->hnpVersionPath, F_OK) == 0 && hnpInfo->isPublic) {
42369570cc8Sopenharmony_ci        /* 刷新软链 */
42469570cc8Sopenharmony_ci        ret = HnpGenerateSoftLink(hnpInfo->hnpVersionPath, hnpInfo->hnpBasePath, &hnpCfg);
42569570cc8Sopenharmony_ci        if (ret != 0) {
42669570cc8Sopenharmony_ci            return ret;
42769570cc8Sopenharmony_ci        }
42869570cc8Sopenharmony_ci        // 释放软链接占用的内存
42969570cc8Sopenharmony_ci        if (hnpCfg.links != NULL) {
43069570cc8Sopenharmony_ci            free(hnpCfg.links);
43169570cc8Sopenharmony_ci        }
43269570cc8Sopenharmony_ci        return HnpPublicDealAfterInstall(hnpInfo, &hnpCfg);
43369570cc8Sopenharmony_ci    }
43469570cc8Sopenharmony_ci
43569570cc8Sopenharmony_ci    ret = HnpInstallForceCheck(&hnpCfg, hnpInfo);
43669570cc8Sopenharmony_ci    if (ret != 0) {
43769570cc8Sopenharmony_ci        // 释放软链接占用的内存
43869570cc8Sopenharmony_ci        if (hnpCfg.links != NULL) {
43969570cc8Sopenharmony_ci            free(hnpCfg.links);
44069570cc8Sopenharmony_ci        }
44169570cc8Sopenharmony_ci        return ret;
44269570cc8Sopenharmony_ci    }
44369570cc8Sopenharmony_ci
44469570cc8Sopenharmony_ci    /* hnp安装 */
44569570cc8Sopenharmony_ci    ret = HnpInstall(srcFile, hnpInfo, &hnpCfg, hnpSignMapInfos, count);
44669570cc8Sopenharmony_ci    // 释放软链接占用的内存
44769570cc8Sopenharmony_ci    if (hnpCfg.links != NULL) {
44869570cc8Sopenharmony_ci        free(hnpCfg.links);
44969570cc8Sopenharmony_ci    }
45069570cc8Sopenharmony_ci    if (ret != 0) {
45169570cc8Sopenharmony_ci        HnpUnInstallPublicHnp(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg.name, hnpCfg.version,
45269570cc8Sopenharmony_ci            hnpInfo->hapInstallInfo->uid, false);
45369570cc8Sopenharmony_ci        return ret;
45469570cc8Sopenharmony_ci    }
45569570cc8Sopenharmony_ci
45669570cc8Sopenharmony_ci    if (hnpInfo->isPublic) {
45769570cc8Sopenharmony_ci        ret = HnpPublicDealAfterInstall(hnpInfo, &hnpCfg);
45869570cc8Sopenharmony_ci        if (ret != 0) {
45969570cc8Sopenharmony_ci            HnpUnInstallPublicHnp(hnpInfo->hapInstallInfo->hapPackageName, hnpCfg.name, hnpCfg.version,
46069570cc8Sopenharmony_ci                hnpInfo->hapInstallInfo->uid, false);
46169570cc8Sopenharmony_ci        }
46269570cc8Sopenharmony_ci    }
46369570cc8Sopenharmony_ci
46469570cc8Sopenharmony_ci    return ret;
46569570cc8Sopenharmony_ci}
46669570cc8Sopenharmony_ci
46769570cc8Sopenharmony_cistatic bool HnpFileCheck(const char *file)
46869570cc8Sopenharmony_ci{
46969570cc8Sopenharmony_ci    const char suffix[] = ".hnp";
47069570cc8Sopenharmony_ci    int len = strlen(file);
47169570cc8Sopenharmony_ci    int suffixLen = strlen(suffix);
47269570cc8Sopenharmony_ci    if ((len >= suffixLen) && (strcmp(file + len - suffixLen, suffix) == 0)) {
47369570cc8Sopenharmony_ci        return true;
47469570cc8Sopenharmony_ci    }
47569570cc8Sopenharmony_ci
47669570cc8Sopenharmony_ci    return false;
47769570cc8Sopenharmony_ci}
47869570cc8Sopenharmony_ci
47969570cc8Sopenharmony_cistatic int HnpPackageGetAndInstall(const char *dirPath, HnpInstallInfo *hnpInfo, char *sunDir,
48069570cc8Sopenharmony_ci    HnpSignMapInfo *hnpSignMapInfos, int *count)
48169570cc8Sopenharmony_ci{
48269570cc8Sopenharmony_ci    DIR *dir;
48369570cc8Sopenharmony_ci    struct dirent *entry;
48469570cc8Sopenharmony_ci    char path[MAX_FILE_PATH_LEN];
48569570cc8Sopenharmony_ci    char sunDirNew[MAX_FILE_PATH_LEN];
48669570cc8Sopenharmony_ci
48769570cc8Sopenharmony_ci    if ((dir = opendir(dirPath)) == NULL) {
48869570cc8Sopenharmony_ci        HNP_LOGE("hnp install opendir:%{public}s unsuccess, errno=%{public}d", dirPath, errno);
48969570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_DIR_OPEN_FAILED;
49069570cc8Sopenharmony_ci    }
49169570cc8Sopenharmony_ci
49269570cc8Sopenharmony_ci    while ((entry = readdir(dir)) != NULL) {
49369570cc8Sopenharmony_ci        if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
49469570cc8Sopenharmony_ci            continue;
49569570cc8Sopenharmony_ci        }
49669570cc8Sopenharmony_ci        if (sprintf_s(path, MAX_FILE_PATH_LEN, "%s/%s", dirPath, entry->d_name) < 0) {
49769570cc8Sopenharmony_ci            HNP_LOGE("hnp install sprintf unsuccess, dir[%{public}s], path[%{public}s]", dirPath, entry->d_name);
49869570cc8Sopenharmony_ci            closedir(dir);
49969570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
50069570cc8Sopenharmony_ci        }
50169570cc8Sopenharmony_ci
50269570cc8Sopenharmony_ci        if (entry->d_type == DT_DIR) {
50369570cc8Sopenharmony_ci            if (sprintf_s(sunDirNew, MAX_FILE_PATH_LEN, "%s%s/", sunDir, entry->d_name) < 0) {
50469570cc8Sopenharmony_ci                HNP_LOGE("hnp install sprintf sub dir unsuccess");
50569570cc8Sopenharmony_ci                closedir(dir);
50669570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_SPRINTF_FAILED;
50769570cc8Sopenharmony_ci            }
50869570cc8Sopenharmony_ci            int ret = HnpPackageGetAndInstall(path, hnpInfo, sunDirNew, hnpSignMapInfos, count);
50969570cc8Sopenharmony_ci            if (ret != 0) {
51069570cc8Sopenharmony_ci                closedir(dir);
51169570cc8Sopenharmony_ci                return ret;
51269570cc8Sopenharmony_ci            }
51369570cc8Sopenharmony_ci        } else {
51469570cc8Sopenharmony_ci            if (HnpFileCheck(path) == false) {
51569570cc8Sopenharmony_ci                continue;
51669570cc8Sopenharmony_ci            }
51769570cc8Sopenharmony_ci            if (sprintf_s(hnpInfo->hnpSignKeyPrefix, MAX_FILE_PATH_LEN, "hnp/%s/%s%s", hnpInfo->hapInstallInfo->abi,
51869570cc8Sopenharmony_ci                sunDir, entry->d_name) < 0) {
51969570cc8Sopenharmony_ci                HNP_LOGE("hnp install sprintf unsuccess,sub[%{public}s],path[%{public}s]", sunDir, entry->d_name);
52069570cc8Sopenharmony_ci                closedir(dir);
52169570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_SPRINTF_FAILED;
52269570cc8Sopenharmony_ci            }
52369570cc8Sopenharmony_ci            int ret = HnpReadAndInstall(path, hnpInfo, hnpSignMapInfos, count);
52469570cc8Sopenharmony_ci            HNP_LOGI("hnp install end, ret=%{public}d", ret);
52569570cc8Sopenharmony_ci            if (ret != 0) {
52669570cc8Sopenharmony_ci                closedir(dir);
52769570cc8Sopenharmony_ci                return ret;
52869570cc8Sopenharmony_ci            }
52969570cc8Sopenharmony_ci        }
53069570cc8Sopenharmony_ci    }
53169570cc8Sopenharmony_ci    closedir(dir);
53269570cc8Sopenharmony_ci    return 0;
53369570cc8Sopenharmony_ci}
53469570cc8Sopenharmony_ci
53569570cc8Sopenharmony_cistatic int HapReadAndInstall(const char *dstPath, HapInstallInfo *installInfo, HnpSignMapInfo *hnpSignMapInfos,
53669570cc8Sopenharmony_ci    int *count)
53769570cc8Sopenharmony_ci{
53869570cc8Sopenharmony_ci    struct dirent *entry;
53969570cc8Sopenharmony_ci    char hnpPath[MAX_FILE_PATH_LEN];
54069570cc8Sopenharmony_ci    HnpInstallInfo hnpInfo = {0};
54169570cc8Sopenharmony_ci    int ret;
54269570cc8Sopenharmony_ci
54369570cc8Sopenharmony_ci    DIR *dir = opendir(installInfo->hnpRootPath);
54469570cc8Sopenharmony_ci    if (dir == NULL) {
54569570cc8Sopenharmony_ci        HNP_LOGE("hnp install opendir:%{public}s unsuccess, errno=%{public}d", installInfo->hnpRootPath, errno);
54669570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_DIR_OPEN_FAILED;
54769570cc8Sopenharmony_ci    }
54869570cc8Sopenharmony_ci
54969570cc8Sopenharmony_ci    hnpInfo.hapInstallInfo = installInfo;
55069570cc8Sopenharmony_ci    /* 遍历src目录 */
55169570cc8Sopenharmony_ci    while ((entry = readdir(dir)) != NULL) {
55269570cc8Sopenharmony_ci        if (strcmp(entry->d_name, "public") == 0) {
55369570cc8Sopenharmony_ci            hnpInfo.isPublic = true;
55469570cc8Sopenharmony_ci            if ((sprintf_s(hnpInfo.hnpBasePath, MAX_FILE_PATH_LEN, "%s/hnppublic", dstPath) < 0) ||
55569570cc8Sopenharmony_ci                (sprintf_s(hnpPath, MAX_FILE_PATH_LEN, "%s/public", installInfo->hnpRootPath) < 0)) {
55669570cc8Sopenharmony_ci                HNP_LOGE("hnp install public base path sprintf unsuccess.");
55769570cc8Sopenharmony_ci                closedir(dir);
55869570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_SPRINTF_FAILED;
55969570cc8Sopenharmony_ci            }
56069570cc8Sopenharmony_ci        } else if (strcmp(entry->d_name, "private") == 0) {
56169570cc8Sopenharmony_ci            hnpInfo.isPublic = false;
56269570cc8Sopenharmony_ci            if ((sprintf_s(hnpInfo.hnpBasePath, MAX_FILE_PATH_LEN, "%s/hnp/%s", dstPath,
56369570cc8Sopenharmony_ci                installInfo->hapPackageName) < 0) || (sprintf_s(hnpPath, MAX_FILE_PATH_LEN, "%s/private",
56469570cc8Sopenharmony_ci                installInfo->hnpRootPath) < 0)) {
56569570cc8Sopenharmony_ci                HNP_LOGE("hnp install private base path sprintf unsuccess.");
56669570cc8Sopenharmony_ci                closedir(dir);
56769570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_SPRINTF_FAILED;
56869570cc8Sopenharmony_ci            }
56969570cc8Sopenharmony_ci        } else {
57069570cc8Sopenharmony_ci            continue;
57169570cc8Sopenharmony_ci        }
57269570cc8Sopenharmony_ci
57369570cc8Sopenharmony_ci        ret = HnpPackageGetAndInstall(hnpPath, &hnpInfo, "", hnpSignMapInfos, count);
57469570cc8Sopenharmony_ci        if (ret != 0) {
57569570cc8Sopenharmony_ci            closedir(dir);
57669570cc8Sopenharmony_ci            return ret;
57769570cc8Sopenharmony_ci        }
57869570cc8Sopenharmony_ci    }
57969570cc8Sopenharmony_ci
58069570cc8Sopenharmony_ci    closedir(dir);
58169570cc8Sopenharmony_ci    return 0;
58269570cc8Sopenharmony_ci}
58369570cc8Sopenharmony_ci
58469570cc8Sopenharmony_cistatic int HnpInstallHnpFileCountGet(char *hnpPath, int *count)
58569570cc8Sopenharmony_ci{
58669570cc8Sopenharmony_ci    DIR *dir;
58769570cc8Sopenharmony_ci    struct dirent *entry;
58869570cc8Sopenharmony_ci    char path[MAX_FILE_PATH_LEN];
58969570cc8Sopenharmony_ci    int ret;
59069570cc8Sopenharmony_ci
59169570cc8Sopenharmony_ci    if ((dir = opendir(hnpPath)) == NULL) {
59269570cc8Sopenharmony_ci        HNP_LOGE("hnp install count get opendir:%{public}s unsuccess, errno=%{public}d", hnpPath, errno);
59369570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_DIR_OPEN_FAILED;
59469570cc8Sopenharmony_ci    }
59569570cc8Sopenharmony_ci
59669570cc8Sopenharmony_ci    while ((entry = readdir(dir)) != NULL) {
59769570cc8Sopenharmony_ci        if ((strcmp(entry->d_name, ".") == 0) || (strcmp(entry->d_name, "..") == 0)) {
59869570cc8Sopenharmony_ci            continue;
59969570cc8Sopenharmony_ci        }
60069570cc8Sopenharmony_ci
60169570cc8Sopenharmony_ci        if (sprintf_s(path, MAX_FILE_PATH_LEN, "%s/%s", hnpPath, entry->d_name) < 0) {
60269570cc8Sopenharmony_ci            HNP_LOGE("hnp install count get sprintf unsuccess, dir[%{public}s], path[%{public}s]", hnpPath,
60369570cc8Sopenharmony_ci                entry->d_name);
60469570cc8Sopenharmony_ci            closedir(dir);
60569570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
60669570cc8Sopenharmony_ci        }
60769570cc8Sopenharmony_ci
60869570cc8Sopenharmony_ci        if (entry->d_type == DT_DIR) {
60969570cc8Sopenharmony_ci            if (sprintf_s(path, MAX_FILE_PATH_LEN, "%s/%s", hnpPath, entry->d_name) < 0) {
61069570cc8Sopenharmony_ci                HNP_LOGE("hnp install sprintf sub dir unsuccess");
61169570cc8Sopenharmony_ci                closedir(dir);
61269570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_SPRINTF_FAILED;
61369570cc8Sopenharmony_ci            }
61469570cc8Sopenharmony_ci            ret = HnpInstallHnpFileCountGet(path, count);
61569570cc8Sopenharmony_ci            if (ret != 0) {
61669570cc8Sopenharmony_ci                closedir(dir);
61769570cc8Sopenharmony_ci                return ret;
61869570cc8Sopenharmony_ci            }
61969570cc8Sopenharmony_ci        } else {
62069570cc8Sopenharmony_ci            if (HnpFileCheck(path) == false) {
62169570cc8Sopenharmony_ci                continue;
62269570cc8Sopenharmony_ci            }
62369570cc8Sopenharmony_ci            ret = HnpFileCountGet(path, count);
62469570cc8Sopenharmony_ci            if (ret != 0) {
62569570cc8Sopenharmony_ci                closedir(dir);
62669570cc8Sopenharmony_ci                return ret;
62769570cc8Sopenharmony_ci            }
62869570cc8Sopenharmony_ci        }
62969570cc8Sopenharmony_ci    }
63069570cc8Sopenharmony_ci
63169570cc8Sopenharmony_ci    closedir(dir);
63269570cc8Sopenharmony_ci    return 0;
63369570cc8Sopenharmony_ci}
63469570cc8Sopenharmony_ci
63569570cc8Sopenharmony_cistatic int HnpInstallHapFileCountGet(const char *root, int *count)
63669570cc8Sopenharmony_ci{
63769570cc8Sopenharmony_ci    struct dirent *entry;
63869570cc8Sopenharmony_ci    char hnpPath[MAX_FILE_PATH_LEN];
63969570cc8Sopenharmony_ci
64069570cc8Sopenharmony_ci    DIR *dir = opendir(root);
64169570cc8Sopenharmony_ci    if (dir == NULL) {
64269570cc8Sopenharmony_ci        HNP_LOGE("hnp install opendir:%{public}s unsuccess, errno=%{public}d", root, errno);
64369570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_DIR_OPEN_FAILED;
64469570cc8Sopenharmony_ci    }
64569570cc8Sopenharmony_ci
64669570cc8Sopenharmony_ci    while ((entry = readdir(dir)) != NULL) {
64769570cc8Sopenharmony_ci        if ((strcmp(entry->d_name, "public") != 0) && (strcmp(entry->d_name, "private") != 0)) {
64869570cc8Sopenharmony_ci            continue;
64969570cc8Sopenharmony_ci        }
65069570cc8Sopenharmony_ci        if (sprintf_s(hnpPath, MAX_FILE_PATH_LEN, "%s/%s", root, entry->d_name) < 0) {
65169570cc8Sopenharmony_ci            HNP_LOGE("hnp install private base path sprintf unsuccess.");
65269570cc8Sopenharmony_ci            closedir(dir);
65369570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
65469570cc8Sopenharmony_ci        }
65569570cc8Sopenharmony_ci
65669570cc8Sopenharmony_ci        int ret = HnpInstallHnpFileCountGet(hnpPath, count);
65769570cc8Sopenharmony_ci        if (ret != 0) {
65869570cc8Sopenharmony_ci            closedir(dir);
65969570cc8Sopenharmony_ci            return ret;
66069570cc8Sopenharmony_ci        }
66169570cc8Sopenharmony_ci    }
66269570cc8Sopenharmony_ci
66369570cc8Sopenharmony_ci    closedir(dir);
66469570cc8Sopenharmony_ci    return 0;
66569570cc8Sopenharmony_ci}
66669570cc8Sopenharmony_ci
66769570cc8Sopenharmony_cistatic int SetHnpRestorecon(char *path)
66869570cc8Sopenharmony_ci{
66969570cc8Sopenharmony_ci    int ret;
67069570cc8Sopenharmony_ci    char publicPath[MAX_FILE_PATH_LEN] = {0};
67169570cc8Sopenharmony_ci    if (sprintf_s(publicPath, MAX_FILE_PATH_LEN, "%s/hnppublic", path) < 0) {
67269570cc8Sopenharmony_ci        HNP_LOGE("sprintf fail, get hnp restorecon path fail");
67369570cc8Sopenharmony_ci        return HNP_ERRNO_INSTALLER_RESTORECON_HNP_PATH_FAIL;
67469570cc8Sopenharmony_ci    }
67569570cc8Sopenharmony_ci
67669570cc8Sopenharmony_ci    if (access(publicPath, F_OK) != 0) {
67769570cc8Sopenharmony_ci        ret = mkdir(publicPath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
67869570cc8Sopenharmony_ci        if ((ret != 0) && (errno != EEXIST)) {
67969570cc8Sopenharmony_ci            HNP_LOGE("mkdir public path fail");
68069570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_MKDIR_PATH_FAILED;
68169570cc8Sopenharmony_ci        }
68269570cc8Sopenharmony_ci    }
68369570cc8Sopenharmony_ci
68469570cc8Sopenharmony_ci    if (RestoreconRecurse(publicPath)) {
68569570cc8Sopenharmony_ci        HNP_LOGE("restorecon hnp path fail");
68669570cc8Sopenharmony_ci        return HNP_ERRNO_INSTALLER_RESTORECON_HNP_PATH_FAIL;
68769570cc8Sopenharmony_ci    }
68869570cc8Sopenharmony_ci
68969570cc8Sopenharmony_ci    return 0;
69069570cc8Sopenharmony_ci}
69169570cc8Sopenharmony_ci
69269570cc8Sopenharmony_cistatic int CheckInstallPath(char *dstPath, HapInstallInfo *installInfo)
69369570cc8Sopenharmony_ci{
69469570cc8Sopenharmony_ci    /* 拼接安装路径 */
69569570cc8Sopenharmony_ci    if (sprintf_s(dstPath, MAX_FILE_PATH_LEN, HNP_DEFAULT_INSTALL_ROOT_PATH"/%d", installInfo->uid) < 0) {
69669570cc8Sopenharmony_ci        HNP_LOGE("hnp install sprintf unsuccess, uid:%{public}d", installInfo->uid);
69769570cc8Sopenharmony_ci        return HNP_ERRNO_INSTALLER_GET_HNP_PATH_FAILED;
69869570cc8Sopenharmony_ci    }
69969570cc8Sopenharmony_ci
70069570cc8Sopenharmony_ci    /* 验证安装路径是否存在 */
70169570cc8Sopenharmony_ci    if (access(dstPath, F_OK) != 0) {
70269570cc8Sopenharmony_ci        HNP_LOGE("hnp install uid path[%{public}s] is not exist", dstPath);
70369570cc8Sopenharmony_ci        return HNP_ERRNO_INSTALLER_GET_REALPATH_FAILED;
70469570cc8Sopenharmony_ci    }
70569570cc8Sopenharmony_ci
70669570cc8Sopenharmony_ci    /* restorecon hnp 安装目录 */
70769570cc8Sopenharmony_ci    return SetHnpRestorecon(dstPath);
70869570cc8Sopenharmony_ci}
70969570cc8Sopenharmony_ci
71069570cc8Sopenharmony_cistatic int HnpInsatllPre(HapInstallInfo *installInfo)
71169570cc8Sopenharmony_ci{
71269570cc8Sopenharmony_ci    char dstPath[MAX_FILE_PATH_LEN];
71369570cc8Sopenharmony_ci    int count = 0;
71469570cc8Sopenharmony_ci    HnpSignMapInfo *hnpSignMapInfos = NULL;
71569570cc8Sopenharmony_ci#ifdef CODE_SIGNATURE_ENABLE
71669570cc8Sopenharmony_ci    struct EntryMapEntryData data = {0};
71769570cc8Sopenharmony_ci    int i;
71869570cc8Sopenharmony_ci#endif
71969570cc8Sopenharmony_ci    int ret;
72069570cc8Sopenharmony_ci
72169570cc8Sopenharmony_ci    if ((ret = CheckInstallPath(dstPath, installInfo)) != 0 ||
72269570cc8Sopenharmony_ci        (ret = HnpInstallHapFileCountGet(installInfo->hnpRootPath, &count)) != 0) {
72369570cc8Sopenharmony_ci        return ret;
72469570cc8Sopenharmony_ci    }
72569570cc8Sopenharmony_ci
72669570cc8Sopenharmony_ci    if (count > 0) {
72769570cc8Sopenharmony_ci        hnpSignMapInfos = (HnpSignMapInfo *)malloc(sizeof(HnpSignMapInfo) * count);
72869570cc8Sopenharmony_ci        if (hnpSignMapInfos == NULL) {
72969570cc8Sopenharmony_ci            return HNP_ERRNO_NOMEM;
73069570cc8Sopenharmony_ci        }
73169570cc8Sopenharmony_ci    }
73269570cc8Sopenharmony_ci
73369570cc8Sopenharmony_ci    count = 0;
73469570cc8Sopenharmony_ci    ret = HapReadAndInstall(dstPath, installInfo, hnpSignMapInfos, &count);
73569570cc8Sopenharmony_ci    HNP_LOGI("sign start hap path[%{public}s],abi[%{public}s],count=%{public}d", installInfo->hapPath, installInfo->abi,
73669570cc8Sopenharmony_ci        count);
73769570cc8Sopenharmony_ci#ifdef CODE_SIGNATURE_ENABLE
73869570cc8Sopenharmony_ci    if ((ret == 0) && (count > 0)) {
73969570cc8Sopenharmony_ci        data.entries = malloc(sizeof(struct EntryMapEntry) * count);
74069570cc8Sopenharmony_ci        if (data.entries == NULL) {
74169570cc8Sopenharmony_ci            return HNP_ERRNO_NOMEM;
74269570cc8Sopenharmony_ci        }
74369570cc8Sopenharmony_ci        for (i = 0; i < count; i++) {
74469570cc8Sopenharmony_ci            data.entries[i].key = hnpSignMapInfos[i].key;
74569570cc8Sopenharmony_ci            data.entries[i].value = hnpSignMapInfos[i].value;
74669570cc8Sopenharmony_ci        }
74769570cc8Sopenharmony_ci        data.count = count;
74869570cc8Sopenharmony_ci        ret = EnforceCodeSignForApp(installInfo->hapPath, &data, FILE_ENTRY_ONLY);
74969570cc8Sopenharmony_ci        HNP_LOGI("sign end ret=%{public}d,last key[%{public}s],value[%{public}s]", ret, data.entries[i - 1].key,
75069570cc8Sopenharmony_ci            data.entries[i - 1].value);
75169570cc8Sopenharmony_ci        free(data.entries);
75269570cc8Sopenharmony_ci        if (ret != 0) {
75369570cc8Sopenharmony_ci            HnpUnInstall(installInfo->uid, installInfo->hapPackageName);
75469570cc8Sopenharmony_ci            ret = HNP_ERRNO_INSTALLER_CODE_SIGN_APP_FAILED;
75569570cc8Sopenharmony_ci        }
75669570cc8Sopenharmony_ci    }
75769570cc8Sopenharmony_ci#endif
75869570cc8Sopenharmony_ci    free(hnpSignMapInfos);
75969570cc8Sopenharmony_ci    return ret;
76069570cc8Sopenharmony_ci}
76169570cc8Sopenharmony_ci
76269570cc8Sopenharmony_cistatic int ParseInstallArgs(int argc, char *argv[], HapInstallInfo *installInfo)
76369570cc8Sopenharmony_ci{
76469570cc8Sopenharmony_ci    int ret;
76569570cc8Sopenharmony_ci    int ch;
76669570cc8Sopenharmony_ci
76769570cc8Sopenharmony_ci    optind = 1; // 从头开始遍历参数
76869570cc8Sopenharmony_ci    while ((ch = getopt_long(argc, argv, "hu:p:i:s:a:f", NULL, NULL)) != -1) {
76969570cc8Sopenharmony_ci        switch (ch) {
77069570cc8Sopenharmony_ci            case 'h' :
77169570cc8Sopenharmony_ci                return HNP_ERRNO_OPERATOR_ARGV_MISS;
77269570cc8Sopenharmony_ci            case 'u': // 用户id
77369570cc8Sopenharmony_ci                ret = HnpInstallerUidGet(optarg, &installInfo->uid);
77469570cc8Sopenharmony_ci                if (ret != 0) {
77569570cc8Sopenharmony_ci                    HNP_LOGE("hnp install argv uid[%{public}s] invalid", optarg);
77669570cc8Sopenharmony_ci                    return ret;
77769570cc8Sopenharmony_ci                }
77869570cc8Sopenharmony_ci                break;
77969570cc8Sopenharmony_ci            case 'p': // app名称
78069570cc8Sopenharmony_ci                installInfo->hapPackageName = (char *)optarg;
78169570cc8Sopenharmony_ci                break;
78269570cc8Sopenharmony_ci            case 'i': // hnp安装目录
78369570cc8Sopenharmony_ci                installInfo->hnpRootPath = (char *)optarg;
78469570cc8Sopenharmony_ci                break;
78569570cc8Sopenharmony_ci            case 's': // hap目录
78669570cc8Sopenharmony_ci                installInfo->hapPath = (char *)optarg;
78769570cc8Sopenharmony_ci                break;
78869570cc8Sopenharmony_ci            case 'a': // 系统abi路径
78969570cc8Sopenharmony_ci                installInfo->abi = (char *)optarg;
79069570cc8Sopenharmony_ci                break;
79169570cc8Sopenharmony_ci            case 'f': // is force
79269570cc8Sopenharmony_ci                installInfo->isForce = true;
79369570cc8Sopenharmony_ci                break;
79469570cc8Sopenharmony_ci            default:
79569570cc8Sopenharmony_ci                break;
79669570cc8Sopenharmony_ci        }
79769570cc8Sopenharmony_ci    }
79869570cc8Sopenharmony_ci
79969570cc8Sopenharmony_ci    if ((installInfo->uid == -1) || (installInfo->hnpRootPath == NULL) || (installInfo->hapPath == NULL) ||
80069570cc8Sopenharmony_ci        (installInfo->abi == NULL) || (installInfo->hapPackageName == NULL)) {
80169570cc8Sopenharmony_ci        HNP_LOGE("argv params is missing.");
80269570cc8Sopenharmony_ci        return HNP_ERRNO_OPERATOR_ARGV_MISS;
80369570cc8Sopenharmony_ci    }
80469570cc8Sopenharmony_ci
80569570cc8Sopenharmony_ci    return 0;
80669570cc8Sopenharmony_ci}
80769570cc8Sopenharmony_ci
80869570cc8Sopenharmony_ciint HnpCmdInstall(int argc, char *argv[])
80969570cc8Sopenharmony_ci{
81069570cc8Sopenharmony_ci    HapInstallInfo installInfo = {0};
81169570cc8Sopenharmony_ci
81269570cc8Sopenharmony_ci    installInfo.uid = -1; // 预设值,判断简单
81369570cc8Sopenharmony_ci    // 解析参数并生成安装信息
81469570cc8Sopenharmony_ci    int ret = ParseInstallArgs(argc, argv, &installInfo);
81569570cc8Sopenharmony_ci    if (ret != 0) {
81669570cc8Sopenharmony_ci        return ret;
81769570cc8Sopenharmony_ci    }
81869570cc8Sopenharmony_ci
81969570cc8Sopenharmony_ci    return HnpInsatllPre(&installInfo);
82069570cc8Sopenharmony_ci}
82169570cc8Sopenharmony_ci
82269570cc8Sopenharmony_ciint HnpCmdUnInstall(int argc, char *argv[])
82369570cc8Sopenharmony_ci{
82469570cc8Sopenharmony_ci    int uid;
82569570cc8Sopenharmony_ci    char *uidArg = NULL;
82669570cc8Sopenharmony_ci    char *packageName = NULL;
82769570cc8Sopenharmony_ci    int ret;
82869570cc8Sopenharmony_ci    int ch;
82969570cc8Sopenharmony_ci
83069570cc8Sopenharmony_ci    optind = 1; // 从头开始遍历参数
83169570cc8Sopenharmony_ci    while ((ch = getopt_long(argc, argv, "hu:p:", NULL, NULL)) != -1) {
83269570cc8Sopenharmony_ci        switch (ch) {
83369570cc8Sopenharmony_ci            case 'h' :
83469570cc8Sopenharmony_ci                return HNP_ERRNO_OPERATOR_ARGV_MISS;
83569570cc8Sopenharmony_ci            case 'u': // uid
83669570cc8Sopenharmony_ci                uidArg = optarg;
83769570cc8Sopenharmony_ci                ret = HnpInstallerUidGet(uidArg, &uid);
83869570cc8Sopenharmony_ci                if (ret != 0) {
83969570cc8Sopenharmony_ci                    HNP_LOGE("hnp install arg uid[%{public}s] invalid", uidArg);
84069570cc8Sopenharmony_ci                    return ret;
84169570cc8Sopenharmony_ci                }
84269570cc8Sopenharmony_ci                break;
84369570cc8Sopenharmony_ci            case 'p': // hnp package name
84469570cc8Sopenharmony_ci                packageName = (char *)optarg;
84569570cc8Sopenharmony_ci                break;
84669570cc8Sopenharmony_ci            default:
84769570cc8Sopenharmony_ci                break;
84869570cc8Sopenharmony_ci            }
84969570cc8Sopenharmony_ci    }
85069570cc8Sopenharmony_ci
85169570cc8Sopenharmony_ci    if ((uidArg == NULL) || (packageName == NULL)) {
85269570cc8Sopenharmony_ci        HNP_LOGE("hnp uninstall params invalid uid[%{public}s], package name[%{public}s]", uidArg, packageName);
85369570cc8Sopenharmony_ci        return HNP_ERRNO_OPERATOR_ARGV_MISS;
85469570cc8Sopenharmony_ci    }
85569570cc8Sopenharmony_ci
85669570cc8Sopenharmony_ci    return HnpUnInstall(uid, packageName);
85769570cc8Sopenharmony_ci}
85869570cc8Sopenharmony_ci
85969570cc8Sopenharmony_ci#ifdef __cplusplus
86069570cc8Sopenharmony_ci}
86169570cc8Sopenharmony_ci#endif
862