1 /*
2 * Copyright (C) 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 #include "decompress.h"
16
17 #include <sstream>
18 #include <fstream>
19 #include <optional>
20 #include <iostream>
21
22 namespace Hdc {
DecompressToLocal(std::string decPath)23 bool Decompress::DecompressToLocal(std::string decPath)
24 {
25 if (!CheckPath(decPath)) {
26 return false;
27 }
28 uint8_t buff[HEADER_LEN];
29 std::ifstream inFile(tarPath);
30 std::optional<Entry> entry = std::nullopt;
31 while (true) {
32 inFile.read(reinterpret_cast<char*>(buff), HEADER_LEN);
33 auto readcnt = inFile.gcount();
34 if (readcnt == 0) {
35 break;
36 }
37 if (inFile.fail() || readcnt != HEADER_LEN) {
38 WRITE_LOG(LOG_FATAL, "read file error");
39 break;
40 }
41 entry = Entry(buff, HEADER_LEN);
42 if (!entry.value().CopyPayload(decPath, inFile)) {
43 entry = std::nullopt;
44 break;
45 }
46 entry = std::nullopt;
47 continue;
48 }
49 inFile.close();
50 return true;
51 }
52
CheckPath(std::string decPath)53 bool Decompress::CheckPath(std::string decPath)
54 {
55 uv_fs_t req;
56 int rc = uv_fs_lstat(nullptr, &req, tarPath.c_str(), nullptr);
57 uv_fs_req_cleanup(&req);
58 if (rc != 0 || !(req.statbuf.st_mode & S_IFREG)) {
59 WRITE_LOG(LOG_FATAL, "%s not exist, or not file", tarPath.c_str());
60 return false;
61 }
62 auto fileSize = req.statbuf.st_size;
63 if (fileSize == 0 || fileSize % HEADER_LEN != 0) {
64 WRITE_LOG(LOG_FATAL, "file is not tar %s", tarPath.c_str());
65 return false;
66 }
67 rc = uv_fs_lstat(nullptr, &req, decPath.c_str(), nullptr);
68 uv_fs_req_cleanup(&req);
69 if (rc == 0) {
70 if (req.statbuf.st_mode & S_IFREG) {
71 WRITE_LOG(LOG_FATAL, "path is exist, and path not dir %s", decPath.c_str());
72 return false;
73 }
74 } else {
75 std::string estr;
76 bool b = Base::TryCreateDirectory(decPath, estr);
77 if (!b) {
78 WRITE_LOG(LOG_FATAL, "mkdir failed decPath:%s estr:%s", decPath.c_str(), estr.c_str());
79 return false;
80 }
81 }
82 return true;
83 }
84 }