// Copyright Epic Games, Inc. All Rights Reserved. #include "status_cmd.h" #include #include #include #include #include #include #include #include namespace zen { StatusCommand::StatusCommand() { m_Options.add_option("", "p", "port", "Host port", cxxopts::value(m_Port)->default_value("0"), ""); m_Options.add_option("", "", "data-dir", "Path to data directory to inspect for running server", cxxopts::value(m_DataDir), ""); } StatusCommand::~StatusCommand() = default; void StatusCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) { ZEN_UNUSED(GlobalOptions); if (!ParseOptions(argc, argv)) { return; } uint16_t EffectivePort = 0; if (!m_DataDir.empty()) { if (!IsFile(m_DataDir / ".lock")) { throw std::runtime_error(fmt::format("Lock file does not exist in directory '{}'", m_DataDir)); } CbValidateError ValidateResult = CbValidateError::None; if (CbObject LockFileObject = ValidateAndReadCompactBinaryObject(IoBufferBuilder::MakeFromFile(m_DataDir / ".lock"), ValidateResult); ValidateResult == CbValidateError::None) { LockFileInfo Info = ReadLockFilePayload(LockFileObject); std::string Reason; if (!ValidateLockFileInfo(Info, Reason)) { throw std::runtime_error(fmt::format("Lock file in directory '{}' is not valid. Reason: '{}'", m_DataDir, Reason)); } EffectivePort = Info.EffectiveListenPort; } else { throw std::runtime_error( fmt::format("Lock file in directory '{}' is malformed. Reason: '{}'", m_DataDir, ToString(ValidateResult))); } } ZenServerState State; if (!State.InitializeReadOnly()) { ZEN_CONSOLE("No Zen state found"); return; } ZEN_CONSOLE("{:>5} {:>6} {:>24} {}", "port", "pid", "session", "socket"); State.Snapshot([&](const ZenServerState::ZenServerEntry& Entry) { bool MatchesAnyPort = (m_Port == 0) && (EffectivePort == 0); bool MatchesEffectivePort = (EffectivePort != 0) && (Entry.EffectiveListenPort.load() == EffectivePort); bool MatchesDesiredPort = (m_Port != 0) && (Entry.DesiredListenPort.load() == m_Port); if (MatchesAnyPort || MatchesEffectivePort || MatchesDesiredPort) { StringBuilder<25> SessionStringBuilder; Entry.GetSessionId().ToString(SessionStringBuilder); std::string SocketPath; if (Entry.HasInstanceInfo()) { ZenServerInstanceInfo Info; if (Info.OpenReadOnly(Entry.GetSessionId())) { InstanceInfoData Data = Info.Read(); if (!Data.UnixSocketPath.empty()) { SocketPath = PathToUtf8(Data.UnixSocketPath); } } } std::string PortStr = Entry.IsNoNetwork() ? std::string("-") : fmt::to_string(Entry.EffectiveListenPort.load()); ZEN_CONSOLE("{:>5} {:>6} {:>24} {}", PortStr, Entry.Pid.load(), SessionStringBuilder, SocketPath); } }); } } // namespace zen