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