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