• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023 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_TAR_FILE_H
17 #define OHOS_FILEMGMT_BACKUP_BACKUP_TAR_FILE_H
18 
19 #include <map>
20 #include <memory>
21 #include <string>
22 #include <sys/stat.h>
23 #include <sys/types.h>
24 #include <unistd.h>
25 #include <vector>
26 
27 namespace OHOS::FileManagement::Backup {
28 namespace {
29 const uint32_t TMAGIC_LEN = 6;
30 const uint32_t TNAME_LEN = 100;
31 const uint32_t TMODE_LEN = 8;
32 const uint32_t TUID_LEN = 8;
33 const uint32_t TGID_LEN = 8;
34 const uint32_t TSIZE_LEN = 12;
35 const uint32_t MTIME_LEN = 12;
36 const uint32_t CHKSUM_LEN = 8;
37 const uint32_t VERSION_LEN = 2;
38 const uint32_t NAME_LEN = 32;
39 const uint32_t MAJOR_LEN = 8;
40 const uint32_t MINOR_LEN = 8;
41 const uint32_t PREFIX_LEN = 155;
42 const uint32_t PADDING_LEN = 12;
43 const uint32_t TMODE_BASE = 100;
44 const uint32_t TUID_BASE = 108;
45 const uint32_t TGID_BASE = 116;
46 const uint32_t TSIZE_BASE = 124;
47 const uint32_t TMTIME_BASE = 136;
48 const uint32_t CHKSUM_BASE = 148;
49 const uint32_t BLOCK_SIZE = 512;
50 const off_t READ_BUFF_SIZE = 512 * 1024;
51 const uint8_t BLANK_SPACE = 0x20;
52 const uint64_t MB_TO_BYTE = 1024 * 1024;
53 const std::string TMAGIC = "ustar";
54 const char REGTYPE = '0';   // regular file
55 const char AREGTYPE = '\0'; // regular file
56 const char SYMTYPE = '2';   // reserved
57 const char DIRTYPE = '5';   // directory
58 const char GNUTYPE_LONGNAME = 'L';
59 } // namespace
60 
61 // 512 bytes
62 using TarHeader = struct {
63     char name[TNAME_LEN];
64     char mode[TMODE_LEN];
65     char uid[TUID_LEN];
66     char gid[TGID_LEN];
67     char size[TSIZE_LEN];
68     char mtime[MTIME_LEN];
69     char chksum[CHKSUM_LEN];
70     char typeFlag;
71     char linkName[TNAME_LEN];
72     char magic[TMAGIC_LEN];
73     char version[VERSION_LEN];
74     char uname[NAME_LEN];
75     char gname[NAME_LEN];
76     char devMajor[MAJOR_LEN];
77     char devMinor[MINOR_LEN];
78     char prefix[PREFIX_LEN];
79     char pad[PADDING_LEN];
80 };
81 using TarMap = std::map<std::string, std::tuple<std::string, struct stat, bool>>;
82 class TarFile {
83 public:
84     static TarFile &GetInstance();
85 
86     bool Packet(const std::vector<std::string> &srcFiles,
87                 const std::string &tarFileName,
88                 const std::string &pkPath,
89                 TarMap &tarMap,
90                 std::function<void(std::string, int)> reportCb);
91 
92     /**
93      * @brief set packet mode
94      *
95      * @param isReset 是否每次重置 tarMap_
96      */
97     void SetPacketMode(bool isReset);
98 
99 private:
TarFile()100     TarFile() {}
101     ~TarFile() = default;
102     TarFile(const TarFile &instance) = delete;
103     TarFile &operator=(const TarFile &instance) = delete;
104 
105     /**
106      * @brief traversal file
107      *
108      * @param filename 文件名
109      * @return true 遍历成功
110      * @return false 遍历失败
111      */
112     bool TraversalFile(std::string &fileName, int &err);
113 
114     /**
115      * @brief add files to the tar package
116      *
117      * @param filename 文件名
118      * @param st 文件参数结构体
119      */
120     bool AddFile(std::string &fileName, const struct stat &st, int &err);
121 
122     /**
123      * @brief write files to content
124      *
125      * @param filename 文件名
126      * @param size 文件大小
127      */
128     bool WriteFileContent(const std::string &fileName, off_t size, int &err);
129 
130     /**
131      * @brief split write
132      *
133      * @param ioBuffer 写入的文件信息
134      * @param read 读取文件
135      */
136     off_t SplitWriteAll(const std::vector<uint8_t> &ioBuffer, off_t read);
137 
138     /**
139      * @brief creaat split tarfile
140      */
141     bool CreateSplitTarFile();
142 
143     /**
144      * @brief complete block
145      *
146      * @param size 完成的块大小
147      */
148     bool CompleteBlock(off_t size);
149 
150     /**
151      * @brief fill split tailblocks
152      */
153     bool FillSplitTailBlocks();
154 
155     /**
156      * @brief set check sum
157      *
158      * @param hdr tar文件结构体
159      */
160     void SetCheckSum(TarHeader &hdr);
161 
162     /**
163      * @brief fill owner name
164      *
165      * @param hdr tar文件结构体
166      * @param st  文件结构体
167      */
168     void FillOwnerName(TarHeader &hdr, const struct stat &st);
169 
170     /**
171      * @brief write long name
172      *
173      * @param name  文件名
174      * @param type  文件类型
175      */
176     bool WriteLongName(std::string &name, char type);
177 
178     /**
179      * @brief read files
180      *
181      * @param fd 文件描述符
182      * @param iobuffer  文件信息数组
183      * @param size  文件大小
184      */
185     off_t ReadAll(int fd, std::vector<uint8_t> &ioBuffer, off_t size);
186 
187     /**
188      * @brief write files
189      *
190      * @param buffer 文件内容数组
191      * @param len  长度
192      */
193     int WriteAll(const std::vector<uint8_t> &buffer, size_t len);
194 
195     /**
196      * @brief write tar header to tar file
197      *
198      * @param header tar文件头结构体
199      */
200     int WriteTarHeader(TarHeader &header);
201 
202     /**
203      * @brief Character conversion
204      *
205      * @param len  长度
206      * @param val  需要转换的值
207      */
208     std::string I2Ocs(int len, off_t val);
209 
210     /**
211      * @brief Character conversion
212      *
213      * @param st   文件信息结构体
214      * @param hdr  tar包文件头
215      */
216     bool I2OcsConvert(const struct stat &st, TarHeader &hdr, std::string &fileName);
217 
218 private:
219     uint32_t fileCount_ {0};
220     TarMap tarMap_ {};
221 
222     std::string rootPath_ {};
223     std::string packagePath_ {};
224     std::string baseTarName_ {};
225     std::string tarFileName_ {};
226 
227     std::vector<uint8_t> ioBuffer_ {};
228 
229     FILE *currentTarFile_ {nullptr};
230     std::string currentTarName_ {};
231     off_t currentTarFileSize_ {0};
232     uint32_t tarFileCount_ {0};
233 
234     std::string currentFileName_ {};
235 
236     bool isReset_ = false;
237 };
238 } // namespace OHOS::FileManagement::Backup
239 
240 #endif // OHOS_FILEMGMT_BACKUP_BACKUP_TAR_FILE_H