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 102 private: TarFile()103 TarFile() {} 104 ~TarFile() = default; 105 TarFile(const TarFile &instance) = delete; 106 TarFile &operator=(const TarFile &instance) = delete; 107 108 /** 109 * @brief traversal file 110 * 111 * @param filename 文件名 112 * @return true 遍历成功 113 * @return false 遍历失败 114 */ 115 bool TraversalFile(std::string &fileName, int &err); 116 117 /** 118 * @brief add files to the tar package 119 * 120 * @param filename 文件名 121 * @param st 文件参数结构体 122 */ 123 bool AddFile(std::string &fileName, const struct stat &st, int &err); 124 125 /** 126 * @brief write files to content 127 * 128 * @param filename 文件名 129 * @param size 文件大小 130 */ 131 bool WriteFileContent(const std::string &fileName, off_t size, int &err); 132 133 /** 134 * @brief split write 135 * 136 * @param ioBuffer 写入的文件信息 137 * @param read 读取文件 138 */ 139 off_t SplitWriteAll(const std::vector<uint8_t> &ioBuffer, off_t read, int &err); 140 141 /** 142 * @brief creaat split tarfile 143 */ 144 bool CreateSplitTarFile(); 145 146 /** 147 * @brief complete block 148 * 149 * @param size 完成的块大小 150 */ 151 bool CompleteBlock(off_t size); 152 153 /** 154 * @brief fill split tailblocks 155 */ 156 bool FillSplitTailBlocks(); 157 158 /** 159 * @brief set check sum 160 * 161 * @param hdr tar文件结构体 162 */ 163 void SetCheckSum(TarHeader &hdr); 164 165 /** 166 * @brief fill owner name 167 * 168 * @param hdr tar文件结构体 169 * @param st 文件结构体 170 */ 171 void FillOwnerName(TarHeader &hdr, const struct stat &st); 172 173 /** 174 * @brief write long name 175 * 176 * @param name 文件名 177 * @param type 文件类型 178 */ 179 bool WriteLongName(std::string &name, char type); 180 181 /** 182 * @brief read files 183 * 184 * @param fd 文件描述符 185 * @param iobuffer 文件信息数组 186 * @param size 文件大小 187 */ 188 off_t ReadAll(int fd, std::vector<uint8_t> &ioBuffer, off_t size); 189 190 /** 191 * @brief write files 192 * 193 * @param buffer 文件内容数组 194 * @param len 长度 195 */ 196 int WriteAll(const std::vector<uint8_t> &buffer, size_t len); 197 198 /** 199 * @brief write tar header to tar file 200 * 201 * @param header tar文件头结构体 202 */ 203 int WriteTarHeader(TarHeader &header); 204 205 /** 206 * @brief Character conversion 207 * 208 * @param len 长度 209 * @param val 需要转换的值 210 */ 211 std::string I2Ocs(int len, off_t val); 212 213 /** 214 * @brief Character conversion 215 * 216 * @param st 文件信息结构体 217 * @param hdr tar包文件头 218 */ 219 bool I2OcsConvert(const struct stat &st, TarHeader &hdr, std::string &fileName); 220 221 bool ToAddFile(std::string &path, int &err); 222 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