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