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 22namespace Hdc { 23bool 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 53bool 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}