1 /*
2 * Copyright (c) 2024 Huawei Device Co., Ltd.
3 * Licensed under the Apache License, Version 2.0 (the "License");
4 * you may not use this file except in compliance with the License.
5 * You may obtain a copy of the License at
6 *
7 * http://www.apache.org/licenses/LICENSE-2.0
8 *
9 * Unless required by applicable law or agreed to in writing, software
10 * distributed under the License is distributed on an "AS IS" BASIS,
11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 * See the License for the specific language governing permissions and
13 * limitations under the License.
14 */
15
16 #include "zip_util.h"
17 #include <securec.h>
18
19 #include "storage_service_log.h"
20
21 namespace OHOS::StorageDaemon {
22 namespace {
23 constexpr int READ_MORE_LENGTH = 100 * 1024;
24 constexpr int ERROR_MEMSET_STRUCT = 1001;
25 constexpr int ERROR_GET_HANDLE = 1002;
26 constexpr int ERROR_ZIP_OPEN = 1003;
27 };
28
CreateZipFile(const std::string & zipPath,int32_t zipMode)29 zipFile ZipUtil::CreateZipFile(const std::string& zipPath, int32_t zipMode)
30 {
31 return zipOpen(zipPath.c_str(), zipMode);
32 }
33
CloseZipFile(zipFile & zipfile)34 void ZipUtil::CloseZipFile(zipFile& zipfile)
35 {
36 zipClose(zipfile, nullptr);
37 }
38
AddFileInZip(zipFile & zipfile,const std::string & srcFile,int keepParentPathStatus,const std::string & destFileName)39 int ZipUtil::AddFileInZip(
40 zipFile& zipfile, const std::string& srcFile, int keepParentPathStatus, const std::string& destFileName)
41 {
42 zip_fileinfo zipInfo;
43 errno_t result = memset_s(&zipInfo, sizeof(zipInfo), 0, sizeof(zipInfo));
44 if (result != EOK) {
45 LOGE("AddFileInZip memset_s error, file:%{public}s.", srcFile.c_str());
46 return ERROR_MEMSET_STRUCT;
47 }
48 FILE *srcFp = GetFileHandle(srcFile);
49 if (srcFp == nullptr) {
50 LOGE("get file handle failed:%{public}s, errno: %{public}d.", srcFile.c_str(), errno);
51 return ERROR_GET_HANDLE;
52 }
53 std::string srcFileName = GetDestFilePath(srcFile, destFileName, keepParentPathStatus);
54 int err = zipOpenNewFileInZip(
55 zipfile, srcFileName.c_str(), &zipInfo, nullptr, 0, nullptr, 0, nullptr, Z_DEFLATED, Z_DEFAULT_COMPRESSION);
56 if (err != ZIP_OK) {
57 LOGE("Minizip failed to zipOpenNewFileInZip,file = %{public}s, errno: %{public}d.", srcFile.c_str(), err);
58 (void)fclose(srcFp);
59 return ERROR_ZIP_OPEN;
60 }
61
62 int errcode = 0;
63 char buf[READ_MORE_LENGTH] = {0};
64 while (!feof(srcFp)) {
65 size_t numBytes = fread(buf, 1, sizeof(buf), srcFp);
66 if (numBytes == 0) {
67 break;
68 }
69 zipWriteInFileInZip(zipfile, buf, static_cast<unsigned int>(numBytes));
70 if (ferror(srcFp)) {
71 LOGE("zip file failed:%{public}s, errno: %{public}d.", srcFile.c_str(), errno);
72 errcode = errno;
73 break;
74 }
75 }
76 (void)fclose(srcFp);
77 zipCloseFileInZip(zipfile);
78 return errcode;
79 }
80
GetFileHandle(const std::string & file)81 FILE* ZipUtil::GetFileHandle(const std::string& file)
82 {
83 char realPath[PATH_MAX] = {0};
84 if (realpath(file.c_str(), realPath) == nullptr) {
85 return nullptr;
86 }
87 return fopen(realPath, "rb");
88 }
89
GetDestFilePath(const std::string & srcFile,const std::string & destFilePath,int keepParentPathStatus)90 std::string ZipUtil::GetDestFilePath(
91 const std::string& srcFile, const std::string& destFilePath, int keepParentPathStatus)
92 {
93 if (!destFilePath.empty()) {
94 return destFilePath;
95 }
96 std::string file = srcFile;
97 std::string result = file;
98 std::string parentPathName;
99 auto pos = file.rfind("/");
100 if (pos != std::string::npos && pos != file.length() - 1) {
101 result = file.substr(pos + 1);
102 std::string parent = file.substr(0, pos);
103 pos = parent.rfind("/");
104 if (pos != std::string::npos && pos != parent.length() - 1) {
105 parentPathName = parent.substr(pos + 1);
106 } else {
107 parentPathName = parent;
108 }
109 }
110 parentPathName.append("/");
111 if (keepParentPathStatus == KEEP_ONE_PARENT_PATH) {
112 // srcFileName with relative directory path
113 result.insert(0, parentPathName);
114 }
115 return result;
116 }
117 }
118