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