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