1 /*
2  * Copyright (C) 2021 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 "executor/zipfolder_output.h"
16 #include <unistd.h>
17 #include "dump_utils.h"
18 #include "file_ex.h"
19 #include "directory_ex.h"
20 #include "hilog_wrapper.h"
21 #include "util/zip_utils.h"
22 #include "dump_common_utils.h"
23 namespace OHOS {
24 namespace HiviewDFX {
25 namespace {
26 static const int FD_UNSET = -1;
27 static const char NEW_LINE_BREAKS_CHAR = '\n';
28 static const std::string NEW_LINE_BREAKS_STR = "\n";
29 } // namespace
ZipFolderOutput()30 ZipFolderOutput::ZipFolderOutput() : fd_(FD_UNSET)
31 {
32     DUMPER_HILOGD(MODULE_COMMON, "create|");
33 }
34 
~ZipFolderOutput()35 ZipFolderOutput::~ZipFolderOutput()
36 {
37     DUMPER_HILOGD(MODULE_COMMON, "release|");
38 
39     if (fd_ > FD_UNSET) {
40         close(fd_);
41     }
42 
43     fd_ = FD_UNSET;
44 }
45 
PreExecute(const std::shared_ptr<DumperParameter> & parameter,StringMatrix dumpDatas)46 DumpStatus ZipFolderOutput::PreExecute(const std::shared_ptr<DumperParameter>& parameter,
47     StringMatrix dumpDatas)
48 {
49     if ((parameter == nullptr) || (dumpDatas == nullptr)) {
50         DUMPER_HILOGE(MODULE_COMMON, "PreExecute error|parameter or dumpDatas is nullptr");
51         return DumpStatus::DUMP_FAIL;
52     }
53     // init myself once
54     if (logDefaultPath_.empty()) {
55         param_ = parameter;
56         auto callback = param_->getClientCallback();
57         if (callback == nullptr) {
58             DUMPER_HILOGE(MODULE_COMMON, "PreExecute error|callback is nullptr");
59             return DumpStatus::DUMP_FAIL;
60         }
61         logDefaultPath_ = callback->GetFolder() + LOG_DEFAULT;
62         fd_= DumpUtils::FdToWrite(logDefaultPath_);
63     }
64 
65     if (fd_ < 0) {
66         DUMPER_HILOGE(MODULE_COMMON, "PreExecute error|fd has issue");
67         return DumpStatus::DUMP_FAIL;
68     }
69 
70     dumpDatas_ = dumpDatas;
71     return DumpStatus::DUMP_OK;
72 }
73 
Execute()74 DumpStatus ZipFolderOutput::Execute()
75 {
76     DUMPER_HILOGI(MODULE_COMMON, "info|ZipFolderOutput Execute");
77     if ((dumpDatas_ == nullptr) || (fd_ < 0)) {
78         DUMPER_HILOGE(MODULE_COMMON, "Execute error|dumpDatas or fd has issue");
79         return DumpStatus::DUMP_FAIL;
80     }
81 
82     std::string outstr;
83 
84     std::string line;
85     for (auto &lineItems : (*dumpDatas_)) {
86         for (auto &item : lineItems) {
87             line.append(item);
88         }
89         lineItems.clear();
90 
91         if (line.empty() || (line.at(line.length() - 1) != NEW_LINE_BREAKS_CHAR)) { // No line breaks
92             line.append(NEW_LINE_BREAKS_STR);
93         }
94 
95         outstr.append(line);
96         line.clear();
97     }
98     if (lseek(fd_, 0, SEEK_END) == -1) {
99         DUMPER_HILOGE(MODULE_COMMON, "lseek fail fd:%{public}d, errno:%{public}d", fd_, errno);
100     }
101     if (!outstr.empty()) {
102         SaveStringToFd(fd_, outstr);
103     }
104     outstr.clear();
105     DUMPER_HILOGI(MODULE_COMMON, "info|ZipFolderOutput Execute end");
106     return DumpStatus::DUMP_OK;
107 }
108 
AfterExecute()109 DumpStatus ZipFolderOutput::AfterExecute()
110 {
111     if (dumpDatas_ != nullptr) {
112         dumpDatas_->clear();
113     }
114 
115     return DumpStatus::DUMP_OK;
116 }
117 
Reset()118 void ZipFolderOutput::Reset()
119 {
120     if (fd_ > FD_UNSET) {
121         DUMPER_HILOGD(MODULE_COMMON, "Reset debug|close");
122         close(fd_);
123     }
124     fd_ = FD_UNSET;
125 
126     const std::shared_ptr<RawParam> callback = (param_ == nullptr) ? nullptr : param_->getClientCallback();
127     if ((param_ != nullptr) && (callback != nullptr)) {
128         DUMPER_HILOGD(MODULE_COMMON, "Reset debug|ZipFolder");
129         auto logZipPath = param_->GetOpts().path_;
130         auto logFolder = callback->GetFolder();
131         ZipUtils::ZipFolder(logFolder, logZipPath, [callback] (int progress, int subprogress) {
132             callback->UpdateProgress(0);
133             return callback->IsCanceled();
134         });
135     }
136 
137     param_ = nullptr;
138 
139     HidumperExecutor::Reset();
140 }
141 } // namespace HiviewDFX
142 } // namespace OHOS
143