• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2023-2024 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 #include "tar_file.h"
17 
18 #include <dirent.h>
19 #include <fcntl.h>
20 #include <grp.h>
21 #include <pwd.h>
22 #include <stack>
23 #include <sys/types.h>
24 #include <unistd.h>
25 
26 #include "b_anony/b_anony.h"
27 #include "b_error/b_error.h"
28 #include "b_resources/b_constants.h"
29 #include "directory_ex.h"
30 #include "filemgmt_libhilog.h"
31 #include "securec.h"
32 
33 namespace OHOS::FileManagement::Backup {
34 using namespace std;
35 namespace {
36 const uint32_t OFF_T_SIZE = 4;
37 const uint32_t PERMISSION_MASK = 07777;
38 const uint64_t MAX_FILE_SIZE = 0777777777777L;
39 const uint32_t OCTSTR_LEN = sizeof(off_t) * 3 + 1;
40 const uint32_t DEFAULT_SLICE_SIZE = 100 * MB_TO_BYTE; // 分片文件大小为100M
41 const uint32_t MAX_FILE_COUNT = 6000;                 // 单个tar包最多包含6000个文件
42 const uint32_t WAIT_INDEX = 100000;
43 const uint32_t WAIT_TIME = 5;
44 const string VERSION = "1.0";
45 const string LONG_LINK_SYMBOL = "longLinkSymbol";
46 } // namespace
47 
GetInstance()48 TarFile &TarFile::GetInstance()
49 {
50     static TarFile instance;
51     return instance;
52 }
53 
Packet(const vector<string> & srcFiles,const string & tarFileName,const string & pkPath,TarMap & tarMap,std::function<void (std::string,int)> reportCb)54 bool TarFile::Packet(const vector<string> &srcFiles, const string &tarFileName, const string &pkPath, TarMap &tarMap,
55     std::function<void(std::string, int)> reportCb)
56 {
57     if (tarFileName.empty() || pkPath.empty()) {
58         HILOGE("Invalid parameter");
59         return false;
60     }
61     HILOGI("Start Packet files, tarFileName is:%{public}s", tarFileName.c_str());
62     ioBuffer_.resize(READ_BUFF_SIZE);
63     baseTarName_ = tarFileName;
64     packagePath_ = pkPath;
65     if (pkPath[pkPath.length() - 1] == '/') {
66         packagePath_ = packagePath_.substr(0, packagePath_.length() - 1);
67     }
68 
69     HILOGI("Start Create  SplitTar files");
70     CreateSplitTarFile();
71 
72     size_t index = 0;
73     for (const auto &filePath : srcFiles) {
74         int err = 0;
75         rootPath_ = filePath;
76         if (!TraversalFile(rootPath_, err)) {
77             HILOGE("ReportErr Failed to traversal file, file path is:%{public}s, err = %{public}d",
78                 GetAnonyPath(filePath).c_str(), err);
79             if (err != EACCES) {
80                 reportCb("", err);
81             }
82         }
83         index++;
84         if (index >= WAIT_INDEX) {
85             HILOGD("Sleep to wait");
86             sleep(WAIT_TIME);
87             index = 0;
88         }
89     }
90     HILOGI("Start Fill SplitTailBlocks");
91     FillSplitTailBlocks();
92 
93     tarMap = tarMap_;
94 
95     if (currentTarFile_ != nullptr) {
96         fclose(currentTarFile_);
97         currentTarFile_ = nullptr;
98     }
99     HILOGI("End Packet files, pkPath is:%{public}s", pkPath.c_str());
100     return true;
101 }
102 
TraversalFile(string & filePath,int & err)103 bool TarFile::TraversalFile(string &filePath, int &err)
104 {
105     if (access(filePath.c_str(), F_OK) != 0) {
106         err = errno;
107         HILOGE("File path does not exists, err = %{public}d", errno);
108         return false;
109     }
110 
111     struct stat curFileStat {};
112     auto ret = memset_s(&curFileStat, sizeof(curFileStat), 0, sizeof(curFileStat));
113     if (ret != EOK) {
114         HILOGE("Failed to call memset_s, err = %{public}d", ret);
115         return false;
116     }
117     if (lstat(filePath.c_str(), &curFileStat) != 0) {
118         err = errno;
119         HILOGE("Failed to lstat, err = %{public}d", errno);
120         return false;
121     }
122     if (!AddFile(filePath, curFileStat, err)) {
123         HILOGE("Failed to add file to tar package, file path is:%{public}s", GetAnonyPath(filePath).c_str());
124         return false;
125     }
126 
127     if (isReset_) {
128         return true;
129     }
130 
131     if (currentTarFileSize_ >= DEFAULT_SLICE_SIZE) {
132         HILOGI("Current tar file size is over %{public}d, start to slice",
133                static_cast<int32_t>(DEFAULT_SLICE_SIZE / MB_TO_BYTE));
134         fileCount_ = 0;
135         FillSplitTailBlocks();
136         CreateSplitTarFile();
137         return true;
138     }
139 
140     // tar包内文件数量大于6000,分片打包
141     fileCount_++;
142     if (fileCount_ == MAX_FILE_COUNT) {
143         HILOGI("The number of files in the tar package exceeds %{public}d, start to slice", MAX_FILE_COUNT);
144         fileCount_ = 0;
145         FillSplitTailBlocks();
146         CreateSplitTarFile();
147     }
148 
149     return true;
150 }
151 
CopyData(TarHeader & hdr,const string & mode,const string & uid,const string & gid,const string & size)152 static bool CopyData(TarHeader &hdr, const string &mode, const string &uid, const string &gid, const string &size)
153 {
154     auto ret = memcpy_s(hdr.mode, sizeof(hdr.mode), mode.c_str(), min(sizeof(hdr.mode) - 1, mode.length()));
155     if (ret != EOK) {
156         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
157         return false;
158     }
159     ret = memcpy_s(hdr.uid, sizeof(hdr.uid), uid.c_str(), min(sizeof(hdr.uid) - 1, uid.length()));
160     if (ret != EOK) {
161         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
162         return false;
163     }
164     ret = memcpy_s(hdr.gid, sizeof(hdr.gid), gid.c_str(), min(sizeof(hdr.gid) - 1, gid.length()));
165     if (ret != EOK) {
166         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
167         return false;
168     }
169     ret = memcpy_s(hdr.size, sizeof(hdr.size), size.c_str(), min(sizeof(hdr.size) - 1, size.length()));
170     if (ret != EOK) {
171         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
172         return false;
173     }
174     return true;
175 }
176 
I2OcsConvert(const struct stat & st,TarHeader & hdr,string & fileName)177 bool TarFile::I2OcsConvert(const struct stat &st, TarHeader &hdr, string &fileName)
178 {
179     auto ret = memset_s(&hdr, sizeof(hdr), 0, sizeof(hdr));
180     if (ret != EOK) {
181         HILOGE("Failed to call memset_s, err = %{public}d", ret);
182         return false;
183     }
184 
185     string mode = I2Ocs(sizeof(hdr.mode), st.st_mode & PERMISSION_MASK);
186     string uid = I2Ocs(sizeof(hdr.uid), st.st_uid);
187     string gid = I2Ocs(sizeof(hdr.gid), st.st_gid);
188     string size = I2Ocs(sizeof(hdr.size), 0);
189     if (!CopyData(hdr, mode, uid, gid, size)) {
190         return false;
191     }
192 
193     string mtime = I2Ocs(sizeof(hdr.mtime), st.st_mtime);
194     ret = memcpy_s(hdr.mtime, sizeof(hdr.mtime), mtime.c_str(), min(sizeof(hdr.mtime) - 1, mtime.length()));
195     if (ret != EOK) {
196         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
197         return false;
198     }
199     ret = memset_s(hdr.chksum, sizeof(hdr.chksum), BLANK_SPACE, sizeof(hdr.chksum));
200     if (ret != EOK) {
201         HILOGE("Failed to call memset_s, err = %{public}d", ret);
202         return false;
203     }
204 
205     if (S_ISREG(st.st_mode)) {
206         hdr.typeFlag = REGTYPE;
207     } else if (S_ISDIR(st.st_mode)) {
208         hdr.typeFlag = DIRTYPE;
209     } else {
210         return true;
211     }
212     off_t hdrSize = st.st_size;
213     if (sizeof(off_t) <= OFF_T_SIZE || st.st_size <= static_cast<off_t>(MAX_FILE_SIZE)) {
214         size = I2Ocs(sizeof(hdr.size), hdrSize);
215         ret = memcpy_s(hdr.size, sizeof(hdr.size), size.c_str(), min(sizeof(hdr.size) - 1, size.length()));
216         if (ret != EOK) {
217             HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
218             return false;
219         }
220     } else {
221         HILOGE("Invalid tar header size");
222         return false;
223     }
224 
225     if (S_ISDIR(st.st_mode) && fileName.back() != '/') {
226         fileName.append("/");
227     }
228 
229     return true;
230 }
231 
ReadyHeader(TarHeader & hdr,const string & fileName)232 static bool ReadyHeader(TarHeader &hdr, const string &fileName)
233 {
234     errno_t ret = EOK;
235     if (fileName.length() < TNAME_LEN) {
236         if (ret = memcpy_s(hdr.name, sizeof(hdr.name), fileName.c_str(), fileName.length()), ret != EOK) {
237             HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
238             return false;
239         }
240     } else {
241         ret = memcpy_s(hdr.name, sizeof(hdr.name), LONG_LINK_SYMBOL.c_str(),
242             min(sizeof(hdr.name) - 1, LONG_LINK_SYMBOL.length()));
243         if (ret != EOK) {
244             HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
245             return false;
246         }
247     }
248     ret = memcpy_s(hdr.magic, sizeof(hdr.magic), TMAGIC.c_str(), min(sizeof(hdr.magic) - 1, TMAGIC.length()));
249     if (ret != EOK) {
250         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
251         return false;
252     }
253     ret = memcpy_s(hdr.version, sizeof(hdr.version), VERSION.c_str(), min(sizeof(hdr.version) - 1, VERSION.length()));
254     if (ret != EOK) {
255         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
256         return false;
257     }
258     return true;
259 }
260 
AddFile(string & fileName,const struct stat & st,int & err)261 bool TarFile::AddFile(string &fileName, const struct stat &st, int &err)
262 {
263     HILOGD("tar file %{public}s", fileName.c_str());
264     currentFileName_ = fileName;
265 
266     TarHeader hdr;
267     if (!I2OcsConvert(st, hdr, fileName)) {
268         HILOGE("Failed to I2OcsConvert");
269         return false;
270     }
271     if (!ReadyHeader(hdr, fileName)) {
272         return false;
273     }
274     if (fileName.length() >= TNAME_LEN) {
275         if (!WriteLongName(fileName, GNUTYPE_LONGNAME)) {
276             return false;
277         }
278     }
279     FillOwnerName(hdr, st);
280     SetCheckSum(hdr);
281 
282     if (hdr.typeFlag != REGTYPE) {
283         if (WriteTarHeader(hdr) != BLOCK_SIZE) {
284             HILOGE("Failed to write all");
285             return false;
286         }
287         currentFileName_ = "";
288         return true;
289     }
290 
291     // write tar header of src file
292     if (WriteTarHeader(hdr) != BLOCK_SIZE) {
293         HILOGE("Failed to write all");
294         return false;
295     }
296     // write src file content to tar file
297     if (!WriteFileContent(fileName, st.st_size, err)) {
298         HILOGE("Failed to write file content");
299         return false;
300     }
301     currentFileName_ = "";
302     return true;
303 }
304 
WriteFileContent(const string & fileName,off_t size,int & err)305 bool TarFile::WriteFileContent(const string &fileName, off_t size, int &err)
306 {
307     int fd = open(fileName.c_str(), O_RDONLY | O_CLOEXEC);
308     if (fd < 0) {
309         err = errno;
310         HILOGE("Failed to open file %{public}s, err = %{public}d", GetAnonyString(fileName).data(), errno);
311         return false;
312     }
313 
314     off_t remain = size;
315     while (remain > 0) {
316         off_t read = ioBuffer_.size();
317         if (remain < read) {
318             read = remain;
319         }
320         // read buffer from src file
321         if (ReadAll(fd, ioBuffer_, read) != read) {
322             HILOGE("Failed to read all");
323             break;
324         }
325 
326         // write buffer to tar file
327         if (SplitWriteAll(ioBuffer_, read) != read) {
328             HILOGE("Failed to split write all");
329             break;
330         }
331         remain -= read;
332     }
333 
334     close(fd);
335     if (remain == 0) {
336         return CompleteBlock(size);
337     }
338     return false;
339 }
340 
SplitWriteAll(const vector<uint8_t> & ioBuffer,off_t read)341 off_t TarFile::SplitWriteAll(const vector<uint8_t> &ioBuffer, off_t read)
342 {
343     off_t len = static_cast<off_t>(ioBuffer.size());
344     if (len > read) {
345         len = read;
346     }
347     off_t count = 0;
348     while (count < len) {
349         auto writeBytes = fwrite(&ioBuffer[count], sizeof(uint8_t), len - count, currentTarFile_);
350         if (writeBytes < 1) {
351             // 再执行一遍
352             writeBytes = fwrite(&ioBuffer[count], sizeof(uint8_t), len - count, currentTarFile_);
353             if (writeBytes < 1) {
354                 HILOGE("Failed to fwrite tar file, err = %{public}d", errno);
355                 return count;
356             }
357         }
358         count += static_cast<off_t>(writeBytes);
359         currentTarFileSize_ += static_cast<off_t>(writeBytes);
360     }
361     return count;
362 }
363 
CreateSplitTarFile()364 bool TarFile::CreateSplitTarFile()
365 {
366     tarFileName_ = baseTarName_ + "." + to_string(tarFileCount_) + ".tar";
367     currentTarName_ = packagePath_ + "/" + tarFileName_;
368     if (currentTarFile_ != nullptr) {
369         fclose(currentTarFile_);
370         currentTarFile_ = nullptr;
371     }
372     // create a tar file
373     currentTarFile_ = fopen(currentTarName_.c_str(), "wb+");
374     if (currentTarFile_ == nullptr) {
375         HILOGE("Failed to open file %{public}s, err = %{public}d", currentTarName_.c_str(), errno);
376         throw BError(BError::Codes::EXT_BACKUP_PACKET_ERROR, "CreateSplitTarFile Failed to open file");
377     }
378     currentTarFileSize_ = 0;
379 
380     return true;
381 }
382 
CompleteBlock(off_t size)383 bool TarFile::CompleteBlock(off_t size)
384 {
385     if ((size % BLOCK_SIZE) > 0) {
386         int append = BLOCK_SIZE - (size % BLOCK_SIZE);
387         vector<uint8_t> buff {};
388         buff.resize(append);
389         WriteAll(buff, append);
390     }
391     return true;
392 }
393 
FillSplitTailBlocks()394 bool TarFile::FillSplitTailBlocks()
395 {
396     if (currentTarFile_ == nullptr) {
397         throw BError(BError::Codes::EXT_BACKUP_PACKET_ERROR, "FillSplitTailBlocks currentTarFile_ is null");
398     }
399 
400     // write tar file tail
401     const int END_BLOCK_SIZE = 1024;
402     vector<uint8_t> buff {};
403     buff.resize(END_BLOCK_SIZE);
404     WriteAll(buff, END_BLOCK_SIZE);
405     fflush(currentTarFile_);
406 
407     struct stat staTar {};
408     int ret = stat(currentTarName_.c_str(), &staTar);
409     if (ret != 0) {
410         HILOGE("Failed to stat file %{public}s, err = %{public}d", currentTarName_.c_str(), errno);
411         throw BError(BError::Codes::EXT_BACKUP_PACKET_ERROR, "FillSplitTailBlocks Failed to stat file");
412     }
413 
414     if (staTar.st_size == 0 && tarFileCount_ > 0 && fileCount_ == 0) {
415         fclose(currentTarFile_);
416         currentTarFile_ = nullptr;
417         remove(currentTarName_.c_str());
418         return true;
419     }
420 
421     if (isReset_) {
422         tarMap_.clear();
423     }
424 
425     tarMap_.emplace(tarFileName_, make_tuple(currentTarName_, staTar, false));
426 
427     fclose(currentTarFile_);
428     currentTarFile_ = nullptr;
429     tarFileCount_++;
430 
431     return true;
432 }
433 
SetCheckSum(TarHeader & hdr)434 void TarFile::SetCheckSum(TarHeader &hdr)
435 {
436     int sum = 0;
437     vector<uint32_t> buffer {};
438     buffer.resize(BLOCK_SIZE);
439     buffer.assign(reinterpret_cast<uint8_t *>(&hdr), reinterpret_cast<uint8_t *>(&hdr) + sizeof(hdr));
440     for (uint32_t index = 0; index < BLOCK_SIZE; index++) {
441         if (index < CHKSUM_BASE || index > CHKSUM_BASE + CHKSUM_LEN - 1) {
442             sum += (buffer[index] & 0xFF);
443         } else {
444             sum += BLANK_SPACE;
445         }
446     }
447     string chksum = I2Ocs(sizeof(hdr.chksum), sum);
448     auto ret = memcpy_s(hdr.chksum, sizeof(hdr.chksum), chksum.c_str(), min(sizeof(hdr.chksum) - 1, chksum.length()));
449     if (ret != EOK) {
450         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
451     }
452 }
453 
FillOwnerName(TarHeader & hdr,const struct stat & st)454 void TarFile::FillOwnerName(TarHeader &hdr, const struct stat &st)
455 {
456     struct passwd *pw = getpwuid(st.st_uid);
457     if (pw != nullptr) {
458         auto ret = snprintf_s(hdr.uname, sizeof(hdr.uname), sizeof(hdr.uname) - 1, "%s", pw->pw_name);
459         if (ret < 0 || ret >= static_cast<int>(sizeof(hdr.uname))) {
460             HILOGE("Fill pw_name failed, err = %{public}d", errno);
461         }
462     } else {
463         auto ret = snprintf_s(hdr.uname, sizeof(hdr.uname), sizeof(hdr.uname) - 1, "%u", st.st_uid);
464         if (ret < 0 || ret >= static_cast<int>(sizeof(hdr.uname))) {
465             HILOGE("Fill uid failed, err = %{public}d", errno);
466         }
467     }
468 
469     struct group *gr = getgrgid(st.st_gid);
470     if (gr != nullptr) {
471         auto ret = snprintf_s(hdr.gname, sizeof(hdr.gname), sizeof(hdr.gname) - 1, "%s", gr->gr_name);
472         if (ret < 0 || ret >= static_cast<int>(sizeof(hdr.gname))) {
473             HILOGE("Fill gr_name failed, err = %{public}d", errno);
474         }
475     } else {
476         auto ret = snprintf_s(hdr.gname, sizeof(hdr.gname), sizeof(hdr.gname) - 1, "%u", st.st_gid);
477         if (ret < 0 || ret >= static_cast<int>(sizeof(hdr.gname))) {
478             HILOGE("Fill gid failed, err = %{public}d", errno);
479         }
480     }
481 }
482 
ReadAll(int fd,vector<uint8_t> & ioBuffer,off_t size)483 off_t TarFile::ReadAll(int fd, vector<uint8_t> &ioBuffer, off_t size)
484 {
485     off_t count = 0;
486     off_t len = static_cast<off_t>(ioBuffer.size());
487     if (len > size) {
488         len = size;
489     }
490     while (count < len) {
491         auto readLen = read(fd, &ioBuffer[count], len - count);
492         count += static_cast<off_t>(readLen);
493         if (readLen == 0) {
494             break;
495         }
496     }
497     return count;
498 }
499 
WriteTarHeader(TarHeader & header)500 int TarFile::WriteTarHeader(TarHeader &header)
501 {
502     vector<uint8_t> buffer {};
503     buffer.resize(BLOCK_SIZE);
504     buffer.assign(reinterpret_cast<uint8_t *>(&header), reinterpret_cast<uint8_t *>(&header) + sizeof(header));
505     int ret = WriteAll(buffer, BLOCK_SIZE);
506     if (ret != BLOCK_SIZE) {
507         buffer.erase(buffer.begin(), buffer.begin() + ret);
508         ret += WriteAll(buffer, BLOCK_SIZE - ret); // 再执行一遍
509     }
510     return ret;
511 }
512 
WriteAll(const vector<uint8_t> & buf,size_t len)513 int TarFile::WriteAll(const vector<uint8_t> &buf, size_t len)
514 {
515     size_t count = 0;
516     while (count < len) {
517         auto i = fwrite(&buf[0] + count, sizeof(char), len - count, currentTarFile_);
518         if (i < 1) {
519             HILOGE("Failed to fwrite tar file, err = %{public}d", errno);
520             return count;
521         }
522         count += i;
523         currentTarFileSize_ += static_cast<off_t>(i);
524     }
525     return count;
526 }
527 
I2Ocs(int len,off_t val)528 string TarFile::I2Ocs(int len, off_t val)
529 {
530     if (len < 1) {
531         HILOGE("Invalid parameter");
532         return "";
533     }
534     char tmp[OCTSTR_LEN] = {0};
535     if (sprintf_s(tmp, sizeof(tmp), "%0*llo", len - 1, val) < 0) {
536         return "";
537     }
538     return string(tmp);
539 }
540 
WriteNormalData(TarHeader & tmp)541 static bool WriteNormalData(TarHeader& tmp)
542 {
543     const string FORMAT = "%0*d";
544 
545     strlcpy(tmp.name, LONG_LINK_SYMBOL.c_str(), sizeof(tmp.name));
546     int ret = sprintf_s(tmp.mode, sizeof(tmp.mode), FORMAT.c_str(), (int)sizeof(tmp.mode) - 1, 0);
547     if (ret < 0) {
548         return false;
549     }
550     ret = sprintf_s(tmp.uid, sizeof(tmp.uid), FORMAT.c_str(), (int)sizeof(tmp.uid) - 1, 0);
551     if (ret < 0) {
552         return false;
553     }
554     ret = sprintf_s(tmp.gid, sizeof(tmp.gid), FORMAT.c_str(), (int)sizeof(tmp.gid) - 1, 0);
555     if (ret < 0) {
556         return false;
557     }
558     ret = sprintf_s(tmp.size, sizeof(tmp.size), FORMAT.c_str(), (int)sizeof(tmp.size) - 1, 0);
559     if (ret < 0) {
560         return false;
561     }
562     ret = sprintf_s(tmp.mtime, sizeof(tmp.mtime), FORMAT.c_str(), (int)sizeof(tmp.mtime) - 1, 0);
563     if (ret < 0) {
564         return false;
565     }
566     return true;
567 }
568 
WriteLongName(string & name,char type)569 bool TarFile::WriteLongName(string &name, char type)
570 {
571     // fill tar header for long name
572     TarHeader tmp;
573     errno_t ret = memset_s(&tmp, sizeof(tmp), 0, sizeof(tmp));
574     if (ret != EOK) {
575         HILOGE("Failed to call memset_s, err = %{public}d", ret);
576         return false;
577     }
578 
579     size_t sz = name.length() + 1;
580     if (!WriteNormalData(tmp)) {
581         return false;
582     }
583     string size = I2Ocs(sizeof(tmp.size), static_cast<off_t>(sz));
584     ret = memcpy_s(tmp.size, sizeof(tmp.size), size.c_str(), min(sizeof(tmp.size) - 1, size.length()));
585     if (ret != EOK) {
586         HILOGE("Failed to call memcpy_s, err = %{public}d", ret);
587         return false;
588     }
589 
590     tmp.typeFlag = type;
591     if (ret = memset_s(tmp.chksum, sizeof(tmp.chksum), BLANK_SPACE, sizeof(tmp.chksum)), ret != EOK) {
592         HILOGE("Failed to call memset_s, err = %{public}d", ret);
593         return false;
594     }
595 
596     strlcpy(tmp.magic, TMAGIC.c_str(), sizeof(tmp.magic));
597     strlcpy(tmp.version, VERSION.c_str(), sizeof(tmp.version));
598 
599     SetCheckSum(tmp);
600 
601     // write long name head to archive
602     if (WriteTarHeader(tmp) != BLOCK_SIZE) {
603         HILOGE("Failed to write long name header");
604         return false;
605     }
606 
607     // write name to archive
608     vector<uint8_t> buffer {};
609     buffer.resize(sz);
610     buffer.assign(name.begin(), name.end());
611     if (static_cast<size_t>(WriteAll(buffer, sz)) != sz) {
612         HILOGE("Failed to write long name buffer");
613         return false;
614     }
615 
616     return CompleteBlock(static_cast<off_t>(sz));
617 }
618 
SetPacketMode(bool isReset)619 void TarFile::SetPacketMode(bool isReset)
620 {
621     isReset_ = isReset;
622 }
623 } // namespace OHOS::FileManagement::Backup