#include "server-conf.hpp" #include "utils.hpp" #include "xyz/openbmc_project/Common/error.hpp" #include #include #if __has_include("../../usr/include/phosphor-logging/elog-errors.hpp") #include "../../usr/include/phosphor-logging/elog-errors.hpp" #else #include #endif #include #include #include #if __has_include() #include #elif __has_include() #include namespace std { // splice experimental::filesystem into std namespace filesystem = std::experimental::filesystem; } // namespace std #else #error filesystem not available #endif namespace phosphor { namespace rsyslog_config { namespace utils = phosphor::rsyslog_utils; using namespace phosphor::logging; using namespace sdbusplus::xyz::openbmc_project::Common::Error; namespace fs = std::filesystem; std::string Server::address(std::string value) { using Argument = xyz::openbmc_project::Common::InvalidArgument; std::string result{}; try { auto serverAddress = address(); if (serverAddress == value) { return serverAddress; } if (!value.empty() && !addressValid(value)) { elog(Argument::ARGUMENT_NAME("Address"), Argument::ARGUMENT_VALUE(value.c_str())); } writeConfig(value, port(), configFilePath.c_str()); result = std::move(NetworkClient::address(value)); } catch (const InvalidArgument& e) { throw; } catch (const InternalFailure& e) { throw; } catch (const std::exception& e) { log(e.what()); elog(); } return result; } uint16_t Server::port(uint16_t value) { uint16_t result{}; try { auto serverPort = port(); if (serverPort == value) { return serverPort; } writeConfig(address(), value, configFilePath.c_str()); result = NetworkClient::port(value); } catch (const InternalFailure& e) { throw; } catch (const std::exception& e) { log(e.what()); elog(); } return result; } void Server::writeConfig(const std::string& serverAddress, uint16_t serverPort, const char* filePath) { fs::create_directory(fs::path(filePath).parent_path()); std::fstream stream(filePath, std::fstream::out); if (serverPort && !serverAddress.empty()) { // write '*.* @@:' stream << "*.* @@" << serverAddress << ":" << serverPort; } else // this is a disable request { fs::remove(filePath); } restart(); } bool Server::addressValid(const std::string& address) { addrinfo hints{}; addrinfo* res = nullptr; hints.ai_family = AF_UNSPEC; hints.ai_socktype = SOCK_STREAM; hints.ai_flags |= AI_CANONNAME; auto result = getaddrinfo(address.c_str(), nullptr, &hints, &res); if (result) { log("bad address", entry("ADDRESS=%s", address.c_str()), entry("ERRNO=%d", result)); return false; } return true; } void Server::restore(const char* filePath) { if (!fs::exists(filePath)) { return; } std::fstream stream(filePath, std::fstream::in); std::string line; std::getline(stream, line); // Ignore if line is commented if ('#' != line.at(0)) { auto pos = line.find(':'); if (pos != std::string::npos) { //"*.* @@
:" constexpr auto start = 6; // Skip "*.* @@" auto serverAddress = line.substr(start, pos - start); auto serverPort = line.substr(pos + 1); NetworkClient::address(std::move(serverAddress)); NetworkClient::port(std::stoul(serverPort)); } } } void Server::restart() { utils::restart(); } } // namespace rsyslog_config } // namespace phosphor