blob: 6dc2ef0521bacceab2ce752644ffa41611db2c40 [file] [log] [blame]
Matt Spinler711d51d2019-11-06 09:36:51 -06001/**
2 * Copyright © 2019 IBM Corporation
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Aatir7b291ec2019-11-19 10:37:37 -060016#include "config.h"
17
18#include "../bcd_time.hpp"
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +080019#include "../json_utils.hpp"
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +080020#include "../paths.hpp"
Aatir186ce8c2019-10-20 15:13:39 -050021#include "../pel.hpp"
Aatir7b291ec2019-11-19 10:37:37 -060022#include "../pel_types.hpp"
23#include "../pel_values.hpp"
Aatir186ce8c2019-10-20 15:13:39 -050024
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +080025#include <Python.h>
26
Aatir186ce8c2019-10-20 15:13:39 -050027#include <CLI/CLI.hpp>
Aatir7b291ec2019-11-19 10:37:37 -060028#include <bitset>
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +080029#include <fstream>
Aatir186ce8c2019-10-20 15:13:39 -050030#include <iostream>
Aatir7b291ec2019-11-19 10:37:37 -060031#include <phosphor-logging/log.hpp>
32#include <regex>
Aatir186ce8c2019-10-20 15:13:39 -050033#include <string>
Aatir7b291ec2019-11-19 10:37:37 -060034#include <xyz/openbmc_project/Common/File/error.hpp>
Aatir186ce8c2019-10-20 15:13:39 -050035
William A. Kennington IIIb6b25572021-05-19 17:09:41 -070036#include "config_main.h"
37
Aatir7b291ec2019-11-19 10:37:37 -060038namespace fs = std::filesystem;
Aatir186ce8c2019-10-20 15:13:39 -050039using namespace phosphor::logging;
40using namespace openpower::pels;
Matt Spinler27de6f32020-02-21 08:35:57 -060041using sdbusplus::exception::SdBusError;
Aatir7b291ec2019-11-19 10:37:37 -060042namespace file_error = sdbusplus::xyz::openbmc_project::Common::File::Error;
43namespace message = openpower::pels::message;
44namespace pv = openpower::pels::pel_values;
Aatir186ce8c2019-10-20 15:13:39 -050045
Miguel Gomez011ccae2021-03-25 23:42:09 +000046const uint8_t critSysTermSeverity = 0x51;
47
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +080048using PELFunc = std::function<void(const PEL&, bool hexDump)>;
Matt Spinler0d804ef2020-05-12 16:16:26 -050049message::Registry registry(getPELReadOnlyDataPath() / message::registryFileName,
Matt Spinlerd8e29002020-04-09 09:11:22 -050050 false);
Matt Spinler27de6f32020-02-21 08:35:57 -060051namespace service
52{
53constexpr auto logging = "xyz.openbmc_project.Logging";
54} // namespace service
55
56namespace interface
57{
58constexpr auto deleteObj = "xyz.openbmc_project.Object.Delete";
59constexpr auto deleteAll = "xyz.openbmc_project.Collection.DeleteAll";
60} // namespace interface
61
62namespace object_path
63{
64constexpr auto logEntry = "/xyz/openbmc_project/logging/entry/";
65constexpr auto logging = "/xyz/openbmc_project/logging";
66} // namespace object_path
67
William A. Kennington IIIb6b25572021-05-19 17:09:41 -070068std::string pelLogDir()
69{
70 return std::string(EXTENSION_PERSIST_DIR) + "/pels/logs";
71}
72
Aatire340c132019-12-09 14:19:29 -060073/**
Aatir37822f62019-12-10 14:40:27 -060074 * @brief helper function to get PEL commit timestamp from file name
75 * @retrun BCDTime - PEL commit timestamp
76 * @param[in] std::string - file name
77 */
78BCDTime fileNameToTimestamp(const std::string& fileName)
79{
80 std::string token = fileName.substr(0, fileName.find("_"));
81 int i = 0;
82 BCDTime tmp;
83 if (token.length() >= 14)
84 {
85 try
86 {
Sumit Kumara1e40842021-06-23 09:52:25 -050087 tmp.yearMSB = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -060088 }
89 catch (std::exception& err)
90 {
91 std::cout << "Conversion failure: " << err.what() << std::endl;
92 }
93 i += 2;
94 try
95 {
Sumit Kumara1e40842021-06-23 09:52:25 -050096 tmp.yearLSB = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -060097 }
98 catch (std::exception& err)
99 {
100 std::cout << "Conversion failure: " << err.what() << std::endl;
101 }
102 i += 2;
103 try
104 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500105 tmp.month = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600106 }
107 catch (std::exception& err)
108 {
109 std::cout << "Conversion failure: " << err.what() << std::endl;
110 }
111 i += 2;
112 try
113 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500114 tmp.day = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600115 }
116 catch (std::exception& err)
117 {
118 std::cout << "Conversion failure: " << err.what() << std::endl;
119 }
120 i += 2;
121 try
122 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500123 tmp.hour = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600124 }
125 catch (std::exception& err)
126 {
127 std::cout << "Conversion failure: " << err.what() << std::endl;
128 }
129 i += 2;
130 try
131 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500132 tmp.minutes = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600133 }
134 catch (std::exception& err)
135 {
136 std::cout << "Conversion failure: " << err.what() << std::endl;
137 }
138 i += 2;
139 try
140 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500141 tmp.seconds = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600142 }
143 catch (std::exception& err)
144 {
145 std::cout << "Conversion failure: " << err.what() << std::endl;
146 }
147 i += 2;
148 try
149 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500150 tmp.hundredths = std::stoul(token.substr(i, 2), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600151 }
152 catch (std::exception& err)
153 {
154 std::cout << "Conversion failure: " << err.what() << std::endl;
155 }
156 }
157 return tmp;
158}
159
160/**
161 * @brief helper function to get PEL id from file name
162 * @retrun uint32_t - PEL id
163 * @param[in] std::string - file name
164 */
165uint32_t fileNameToPELId(const std::string& fileName)
166{
167 uint32_t num = 0;
168 try
169 {
Sumit Kumara1e40842021-06-23 09:52:25 -0500170 num = std::stoul(fileName.substr(fileName.find("_") + 1), 0, 16);
Aatir37822f62019-12-10 14:40:27 -0600171 }
172 catch (std::exception& err)
173 {
174 std::cout << "Conversion failure: " << err.what() << std::endl;
175 }
176 return num;
177}
178
179/**
Aatire340c132019-12-09 14:19:29 -0600180 * @brief helper function to check string suffix
181 * @retrun bool - true with suffix matches
182 * @param[in] std::string - string to check for suffix
183 * @param[in] std::string - suffix string
184 */
185bool ends_with(const std::string& str, const std::string& end)
186{
187 size_t slen = str.size(), elen = end.size();
188 if (slen < elen)
189 return false;
190 while (elen)
191 {
192 if (str[--slen] != end[--elen])
193 return false;
194 }
195 return true;
196}
197
Aatir37822f62019-12-10 14:40:27 -0600198/**
199 * @brief get data form raw PEL file.
200 * @param[in] std::string Name of file with raw PEL
201 * @return std::vector<uint8_t> char vector read from raw PEL file.
202 */
Aatirbad5f8a2019-12-10 15:27:16 -0600203std::vector<uint8_t> getFileData(const std::string& name)
Aatir37822f62019-12-10 14:40:27 -0600204{
205 std::ifstream file(name, std::ifstream::in);
206 if (file.good())
207 {
208 std::vector<uint8_t> data{std::istreambuf_iterator<char>(file),
209 std::istreambuf_iterator<char>()};
210 return data;
211 }
212 else
213 {
Aatir37822f62019-12-10 14:40:27 -0600214 return {};
215 }
216}
217
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800218/**
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800219 * @brief Initialize Python interpreter and gather all UD parser modules under
220 * the paths found in Python sys.path and the current user directory.
221 * This is to prevent calling a non-existant module which causes Python
222 * to print an import error message and breaking JSON output.
223 *
224 * @return std::vector<std::string> Vector of plugins found in filesystem
225 */
226std::vector<std::string> getPlugins()
227{
228 Py_Initialize();
229 std::vector<std::string> plugins;
230 std::vector<std::string> siteDirs;
Harisuddin Mohamed Isac8d6cc62020-08-19 22:47:19 +0800231 std::array<std::string, 2> parserDirs = {"udparsers", "srcparsers"};
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800232 PyObject* pName = PyUnicode_FromString("sys");
233 PyObject* pModule = PyImport_Import(pName);
234 Py_XDECREF(pName);
235 PyObject* pDict = PyModule_GetDict(pModule);
236 Py_XDECREF(pModule);
237 PyObject* pResult = PyDict_GetItemString(pDict, "path");
238 PyObject* pValue = PyUnicode_FromString(".");
239 PyList_Append(pResult, pValue);
240 Py_XDECREF(pValue);
241 auto list_size = PyList_Size(pResult);
242 for (auto i = 0; i < list_size; i++)
243 {
244 PyObject* item = PyList_GetItem(pResult, i);
245 PyObject* pBytes = PyUnicode_AsEncodedString(item, "utf-8", "~E~");
246 const char* output = PyBytes_AS_STRING(pBytes);
247 Py_XDECREF(pBytes);
248 std::string tmpStr(output);
249 siteDirs.push_back(tmpStr);
250 }
251 for (const auto& dir : siteDirs)
252 {
Harisuddin Mohamed Isac8d6cc62020-08-19 22:47:19 +0800253 for (const auto& parserDir : parserDirs)
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800254 {
Harisuddin Mohamed Isac8d6cc62020-08-19 22:47:19 +0800255 if (fs::exists(dir + "/" + parserDir))
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800256 {
Harisuddin Mohamed Isac8d6cc62020-08-19 22:47:19 +0800257 for (const auto& entry :
258 fs::directory_iterator(dir + "/" + parserDir))
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800259 {
Harisuddin Mohamed Isac8d6cc62020-08-19 22:47:19 +0800260 if (entry.is_directory() and
261 fs::exists(entry.path().string() + "/" +
262 entry.path().stem().string() + ".py"))
263 {
264 plugins.push_back(entry.path().stem());
265 }
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800266 }
267 }
268 }
269 }
270 return plugins;
271}
272
273/**
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800274 * @brief Creates JSON string of a PEL entry if fullPEL is false or prints to
275 * stdout the full PEL in JSON if fullPEL is true
276 * @param[in] itr - std::map iterator of <uint32_t, BCDTime>
277 * @param[in] hidden - Boolean to include hidden PELs
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800278 * @param[in] includeInfo - Boolean to include informational PELs
Miguel Gomez011ccae2021-03-25 23:42:09 +0000279 * @param[in] critSysTerm - Boolean to include critical error and system
280 * termination PELs
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800281 * @param[in] fullPEL - Boolean to print full JSON representation of PEL
282 * @param[in] foundPEL - Boolean to check if any PEL is present
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800283 * @param[in] scrubRegex - SRC regex object
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800284 * @param[in] plugins - Vector of strings of plugins found in filesystem
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800285 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800286 * @return std::string - JSON string of PEL entry (empty if fullPEL is true)
287 */
Aatir7b291ec2019-11-19 10:37:37 -0600288template <typename T>
Miguel Gomez011ccae2021-03-25 23:42:09 +0000289std::string genPELJSON(T itr, bool hidden, bool includeInfo, bool critSysTerm,
290 bool fullPEL, bool& foundPEL,
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800291 const std::optional<std::regex>& scrubRegex,
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500292 const std::vector<std::string>& plugins, bool hexDump,
293 bool archive)
Aatir7b291ec2019-11-19 10:37:37 -0600294{
295 std::size_t found;
296 std::string val;
297 char tmpValStr[50];
298 std::string listStr;
William A. Kennington IIIb6b25572021-05-19 17:09:41 -0700299 char name[51];
300 sprintf(name, "/%.2X%.2X%.2X%.2X%.2X%.2X%.2X%.2X_%.8X", itr.second.yearMSB,
Aatir7b291ec2019-11-19 10:37:37 -0600301 itr.second.yearLSB, itr.second.month, itr.second.day,
302 itr.second.hour, itr.second.minutes, itr.second.seconds,
303 itr.second.hundredths, itr.first);
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500304 auto fileName = (archive ? pelLogDir() + "/archive" : pelLogDir()) + name;
Aatir7b291ec2019-11-19 10:37:37 -0600305 try
306 {
Aatir37822f62019-12-10 14:40:27 -0600307 std::vector<uint8_t> data = getFileData(fileName);
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800308 if (data.empty())
Aatir37822f62019-12-10 14:40:27 -0600309 {
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800310 log<level::ERR>("Empty PEL file",
311 entry("FILENAME=%s", fileName.c_str()));
312 return listStr;
313 }
314 PEL pel{data};
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800315 if (!pel.valid())
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800316 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800317 return listStr;
318 }
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800319 if (!includeInfo && pel.userHeader().severity() == 0)
320 {
321 return listStr;
322 }
Miguel Gomez011ccae2021-03-25 23:42:09 +0000323 if (critSysTerm && pel.userHeader().severity() != critSysTermSeverity)
324 {
325 return listStr;
326 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800327 std::bitset<16> actionFlags{pel.userHeader().actionFlags()};
328 if (!hidden && actionFlags.test(hiddenFlagBit))
329 {
330 return listStr;
331 }
332 if (pel.primarySRC() && scrubRegex)
333 {
334 val = pel.primarySRC().value()->asciiString();
335 if (std::regex_search(trimEnd(val), scrubRegex.value(),
336 std::regex_constants::match_not_null))
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800337 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800338 return listStr;
339 }
340 }
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800341 if (hexDump)
342 {
343 std::cout << dumpHex(std::data(pel.data()), pel.size(), 0, false)
344 << std::endl;
345 }
346 else if (fullPEL)
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800347 {
348 if (!foundPEL)
349 {
350 std::cout << "[\n";
351 foundPEL = true;
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800352 }
353 else
Aatir7b291ec2019-11-19 10:37:37 -0600354 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800355 std::cout << ",\n\n";
356 }
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800357 pel.toJSON(registry, plugins);
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800358 }
359 else
360 {
361 // id
Matt Spinler3025d0b2021-06-02 15:12:52 -0600362 listStr += " \"" +
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800363 getNumberString("0x%X", pel.privateHeader().id()) +
364 "\": {\n";
365 // ASCII
366 if (pel.primarySRC())
367 {
368 val = pel.primarySRC().value()->asciiString();
Matt Spinler3025d0b2021-06-02 15:12:52 -0600369 jsonInsert(listStr, "SRC", trimEnd(val), 2);
370
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800371 // Registry message
372 auto regVal = pel.primarySRC().value()->getErrorDetails(
373 registry, DetailLevel::message, true);
374 if (regVal)
Harisuddin Mohamed Isa0f717e12020-01-15 20:05:33 +0800375 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800376 val = regVal.value();
Matt Spinler3025d0b2021-06-02 15:12:52 -0600377 jsonInsert(listStr, "Message", val, 2);
Aatir37822f62019-12-10 14:40:27 -0600378 }
Aatir7b291ec2019-11-19 10:37:37 -0600379 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800380 else
381 {
Matt Spinler3025d0b2021-06-02 15:12:52 -0600382 jsonInsert(listStr, "SRC", "No SRC", 2);
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800383 }
Matt Spinler3025d0b2021-06-02 15:12:52 -0600384
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800385 // platformid
Matt Spinler3025d0b2021-06-02 15:12:52 -0600386 jsonInsert(listStr, "PLID",
387 getNumberString("0x%X", pel.privateHeader().plid()), 2);
388
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800389 // creatorid
390 std::string creatorID =
391 getNumberString("%c", pel.privateHeader().creatorID());
392 val = pv::creatorIDs.count(creatorID) ? pv::creatorIDs.at(creatorID)
393 : "Unknown Creator ID";
Matt Spinler3025d0b2021-06-02 15:12:52 -0600394 jsonInsert(listStr, "CreatorID", val, 2);
395
396 // subsystem
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800397 std::string subsystem = pv::getValue(pel.userHeader().subsystem(),
398 pel_values::subsystemValues);
Matt Spinler3025d0b2021-06-02 15:12:52 -0600399 jsonInsert(listStr, "Subsystem", subsystem, 2);
400
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800401 // commit time
402 sprintf(tmpValStr, "%02X/%02X/%02X%02X %02X:%02X:%02X",
403 pel.privateHeader().commitTimestamp().month,
404 pel.privateHeader().commitTimestamp().day,
405 pel.privateHeader().commitTimestamp().yearMSB,
406 pel.privateHeader().commitTimestamp().yearLSB,
407 pel.privateHeader().commitTimestamp().hour,
408 pel.privateHeader().commitTimestamp().minutes,
409 pel.privateHeader().commitTimestamp().seconds);
Matt Spinler3025d0b2021-06-02 15:12:52 -0600410 jsonInsert(listStr, "Commit Time", tmpValStr, 2);
411
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800412 // severity
413 std::string severity = pv::getValue(pel.userHeader().severity(),
414 pel_values::severityValues);
Matt Spinler3025d0b2021-06-02 15:12:52 -0600415 jsonInsert(listStr, "Sev", severity, 2);
416
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800417 // compID
Matt Spinler3025d0b2021-06-02 15:12:52 -0600418 jsonInsert(listStr, "CompID",
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800419 getNumberString(
Matt Spinler3025d0b2021-06-02 15:12:52 -0600420 "0x%X", pel.privateHeader().header().componentID),
421 2);
422
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800423 found = listStr.rfind(",");
424 if (found != std::string::npos)
425 {
426 listStr.replace(found, 1, "");
Matt Spinler3025d0b2021-06-02 15:12:52 -0600427 listStr += " },\n";
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800428 }
429 foundPEL = true;
Aatir7b291ec2019-11-19 10:37:37 -0600430 }
431 }
432 catch (std::exception& e)
433 {
434 log<level::ERR>("Hit exception while reading PEL File",
435 entry("FILENAME=%s", fileName.c_str()),
436 entry("ERROR=%s", e.what()));
437 }
438 return listStr;
439}
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800440
Aatir7b291ec2019-11-19 10:37:37 -0600441/**
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800442 * @brief Print a list of PELs or a JSON array of PELs
443 * @param[in] order - Boolean to print in reverse orser
444 * @param[in] hidden - Boolean to include hidden PELs
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800445 * @param[in] includeInfo - Boolean to include informational PELs
Miguel Gomez011ccae2021-03-25 23:42:09 +0000446 * @param[in] critSysTerm - Boolean to include critical error and system
447 * termination PELs
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800448 * @param[in] fullPEL - Boolean to print full PEL into a JSON array
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800449 * @param[in] scrubRegex - SRC regex object
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800450 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
Aatir7b291ec2019-11-19 10:37:37 -0600451 */
Miguel Gomez011ccae2021-03-25 23:42:09 +0000452void printPELs(bool order, bool hidden, bool includeInfo, bool critSysTerm,
453 bool fullPEL, const std::optional<std::regex>& scrubRegex,
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500454 bool hexDump, bool archive = false)
Aatir7b291ec2019-11-19 10:37:37 -0600455{
456 std::string listStr;
457 std::map<uint32_t, BCDTime> PELs;
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800458 std::vector<std::string> plugins;
Aatir7b291ec2019-11-19 10:37:37 -0600459 listStr = "{\n";
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500460 for (auto it = (archive ? fs::directory_iterator(pelLogDir() + "/archive")
461 : fs::directory_iterator(pelLogDir()));
Aatir7b291ec2019-11-19 10:37:37 -0600462 it != fs::directory_iterator(); ++it)
463 {
464 if (!fs::is_regular_file((*it).path()))
465 {
466 continue;
467 }
Aatir37822f62019-12-10 14:40:27 -0600468 else
Aatir7b291ec2019-11-19 10:37:37 -0600469 {
Aatir37822f62019-12-10 14:40:27 -0600470 PELs.emplace(fileNameToPELId((*it).path().filename()),
471 fileNameToTimestamp((*it).path().filename()));
Aatir7b291ec2019-11-19 10:37:37 -0600472 }
473 }
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500474
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800475 bool foundPEL = false;
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800476
477 if (fullPEL && !hexDump)
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800478 {
479 plugins = getPlugins();
480 }
Miguel Gomez011ccae2021-03-25 23:42:09 +0000481 auto buildJSON = [&listStr, &hidden, &includeInfo, &critSysTerm, &fullPEL,
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500482 &foundPEL, &scrubRegex, &plugins, &hexDump,
483 &archive](const auto& i) {
Miguel Gomez011ccae2021-03-25 23:42:09 +0000484 listStr += genPELJSON(i, hidden, includeInfo, critSysTerm, fullPEL,
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500485 foundPEL, scrubRegex, plugins, hexDump, archive);
Aatir37822f62019-12-10 14:40:27 -0600486 };
Aatir7b291ec2019-11-19 10:37:37 -0600487 if (order)
488 {
489 std::for_each(PELs.rbegin(), PELs.rend(), buildJSON);
490 }
491 else
492 {
493 std::for_each(PELs.begin(), PELs.end(), buildJSON);
494 }
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800495 if (hexDump)
496 {
497 return;
498 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800499 if (foundPEL)
Aatir7b291ec2019-11-19 10:37:37 -0600500 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800501 if (fullPEL)
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800502 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800503 std::cout << "]" << std::endl;
504 }
505 else
506 {
507 std::size_t found;
508 found = listStr.rfind(",");
509 if (found != std::string::npos)
510 {
511 listStr.replace(found, 1, "");
512 listStr += "}\n";
513 printf("%s", listStr.c_str());
514 }
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800515 }
516 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800517 else
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800518 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800519 std::string emptyJSON = fullPEL ? "[]" : "{}";
520 std::cout << emptyJSON << std::endl;
Aatir7b291ec2019-11-19 10:37:37 -0600521 }
522}
Aatir186ce8c2019-10-20 15:13:39 -0500523
Matt Spinler27de6f32020-02-21 08:35:57 -0600524/**
525 * @brief Calls the function passed in on the PEL with the ID
526 * passed in.
527 *
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800528 * @param[in] id - The string version of the PEL or BMC Log ID, either with or
Matt Spinler27de6f32020-02-21 08:35:57 -0600529 * without the 0x prefix.
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800530 * @param[in] func - The std::function<void(const PEL&, bool hexDump)> function
531 * to run.
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800532 * @param[in] useBMC - if true, search by BMC Log ID, else search by PEL ID
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800533 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
Matt Spinler27de6f32020-02-21 08:35:57 -0600534 */
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800535void callFunctionOnPEL(const std::string& id, const PELFunc& func,
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500536 bool useBMC = false, bool hexDump = false,
537 bool archive = false)
Matt Spinler27de6f32020-02-21 08:35:57 -0600538{
539 std::string pelID{id};
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800540 if (!useBMC)
Matt Spinler27de6f32020-02-21 08:35:57 -0600541 {
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800542 std::transform(pelID.begin(), pelID.end(), pelID.begin(), toupper);
543
544 if (pelID.find("0X") == 0)
545 {
546 pelID.erase(0, 2);
547 }
Matt Spinler27de6f32020-02-21 08:35:57 -0600548 }
549
550 bool found = false;
551
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500552 for (auto it = (archive ? fs::directory_iterator(pelLogDir() + "/archive")
553 : fs::directory_iterator(pelLogDir()));
Matt Spinler27de6f32020-02-21 08:35:57 -0600554 it != fs::directory_iterator(); ++it)
555 {
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800556 // The PEL ID is part of the filename, so use that to find the PEL if
557 // "useBMC" is set to false, otherwise we have to search within the PEL
Matt Spinler27de6f32020-02-21 08:35:57 -0600558
559 if (!fs::is_regular_file((*it).path()))
560 {
561 continue;
562 }
563
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800564 if ((ends_with((*it).path(), pelID) && !useBMC) || useBMC)
Matt Spinler27de6f32020-02-21 08:35:57 -0600565 {
Matt Spinler27de6f32020-02-21 08:35:57 -0600566 auto data = getFileData((*it).path());
567 if (!data.empty())
568 {
569 PEL pel{data};
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800570 if (!useBMC ||
571 (useBMC && pel.obmcLogID() == std::stoul(id, nullptr, 0)))
Matt Spinler27de6f32020-02-21 08:35:57 -0600572 {
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800573 found = true;
574 try
575 {
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800576 func(pel, hexDump);
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800577 break;
578 }
579 catch (std::exception& e)
580 {
581 std::cerr << " Internal function threw an exception: "
582 << e.what() << "\n";
583 exit(1);
584 }
Matt Spinler27de6f32020-02-21 08:35:57 -0600585 }
586 }
587 else
588 {
589 std::cerr << "Could not read PEL file\n";
590 exit(1);
591 }
Matt Spinler27de6f32020-02-21 08:35:57 -0600592 }
593 }
594
595 if (!found)
596 {
597 std::cerr << "PEL not found\n";
598 exit(1);
599 }
600}
601
602/**
Matt Spinler25d986c2021-02-10 13:26:18 -0600603 * @brief Delete a PEL file.
Matt Spinler27de6f32020-02-21 08:35:57 -0600604 *
Matt Spinler25d986c2021-02-10 13:26:18 -0600605 * @param[in] id - The PEL ID to delete.
Matt Spinler27de6f32020-02-21 08:35:57 -0600606 */
Matt Spinler25d986c2021-02-10 13:26:18 -0600607void deletePEL(const std::string& id)
Matt Spinler27de6f32020-02-21 08:35:57 -0600608{
Matt Spinler25d986c2021-02-10 13:26:18 -0600609 std::string pelID{id};
Matt Spinler27de6f32020-02-21 08:35:57 -0600610
Matt Spinler25d986c2021-02-10 13:26:18 -0600611 std::transform(pelID.begin(), pelID.end(), pelID.begin(), toupper);
612
613 if (pelID.find("0X") == 0)
Matt Spinler27de6f32020-02-21 08:35:57 -0600614 {
Matt Spinler25d986c2021-02-10 13:26:18 -0600615 pelID.erase(0, 2);
Matt Spinler27de6f32020-02-21 08:35:57 -0600616 }
Matt Spinler25d986c2021-02-10 13:26:18 -0600617
William A. Kennington IIIb6b25572021-05-19 17:09:41 -0700618 for (auto it = fs::directory_iterator(pelLogDir());
Matt Spinler25d986c2021-02-10 13:26:18 -0600619 it != fs::directory_iterator(); ++it)
Matt Spinler27de6f32020-02-21 08:35:57 -0600620 {
Matt Spinler25d986c2021-02-10 13:26:18 -0600621 if (ends_with((*it).path(), pelID))
622 {
623 fs::remove((*it).path());
624 }
Matt Spinler27de6f32020-02-21 08:35:57 -0600625 }
626}
627
628/**
Matt Spinler25d986c2021-02-10 13:26:18 -0600629 * @brief Delete all PEL files.
Matt Spinler27de6f32020-02-21 08:35:57 -0600630 */
631void deleteAllPELs()
632{
Matt Spinler25d986c2021-02-10 13:26:18 -0600633 log<level::INFO>("peltool deleting all event logs");
Matt Spinler27de6f32020-02-21 08:35:57 -0600634
William A. Kennington IIIb6b25572021-05-19 17:09:41 -0700635 for (const auto& entry : fs::directory_iterator(pelLogDir()))
Matt Spinler27de6f32020-02-21 08:35:57 -0600636 {
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500637 if (!fs::is_regular_file(entry.path()))
638 {
639 continue;
640 }
Matt Spinler25d986c2021-02-10 13:26:18 -0600641 fs::remove(entry.path());
Matt Spinler27de6f32020-02-21 08:35:57 -0600642 }
643}
644
Matt Spinler1b420bc2020-02-21 08:54:25 -0600645/**
646 * @brief Display a single PEL
647 *
648 * @param[in] pel - the PEL to display
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800649 * @param[in] hexDump - Boolean to print hexdump of PEL instead of JSON
Matt Spinler1b420bc2020-02-21 08:54:25 -0600650 */
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800651void displayPEL(const PEL& pel, bool hexDump)
Matt Spinler1b420bc2020-02-21 08:54:25 -0600652{
653 if (pel.valid())
654 {
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800655 if (hexDump)
656 {
657 std::string dstr =
658 dumpHex(std::data(pel.data()), pel.size(), 0, false);
659 std::cout << dstr << std::endl;
660 }
661 else
662 {
663 auto plugins = getPlugins();
664 pel.toJSON(registry, plugins);
665 }
Matt Spinler1b420bc2020-02-21 08:54:25 -0600666 }
667 else
668 {
669 std::cerr << "PEL was malformed\n";
670 exit(1);
671 }
672}
673
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800674/**
675 * @brief Print number of PELs
676 * @param[in] hidden - Bool to include hidden logs
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800677 * @param[in] includeInfo - Bool to include informational logs
Miguel Gomez011ccae2021-03-25 23:42:09 +0000678 * @param[in] critSysTerm - Bool to include CritSysTerm
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800679 * @param[in] scrubRegex - SRC regex object
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800680 */
Miguel Gomez011ccae2021-03-25 23:42:09 +0000681void printPELCount(bool hidden, bool includeInfo, bool critSysTerm,
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800682 const std::optional<std::regex>& scrubRegex)
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800683{
684 std::size_t count = 0;
William A. Kennington IIIb6b25572021-05-19 17:09:41 -0700685
686 for (auto it = fs::directory_iterator(pelLogDir());
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800687 it != fs::directory_iterator(); ++it)
688 {
689 if (!fs::is_regular_file((*it).path()))
690 {
691 continue;
692 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800693 std::vector<uint8_t> data = getFileData((*it).path());
694 if (data.empty())
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800695 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800696 continue;
697 }
698 PEL pel{data};
699 if (!pel.valid())
700 {
701 continue;
702 }
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800703 if (!includeInfo && pel.userHeader().severity() == 0)
704 {
705 continue;
706 }
Miguel Gomez011ccae2021-03-25 23:42:09 +0000707 if (critSysTerm && pel.userHeader().severity() != critSysTermSeverity)
708 {
709 continue;
710 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800711 std::bitset<16> actionFlags{pel.userHeader().actionFlags()};
712 if (!hidden && actionFlags.test(hiddenFlagBit))
713 {
714 continue;
715 }
716 if (pel.primarySRC() && scrubRegex)
717 {
718 std::string val = pel.primarySRC().value()->asciiString();
719 if (std::regex_search(trimEnd(val), scrubRegex.value(),
720 std::regex_constants::match_not_null))
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800721 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800722 continue;
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800723 }
724 }
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800725 count++;
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800726 }
727 std::cout << "{\n"
728 << " \"Number of PELs found\": "
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800729 << getNumberString("%d", count) << "\n}\n";
730}
731
732/**
733 * @brief Generate regex pattern object from file contents
734 * @param[in] scrubFile - File containing regex pattern
735 * @return std::regex - SRC regex object
736 */
737std::regex genRegex(std::string& scrubFile)
738{
739 std::string pattern;
740 std::ifstream contents(scrubFile);
741 if (contents.fail())
742 {
743 std::cerr << "Can't open \"" << scrubFile << "\"\n";
744 exit(1);
745 }
746 std::string line;
747 while (std::getline(contents, line))
748 {
749 if (!line.empty())
750 {
751 pattern.append(line + "|");
752 }
753 }
754 try
755 {
756 std::regex scrubRegex(pattern, std::regex::icase);
757 return scrubRegex;
758 }
759 catch (std::regex_error& e)
760 {
761 if (e.code() == std::regex_constants::error_collate)
762 std::cerr << "Invalid collating element request\n";
763 else if (e.code() == std::regex_constants::error_ctype)
764 std::cerr << "Invalid character class\n";
765 else if (e.code() == std::regex_constants::error_escape)
766 std::cerr << "Invalid escape character or trailing escape\n";
767 else if (e.code() == std::regex_constants::error_backref)
768 std::cerr << "Invalid back reference\n";
769 else if (e.code() == std::regex_constants::error_brack)
770 std::cerr << "Mismatched bracket ([ or ])\n";
771 else if (e.code() == std::regex_constants::error_paren)
772 {
773 // to catch return code error_badrepeat when error_paren is retured
774 // instead
775 size_t pos = pattern.find_first_of("*+?{");
776 while (pos != std::string::npos)
777 {
778 if (pos == 0 || pattern.substr(pos - 1, 1) == "|")
779 {
780 std::cerr
781 << "A repetition character (*, ?, +, or {) was not "
782 "preceded by a valid regular expression\n";
783 exit(1);
784 }
785 pos = pattern.find_first_of("*+?{", pos + 1);
786 }
787 std::cerr << "Mismatched parentheses (( or ))\n";
788 }
789 else if (e.code() == std::regex_constants::error_brace)
790 std::cerr << "Mismatched brace ({ or })\n";
791 else if (e.code() == std::regex_constants::error_badbrace)
792 std::cerr << "Invalid range inside a { }\n";
793 else if (e.code() == std::regex_constants::error_range)
794 std::cerr << "Invalid character range (e.g., [z-a])\n";
795 else if (e.code() == std::regex_constants::error_space)
796 std::cerr << "Insufficient memory to handle regular expression\n";
797 else if (e.code() == std::regex_constants::error_badrepeat)
798 std::cerr << "A repetition character (*, ?, +, or {) was not "
799 "preceded by a valid regular expression\n";
800 else if (e.code() == std::regex_constants::error_complexity)
801 std::cerr << "The requested match is too complex\n";
802 else if (e.code() == std::regex_constants::error_stack)
803 std::cerr << "Insufficient memory to evaluate a match\n";
804 exit(1);
805 }
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800806}
807
Aatir186ce8c2019-10-20 15:13:39 -0500808static void exitWithError(const std::string& help, const char* err)
809{
810 std::cerr << "ERROR: " << err << std::endl << help << std::endl;
811 exit(-1);
812}
813
814int main(int argc, char** argv)
815{
816 CLI::App app{"OpenBMC PEL Tool"};
817 std::string fileName;
Aatire340c132019-12-09 14:19:29 -0600818 std::string idPEL;
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800819 std::string bmcId;
Matt Spinler27de6f32020-02-21 08:35:57 -0600820 std::string idToDelete;
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800821 std::string scrubFile;
822 std::optional<std::regex> scrubRegex;
Aatire340c132019-12-09 14:19:29 -0600823 bool listPEL = false;
824 bool listPELDescOrd = false;
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800825 bool hidden = false;
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800826 bool includeInfo = false;
Miguel Gomez011ccae2021-03-25 23:42:09 +0000827 bool critSysTerm = false;
Matt Spinler27de6f32020-02-21 08:35:57 -0600828 bool deleteAll = false;
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800829 bool showPELCount = false;
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800830 bool fullPEL = false;
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800831 bool hexDump = false;
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500832 bool archive = false;
Matt Spinler27de6f32020-02-21 08:35:57 -0600833
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800834 app.set_help_flag("--help", "Print this help message and exit");
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800835 app.add_option("--file", fileName, "Display a PEL using its Raw PEL file");
Aatire340c132019-12-09 14:19:29 -0600836 app.add_option("-i, --id", idPEL, "Display a PEL based on its ID");
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800837 app.add_option("--bmc-id", bmcId,
838 "Display a PEL based on its BMC Event ID");
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800839 app.add_flag("-a", fullPEL, "Display all PELs");
Aatirbad5f8a2019-12-10 15:27:16 -0600840 app.add_flag("-l", listPEL, "List PELs");
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800841 app.add_flag("-n", showPELCount, "Show number of PELs");
Aatir7b291ec2019-11-19 10:37:37 -0600842 app.add_flag("-r", listPELDescOrd, "Reverse order of output");
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800843 app.add_flag("-h", hidden, "Include hidden PELs");
Harisuddin Mohamed Isa0c57a672020-03-27 14:16:28 +0800844 app.add_flag("-f,--info", includeInfo, "Include informational PELs");
Miguel Gomez011ccae2021-03-25 23:42:09 +0000845 app.add_flag("-t, --termination", critSysTerm,
846 "List only critical system terminating PELs");
Matt Spinler27de6f32020-02-21 08:35:57 -0600847 app.add_option("-d, --delete", idToDelete, "Delete a PEL based on its ID");
848 app.add_flag("-D, --delete-all", deleteAll, "Delete all PELs");
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800849 app.add_option("-s, --scrub", scrubFile,
850 "File containing SRC regular expressions to ignore");
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800851 app.add_flag("-x", hexDump, "Display PEL(s) in hexdump instead of JSON");
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500852 app.add_flag("--archive", archive, "List or display archived PELs");
Matt Spinler27de6f32020-02-21 08:35:57 -0600853
Aatir186ce8c2019-10-20 15:13:39 -0500854 CLI11_PARSE(app, argc, argv);
855
856 if (!fileName.empty())
857 {
858 std::vector<uint8_t> data = getFileData(fileName);
859 if (!data.empty())
860 {
861 PEL pel{data};
Harisuddin Mohamed Isaed32c8d2020-10-01 18:12:39 +0800862 if (hexDump)
863 {
864 std::string dstr =
865 dumpHex(std::data(pel.data()), pel.size(), 0, false);
866 std::cout << dstr << std::endl;
867 }
868 else
869 {
870 auto plugins = getPlugins();
871 pel.toJSON(registry, plugins);
872 }
Aatir186ce8c2019-10-20 15:13:39 -0500873 }
874 else
875 {
876 exitWithError(app.help("", CLI::AppFormatMode::All),
877 "Raw PEL file can't be read.");
878 }
879 }
Aatire340c132019-12-09 14:19:29 -0600880 else if (!idPEL.empty())
881 {
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500882 callFunctionOnPEL(idPEL, displayPEL, false, hexDump, archive);
Harisuddin Mohamed Isa58d3a982020-09-17 19:48:05 +0800883 }
884 else if (!bmcId.empty())
885 {
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500886 callFunctionOnPEL(bmcId, displayPEL, true, hexDump, archive);
Aatire340c132019-12-09 14:19:29 -0600887 }
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800888 else if (fullPEL || listPEL)
Aatir7b291ec2019-11-19 10:37:37 -0600889 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800890 if (!scrubFile.empty())
891 {
892 scrubRegex = genRegex(scrubFile);
893 }
Miguel Gomez011ccae2021-03-25 23:42:09 +0000894 printPELs(listPELDescOrd, hidden, includeInfo, critSysTerm, fullPEL,
Sumit Kumar1d8835b2021-06-07 09:35:30 -0500895 scrubRegex, hexDump, archive);
Harisuddin Mohamed Isad4002f32020-02-26 16:19:58 +0800896 }
897 else if (showPELCount)
898 {
Harisuddin Mohamed Isa6f005192020-03-10 17:39:53 +0800899 if (!scrubFile.empty())
900 {
901 scrubRegex = genRegex(scrubFile);
902 }
Miguel Gomez011ccae2021-03-25 23:42:09 +0000903 printPELCount(hidden, includeInfo, critSysTerm, scrubRegex);
Aatir7b291ec2019-11-19 10:37:37 -0600904 }
Matt Spinler27de6f32020-02-21 08:35:57 -0600905 else if (!idToDelete.empty())
906 {
Matt Spinler25d986c2021-02-10 13:26:18 -0600907 deletePEL(idToDelete);
Matt Spinler27de6f32020-02-21 08:35:57 -0600908 }
909 else if (deleteAll)
910 {
911 deleteAllPELs();
912 }
Aatir186ce8c2019-10-20 15:13:39 -0500913 else
914 {
Harisuddin Mohamed Isaa214ed32020-02-28 15:58:23 +0800915 std::cout << app.help("", CLI::AppFormatMode::All) << std::endl;
Aatir186ce8c2019-10-20 15:13:39 -0500916 }
Harisuddin Mohamed Isaf67bafd2020-07-06 17:51:21 +0800917 Py_Finalize();
Aatir186ce8c2019-10-20 15:13:39 -0500918 return 0;
919}