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