1 #include <iostream> 2 #include <string> 3 #include <sstream> 4 #include <fstream> 5 #include <stdexcept> 6 #include <phosphor-logging/log.hpp> 7 #include "version.hpp" 8 #include <phosphor-logging/elog-errors.hpp> 9 #include "xyz/openbmc_project/Common/error.hpp" 10 #include "item_updater.hpp" 11 #include <openssl/sha.h> 12 13 namespace openpower 14 { 15 namespace software 16 { 17 namespace updater 18 { 19 20 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 21 using namespace phosphor::logging; 22 using Argument = xyz::openbmc_project::Common::InvalidArgument; 23 24 std::string Version::getId(const std::string& version) 25 { 26 27 if (version.empty()) 28 { 29 log<level::ERR>("Error version is empty"); 30 elog<InvalidArgument>(Argument::ARGUMENT_NAME("Version"), 31 Argument::ARGUMENT_VALUE(version.c_str())); 32 } 33 34 unsigned char digest[SHA512_DIGEST_LENGTH]; 35 SHA512_CTX ctx; 36 SHA512_Init(&ctx); 37 SHA512_Update(&ctx, version.c_str(), strlen(version.c_str())); 38 SHA512_Final(digest, &ctx); 39 char mdString[SHA512_DIGEST_LENGTH * 2 + 1]; 40 for (int i = 0; i < SHA512_DIGEST_LENGTH; i++) 41 { 42 snprintf(&mdString[i * 2], 3, "%02x", (unsigned int)digest[i]); 43 } 44 45 // Only need 8 hex digits. 46 std::string hexId = std::string(mdString); 47 return (hexId.substr(0, 8)); 48 } 49 50 std::map<std::string, std::string> 51 Version::getValue(const std::string& filePath, 52 std::map<std::string, std::string> keys) 53 { 54 if (filePath.empty()) 55 { 56 log<level::ERR>("Error filePath is empty"); 57 elog<InvalidArgument>(Argument::ARGUMENT_NAME("FilePath"), 58 Argument::ARGUMENT_VALUE(filePath.c_str())); 59 } 60 61 std::ifstream efile; 62 std::string line; 63 efile.exceptions(std::ifstream::failbit | std::ifstream::badbit | 64 std::ifstream::eofbit); 65 66 try 67 { 68 efile.open(filePath); 69 while (getline(efile, line)) 70 { 71 for (auto& key : keys) 72 { 73 auto value = key.first + "="; 74 auto keySize = value.length(); 75 if (line.compare(0, keySize, value) == 0) 76 { 77 key.second = line.substr(keySize); 78 break; 79 } 80 } 81 } 82 efile.close(); 83 } 84 catch (const std::exception& e) 85 { 86 if (!efile.eof()) 87 { 88 log<level::ERR>("Error in reading file"); 89 } 90 efile.close(); 91 } 92 93 return keys; 94 } 95 96 void Delete::delete_() 97 { 98 if (parent.eraseCallback) 99 { 100 parent.eraseCallback(parent.getId(parent.version())); 101 } 102 } 103 104 void Version::updateDeleteInterface(sdbusplus::message::message& msg) 105 { 106 std::string interface, chassisState; 107 std::map<std::string, sdbusplus::message::variant<std::string>> properties; 108 109 msg.read(interface, properties); 110 111 for (const auto& p : properties) 112 { 113 if (p.first == "CurrentPowerState") 114 { 115 chassisState = p.second.get<std::string>(); 116 } 117 } 118 if (chassisState.empty()) 119 { 120 // The chassis power state property did not change, return. 121 return; 122 } 123 124 if ((parent.isVersionFunctional(this->versionId)) && 125 (chassisState != CHASSIS_STATE_OFF)) 126 { 127 if (deleteObject) 128 { 129 deleteObject.reset(nullptr); 130 } 131 } 132 else 133 { 134 if (!deleteObject) 135 { 136 deleteObject = std::make_unique<Delete>(bus, objPath, *this); 137 } 138 } 139 } 140 141 } // namespace updater 142 } // namespace software 143 } // namespace openpower 144