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 "compress.h"
16
17 #include <fstream>
18
19 namespace Hdc {
AddPath(std::string path)20 bool Compress::AddPath(std::string path)
21 {
22 uv_fs_t req;
23 int rc = uv_fs_lstat(nullptr, &req, path.c_str(), nullptr);
24 uv_fs_req_cleanup(&req);
25 if (rc != 0) {
26 WRITE_LOG(LOG_FATAL, "%s is not exist", path.c_str());
27 return false;
28 }
29 if (req.statbuf.st_mode & S_IFREG) {
30 return AddEntry(path);
31 }
32 if (!AddEntry(path)) {
33 WRITE_LOG(LOG_DEBUG, "AddEntry failed dir:%s", path.c_str());
34 return false;
35 }
36 rc = uv_fs_scandir(nullptr, &req, path.c_str(), 0, nullptr);
37 if (rc < 0) {
38 WRITE_LOG(LOG_DEBUG, "uv_fs_scandir failed dir:%s", path.c_str());
39 uv_fs_req_cleanup(&req);
40 return false;
41 }
42 uv_dirent_t dent;
43 while (uv_fs_scandir_next(&req, &dent) != UV_EOF) {
44 if (strncmp(dent.name, ".", 1) == 0 || strncmp(dent.name, "..", 2) == 0) {
45 continue;
46 }
47 string subpath = path + Base::GetPathSep() + dent.name;
48 if (!AddPath(subpath)) {
49 uv_fs_req_cleanup(&req);
50 return false;
51 }
52 }
53 uv_fs_req_cleanup(&req);
54 return true;
55 }
56
AddEntry(std::string path)57 bool Compress::AddEntry(std::string path)
58 {
59 if (this->maxcount > 0 && this->entrys.size() > this->maxcount) {
60 WRITE_LOG(LOG_FATAL, "Entry.size %zu exceeded maximum %zu", entrys.size(), maxcount);
61 return false;
62 }
63 if (this->prefix.length() > 0 && path == this->prefix) {
64 WRITE_LOG(LOG_DEBUG, "Ignoring compressed root directory");
65 return true;
66 }
67 Entry entry(this->prefix, path);
68 WRITE_LOG(LOG_DEBUG, "AddEntry %s", path.c_str());
69 entrys.push_back(entry);
70 return true;
71 }
72
SaveToFile(std::string localPath)73 bool Compress::SaveToFile(std::string localPath)
74 {
75 if (localPath.length() <= 0) {
76 localPath = "tmp.tar";
77 }
78 uv_fs_t req;
79 int rc = uv_fs_lstat(nullptr, &req, localPath.c_str(), nullptr);
80 if (rc == 0 && req.statbuf.st_mode & S_IFDIR) {
81 return false;
82 }
83
84 std::ofstream file(localPath.c_str(), std::ios::out | std::ios::binary);
85 if (!file.is_open()) {
86 WRITE_LOG(LOG_FATAL, "SaveToFile open file %s failed", localPath.c_str());
87 return false;
88 }
89 WRITE_LOG(LOG_DEBUG, "SaveToFile entrys len : %u", entrys.size());
90 for (auto& entry : entrys) {
91 entry.WriteToTar(file);
92 }
93 file.close();
94 return true;
95 }
96
UpdataPrefix(std::string pathPrefix)97 void Compress::UpdataPrefix(std::string pathPrefix)
98 {
99 this->prefix = pathPrefix;
100 }
101
UpdataMaxCount(size_t maxCount)102 void Compress::UpdataMaxCount(size_t maxCount)
103 {
104 this->maxcount = maxCount;
105 }
106 }
107