|  | #include "system_configuration.hpp" | 
|  |  | 
|  | #include <phosphor-logging/elog-errors.hpp> | 
|  | #include <phosphor-logging/lg2.hpp> | 
|  | #include <stdplus/pinned.hpp> | 
|  | #include <xyz/openbmc_project/Common/error.hpp> | 
|  |  | 
|  | namespace phosphor | 
|  | { | 
|  | namespace network | 
|  | { | 
|  |  | 
|  | static constexpr char HOSTNAMED_SVC[] = "org.freedesktop.hostname1"; | 
|  | static constexpr char HOSTNAMED_OBJ[] = "/org/freedesktop/hostname1"; | 
|  | static constexpr char HOSTNAMED_INTF[] = "org.freedesktop.hostname1"; | 
|  |  | 
|  | using namespace phosphor::logging; | 
|  | using namespace sdbusplus::xyz::openbmc_project::Common::Error; | 
|  | using Argument = xyz::openbmc_project::Common::InvalidArgument; | 
|  |  | 
|  | static constexpr char propMatch[] = | 
|  | "type='signal',sender='org.freedesktop.hostname1'," | 
|  | "path='/org/freedesktop/hostname1'," | 
|  | "interface='org.freedesktop.DBus.Properties',member='PropertiesChanged'," | 
|  | "arg0='org.freedesktop.hostname1'"; | 
|  |  | 
|  | SystemConfiguration::SystemConfiguration( | 
|  | stdplus::PinnedRef<sdbusplus::bus_t> bus, stdplus::const_zstring objPath) : | 
|  | Iface(bus, objPath.c_str(), Iface::action::defer_emit), bus(bus), | 
|  | hostnamePropMatch( | 
|  | bus, propMatch, | 
|  | [sc = stdplus::PinnedRef(*this)](sdbusplus::message_t& m) { | 
|  | std::string intf; | 
|  | std::unordered_map<std::string, std::variant<std::string>> values; | 
|  | try | 
|  | { | 
|  | m.read(intf, values); | 
|  | auto it = values.find("Hostname"); | 
|  | if (it == values.end()) | 
|  | { | 
|  | return; | 
|  | } | 
|  | sc.get().Iface::hostName(std::get<std::string>(it->second)); | 
|  | } | 
|  | catch (const std::exception& e) | 
|  | { | 
|  | lg2::error("Hostname match parsing failed: {ERROR}", "ERROR", | 
|  | e); | 
|  | } | 
|  | }) | 
|  | { | 
|  | try | 
|  | { | 
|  | std::variant<std::string> name; | 
|  | auto req = | 
|  | bus.get().new_method_call(HOSTNAMED_SVC, HOSTNAMED_OBJ, | 
|  | "org.freedesktop.DBus.Properties", "Get"); | 
|  |  | 
|  | req.append(HOSTNAMED_INTF, "Hostname"); | 
|  | auto reply = req.call(); | 
|  | reply.read(name); | 
|  | SystemConfigIntf::hostName(std::get<std::string>(name), true); | 
|  | } | 
|  | catch (const std::exception& e) | 
|  | { | 
|  | lg2::error("Failed to get hostname: {ERROR}", "ERROR", e); | 
|  | } | 
|  |  | 
|  | emit_object_added(); | 
|  | } | 
|  |  | 
|  | std::string SystemConfiguration::hostName(std::string name) | 
|  | { | 
|  | if (SystemConfigIntf::hostName() == name) | 
|  | { | 
|  | return name; | 
|  | } | 
|  | try | 
|  | { | 
|  | auto method = bus.get().new_method_call( | 
|  | HOSTNAMED_SVC, HOSTNAMED_OBJ, HOSTNAMED_INTF, "SetStaticHostname"); | 
|  | method.append(name, /*interactive=*/false); | 
|  | method.call(); | 
|  | return SystemConfigIntf::hostName(std::move(name)); | 
|  | } | 
|  | catch (const sdbusplus::exception::SdBusError& e) | 
|  | { | 
|  | lg2::error("Failed to set hostname {HOSTNAME}: {ERROR} ", "HOSTNAME", | 
|  | name, "ERROR", e); | 
|  | auto dbusError = e.get_error(); | 
|  | if ((dbusError != nullptr) && | 
|  | (strcmp(dbusError->name, | 
|  | "org.freedesktop.DBus.Error.InvalidArgs") == 0)) | 
|  | { | 
|  | elog<InvalidArgument>(Argument::ARGUMENT_NAME("Hostname"), | 
|  | Argument::ARGUMENT_VALUE(name.c_str())); | 
|  | } | 
|  | } | 
|  | return SystemConfigIntf::hostName(); | 
|  | } | 
|  |  | 
|  | } // namespace network | 
|  | } // namespace phosphor |