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