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