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