• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2022-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 "b_hiaudit/zip_util.h"
17 
18 #include <cerrno>
19 #include <fstream>
20 #include <securec.h>
21 
22 #include "filemgmt_libhilog.h"
23 
24 namespace OHOS::FileManagement::Backup {
25 namespace {
26 constexpr int READ_MORE_LENGTH = 100 * 1024;
27 constexpr int ERROR_MEMSET_STRUCT = 1001;
28 constexpr int ERROR_GET_HANDLE = 1002;
29 };
30 
CreateZipFile(const std::string & zipPath,int32_t zipMode)31 zipFile ZipUtil::CreateZipFile(const std::string &zipPath, int32_t zipMode)
32 {
33     return zipOpen(zipPath.c_str(), zipMode);
34 }
35 
CloseZipFile(zipFile zipfile)36 void ZipUtil::CloseZipFile(zipFile zipfile)
37 {
38     zipClose(zipfile, nullptr);
39 }
40 
AddFileInZip(zipFile zipfile,const std::string & srcFile,int keepParentPathStatus,const std::string & destFileName)41 int ZipUtil::AddFileInZip(zipFile zipfile, const std::string &srcFile, int keepParentPathStatus,
42     const std::string &destFileName)
43 {
44     zip_fileinfo zipInfo;
45     errno_t result = memset_s(&zipInfo, sizeof(zipInfo), 0, sizeof(zipInfo));
46     if (result != EOK) {
47         HILOGE("AddFileInZip memset_s error, file:%{public}s.", srcFile.c_str());
48         return ERROR_MEMSET_STRUCT;
49     }
50     FILE *srcFp = GetFileHandle(srcFile);
51     if (srcFp == nullptr) {
52         HILOGE("get file handle failed:%{public}s, errno: %{public}d.", srcFile.c_str(), errno);
53         return ERROR_GET_HANDLE;
54     }
55     std::string srcFileName = GetDestFilePath(srcFile, destFileName, keepParentPathStatus);
56     int errcode = zipOpenNewFileInZip(zipfile, srcFileName.c_str(), &zipInfo, nullptr, 0, nullptr, 0, nullptr,
57         Z_DEFLATED, Z_DEFAULT_COMPRESSION);
58     if (errcode != Z_OK) {
59         HILOGE("zipOpenNewFileInZip failed:%{public}s, errno: %{public}d.", srcFile.c_str(), errcode);
60         (void)fclose(srcFp);
61         zipCloseFileInZip(zipfile);
62         return errcode;
63     }
64 
65     char buf[READ_MORE_LENGTH] = {0};
66     while (!feof(srcFp)) {
67         size_t numBytes = fread(buf, 1, sizeof(buf), srcFp);
68         if (numBytes == 0) {
69             break;
70         }
71         errcode = zipWriteInFileInZip(zipfile, buf, static_cast<unsigned int>(numBytes));
72         if (errcode != Z_OK) {
73             HILOGE("zipOpenNewFileInZip failed:%{public}s, errno: %{public}d.", srcFile.c_str(), errcode);
74             break;
75         }
76         if (ferror(srcFp)) {
77             HILOGE("zip file failed:%{public}s, errno: %{public}d.", srcFile.c_str(), errno);
78             errcode = errno;
79             break;
80         }
81     }
82     (void)fclose(srcFp);
83     zipCloseFileInZip(zipfile);
84     return errcode;
85 }
86 
GetFileHandle(const std::string & file)87 FILE *ZipUtil::GetFileHandle(const std::string &file)
88 {
89     char realPath[PATH_MAX] = {0};
90     if (realpath(file.c_str(), realPath) == nullptr) {
91         return nullptr;
92     }
93     return fopen(realPath, "rb");
94 }
95 
GetDestFilePath(const std::string & srcFile,const std::string & destFilePath,int keepParentPathStatus)96 std::string ZipUtil::GetDestFilePath(const std::string &srcFile, const std::string &destFilePath,
97     int keepParentPathStatus)
98 {
99     if (!destFilePath.empty()) {
100         return destFilePath;
101     }
102     std::string file = srcFile;
103     std::string result = file;
104     std::string parentPathName;
105     auto pos = file.rfind("/");
106     if (pos != std::string::npos && pos != file.length() - 1) {
107         result = file.substr(pos + 1);
108         std::string parent = file.substr(0, pos);
109         pos = parent.rfind("/");
110         if (pos != std::string::npos && pos != parent.length() - 1) {
111             parentPathName = parent.substr(pos + 1);
112         } else {
113             parentPathName = parent;
114         }
115     }
116     parentPathName.append("/");
117     if (keepParentPathStatus == KEEP_ONE_PARENT_PATH) {
118         // srcFileName with relative directory path
119         result.insert(0, parentPathName);
120     }
121     return result;
122 }
123 }
124