xref: /base/startup/appspawn/service/hnp/base/hnp_zip.c (revision 69570cc8)
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 <string.h>
1869570cc8Sopenharmony_ci#include <stdlib.h>
1969570cc8Sopenharmony_ci#include <sys/stat.h>
2069570cc8Sopenharmony_ci#include <errno.h>
2169570cc8Sopenharmony_ci#include <unistd.h>
2269570cc8Sopenharmony_ci
2369570cc8Sopenharmony_ci#include <dirent.h>
2469570cc8Sopenharmony_ci#ifdef _WIN32
2569570cc8Sopenharmony_ci#include <windows.h>
2669570cc8Sopenharmony_ci
2769570cc8Sopenharmony_ci#endif
2869570cc8Sopenharmony_ci
2969570cc8Sopenharmony_ci#include "zlib.h"
3069570cc8Sopenharmony_ci#include "contrib/minizip/zip.h"
3169570cc8Sopenharmony_ci#include "contrib/minizip/unzip.h"
3269570cc8Sopenharmony_ci
3369570cc8Sopenharmony_ci#include "securec.h"
3469570cc8Sopenharmony_ci
3569570cc8Sopenharmony_ci#include "hnp_base.h"
3669570cc8Sopenharmony_ci
3769570cc8Sopenharmony_ci#ifdef __cplusplus
3869570cc8Sopenharmony_ciextern "C" {
3969570cc8Sopenharmony_ci#endif
4069570cc8Sopenharmony_ci
4169570cc8Sopenharmony_ci#define ZIP_EXTERNAL_FA_OFFSET 16
4269570cc8Sopenharmony_ci
4369570cc8Sopenharmony_ci// zipOpenNewFileInZip3只识别带‘/’的路径,需要将路径中‘\’转换成‘/’
4469570cc8Sopenharmony_cistatic void TransPath(const char *input, char *output)
4569570cc8Sopenharmony_ci{
4669570cc8Sopenharmony_ci    int len = strlen(input);
4769570cc8Sopenharmony_ci    for (int i = 0; i < len; i++) {
4869570cc8Sopenharmony_ci        if (input[i] == '\\') {
4969570cc8Sopenharmony_ci            output[i] = '/';
5069570cc8Sopenharmony_ci        } else {
5169570cc8Sopenharmony_ci            output[i] = input[i];
5269570cc8Sopenharmony_ci        }
5369570cc8Sopenharmony_ci    }
5469570cc8Sopenharmony_ci    output[len] = '\0';
5569570cc8Sopenharmony_ci}
5669570cc8Sopenharmony_ci
5769570cc8Sopenharmony_ci#ifdef _WIN32
5869570cc8Sopenharmony_ci// 转换char路径字符串为wchar_t宽字符串,支持路径字符串长度超过260
5969570cc8Sopenharmony_cistatic bool TransWidePath(const char *inPath, wchar_t *outPath)
6069570cc8Sopenharmony_ci{
6169570cc8Sopenharmony_ci    wchar_t tmpPath[MAX_FILE_PATH_LEN] = {0};
6269570cc8Sopenharmony_ci    MultiByteToWideChar(CP_ACP, 0, inPath, -1, tmpPath, MAX_FILE_PATH_LEN);
6369570cc8Sopenharmony_ci    if (swprintf_s(outPath, MAX_FILE_PATH_LEN, L"\\\\?\\%ls", tmpPath) < 0) {
6469570cc8Sopenharmony_ci        HNP_LOGE("swprintf unsuccess.");
6569570cc8Sopenharmony_ci        return false;
6669570cc8Sopenharmony_ci    }
6769570cc8Sopenharmony_ci    return true;
6869570cc8Sopenharmony_ci}
6969570cc8Sopenharmony_ci#endif
7069570cc8Sopenharmony_ci
7169570cc8Sopenharmony_ci// 向zip压缩包中添加文件
7269570cc8Sopenharmony_cistatic int ZipAddFile(const char* file, int offset, zipFile zf)
7369570cc8Sopenharmony_ci{
7469570cc8Sopenharmony_ci    int err;
7569570cc8Sopenharmony_ci    char buf[1024];
7669570cc8Sopenharmony_ci    char transPath[MAX_FILE_PATH_LEN];
7769570cc8Sopenharmony_ci    size_t len;
7869570cc8Sopenharmony_ci    FILE *f;
7969570cc8Sopenharmony_ci    zip_fileinfo fileInfo = {0};
8069570cc8Sopenharmony_ci
8169570cc8Sopenharmony_ci#ifdef _WIN32
8269570cc8Sopenharmony_ci    struct _stat buffer = {0};
8369570cc8Sopenharmony_ci    // 使用wchar_t支持处理字符串长度超过260的路径字符串
8469570cc8Sopenharmony_ci    wchar_t wideFullPath[MAX_FILE_PATH_LEN] = {0};
8569570cc8Sopenharmony_ci    if (!TransWidePath(file, wideFullPath)) {
8669570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_STAT_FAILED;
8769570cc8Sopenharmony_ci    }
8869570cc8Sopenharmony_ci    if (_wstat(wideFullPath, &buffer) != 0) {
8969570cc8Sopenharmony_ci        HNP_LOGE("get filefile[%{public}s] stat fail.", file);
9069570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_STAT_FAILED;
9169570cc8Sopenharmony_ci    }
9269570cc8Sopenharmony_ci    buffer.st_mode |= S_IXOTH;
9369570cc8Sopenharmony_ci#else
9469570cc8Sopenharmony_ci    struct stat buffer = {0};
9569570cc8Sopenharmony_ci    if (stat(file, &buffer) != 0) {
9669570cc8Sopenharmony_ci        HNP_LOGE("get filefile[%{public}s] stat fail.", file);
9769570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_STAT_FAILED;
9869570cc8Sopenharmony_ci    }
9969570cc8Sopenharmony_ci#endif
10069570cc8Sopenharmony_ci    fileInfo.external_fa = (buffer.st_mode & 0xFFFF) << ZIP_EXTERNAL_FA_OFFSET;
10169570cc8Sopenharmony_ci    TransPath(file, transPath);
10269570cc8Sopenharmony_ci    err = zipOpenNewFileInZip3(zf, transPath + offset, &fileInfo, NULL, 0, NULL, 0, NULL, Z_DEFLATED,
10369570cc8Sopenharmony_ci        Z_BEST_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0);
10469570cc8Sopenharmony_ci    if (err != ZIP_OK) {
10569570cc8Sopenharmony_ci        HNP_LOGE("open new file[%{public}s] in zip unsuccess ", file);
10669570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
10769570cc8Sopenharmony_ci    }
10869570cc8Sopenharmony_ci#ifdef _WIN32
10969570cc8Sopenharmony_ci    f = _wfopen(wideFullPath, L"rb");
11069570cc8Sopenharmony_ci#else
11169570cc8Sopenharmony_ci    f = fopen(file, "rb");
11269570cc8Sopenharmony_ci#endif
11369570cc8Sopenharmony_ci    if (f == NULL) {
11469570cc8Sopenharmony_ci        HNP_LOGE("open file[%{public}s] unsuccess ", file);
11569570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
11669570cc8Sopenharmony_ci    }
11769570cc8Sopenharmony_ci
11869570cc8Sopenharmony_ci    while ((len = fread(buf, 1, sizeof(buf), f)) > 0) {
11969570cc8Sopenharmony_ci        zipWriteInFileInZip(zf, buf, len);
12069570cc8Sopenharmony_ci    }
12169570cc8Sopenharmony_ci    (void)fclose(f);
12269570cc8Sopenharmony_ci    zipCloseFileInZip(zf);
12369570cc8Sopenharmony_ci    return 0;
12469570cc8Sopenharmony_ci}
12569570cc8Sopenharmony_ci
12669570cc8Sopenharmony_ci// 判断是否为目录
12769570cc8Sopenharmony_cistatic int IsDirPath(struct dirent *entry, char *fullPath, int *isDir)
12869570cc8Sopenharmony_ci{
12969570cc8Sopenharmony_ci#ifdef _WIN32
13069570cc8Sopenharmony_ci    // 使用wchar_t支持处理字符串长度超过260的路径字符串
13169570cc8Sopenharmony_ci    wchar_t wideFullPath[MAX_FILE_PATH_LEN] = {0};
13269570cc8Sopenharmony_ci    if (!TransWidePath(fullPath, wideFullPath)) {
13369570cc8Sopenharmony_ci        return HNP_ERRNO_GET_FILE_ATTR_FAILED;
13469570cc8Sopenharmony_ci    }
13569570cc8Sopenharmony_ci    DWORD fileAttr = GetFileAttributesW(wideFullPath);
13669570cc8Sopenharmony_ci    if (fileAttr == INVALID_FILE_ATTRIBUTES) {
13769570cc8Sopenharmony_ci        DWORD err = GetLastError();
13869570cc8Sopenharmony_ci        HNP_LOGE("get file[%{public}s] attr unsuccess, errno[%{public}lu].", fullPath, err);
13969570cc8Sopenharmony_ci        return HNP_ERRNO_GET_FILE_ATTR_FAILED;
14069570cc8Sopenharmony_ci    }
14169570cc8Sopenharmony_ci    *isDir = (int)(fileAttr & FILE_ATTRIBUTE_DIRECTORY);
14269570cc8Sopenharmony_ci#else
14369570cc8Sopenharmony_ci    *isDir = (int)(entry->d_type == DT_DIR);
14469570cc8Sopenharmony_ci#endif
14569570cc8Sopenharmony_ci
14669570cc8Sopenharmony_ci    return 0;
14769570cc8Sopenharmony_ci}
14869570cc8Sopenharmony_ci
14969570cc8Sopenharmony_cistatic int ZipAddDir(const char *sourcePath, int offset, zipFile zf);
15069570cc8Sopenharmony_ci
15169570cc8Sopenharmony_cistatic int ZipHandleDir(char *fullPath, int offset, zipFile zf)
15269570cc8Sopenharmony_ci{
15369570cc8Sopenharmony_ci    int ret;
15469570cc8Sopenharmony_ci    char transPath[MAX_FILE_PATH_LEN];
15569570cc8Sopenharmony_ci    TransPath(fullPath, transPath);
15669570cc8Sopenharmony_ci    if (zipOpenNewFileInZip3(zf, transPath + offset, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED,
15769570cc8Sopenharmony_ci                             Z_BEST_COMPRESSION, 0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY,
15869570cc8Sopenharmony_ci                             NULL, 0) != ZIP_OK) {
15969570cc8Sopenharmony_ci        HNP_LOGE("open new file[%{public}s] in zip unsuccess ", fullPath);
16069570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
16169570cc8Sopenharmony_ci    }
16269570cc8Sopenharmony_ci    zipCloseFileInZip(zf);
16369570cc8Sopenharmony_ci    ret = ZipAddDir(fullPath, offset, zf);
16469570cc8Sopenharmony_ci    if (ret != 0) {
16569570cc8Sopenharmony_ci        HNP_LOGE("zip add dir[%{public}s] unsuccess ", fullPath);
16669570cc8Sopenharmony_ci        return ret;
16769570cc8Sopenharmony_ci    }
16869570cc8Sopenharmony_ci    return 0;
16969570cc8Sopenharmony_ci}
17069570cc8Sopenharmony_ci
17169570cc8Sopenharmony_ci// sourcePath--文件夹路径  zf--压缩文件句柄
17269570cc8Sopenharmony_cistatic int ZipAddDir(const char *sourcePath, int offset, zipFile zf)
17369570cc8Sopenharmony_ci{
17469570cc8Sopenharmony_ci    struct dirent *entry;
17569570cc8Sopenharmony_ci    char fullPath[MAX_FILE_PATH_LEN];
17669570cc8Sopenharmony_ci    int isDir;
17769570cc8Sopenharmony_ci
17869570cc8Sopenharmony_ci    DIR *dir = opendir(sourcePath);
17969570cc8Sopenharmony_ci    if (dir == NULL) {
18069570cc8Sopenharmony_ci        HNP_LOGE("open dir=%{public}s unsuccess ", sourcePath);
18169570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_DIR_OPEN_FAILED;
18269570cc8Sopenharmony_ci    }
18369570cc8Sopenharmony_ci
18469570cc8Sopenharmony_ci    while ((entry = readdir(dir)) != NULL) {
18569570cc8Sopenharmony_ci        if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
18669570cc8Sopenharmony_ci            continue;
18769570cc8Sopenharmony_ci        }
18869570cc8Sopenharmony_ci        if (sprintf_s(fullPath, MAX_FILE_PATH_LEN, "%s%s", sourcePath, entry->d_name) < 0) {
18969570cc8Sopenharmony_ci            HNP_LOGE("sprintf unsuccess.");
19069570cc8Sopenharmony_ci            closedir(dir);
19169570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
19269570cc8Sopenharmony_ci        }
19369570cc8Sopenharmony_ci        int ret = IsDirPath(entry, fullPath, &isDir);
19469570cc8Sopenharmony_ci        if (ret != 0) {
19569570cc8Sopenharmony_ci            closedir(dir);
19669570cc8Sopenharmony_ci            return ret;
19769570cc8Sopenharmony_ci        }
19869570cc8Sopenharmony_ci        if (isDir) {
19969570cc8Sopenharmony_ci            int endPos = strlen(fullPath);
20069570cc8Sopenharmony_ci            if (endPos + 1 < MAX_FILE_PATH_LEN) {
20169570cc8Sopenharmony_ci                fullPath[endPos] = DIR_SPLIT_SYMBOL;
20269570cc8Sopenharmony_ci                fullPath[endPos + 1] = '\0';
20369570cc8Sopenharmony_ci            } else {
20469570cc8Sopenharmony_ci                closedir(dir);
20569570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_STRING_LEN_OVER_LIMIT;
20669570cc8Sopenharmony_ci            }
20769570cc8Sopenharmony_ci            ret = ZipHandleDir(fullPath, offset, zf);
20869570cc8Sopenharmony_ci            if (ret != 0) {
20969570cc8Sopenharmony_ci                closedir(dir);
21069570cc8Sopenharmony_ci                return ret;
21169570cc8Sopenharmony_ci            }
21269570cc8Sopenharmony_ci        } else if ((ret = ZipAddFile(fullPath, offset, zf)) != 0) {
21369570cc8Sopenharmony_ci            HNP_LOGE("zip add file[%{public}s] unsuccess ", fullPath);
21469570cc8Sopenharmony_ci            closedir(dir);
21569570cc8Sopenharmony_ci            return ret;
21669570cc8Sopenharmony_ci        }
21769570cc8Sopenharmony_ci    }
21869570cc8Sopenharmony_ci    closedir(dir);
21969570cc8Sopenharmony_ci
22069570cc8Sopenharmony_ci    return 0;
22169570cc8Sopenharmony_ci}
22269570cc8Sopenharmony_ci
22369570cc8Sopenharmony_cistatic int ZipDir(const char *sourcePath, int offset, zipFile zf)
22469570cc8Sopenharmony_ci{
22569570cc8Sopenharmony_ci    int ret;
22669570cc8Sopenharmony_ci    char transPath[MAX_FILE_PATH_LEN];
22769570cc8Sopenharmony_ci
22869570cc8Sopenharmony_ci    TransPath(sourcePath, transPath);
22969570cc8Sopenharmony_ci
23069570cc8Sopenharmony_ci    // 将外层文件夹信息保存到zip文件中
23169570cc8Sopenharmony_ci    ret = zipOpenNewFileInZip3(zf, transPath + offset, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION,
23269570cc8Sopenharmony_ci        0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0);
23369570cc8Sopenharmony_ci    if (ret != ZIP_OK) {
23469570cc8Sopenharmony_ci        HNP_LOGE("open new file[%{public}s] in zip unsuccess ", sourcePath + offset);
23569570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
23669570cc8Sopenharmony_ci    }
23769570cc8Sopenharmony_ci    zipCloseFileInZip(zf);
23869570cc8Sopenharmony_ci    ret = ZipAddDir(sourcePath, offset, zf);
23969570cc8Sopenharmony_ci
24069570cc8Sopenharmony_ci    return ret;
24169570cc8Sopenharmony_ci}
24269570cc8Sopenharmony_ci
24369570cc8Sopenharmony_ciint HnpZip(const char *inputDir, zipFile zf)
24469570cc8Sopenharmony_ci{
24569570cc8Sopenharmony_ci    int ret;
24669570cc8Sopenharmony_ci    char *strPtr;
24769570cc8Sopenharmony_ci    int offset;
24869570cc8Sopenharmony_ci    char sourcePath[MAX_FILE_PATH_LEN];
24969570cc8Sopenharmony_ci
25069570cc8Sopenharmony_ci    // zip压缩文件内只保存相对路径,不保存绝对路径信息,偏移到压缩文件夹位置
25169570cc8Sopenharmony_ci    strPtr = strrchr(inputDir, DIR_SPLIT_SYMBOL);
25269570cc8Sopenharmony_ci    if (strPtr == NULL) {
25369570cc8Sopenharmony_ci        offset = 0;
25469570cc8Sopenharmony_ci    } else {
25569570cc8Sopenharmony_ci        offset = strPtr - inputDir + 1;
25669570cc8Sopenharmony_ci    }
25769570cc8Sopenharmony_ci
25869570cc8Sopenharmony_ci    // zip函数根据后缀是否'/'区分目录还是文件
25969570cc8Sopenharmony_ci    ret = sprintf_s(sourcePath, MAX_FILE_PATH_LEN, "%s%c", inputDir, DIR_SPLIT_SYMBOL);
26069570cc8Sopenharmony_ci    if (ret < 0) {
26169570cc8Sopenharmony_ci        HNP_LOGE("sprintf unsuccess.");
26269570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
26369570cc8Sopenharmony_ci    }
26469570cc8Sopenharmony_ci
26569570cc8Sopenharmony_ci    ret = ZipDir(sourcePath, offset, zf);
26669570cc8Sopenharmony_ci
26769570cc8Sopenharmony_ci    return ret;
26869570cc8Sopenharmony_ci}
26969570cc8Sopenharmony_ci
27069570cc8Sopenharmony_ciint HnpAddFileToZip(zipFile zf, char *filename, char *buff, int size)
27169570cc8Sopenharmony_ci{
27269570cc8Sopenharmony_ci    int ret;
27369570cc8Sopenharmony_ci    char transPath[MAX_FILE_PATH_LEN];
27469570cc8Sopenharmony_ci
27569570cc8Sopenharmony_ci    TransPath(filename, transPath);
27669570cc8Sopenharmony_ci
27769570cc8Sopenharmony_ci    // 将外层文件夹信息保存到zip文件中
27869570cc8Sopenharmony_ci    ret = zipOpenNewFileInZip3(zf, transPath, NULL, NULL, 0, NULL, 0, NULL, Z_DEFLATED, Z_BEST_COMPRESSION,
27969570cc8Sopenharmony_ci        0, -MAX_WBITS, DEF_MEM_LEVEL, Z_DEFAULT_STRATEGY, NULL, 0);
28069570cc8Sopenharmony_ci    if (ret != ZIP_OK) {
28169570cc8Sopenharmony_ci        HNP_LOGE("open new file[%{public}s] in zip unsuccess ", filename);
28269570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_CREATE_ZIP_FAILED;
28369570cc8Sopenharmony_ci    }
28469570cc8Sopenharmony_ci    zipWriteInFileInZip(zf, buff, size);
28569570cc8Sopenharmony_ci    zipCloseFileInZip(zf);
28669570cc8Sopenharmony_ci
28769570cc8Sopenharmony_ci    return 0;
28869570cc8Sopenharmony_ci}
28969570cc8Sopenharmony_ci
29069570cc8Sopenharmony_cistatic int HnpUnZipForFile(const char *filePath, unzFile zipFile, unz_file_info fileInfo)
29169570cc8Sopenharmony_ci{
29269570cc8Sopenharmony_ci#ifdef _WIN32
29369570cc8Sopenharmony_ci    return 0;
29469570cc8Sopenharmony_ci#else
29569570cc8Sopenharmony_ci    int ret;
29669570cc8Sopenharmony_ci    mode_t mode = (fileInfo.external_fa >> ZIP_EXTERNAL_FA_OFFSET) & 0xFFFF;
29769570cc8Sopenharmony_ci
29869570cc8Sopenharmony_ci    /* 如果解压缩的是目录 */
29969570cc8Sopenharmony_ci    if (filePath[strlen(filePath) - 1] == '/') {
30069570cc8Sopenharmony_ci        mkdir(filePath, S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH);
30169570cc8Sopenharmony_ci    } else {
30269570cc8Sopenharmony_ci        FILE *outFile = fopen(filePath, "wb");
30369570cc8Sopenharmony_ci        if (outFile == NULL) {
30469570cc8Sopenharmony_ci            HNP_LOGE("unzip open file:%{public}s unsuccess!", filePath);
30569570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_FILE_OPEN_FAILED;
30669570cc8Sopenharmony_ci        }
30769570cc8Sopenharmony_ci        unzOpenCurrentFile(zipFile);
30869570cc8Sopenharmony_ci        int readSize = 0;
30969570cc8Sopenharmony_ci        do {
31069570cc8Sopenharmony_ci            char buffer[BUFFER_SIZE];
31169570cc8Sopenharmony_ci            readSize = unzReadCurrentFile(zipFile, buffer, sizeof(buffer));
31269570cc8Sopenharmony_ci            if (readSize < 0) {
31369570cc8Sopenharmony_ci                HNP_LOGE("unzip read zip:%{public}s file unsuccess", (char *)zipFile);
31469570cc8Sopenharmony_ci                fclose(outFile);
31569570cc8Sopenharmony_ci                unzCloseCurrentFile(zipFile);
31669570cc8Sopenharmony_ci                return HNP_ERRNO_BASE_UNZIP_READ_FAILED;
31769570cc8Sopenharmony_ci            }
31869570cc8Sopenharmony_ci
31969570cc8Sopenharmony_ci            fwrite(buffer, readSize, sizeof(char), outFile);
32069570cc8Sopenharmony_ci        } while (readSize > 0);
32169570cc8Sopenharmony_ci
32269570cc8Sopenharmony_ci        fclose(outFile);
32369570cc8Sopenharmony_ci        unzCloseCurrentFile(zipFile);
32469570cc8Sopenharmony_ci        /* 如果其他人有可执行权限,那么将解压后的权限设置成755,否则为744 */
32569570cc8Sopenharmony_ci        if ((mode & S_IXOTH) != 0) {
32669570cc8Sopenharmony_ci            ret = chmod(filePath, S_IRWXU | S_IRGRP | S_IXGRP | S_IROTH | S_IXOTH);
32769570cc8Sopenharmony_ci        } else {
32869570cc8Sopenharmony_ci            ret = chmod(filePath, S_IRWXU | S_IRGRP | S_IROTH);
32969570cc8Sopenharmony_ci        }
33069570cc8Sopenharmony_ci        if (ret != 0) {
33169570cc8Sopenharmony_ci            HNP_LOGE("hnp install chmod unsuccess, src:%{public}s, errno:%{public}d", filePath, errno);
33269570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_CHMOD_FAILED;
33369570cc8Sopenharmony_ci        }
33469570cc8Sopenharmony_ci    }
33569570cc8Sopenharmony_ci    return 0;
33669570cc8Sopenharmony_ci#endif
33769570cc8Sopenharmony_ci}
33869570cc8Sopenharmony_ci
33969570cc8Sopenharmony_cistatic bool HnpELFFileCheck(const char *path)
34069570cc8Sopenharmony_ci{
34169570cc8Sopenharmony_ci    FILE *fp;
34269570cc8Sopenharmony_ci    char buff[HNP_ELF_FILE_CHECK_HEAD_LEN];
34369570cc8Sopenharmony_ci
34469570cc8Sopenharmony_ci    fp = fopen(path, "rb");
34569570cc8Sopenharmony_ci    if (fp == NULL) {
34669570cc8Sopenharmony_ci        return false;
34769570cc8Sopenharmony_ci    }
34869570cc8Sopenharmony_ci
34969570cc8Sopenharmony_ci    size_t readLen = fread(buff, sizeof(char), HNP_ELF_FILE_CHECK_HEAD_LEN, fp);
35069570cc8Sopenharmony_ci    if (readLen != HNP_ELF_FILE_CHECK_HEAD_LEN) {
35169570cc8Sopenharmony_ci        (void)fclose(fp);
35269570cc8Sopenharmony_ci        return false;
35369570cc8Sopenharmony_ci    }
35469570cc8Sopenharmony_ci
35569570cc8Sopenharmony_ci    if (buff[HNP_INDEX_0] == 0x7F && buff[HNP_INDEX_1] == 'E' && buff[HNP_INDEX_2] == 'L' && buff[HNP_INDEX_3] == 'F') {
35669570cc8Sopenharmony_ci        (void)fclose(fp);
35769570cc8Sopenharmony_ci        return true;
35869570cc8Sopenharmony_ci    }
35969570cc8Sopenharmony_ci
36069570cc8Sopenharmony_ci    (void)fclose(fp);
36169570cc8Sopenharmony_ci    return false;
36269570cc8Sopenharmony_ci}
36369570cc8Sopenharmony_ci
36469570cc8Sopenharmony_cistatic int HnpInstallAddSignMap(const char* hnpSignKeyPrefix, const char *key, const char *value,
36569570cc8Sopenharmony_ci    HnpSignMapInfo *hnpSignMapInfos, int *count)
36669570cc8Sopenharmony_ci{
36769570cc8Sopenharmony_ci    int ret;
36869570cc8Sopenharmony_ci    int sum = *count;
36969570cc8Sopenharmony_ci
37069570cc8Sopenharmony_ci    if (HnpELFFileCheck(value) == false) {
37169570cc8Sopenharmony_ci        return 0;
37269570cc8Sopenharmony_ci    }
37369570cc8Sopenharmony_ci
37469570cc8Sopenharmony_ci    ret = sprintf_s(hnpSignMapInfos[sum].key, MAX_FILE_PATH_LEN, "%s!/%s", hnpSignKeyPrefix, key);
37569570cc8Sopenharmony_ci    if (ret < 0) {
37669570cc8Sopenharmony_ci        HNP_LOGE("add sign map sprintf unsuccess.");
37769570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_SPRINTF_FAILED;
37869570cc8Sopenharmony_ci    }
37969570cc8Sopenharmony_ci
38069570cc8Sopenharmony_ci    ret = strcpy_s(hnpSignMapInfos[sum].value, MAX_FILE_PATH_LEN, value);
38169570cc8Sopenharmony_ci    if (ret != EOK) {
38269570cc8Sopenharmony_ci        HNP_LOGE("add sign map strcpy[%{public}s] unsuccess.", value);
38369570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_COPY_FAILED;
38469570cc8Sopenharmony_ci    }
38569570cc8Sopenharmony_ci
38669570cc8Sopenharmony_ci    *count  = sum + 1;
38769570cc8Sopenharmony_ci    return 0;
38869570cc8Sopenharmony_ci}
38969570cc8Sopenharmony_ci
39069570cc8Sopenharmony_ciint HnpFileCountGet(const char *path, int *count)
39169570cc8Sopenharmony_ci{
39269570cc8Sopenharmony_ci    int sum = 0;
39369570cc8Sopenharmony_ci
39469570cc8Sopenharmony_ci    unzFile zipFile = unzOpen(path);
39569570cc8Sopenharmony_ci    if (zipFile == NULL) {
39669570cc8Sopenharmony_ci        HNP_LOGE("unzip open hnp:%{public}s unsuccess!", path);
39769570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_UNZIP_OPEN_FAILED;
39869570cc8Sopenharmony_ci    }
39969570cc8Sopenharmony_ci
40069570cc8Sopenharmony_ci    int ret = unzGoToFirstFile(zipFile);
40169570cc8Sopenharmony_ci    while (ret == UNZ_OK) {
40269570cc8Sopenharmony_ci        sum++;
40369570cc8Sopenharmony_ci        ret = unzGetCurrentFileInfo(zipFile, NULL, NULL, 0, NULL, 0, NULL, 0);
40469570cc8Sopenharmony_ci        if (ret != UNZ_OK) {
40569570cc8Sopenharmony_ci            HNP_LOGE("unzip get zip:%{public}s info unsuccess!", path);
40669570cc8Sopenharmony_ci            unzClose(zipFile);
40769570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_UNZIP_GET_INFO_FAILED;
40869570cc8Sopenharmony_ci        }
40969570cc8Sopenharmony_ci
41069570cc8Sopenharmony_ci        ret = unzGoToNextFile(zipFile);
41169570cc8Sopenharmony_ci    }
41269570cc8Sopenharmony_ci
41369570cc8Sopenharmony_ci    unzClose(zipFile);
41469570cc8Sopenharmony_ci    *count += sum;
41569570cc8Sopenharmony_ci    return 0;
41669570cc8Sopenharmony_ci}
41769570cc8Sopenharmony_ci
41869570cc8Sopenharmony_ciint HnpUnZip(const char *inputFile, const char *outputDir, const char *hnpSignKeyPrefix,
41969570cc8Sopenharmony_ci    HnpSignMapInfo *hnpSignMapInfos, int *count)
42069570cc8Sopenharmony_ci{
42169570cc8Sopenharmony_ci    char fileName[MAX_FILE_PATH_LEN];
42269570cc8Sopenharmony_ci    unz_file_info fileInfo;
42369570cc8Sopenharmony_ci    char filePath[MAX_FILE_PATH_LEN];
42469570cc8Sopenharmony_ci
42569570cc8Sopenharmony_ci    HNP_LOGI("HnpUnZip zip=%{public}s, output=%{public}s", inputFile, outputDir);
42669570cc8Sopenharmony_ci
42769570cc8Sopenharmony_ci    unzFile zipFile = unzOpen(inputFile);
42869570cc8Sopenharmony_ci    if (zipFile == NULL) {
42969570cc8Sopenharmony_ci        HNP_LOGE("unzip open hnp:%{public}s unsuccess!", inputFile);
43069570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_UNZIP_OPEN_FAILED;
43169570cc8Sopenharmony_ci    }
43269570cc8Sopenharmony_ci
43369570cc8Sopenharmony_ci    int result = unzGoToFirstFile(zipFile);
43469570cc8Sopenharmony_ci    while (result == UNZ_OK) {
43569570cc8Sopenharmony_ci        result = unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, sizeof(fileName), NULL, 0, NULL, 0);
43669570cc8Sopenharmony_ci        if (result != UNZ_OK) {
43769570cc8Sopenharmony_ci            HNP_LOGE("unzip get zip:%{public}s info unsuccess!", inputFile);
43869570cc8Sopenharmony_ci            unzClose(zipFile);
43969570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_UNZIP_GET_INFO_FAILED;
44069570cc8Sopenharmony_ci        }
44169570cc8Sopenharmony_ci        if (strstr(fileName, "../")) {
44269570cc8Sopenharmony_ci            HNP_LOGE("unzip filename[%{public}s],does not allow the use of ../", fileName);
44369570cc8Sopenharmony_ci            unzClose(zipFile);
44469570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_UNZIP_GET_INFO_FAILED;
44569570cc8Sopenharmony_ci        }
44669570cc8Sopenharmony_ci        char *slash = strchr(fileName, '/');
44769570cc8Sopenharmony_ci        if (slash != NULL) {
44869570cc8Sopenharmony_ci            slash++;
44969570cc8Sopenharmony_ci        } else {
45069570cc8Sopenharmony_ci            slash = fileName;
45169570cc8Sopenharmony_ci        }
45269570cc8Sopenharmony_ci
45369570cc8Sopenharmony_ci        if (sprintf_s(filePath, MAX_FILE_PATH_LEN, "%s/%s", outputDir, slash) < 0) {
45469570cc8Sopenharmony_ci            HNP_LOGE("sprintf unsuccess.");
45569570cc8Sopenharmony_ci            unzClose(zipFile);
45669570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_SPRINTF_FAILED;
45769570cc8Sopenharmony_ci        }
45869570cc8Sopenharmony_ci
45969570cc8Sopenharmony_ci        result = HnpUnZipForFile(filePath, zipFile, fileInfo);
46069570cc8Sopenharmony_ci        if (result != 0) {
46169570cc8Sopenharmony_ci            HNP_LOGE("unzip for file:%{public}s unsuccess", filePath);
46269570cc8Sopenharmony_ci            unzClose(zipFile);
46369570cc8Sopenharmony_ci            return result;
46469570cc8Sopenharmony_ci        }
46569570cc8Sopenharmony_ci        result = HnpInstallAddSignMap(hnpSignKeyPrefix, fileName, filePath, hnpSignMapInfos, count);
46669570cc8Sopenharmony_ci        if (result != 0) {
46769570cc8Sopenharmony_ci            unzClose(zipFile);
46869570cc8Sopenharmony_ci            return result;
46969570cc8Sopenharmony_ci        }
47069570cc8Sopenharmony_ci        result = unzGoToNextFile(zipFile);
47169570cc8Sopenharmony_ci    }
47269570cc8Sopenharmony_ci
47369570cc8Sopenharmony_ci    unzClose(zipFile);
47469570cc8Sopenharmony_ci    return 0;
47569570cc8Sopenharmony_ci}
47669570cc8Sopenharmony_ci
47769570cc8Sopenharmony_ciint HnpCfgGetFromZip(const char *inputFile, HnpCfgInfo *hnpCfg)
47869570cc8Sopenharmony_ci{
47969570cc8Sopenharmony_ci    char fileName[MAX_FILE_PATH_LEN];
48069570cc8Sopenharmony_ci    unz_file_info fileInfo;
48169570cc8Sopenharmony_ci    char *cfgStream = NULL;
48269570cc8Sopenharmony_ci
48369570cc8Sopenharmony_ci    unzFile zipFile = unzOpen(inputFile);
48469570cc8Sopenharmony_ci    if (zipFile == NULL) {
48569570cc8Sopenharmony_ci        HNP_LOGE("unzip open hnp:%{public}s unsuccess!", inputFile);
48669570cc8Sopenharmony_ci        return HNP_ERRNO_BASE_UNZIP_OPEN_FAILED;
48769570cc8Sopenharmony_ci    }
48869570cc8Sopenharmony_ci
48969570cc8Sopenharmony_ci    int ret = unzGoToFirstFile(zipFile);
49069570cc8Sopenharmony_ci    while (ret == UNZ_OK) {
49169570cc8Sopenharmony_ci        ret = unzGetCurrentFileInfo(zipFile, &fileInfo, fileName, sizeof(fileName), NULL, 0, NULL, 0);
49269570cc8Sopenharmony_ci        if (ret != UNZ_OK) {
49369570cc8Sopenharmony_ci            HNP_LOGE("unzip get zip:%{public}s info unsuccess!", inputFile);
49469570cc8Sopenharmony_ci            unzClose(zipFile);
49569570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_UNZIP_GET_INFO_FAILED;
49669570cc8Sopenharmony_ci        }
49769570cc8Sopenharmony_ci        char *fileNameTmp = strrchr(fileName, DIR_SPLIT_SYMBOL);
49869570cc8Sopenharmony_ci        if (fileNameTmp == NULL) {
49969570cc8Sopenharmony_ci            fileNameTmp = fileName;
50069570cc8Sopenharmony_ci        } else {
50169570cc8Sopenharmony_ci            fileNameTmp++;
50269570cc8Sopenharmony_ci        }
50369570cc8Sopenharmony_ci        if (strcmp(fileNameTmp, HNP_CFG_FILE_NAME) != 0) {
50469570cc8Sopenharmony_ci            ret = unzGoToNextFile(zipFile);
50569570cc8Sopenharmony_ci            continue;
50669570cc8Sopenharmony_ci        }
50769570cc8Sopenharmony_ci
50869570cc8Sopenharmony_ci        unzOpenCurrentFile(zipFile);
50969570cc8Sopenharmony_ci        cfgStream = malloc(fileInfo.uncompressed_size);
51069570cc8Sopenharmony_ci        if (cfgStream == NULL) {
51169570cc8Sopenharmony_ci            HNP_LOGE("malloc unsuccess. size=%{public}lu, errno=%{public}d", fileInfo.uncompressed_size, errno);
51269570cc8Sopenharmony_ci            unzClose(zipFile);
51369570cc8Sopenharmony_ci            return HNP_ERRNO_NOMEM;
51469570cc8Sopenharmony_ci        }
51569570cc8Sopenharmony_ci        int readSize = unzReadCurrentFile(zipFile, cfgStream, fileInfo.uncompressed_size);
51669570cc8Sopenharmony_ci        if (readSize < 0 || (uLong)readSize != fileInfo.uncompressed_size) {
51769570cc8Sopenharmony_ci            free(cfgStream);
51869570cc8Sopenharmony_ci            unzClose(zipFile);
51969570cc8Sopenharmony_ci            HNP_LOGE("unzip read zip:%{public}s info size[%{public}lu]=>[%{public}d] error!", inputFile,
52069570cc8Sopenharmony_ci                fileInfo.uncompressed_size, readSize);
52169570cc8Sopenharmony_ci            return HNP_ERRNO_BASE_FILE_READ_FAILED;
52269570cc8Sopenharmony_ci        }
52369570cc8Sopenharmony_ci        break;
52469570cc8Sopenharmony_ci    }
52569570cc8Sopenharmony_ci    unzClose(zipFile);
52669570cc8Sopenharmony_ci    ret = HnpCfgGetFromSteam(cfgStream, hnpCfg);
52769570cc8Sopenharmony_ci    free(cfgStream);
52869570cc8Sopenharmony_ci    return ret;
52969570cc8Sopenharmony_ci}
53069570cc8Sopenharmony_ci
53169570cc8Sopenharmony_ci#ifdef __cplusplus
53269570cc8Sopenharmony_ci}
53369570cc8Sopenharmony_ci#endif
534