1 /*
2  * Copyright (c) 2023-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 #ifndef OHOS_FILEMGMT_BACKUP_BACKUP_UNTAR_FILE_H
17 #define OHOS_FILEMGMT_BACKUP_BACKUP_UNTAR_FILE_H
18 
19 #include "tar_file.h"
20 #include "b_json/b_report_entity.h"
21 
22 namespace OHOS::FileManagement::Backup {
23 struct FileStatInfo {
24     std::string fullPath {};
25     mode_t mode {0};
26     uid_t uid {0};
27     gid_t gid {0};
28     off_t mtime {0};
29     std::string longName {};
30 };
31 
32 using ErrFileInfo = std::map<std::string, std::vector<int>>;
33 using EndFileInfo = std::map<std::string, off_t>;
34 
35 const int FIRST_PARAM = 0;
36 const int SECOND_PARAM = 1;
37 const int THIRD_PARAM = 2;
38 class UntarFile {
39 public:
40     typedef enum { ERR_FORMAT = -1 } ErrorCode;
41     static UntarFile &GetInstance();
42     std::tuple<int, EndFileInfo, ErrFileInfo> UnPacket(
43         const std::string &tarFile, const std::string &rootPath);
44     std::tuple<int, EndFileInfo, ErrFileInfo> IncrementalUnPacket(
45         const std::string &tarFile, const std::string &rootPath,
46         const std::unordered_map<std::string, struct ReportFileInfo> &includes);
47 
48 private:
49     UntarFile() = default;
50     ~UntarFile() = default;
51     UntarFile(const UntarFile &instance) = delete;
52     UntarFile &operator=(const UntarFile &instance) = delete;
53 
54     /**
55      * @brief parse tar file
56      *
57      * @param rootpath 解包的目标路径
58      */
59     std::tuple<int, EndFileInfo, ErrFileInfo> ParseTarFile(const std::string &rootPath);
60 
61     /**
62      * @brief parse incremental tar file
63      *
64      * @param rootpath 解包的目标路径
65      */
66     std::tuple<int, EndFileInfo, ErrFileInfo> ParseIncrementalTarFile(const std::string &rootPath);
67 
68     /**
69      * @brief verfy check sum
70      *
71      * @param tarHeader tar文件头
72      */
73     bool VerifyChecksum(TarHeader &tarHeader);
74 
75     /**
76      * @brief is valid tarblock
77      *
78      * @param tarHeader tar文件头
79      */
80     bool IsValidTarBlock(TarHeader &tarHeader);
81 
82     /**
83      * @brief get real path
84      *
85      * @param rootpath 解包的目标路径
86      * @param pathName 文件路径名
87      */
88     std::string GenRealPath(const std::string &rootPath, const std::string &pathName);
89 
90     /**
91      * @brief creat dir
92      *
93      * @param path 文件路径名
94      * @param mode 文件打开模式
95      */
96     ErrFileInfo CreateDir(std::string &path, mode_t mode);
97 
98     /**
99      * @brief creat a file
100      *
101      * @param path 文件路径名
102      */
103     FILE *CreateFile(std::string &path);
104 
105     /**
106      * @brief parse regular file
107      *
108      * @param info 文件属性结构体
109      * @param typeFlag 文件类型标志
110      */
111     ErrFileInfo ParseRegularFile(FileStatInfo &info);
112 
113     /**
114      * @brief handle tar buffer
115      *
116      * @param buff 读取tar文件数据缓冲区
117      * @param name 文件名
118      * @param info 文件属性结构体
119      */
120     off_t HandleTarBuffer(const std::string &buff, const std::string &name, FileStatInfo &info);
121 
122     /**
123      * @brief parse file by typeFlag
124      *
125      * @param typeFlag 文件类型标志
126      * @param info 文件属性结构体
127      */
128     std::tuple<int, bool, ErrFileInfo> ParseFileByTypeFlag(char typeFlag, FileStatInfo &info);
129 
130     /**
131      * @brief parse incremental file by typeFlag
132      *
133      * @param typeFlag 文件类型标志
134      * @param info 文件属性结构体
135      */
136     std::tuple<int, bool, ErrFileInfo> ParseIncrementalFileByTypeFlag(char typeFlag, FileStatInfo &info);
137 
138     /**
139      * @brief Check tar and fill tar size
140      */
141     int CheckAndFillTarSize();
142 
143     /**
144      * @brief Read long name and recode errinfo
145      *
146      * @param info file state info
147      */
148     std::tuple<int, ErrFileInfo> ReadLongName(FileStatInfo &info);
149 
150     /**
151      * @brief deal parse tar file result
152      *
153      * @param result parse tar file result info
154      * @param fileSize size of the file in tar
155      * @param fileName file state info
156      * @param fileInfos out param, record file info
157      * @param errInfos out param, record err file info
158      */
159     int DealParseTarFileResult(const std::tuple<int, bool, ErrFileInfo> &result,
160         const off_t fileSize, const std::string &fileName, EndFileInfo &fileInfos, ErrFileInfo &errInfos);
161 
162     /**
163      * @brief deal incremental parse tar file result
164      *
165      * @param result parse tar file result info
166      * @param fileSize size of the file in tar
167      * @param fileName file state info
168      * @param fileInfos out param, record file info
169      * @param errInfos out param, record err file info
170      */
171     int DealIncreParseTarFileResult(const std::tuple<int, bool, ErrFileInfo> &result,
172         const off_t fileSize, const std::string &fileName, EndFileInfo &fileInfos, ErrFileInfo &errInfos);
173 
174     /**
175      * @brief check if tar block valid
176      *
177      * @param buff check buff info
178      * @param header check header info
179      * @param ret out param, the err info
180      */
181     bool CheckIfTarBlockValid(char *buff, size_t buffLen, TarHeader *header, int &ret);
182 
183     /**
184      * @brief deal file tag info
185      *
186      * @param errFileInfo out param, err file info
187      * @param info out param, file info
188      * @param isFilter out param, is Filter
189      * @param tmpFullPath in param, tmpFullPath
190      */
191     bool DealFileTag(ErrFileInfo &errFileInfo,
192         FileStatInfo &info, bool &isFilter, const std::string &tmpFullPath);
193 
194 private:
195     std::string rootPath_ {};
196 
197     FILE *tarFilePtr_ {nullptr};
198     off_t tarFileSize_ {0};
199     off_t tarFileBlockCnt_ {0};
200     off_t pos_ {0};
201     size_t readCnt_ {0};
202     std::unordered_map<std::string, struct ReportFileInfo> includes_;
203 };
204 } // namespace OHOS::FileManagement::Backup
205 
206 #endif // OHOS_FILEMGMT_BACKUP_BACKUP_UNTAR_FILE_H