xref: /openbmc/phosphor-bmc-code-mgmt/bmc/utils.cpp (revision cab87e9cdeeb3e166d6d577511f6be4dc7721aca)
1*cab87e9cSJagpal Singh Gill #include "utils.hpp"
2*cab87e9cSJagpal Singh Gill 
3*cab87e9cSJagpal Singh Gill #include <unistd.h>
4*cab87e9cSJagpal Singh Gill 
5*cab87e9cSJagpal Singh Gill #include <phosphor-logging/lg2.hpp>
6*cab87e9cSJagpal Singh Gill 
7*cab87e9cSJagpal Singh Gill namespace utils
8*cab87e9cSJagpal Singh Gill {
9*cab87e9cSJagpal Singh Gill 
10*cab87e9cSJagpal Singh Gill PHOSPHOR_LOG2_USING;
11*cab87e9cSJagpal Singh Gill 
getService(sdbusplus::bus_t & bus,const std::string & path,const std::string & interface)12*cab87e9cSJagpal Singh Gill std::string getService(sdbusplus::bus_t& bus, const std::string& path,
13*cab87e9cSJagpal Singh Gill                        const std::string& interface)
14*cab87e9cSJagpal Singh Gill {
15*cab87e9cSJagpal Singh Gill     auto method = bus.new_method_call(MAPPER_BUSNAME, MAPPER_PATH,
16*cab87e9cSJagpal Singh Gill                                       MAPPER_BUSNAME, "GetObject");
17*cab87e9cSJagpal Singh Gill 
18*cab87e9cSJagpal Singh Gill     method.append(path);
19*cab87e9cSJagpal Singh Gill     method.append(std::vector<std::string>({interface}));
20*cab87e9cSJagpal Singh Gill 
21*cab87e9cSJagpal Singh Gill     std::vector<std::pair<std::string, std::vector<std::string>>> response;
22*cab87e9cSJagpal Singh Gill 
23*cab87e9cSJagpal Singh Gill     try
24*cab87e9cSJagpal Singh Gill     {
25*cab87e9cSJagpal Singh Gill         auto reply = bus.call(method);
26*cab87e9cSJagpal Singh Gill         reply.read(response);
27*cab87e9cSJagpal Singh Gill         if (response.empty())
28*cab87e9cSJagpal Singh Gill         {
29*cab87e9cSJagpal Singh Gill             error(
30*cab87e9cSJagpal Singh Gill                 "Empty response from mapper for getting service name: {PATH} {INTERFACE}",
31*cab87e9cSJagpal Singh Gill                 "PATH", path, "INTERFACE", interface);
32*cab87e9cSJagpal Singh Gill             return std::string{};
33*cab87e9cSJagpal Singh Gill         }
34*cab87e9cSJagpal Singh Gill     }
35*cab87e9cSJagpal Singh Gill     catch (const sdbusplus::exception_t& e)
36*cab87e9cSJagpal Singh Gill     {
37*cab87e9cSJagpal Singh Gill         error("Error in mapper method call for ({PATH}, {INTERFACE}: {ERROR}",
38*cab87e9cSJagpal Singh Gill               "ERROR", e, "PATH", path, "INTERFACE", interface);
39*cab87e9cSJagpal Singh Gill         return std::string{};
40*cab87e9cSJagpal Singh Gill     }
41*cab87e9cSJagpal Singh Gill     return response[0].first;
42*cab87e9cSJagpal Singh Gill }
43*cab87e9cSJagpal Singh Gill 
setProperty(sdbusplus::bus_t & bus,const std::string & objectPath,const std::string & interface,const std::string & propertyName,const PropertyValue & value)44*cab87e9cSJagpal Singh Gill void setProperty(sdbusplus::bus_t& bus, const std::string& objectPath,
45*cab87e9cSJagpal Singh Gill                  const std::string& interface, const std::string& propertyName,
46*cab87e9cSJagpal Singh Gill                  const PropertyValue& value)
47*cab87e9cSJagpal Singh Gill {
48*cab87e9cSJagpal Singh Gill     auto service = getService(bus, objectPath, interface);
49*cab87e9cSJagpal Singh Gill     if (service.empty())
50*cab87e9cSJagpal Singh Gill     {
51*cab87e9cSJagpal Singh Gill         return;
52*cab87e9cSJagpal Singh Gill     }
53*cab87e9cSJagpal Singh Gill 
54*cab87e9cSJagpal Singh Gill     auto method = bus.new_method_call(service.c_str(), objectPath.c_str(),
55*cab87e9cSJagpal Singh Gill                                       "org.freedesktop.DBus.Properties", "Set");
56*cab87e9cSJagpal Singh Gill     method.append(interface.c_str(), propertyName.c_str(), value);
57*cab87e9cSJagpal Singh Gill 
58*cab87e9cSJagpal Singh Gill     bus.call_noreply(method);
59*cab87e9cSJagpal Singh Gill }
60*cab87e9cSJagpal Singh Gill 
mergeFiles(const std::vector<std::string> & srcFiles,const std::string & dstFile)61*cab87e9cSJagpal Singh Gill void mergeFiles(const std::vector<std::string>& srcFiles,
62*cab87e9cSJagpal Singh Gill                 const std::string& dstFile)
63*cab87e9cSJagpal Singh Gill {
64*cab87e9cSJagpal Singh Gill     std::ofstream outFile(dstFile, std::ios::out);
65*cab87e9cSJagpal Singh Gill     for (const auto& file : srcFiles)
66*cab87e9cSJagpal Singh Gill     {
67*cab87e9cSJagpal Singh Gill         std::ifstream inFile;
68*cab87e9cSJagpal Singh Gill         inFile.open(file, std::ios_base::in);
69*cab87e9cSJagpal Singh Gill         if (!inFile)
70*cab87e9cSJagpal Singh Gill         {
71*cab87e9cSJagpal Singh Gill             continue;
72*cab87e9cSJagpal Singh Gill         }
73*cab87e9cSJagpal Singh Gill 
74*cab87e9cSJagpal Singh Gill         inFile.peek();
75*cab87e9cSJagpal Singh Gill         if (inFile.eof())
76*cab87e9cSJagpal Singh Gill         {
77*cab87e9cSJagpal Singh Gill             inFile.close();
78*cab87e9cSJagpal Singh Gill             continue;
79*cab87e9cSJagpal Singh Gill         }
80*cab87e9cSJagpal Singh Gill 
81*cab87e9cSJagpal Singh Gill         outFile << inFile.rdbuf();
82*cab87e9cSJagpal Singh Gill         inFile.close();
83*cab87e9cSJagpal Singh Gill     }
84*cab87e9cSJagpal Singh Gill     outFile.close();
85*cab87e9cSJagpal Singh Gill }
86*cab87e9cSJagpal Singh Gill 
87*cab87e9cSJagpal Singh Gill namespace internal
88*cab87e9cSJagpal Singh Gill {
89*cab87e9cSJagpal Singh Gill 
90*cab87e9cSJagpal Singh Gill /* @brief Helper function to build a string from command arguments */
buildCommandStr(char ** args)91*cab87e9cSJagpal Singh Gill static std::string buildCommandStr(char** args)
92*cab87e9cSJagpal Singh Gill {
93*cab87e9cSJagpal Singh Gill     std::string command = "";
94*cab87e9cSJagpal Singh Gill     for (int i = 0; args[i]; i++)
95*cab87e9cSJagpal Singh Gill     {
96*cab87e9cSJagpal Singh Gill         command += args[i];
97*cab87e9cSJagpal Singh Gill         command += " ";
98*cab87e9cSJagpal Singh Gill     }
99*cab87e9cSJagpal Singh Gill     return command;
100*cab87e9cSJagpal Singh Gill }
101*cab87e9cSJagpal Singh Gill 
executeCmd(char ** args)102*cab87e9cSJagpal Singh Gill std::pair<int, std::string> executeCmd(char** args)
103*cab87e9cSJagpal Singh Gill {
104*cab87e9cSJagpal Singh Gill     std::array<char, 512> buffer;
105*cab87e9cSJagpal Singh Gill     std::string cmd = buildCommandStr(args);
106*cab87e9cSJagpal Singh Gill     std::stringstream result;
107*cab87e9cSJagpal Singh Gill     int rc;
108*cab87e9cSJagpal Singh Gill     FILE* pipe = popen(cmd.c_str(), "r");
109*cab87e9cSJagpal Singh Gill     if (!pipe)
110*cab87e9cSJagpal Singh Gill     {
111*cab87e9cSJagpal Singh Gill         error("Failed to execute command: {COMMAND}", "COMMAND", cmd);
112*cab87e9cSJagpal Singh Gill         return {-1, std::string{}};
113*cab87e9cSJagpal Singh Gill     }
114*cab87e9cSJagpal Singh Gill     while (fgets(buffer.data(), buffer.size(), pipe) != nullptr)
115*cab87e9cSJagpal Singh Gill     {
116*cab87e9cSJagpal Singh Gill         result << buffer.data();
117*cab87e9cSJagpal Singh Gill     }
118*cab87e9cSJagpal Singh Gill     rc = pclose(pipe);
119*cab87e9cSJagpal Singh Gill     return {rc, result.str()};
120*cab87e9cSJagpal Singh Gill }
121*cab87e9cSJagpal Singh Gill 
122*cab87e9cSJagpal Singh Gill } // namespace internal
123*cab87e9cSJagpal Singh Gill 
124*cab87e9cSJagpal Singh Gill } // namespace utils
125