diff options
| author | Liam Mitchell <[email protected]> | 2025-08-22 16:12:38 -0700 |
|---|---|---|
| committer | GitHub Enterprise <[email protected]> | 2025-08-22 16:12:38 -0700 |
| commit | 207c4a32612891711d9d69466b6dfc653428bb07 (patch) | |
| tree | d4b8de42a91ee3327b14fc0aa66c92bc3de46555 | |
| parent | 5.6.18-pre0 (diff) | |
| parent | Move windows service utilities to zenutil and fix clang-format errors (diff) | |
| download | zen-207c4a32612891711d9d69466b6dfc653428bb07.tar.xz zen-207c4a32612891711d9d69466b6dfc653428bb07.zip | |
Merge pull request #139 from ue-foundation/de/zen-service-command
zen service command
51 files changed, 5253 insertions, 20 deletions
diff --git a/.DS_Store b/.DS_Store Binary files differnew file mode 100644 index 000000000..038340bdc --- /dev/null +++ b/.DS_Store diff --git a/.github/workflows/validate.yml b/.github/workflows/validate.yml index 7487297f4..5a898b730 100644 --- a/.github/workflows/validate.yml +++ b/.github/workflows/validate.yml @@ -157,6 +157,13 @@ jobs: env: VCPKG_ROOT: ${{ github.workspace }}/.vcpkg + - name: Upload config logs + if: ${{ (failure() || success()) }} + uses: actions/upload-artifact@v3 + with: + name: vcpkg-logs-${{ matrix.config }} + path: .vcpkg/buildtrees/**/*.log + - name: Build & Test if: ${{ matrix.config == 'debug' }} run: | diff --git a/CHANGELOG.md b/CHANGELOG.md index 6b09756b5..912536d40 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,25 @@ ## +- **EXPERIMENTAL** Feature: Added command line tool `zen service` to do maintenance operations for running zenserver as a local service + - `zen service status` - Check the status of zenservice as local service, indidicating if it is installed, running and the options it was installed with + - `zen service install` - Install zenserver as a local service, this requires admin/sudo priviliges to execute properly + - `--executable` - Path to zenserver executable. Defaults to same path as `zen` command line executable that was issued but with filename replaced. + - `--name` - Name of the installed service. Defaults to `ZenServer` + - `--full` - If necessary, will uninstall a currently running service, then copy updated Zen binaries and debugging information to the location specified by `--install-path` and start the service. Requires `--install-path` to be specified. + - `--install-path` - Path to install service binaries. Only necessary in conjunction with `--full`. + - `--display-name` - Windows only, the user friendly display name of the service. Defaults to `Unreal Zen Storage Service` + - `--description` - Windows only, the user friendly description of the service + - `--allow-elevation` - Windows only, if command is not run with elevated priviliges, the command will attempt to relaunch itself with elevated priviliges + - `--user` - Linux only, username to install service under. Will attempt to determine user via SUDO_USER environment variable if not set. + - `-- ` - All options given after the double dash will be added as command line arguments to the zenserver executable when starting the service + - `zen service uninstall` - Uninstall zenserver as a local service, this requires admin/sudo priviliges to execute properly + - `--name` - Name of the installed service. Defaults to `ZenServer` + - `--allow-elevation` - Windows only, if command is not run with elevated priviliges, the command will attempt to relaunch itself with elevated priviliges + - `zen service start` - Start the installed zenserver local service, this requires admin/sudo priviliges to execute properly + - `--name` - Name of the installed service. Defaults to `ZenServer` + - `--allow-elevation` - Windows only, if command is not run with elevated priviliges, the command will attempt to relaunch itself with elevated priviliges + - `zen service stop` - Stops the running installed zenserver local service, this requires admin/sudo priviliges to execute properly + - `--name` - Name of the installed service. Defaults to `ZenServer` + - `--allow-elevation` - Windows only, if command is not run with elevated priviliges, the command will attempt to relaunch itself with elevated priviliges - Feature: `zen print` now has a `--show-type-info` option to add type information to output of compact binary content - Improvement: `zen print` now allows output of compact binary content even if they are in non-optimal format (Unifom vs Non-Uniform arrays and objects) - Improvement: Switch to bits/sec for logged/output transfer rate when doing oplog import/export diff --git a/src/zen/cmds/service_cmd.cpp b/src/zen/cmds/service_cmd.cpp new file mode 100644 index 000000000..3847c423d --- /dev/null +++ b/src/zen/cmds/service_cmd.cpp @@ -0,0 +1,609 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include "service_cmd.h" + +#include <zencore/filesystem.h> +#include <zencore/fmtutils.h> +#include <zencore/logging.h> +#include <zencore/zencore.h> +#include <zenutil/service.h> +#include <filesystem> + +#if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> +# include <shellapi.h> +# include <Shlwapi.h> +#endif + +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC +# include <unistd.h> +#endif + +ZEN_THIRD_PARTY_INCLUDES_START +#include <gsl/gsl-lite.hpp> +ZEN_THIRD_PARTY_INCLUDES_END + +#include <memory> + +namespace zen { + +////////////////////////////////////////////////////////////////////////// + +namespace { + +#if ZEN_PLATFORM_WINDOWS + BOOL IsElevated() + { + BOOL fRet = FALSE; + HANDLE hToken = NULL; + if (OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken)) + { + TOKEN_ELEVATION Elevation; + DWORD cbSize = sizeof(TOKEN_ELEVATION); + if (GetTokenInformation(hToken, TokenElevation, &Elevation, sizeof(Elevation), &cbSize)) + { + fRet = Elevation.TokenIsElevated; + } + } + if (hToken) + { + CloseHandle(hToken); + } + return fRet; + } + + int WinRelaunchElevated() + { + TCHAR CurrentDir[4096]; + GetCurrentDirectory(4096, CurrentDir); + + ExtendableWideStringBuilder<256> Parameters; + std::filesystem::path ExecutablePath = GetRunningExecutablePath(); + std::wstring CommandLine(GetCommandLine()); + std::wstring CommandArguments(PathGetArgs(CommandLine.data())); + + ZEN_CONSOLE("Attempting to run '{} {}' elevated...", ExecutablePath, WideToUtf8(CommandArguments)); + + SHELLEXECUTEINFO shExInfo = {0}; + shExInfo.cbSize = sizeof(shExInfo); + shExInfo.fMask = SEE_MASK_NOCLOSEPROCESS | SEE_MASK_NO_CONSOLE; + shExInfo.hwnd = 0; + shExInfo.lpVerb = TEXT("runas"); // Operation to perform + shExInfo.lpFile = ExecutablePath.c_str(); // Application to start + shExInfo.lpParameters = CommandArguments.c_str(); // Additional parameters + shExInfo.lpDirectory = CurrentDir; + shExInfo.nShow = SW_SHOW; + shExInfo.hInstApp = 0; + + DWORD ReturnCode = 1; + if (ShellExecuteEx(&shExInfo)) + { + WaitForSingleObject(shExInfo.hProcess, INFINITE); + GetExitCodeProcess(shExInfo.hProcess, &ReturnCode); + CloseHandle(shExInfo.hProcess); + if (ReturnCode == 0) + { + ZEN_CONSOLE("Elevated execution completed successfully."); + } + else + { + ZEN_CONSOLE("Elevated execution completed unsuccessfully, return code: '{}'.", ReturnCode); + } + } + else + { + ZEN_CONSOLE("Failed to run elevated, operation did not complete."); + ReturnCode = DWORD(-1); + } + return (int)ReturnCode; + } + +#else // ZEN_PLATFORM_WINDOWS + + bool IsElevated() { return geteuid() == 0; } + +#endif // ZEN_PLATFORM_WINDOWS + + int RunElevated(bool AllowElevation) + { +#if ZEN_PLATFORM_WINDOWS + if (AllowElevation) + { + return WinRelaunchElevated(); + } + else + { + ZEN_CONSOLE( + "This command requires elevated priviliges. Run command with elevated priviliges or add '--allow-elevation' command line " + "option."); + return 1; + } +#endif // ZEN_PLATFORM_WINDOWS +#if ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + ZEN_UNUSED(AllowElevation); + ZEN_CONSOLE("This command requires elevated priviliges. Run the command with `sudo`"); + return 1; +#endif // ZEN_PLATFORM_LINUX || ZEN_PLATFORM_MAC + } + +} // namespace + +ServiceCommand::ServiceCommand() +{ + m_Options.add_option("", + "v", + "verb", + fmt::format("Verb for service - {}, {}, {}, {}, {}. Use '--' ", + m_StatusOptions.program(), + m_InstallOptions.program(), + m_UninstallOptions.program(), + m_StartOptions.program(), + m_StopOptions.program()), + cxxopts::value(m_Verb), + "<verb>"); + m_Options.parse_positional({"verb"}); + m_Options.positional_help("verb"); + + m_StatusOptions.add_options()("h,help", "Print help"); + m_StatusOptions.add_option("", + "n", + "name", + fmt::format("Service name, defaults to \"{}\"", m_ServiceName), + cxxopts::value(m_ServiceName), + "<name>"); + m_StatusOptions.parse_positional({"name"}); + m_StatusOptions.positional_help("name"); + + m_InstallOptions.add_options()("h,help", "Print help"); + m_InstallOptions.add_option("", "s", "executable", "Path to server executable", cxxopts::value(m_ServerExecutable), "<path>"); + m_InstallOptions.add_option("", + "n", + "name", + fmt::format("Service name, defaults to \"{}\"", m_ServiceName), + cxxopts::value(m_ServiceName), + "<name>"); + + m_InstallOptions.add_option("", + "", + "full", + fmt::format("Uninstall a running service and update service binaries before installing"), + cxxopts::value(m_FullInstall), + "<full>"); + m_InstallOptions.add_option("", + "", + "install-path", + fmt::format("Path in which to install service binaries"), + cxxopts::value(m_InstallPath), + "<install-path>"); + + m_InstallOptions.add_option("", "u", "user", "User to run service as, defaults to current user", cxxopts::value(m_UserName), "<user>"); +#if ZEN_PLATFORM_WINDOWS + m_InstallOptions.add_option("", + "d", + "display-name", + fmt::format("Service display, defaults to \"{}\"", m_ServiceDisplayName), + cxxopts::value(m_ServiceDisplayName), + "<display-name>"); + m_InstallOptions.add_option("", + "", + "description", + fmt::format("Service description", m_ServiceDescription), + cxxopts::value(m_ServiceDescription), + "<description>"); + m_InstallOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); + m_InstallOptions.parse_positional({"executable", "name", "display-name"}); +#else + m_InstallOptions.parse_positional({"executable", "name"}); +#endif // ZEN_PLATFORM_WINDOWS + m_InstallOptions.positional_help("executable name display-name"); + + m_UninstallOptions.add_options()("h,help", "Print help"); + m_UninstallOptions.add_option("", + "n", + "name", + fmt::format("Service name, defaults to \"{}\"", m_ServiceName), + cxxopts::value(m_ServiceName), + "<name>"); + m_UninstallOptions.parse_positional({"name"}); + m_UninstallOptions.positional_help("name"); +#if ZEN_PLATFORM_WINDOWS + m_UninstallOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS + + m_StartOptions.add_options()("h,help", "Print help"); + m_StartOptions.add_option("", + "n", + "name", + fmt::format("Service name, defaults to \"{}\"", m_ServiceName), + cxxopts::value(m_ServiceName), + "<name>"); + m_StartOptions.parse_positional({"name"}); + m_StartOptions.positional_help("name"); +#if ZEN_PLATFORM_WINDOWS + m_StartOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS + + m_StopOptions.add_options()("h,help", "Print help"); + m_StopOptions.add_option("", + "n", + "name", + fmt::format("Service name, defaults to \"{}\"", m_ServiceName), + cxxopts::value(m_ServiceName), + "<name>"); + m_StopOptions.parse_positional({"name"}); + m_StopOptions.positional_help("name"); +#if ZEN_PLATFORM_WINDOWS + m_StopOptions.add_option("", + "", + "allow-elevation", + fmt::format("Allow attempt to relauch command using an elevated"), + cxxopts::value(m_AllowElevation), + "<allow-elevation>"); +#endif // ZEN_PLATFORM_WINDOWS +} + +ServiceCommand::~ServiceCommand() = default; + +std::string +FmtServiceInfo(const ServiceInfo& Info, std::string_view Prefix) +{ + std::string Result = fmt::format( + "{}Status: {}\n" + "{}Executable: {}\n" + "{}CommandLineOptions: {}", + Prefix, + ToString(Info.Status), + Prefix, + Info.Spec.ExecutablePath, + Prefix, + Info.Spec.CommandLineOptions); + +#if ZEN_PLATFORM_WINDOWS + Result += fmt::format( + "\n" + "{}Display Name: {}\n" + "{}Description: {}", + Prefix, + Info.Spec.DisplayName, + Prefix, + Info.Spec.Description); +#endif // ZEN_PLATFORM_WINDOWS + + return Result; +} + +enum class ServiceStatusReturnCode +{ + Running = 0, // successful return indicates proper installation and everything running smoothly + NotInstalled, + NotRunning, + UnknownError +}; + +int +ServiceCommand::Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) +{ + ZEN_UNUSED(GlobalOptions); + + using namespace std::literals; + + std::vector<char*> SubCommandArguments; + cxxopts::Options* SubOption = nullptr; + int ParentCommandArgCount = GetSubCommand(m_Options, argc, argv, m_SubCommands, SubOption, SubCommandArguments); + if (!ParseOptions(ParentCommandArgCount, argv)) + { + return 0; + } + + if (SubOption == nullptr) + { + throw zen::OptionParseException("command verb is missing"); + } + + if (!ParseOptions(*SubOption, gsl::narrow<int>(SubCommandArguments.size()), SubCommandArguments.data())) + { + return 0; + } + + if (SubOption == &m_StatusOptions) + { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Can't get information about service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return gsl::narrow<int>(ServiceStatusReturnCode::UnknownError); + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return gsl::narrow<int>(ServiceStatusReturnCode::NotInstalled); + } + else if (Info.Status != ServiceStatus::Running) + { + ZEN_CONSOLE("Service '{}' is not running", m_ServiceName); + return gsl::narrow<int>(ServiceStatusReturnCode::NotRunning); + } + else + { + ZEN_CONSOLE("Service '{}':\n{}", m_ServiceName, FmtServiceInfo(Info, " ")); + } + } + + if (SubOption == &m_InstallOptions) + { + if (!IsElevated()) + { + return RunElevated(m_AllowElevation); + } + + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (!Ec && Info.Status != ServiceStatus::NotInstalled) + { + if (m_FullInstall) + { + if (Info.Status == ServiceStatus::Running) + { + Ec = StopService(m_ServiceName); + if (Ec) + { + ZEN_CONSOLE("Failed to stop service '{}' using '{}'. Reason: '{}'", + m_ServiceName, + m_ServerExecutable, + Ec.message()); + + return 1; + } + + int Timeout = 30000; // Wait up to 30 seconds for the service to fully stop before uninstalling + while (Timeout > 0) + { + Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to wait for service to stop: '{}'", Ec.message()); + return 1; + } + + if (Info.Status == ServiceStatus::Stopped) + { + break; + } + + Sleep(100); + Timeout -= 100; + } + + if (Info.Status != ServiceStatus::Stopped) + { + ZEN_CONSOLE("Timed out waiting for service to stop"); + return 1; + } + } + + Ec = UninstallService(m_ServiceName); + if (Ec) + { + ZEN_CONSOLE("Failed to uninstall running service '{}' using '{}'. Reason: '{}'", + m_ServiceName, + m_ServerExecutable, + Ec.message()); + + return 1; + } + } + else + { + ZEN_CONSOLE("Service '{}' already installed:\n{}", m_ServiceName, FmtServiceInfo(Info, " ")); + return 1; + } + } + if (m_ServerExecutable.empty()) + { + std::filesystem::path ExePath = zen::GetRunningExecutablePath(); + ExePath.replace_filename("zenserver" + ExePath.extension().string()); + m_ServerExecutable = ExePath; + } + m_ServerExecutable = std::filesystem::absolute(m_ServerExecutable); + + if (m_FullInstall) + { + if (m_InstallPath.empty()) + { + throw zen::OptionParseException("--full requires --install-path to be specified"); + } + + std::filesystem::path ExePath = zen::GetRunningExecutablePath(); + + std::filesystem::path FilesToCopy[] = { + ExePath, + m_ServerExecutable, +#if ZEN_PLATFORM_WINDOWS + ExePath.replace_extension("pdb"), + m_ServerExecutable.replace_extension("pdb"), + ExePath + .replace_filename("crashpad_handler.exe") +#endif +#if ZEN_PLATFORM_MAC + ExePath.replace_filename("crashpad_handler") +#endif + }; + + std::filesystem::path DestinationExePath = m_InstallPath / ExePath.filename(); + std::filesystem::path DestinationServerPath = m_InstallPath / m_ServerExecutable.filename(); + + if (!std::filesystem::is_directory(m_InstallPath) && !CreateDirectories(m_InstallPath)) + { + ZEN_CONSOLE("Unable to create install directory '{}'", m_InstallPath); + return 1; + } + + for (const std::filesystem::path& File : FilesToCopy) + { + std::filesystem::path Destination = m_InstallPath / File.filename(); + if (!CopyFile(File, Destination, {.EnableClone = false})) + { + ZEN_CONSOLE("Failed to copy '{}' to '{}'", File, Destination); + return 1; + } + + ZEN_INFO("Copied '{}' to '{}'", File, Destination); + + if (File.extension() != "pdb") + { + std::filesystem::permissions(Destination, std::filesystem::perms::owner_exec, std::filesystem::perm_options::add); + } + } + + m_ServerExecutable = m_InstallPath / m_ServerExecutable.filename(); + } + + Ec = InstallService( + m_ServiceName, + ServiceSpec { + .ExecutablePath = m_ServerExecutable, .CommandLineOptions = GlobalOptions.PassthroughCommandLine, .UserName = m_UserName +#if ZEN_PLATFORM_WINDOWS + , + .DisplayName = m_ServiceDisplayName, .Description = m_ServiceDescription +#endif // ZEN_PLATFORM_WINDOWS + }); + if (Ec) + { + ZEN_CONSOLE("Failed to install service '{}' using '{}' . Reason: '{}'", m_ServiceName, m_ServerExecutable, Ec.message()); + return 1; + } + ZEN_CONSOLE("Installed service '{}' using '{}' successfully", m_ServiceName, m_ServerExecutable); + + if (m_FullInstall) + { + Ec = StartService(m_ServiceName); + if (Ec) + { + ZEN_CONSOLE("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + } + } + + if (SubOption == &m_UninstallOptions) + { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 0; + } + if (Info.Status != ServiceStatus::Stopped) + { + ZEN_CONSOLE("Service '{}' is running, stop before uninstalling", m_ServiceName); + return 0; + } + + if (!IsElevated()) + { + return RunElevated(m_AllowElevation); + } + + Ec = UninstallService(m_ServiceName); + if (Ec) + { + ZEN_CONSOLE("Failed to uninstall service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + ZEN_CONSOLE("Uninstalled service {} successfully", m_ServiceName); + } + + if (SubOption == &m_StartOptions) + { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 1; + } + if (Info.Status != ServiceStatus::Stopped) + { + ZEN_CONSOLE("Service '{}' is already running", m_ServiceName); + return 1; + } + + if (!IsElevated()) + { + return RunElevated(m_AllowElevation); + } + + Ec = StartService(m_ServiceName); + if (Ec) + { + ZEN_CONSOLE("Failed to start service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + ZEN_CONSOLE("Started service '{}' successfully", m_ServiceName); + } + + if (SubOption == &m_StopOptions) + { + ServiceInfo Info; + std::error_code Ec = QueryInstalledService(m_ServiceName, Info); + if (Ec) + { + ZEN_CONSOLE("Failed to inspect installed service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + if (Info.Status == ServiceStatus::NotInstalled) + { + ZEN_CONSOLE("Service '{}' is not installed", m_ServiceName); + return 1; + } + if (Info.Status != ServiceStatus::Running) + { + ZEN_CONSOLE("Service '{}' is not running", m_ServiceName); + return 1; + } + + if (!IsElevated()) + { + return RunElevated(m_AllowElevation); + } + + Ec = StopService(m_ServiceName); + if (Ec) + { + ZEN_CONSOLE("Failed to stop service '{}'. Reason: '{}'", m_ServiceName, Ec.message()); + return 1; + } + ZEN_CONSOLE("Stopped service '{}' successfully", m_ServiceName); + } + + return 0; +} + +} // namespace zen diff --git a/src/zen/cmds/service_cmd.h b/src/zen/cmds/service_cmd.h new file mode 100644 index 000000000..359e8e854 --- /dev/null +++ b/src/zen/cmds/service_cmd.h @@ -0,0 +1,55 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include "../zen.h" + +#include <filesystem> + +namespace zen { + +class ServiceCommand : public ZenCmdBase +{ +public: + static constexpr char Name[] = "service"; + static constexpr char Description[] = "Manage zenserver as a service - status, install, uninstall, start and stop"; + + ServiceCommand(); + ~ServiceCommand(); + + virtual int Run(const ZenCliOptions& GlobalOptions, int argc, char** argv) override; + virtual cxxopts::Options& Options() override { return m_Options; } + +private: + cxxopts::Options m_Options{Name, Description}; + + std::string m_Verb; // create, info, remove + + std::string m_ServiceName = "ZenServer"; + std::string m_UserName; + + bool m_AllowElevation = false; + + cxxopts::Options m_StatusOptions{"status", "Show information about an installed zenserver service"}; + + cxxopts::Options m_InstallOptions{ + "install", + "Install zenserver as a service. Arguments following \" -- \" will be added as parameters to the installed service."}; + std::filesystem::path m_ServerExecutable; + std::filesystem::path m_InstallPath; + bool m_FullInstall = false; +#if ZEN_PLATFORM_WINDOWS + std::string m_ServiceDisplayName = "Unreal Zen Storage Service"; + std::string m_ServiceDescription; +#endif // ZEN_PLATFORM_WINDOWS + + cxxopts::Options m_UninstallOptions{"uninstall", "Uninstall zenserver as a service"}; + + cxxopts::Options m_StartOptions{"start", "Start an installed zenserver service"}; + + cxxopts::Options m_StopOptions{"stop", "Start an installed zenserver service"}; + + cxxopts::Options* m_SubCommands[5] = {&m_StatusOptions, &m_InstallOptions, &m_UninstallOptions, &m_StartOptions, &m_StopOptions}; +}; + +} // namespace zen diff --git a/src/zen/xmake.lua b/src/zen/xmake.lua index bf595a21d..dadda32dd 100644 --- a/src/zen/xmake.lua +++ b/src/zen/xmake.lua @@ -17,8 +17,7 @@ target("zen") add_files("zen.rc") add_ldflags("/subsystem:console,5.02") add_ldflags("/LTCG") - add_links("crypt32", "wldap32", "Ws2_32") - + add_links("crypt32", "wldap32", "Ws2_32", "Shlwapi") add_links("dbghelp", "winhttp", "version") -- for Sentry end diff --git a/src/zen/zen.cpp b/src/zen/zen.cpp index 6376bbad2..accd0d105 100644 --- a/src/zen/zen.cpp +++ b/src/zen/zen.cpp @@ -17,6 +17,7 @@ #include "cmds/rpcreplay_cmd.h" #include "cmds/run_cmd.h" #include "cmds/serve_cmd.h" +#include "cmds/service_cmd.h" #include "cmds/status_cmd.h" #include "cmds/top_cmd.h" #include "cmds/trace_cmd.h" @@ -695,6 +696,7 @@ main(int argc, char** argv) WipeCommand WipeCmd; WorkspaceCommand WorkspaceCmd; WorkspaceShareCommand WorkspaceShareCmd; + ServiceCommand ServiceCmd; const struct CommandInfo { @@ -752,6 +754,7 @@ main(int argc, char** argv) {WipeCommand::Name, &WipeCmd, WipeCommand::Description}, {WorkspaceCommand::Name, &WorkspaceCmd, WorkspaceCommand::Description}, {WorkspaceShareCommand::Name, &WorkspaceShareCmd, WorkspaceShareCommand::Description}, + {ServiceCommand::Name, &ServiceCmd, ServiceCommand::Description}, // clang-format on }; diff --git a/src/zencore-test/zencore-test.cpp b/src/zencore-test/zencore-test.cpp index 928c4e5c2..0f64f4a5f 100644 --- a/src/zencore-test/zencore-test.cpp +++ b/src/zencore-test/zencore-test.cpp @@ -13,6 +13,7 @@ #if ZEN_WITH_TESTS # define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> +# include <zencore/process.h> #endif int @@ -21,6 +22,10 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) #if ZEN_WITH_TESTS zen::zencore_forcelinktests(); +# if ZEN_PLATFORM_LINUX + zen::IgnoreChildSignals(); +# endif + zen::TraceInit("zencore-test"); zen::logging::InitializeLogging(); zen::MaximizeOpenFileCount(); diff --git a/src/zencore/filesystem.cpp b/src/zencore/filesystem.cpp index 46337ffc8..8327838c9 100644 --- a/src/zencore/filesystem.cpp +++ b/src/zencore/filesystem.cpp @@ -900,6 +900,8 @@ CopyFile(const std::filesystem::path& FromPath, const std::filesystem::path& ToP size_t FileSizeBytes = Stat.st_size; + fchown(ToFd, Stat.st_uid, Stat.st_gid); + // Copy impl const size_t BufferSize = Min(FileSizeBytes, 64u << 10); void* Buffer = malloc(BufferSize); diff --git a/src/zencore/include/zencore/memory/fmalloc.h b/src/zencore/include/zencore/memory/fmalloc.h index aeb05b651..5b476429e 100644 --- a/src/zencore/include/zencore/memory/fmalloc.h +++ b/src/zencore/include/zencore/memory/fmalloc.h @@ -2,6 +2,8 @@ #pragma once +#include <cstddef> + #include <zenbase/zenbase.h> namespace zen { diff --git a/src/zencore/include/zencore/process.h b/src/zencore/include/zencore/process.h index d3e1de703..98d352db6 100644 --- a/src/zencore/include/zencore/process.h +++ b/src/zencore/include/zencore/process.h @@ -51,6 +51,7 @@ struct CreateProcOptions Flag_NewConsole = 1 << 0, Flag_Elevated = 1 << 1, Flag_Unelevated = 1 << 2, + Flag_NoConsole = 1 << 3, }; const std::filesystem::path* WorkingDirectory = nullptr; @@ -100,6 +101,10 @@ int GetProcessId(CreateProcResult ProcId); std::filesystem::path GetProcessExecutablePath(int Pid, std::error_code& OutEc); std::error_code FindProcess(const std::filesystem::path& ExecutableImage, ProcessHandle& OutHandle, bool IncludeSelf = true); +#if ZEN_PLATFORM_LINUX +void IgnoreChildSignals(); +#endif + void process_forcelink(); // internal } // namespace zen diff --git a/src/zencore/memory/mallocmimalloc.cpp b/src/zencore/memory/mallocmimalloc.cpp index 1919af3bf..1f9aff404 100644 --- a/src/zencore/memory/mallocmimalloc.cpp +++ b/src/zencore/memory/mallocmimalloc.cpp @@ -1,5 +1,7 @@ // Copyright Epic Games, Inc. All Rights Reserved. +#include <cstring> + #include <zencore/intmath.h> #include <zencore/memory/align.h> #include <zencore/memory/mallocmimalloc.h> diff --git a/src/zencore/process.cpp b/src/zencore/process.cpp index fcbe657cb..0b25d14f4 100644 --- a/src/zencore/process.cpp +++ b/src/zencore/process.cpp @@ -24,7 +24,6 @@ # include <sys/sem.h> # include <sys/stat.h> # include <sys/syscall.h> -# include <sys/sysctl.h> # include <sys/wait.h> # include <time.h> # include <unistd.h> @@ -32,6 +31,8 @@ #if ZEN_PLATFORM_MAC # include <libproc.h> +# include <sys/types.h> +# include <sys/sysctl.h> #endif ZEN_THIRD_PARTY_INCLUDES_START @@ -41,7 +42,9 @@ ZEN_THIRD_PARTY_INCLUDES_END namespace zen { #if ZEN_PLATFORM_LINUX -const bool bNoZombieChildren = []() { +void +IgnoreChildSignals() +{ // When a child process exits it is put into a zombie state until the parent // collects its result. This doesn't fit the Windows-like model that Zen uses // where there is a less strict familial model and no zombification. Ignoring @@ -52,8 +55,7 @@ const bool bNoZombieChildren = []() { sigemptyset(&Action.sa_mask); Action.sa_handler = SIG_IGN; sigaction(SIGCHLD, &Action, nullptr); - return true; -}(); +} static char GetPidStatus(int Pid, std::error_code& OutEc) @@ -443,6 +445,10 @@ CreateProcNormal(const std::filesystem::path& Executable, std::string_view Comma { CreationFlags |= CREATE_NEW_CONSOLE; } + if (Options.Flags & CreateProcOptions::Flag_NoConsole) + { + CreationFlags |= CREATE_NO_WINDOW; + } const wchar_t* WorkingDir = nullptr; if (Options.WorkingDirectory != nullptr) @@ -588,6 +594,10 @@ CreateProcUnelevated(const std::filesystem::path& Executable, std::string_view C { CreateProcFlags |= CREATE_NEW_CONSOLE; } + if (Options.Flags & CreateProcOptions::Flag_NoConsole) + { + CreateProcFlags |= CREATE_NO_WINDOW; + } ExtendableWideStringBuilder<256> CommandLineZ; CommandLineZ << CommandLine; @@ -798,6 +808,11 @@ IsProcessRunning(int pid, std::error_code& OutEc) { return false; } + if (Error == ERROR_ACCESS_DENIED) + { + // Process is running under other user probably, assume it is running + return true; + } OutEc = MakeErrorCode(Error); return false; } @@ -840,6 +855,10 @@ IsProcessRunning(int pid, std::error_code& OutEc) { return false; } + else if (Error == EPERM) + { + return true; // Running under a user we don't have access to, assume it is live + } else { OutEc = MakeErrorCode(Error); diff --git a/src/zencore/thread.cpp b/src/zencore/thread.cpp index 0d5ad6091..b8ec85a4a 100644 --- a/src/zencore/thread.cpp +++ b/src/zencore/thread.cpp @@ -485,7 +485,7 @@ NamedMutex::Create(std::string_view MutexName) ExtendableStringBuilder<64> Name; Name << "/tmp/" << MutexName; - int Inner = open(Name.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, 0666); + int Inner = open(Name.c_str(), O_RDWR | O_CREAT | O_CLOEXEC, geteuid() == 0 ? 0766 : 0666); if (Inner < 0) { return false; diff --git a/src/zenhttp-test/zenhttp-test.cpp b/src/zenhttp-test/zenhttp-test.cpp index a1327320e..116971b02 100644 --- a/src/zenhttp-test/zenhttp-test.cpp +++ b/src/zenhttp-test/zenhttp-test.cpp @@ -9,6 +9,7 @@ #if ZEN_WITH_TESTS # define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> +# include <zencore/process.h> #endif int @@ -17,6 +18,10 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) #if ZEN_WITH_TESTS zen::zenhttp_forcelinktests(); +# if ZEN_PLATFORM_LINUX + zen::IgnoreChildSignals(); +# endif + zen::TraceInit("zenhttp-test"); zen::logging::InitializeLogging(); zen::MaximizeOpenFileCount(); diff --git a/src/zennet-test/zennet-test.cpp b/src/zennet-test/zennet-test.cpp index bac0dec8f..a341bd344 100644 --- a/src/zennet-test/zennet-test.cpp +++ b/src/zennet-test/zennet-test.cpp @@ -10,6 +10,7 @@ #if ZEN_WITH_TESTS # define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> +# include <zencore/process.h> #endif int @@ -18,6 +19,10 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char** argv) #if ZEN_WITH_TESTS zen::zennet_forcelinktests(); +# if ZEN_PLATFORM_LINUX + zen::IgnoreChildSignals(); +# endif + zen::TraceInit("zennet-test"); zen::logging::InitializeLogging(); zen::MaximizeOpenFileCount(); diff --git a/src/zenserver-test/zenserver-test.cpp b/src/zenserver-test/zenserver-test.cpp index f913c108c..77ed87cb1 100644 --- a/src/zenserver-test/zenserver-test.cpp +++ b/src/zenserver-test/zenserver-test.cpp @@ -103,6 +103,10 @@ main(int argc, char** argv) using namespace std::literals; using namespace zen; +# if ZEN_PLATFORM_LINUX + IgnoreChildSignals(); +# endif + zen::TraceInit("zenserver-test"); zen::logging::InitializeLogging(); diff --git a/src/zenserver/main.cpp b/src/zenserver/main.cpp index 553562473..d8922f885 100644 --- a/src/zenserver/main.cpp +++ b/src/zenserver/main.cpp @@ -24,12 +24,14 @@ #include <zencore/memory/memorytrace.h> #include <zencore/memory/newdelete.h> +#include <zenutil/service.h> + #include "config.h" #include "diag/logging.h" #if ZEN_PLATFORM_WINDOWS # include <zencore/windows.h> -# include "windows/service.h" +# include <zenutil/windows/service.h> #endif ////////////////////////////////////////////////////////////////////////// @@ -91,6 +93,7 @@ ZenEntryPoint::ZenEntryPoint(ZenServerOptions& ServerOptions) : m_ServerOptions( int ZenEntryPoint::Run() { + ZEN_INFO("ZenEntryPoint::Run()"); zen::SetCurrentThreadName("main"); #if ZEN_USE_SENTRY @@ -288,6 +291,8 @@ ZenEntryPoint::Run() }}); auto CleanupShutdown = MakeGuard([&ShutdownEvent, &ShutdownThread] { + ReportServiceStatus(ServiceStatus::Stopping); + if (ShutdownEvent) { ShutdownEvent->Set(); @@ -303,6 +308,7 @@ ZenEntryPoint::Run() Server.SetIsReadyFunc([&] { m_LockFile.Update(MakeLockData(true), Ec); + ReportServiceStatus(ServiceStatus::Running); NotifyReady(); }); @@ -313,6 +319,14 @@ ZenEntryPoint::Run() ZEN_CRITICAL("Caught assert exception in main for process {}: {}", zen::GetCurrentProcessId(), AssertEx.FullDescription()); RequestApplicationExit(1); } + catch (const std::system_error& e) + { + ZEN_CRITICAL("Caught system error exception in main for process {}: {} ({})", + zen::GetCurrentProcessId(), + e.what(), + e.code().value()); + RequestApplicationExit(1); + } catch (const std::exception& e) { ZEN_CRITICAL("Caught exception in main for process {}: {}", zen::GetCurrentProcessId(), e.what()); @@ -321,6 +335,8 @@ ZenEntryPoint::Run() ShutdownServerLogging(); + ReportServiceStatus(ServiceStatus::Stopped); + return ApplicationExitCode(); } @@ -390,6 +406,10 @@ main(int argc, char* argv[]) signal(SIGINT, utils::SignalCallbackHandler); signal(SIGTERM, utils::SignalCallbackHandler); +#if ZEN_PLATFORM_LINUX + IgnoreChildSignals(); +#endif + try { ZenServerOptions ServerOptions; diff --git a/src/zenstore-test/zenstore-test.cpp b/src/zenstore-test/zenstore-test.cpp index 04f5a8e10..6ae0b84b0 100644 --- a/src/zenstore-test/zenstore-test.cpp +++ b/src/zenstore-test/zenstore-test.cpp @@ -10,6 +10,7 @@ #if ZEN_WITH_TESTS # define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> +# include <zencore/process.h> #endif int @@ -18,6 +19,10 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) #if ZEN_WITH_TESTS zen::zenstore_forcelinktests(); +# if ZEN_PLATFORM_LINUX + zen::IgnoreChildSignals(); +# endif + zen::TraceInit("zenstore-test"); zen::logging::InitializeLogging(); zen::MaximizeOpenFileCount(); diff --git a/src/zenutil-test/zenutil-test.cpp b/src/zenutil-test/zenutil-test.cpp index ca8208314..eb4a17918 100644 --- a/src/zenutil-test/zenutil-test.cpp +++ b/src/zenutil-test/zenutil-test.cpp @@ -10,6 +10,7 @@ #if ZEN_WITH_TESTS # define ZEN_TEST_WITH_RUNNER 1 # include <zencore/testing.h> +# include <zencore/process.h> #endif int @@ -18,6 +19,10 @@ main([[maybe_unused]] int argc, [[maybe_unused]] char* argv[]) #if ZEN_WITH_TESTS zen::zenutil_forcelinktests(); +# if ZEN_PLATFORM_LINUX + zen::IgnoreChildSignals(); +# endif + zen::TraceInit("zencore-test"); zen::logging::InitializeLogging(); zen::MaximizeOpenFileCount(); diff --git a/src/zenutil/chunking.cpp b/src/zenutil/chunking.cpp index 30edd322a..71f0a06e4 100644 --- a/src/zenutil/chunking.cpp +++ b/src/zenutil/chunking.cpp @@ -5,6 +5,7 @@ #include <gsl/gsl-lite.hpp> #include <cmath> +#include <cstring> namespace zen::detail { diff --git a/src/zenutil/chunkrequests.cpp b/src/zenutil/chunkrequests.cpp index 745363668..e28df02a8 100644 --- a/src/zenutil/chunkrequests.cpp +++ b/src/zenutil/chunkrequests.cpp @@ -1,5 +1,7 @@ // Copyright Epic Games, Inc. All Rights Reserved. +#include <algorithm> + #include <zenutil/chunkrequests.h> #include <zencore/blake3.h> diff --git a/src/zenutil/include/zenutil/service.h b/src/zenutil/include/zenutil/service.h new file mode 100644 index 000000000..a8bb868b3 --- /dev/null +++ b/src/zenutil/include/zenutil/service.h @@ -0,0 +1,58 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#pragma once + +#include <zenbase/zenbase.h> + +#include <filesystem> +#include <optional> + +namespace zen { + +enum class ServiceLevel +{ + CurrentUser, + AllUsers, + SystemService +}; + +struct ServiceSpec +{ + std::filesystem::path ExecutablePath; + std::string CommandLineOptions; + std::string UserName; +#if ZEN_PLATFORM_WINDOWS + std::string DisplayName; + std::string Description; +#endif // ZEN_PLATFORM_WINDOWS +}; + +enum class ServiceStatus +{ + NotInstalled, + Starting, + Running, + Stopping, + Stopped, + Pausing, + Paused, + Resuming +}; + +struct ServiceInfo +{ + ServiceStatus Status; + ServiceSpec Spec; +}; + +std::string_view ToString(ServiceStatus Status); + +std::error_code InstallService(std::string_view ServiceName, const ServiceSpec& Spec); +std::error_code UninstallService(std::string_view ServiceName); +std::error_code QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo); +std::error_code StartService(std::string_view ServiceName); +std::error_code StopService(std::string_view ServiceName); + +void ReportServiceStatus(ServiceStatus Status); + +} // namespace zen diff --git a/src/zenserver/windows/service.h b/src/zenutil/include/zenutil/windows/service.h index 7c9610983..ca0270a36 100644 --- a/src/zenserver/windows/service.h +++ b/src/zenutil/include/zenutil/windows/service.h @@ -2,6 +2,8 @@ #pragma once +#include <zencore/windows.h> + class WindowsService { public: @@ -18,3 +20,5 @@ public: int SvcMain(); static void __stdcall SvcCtrlHandler(unsigned long); }; + +VOID ReportSvcStatus(DWORD dwCurrentState, DWORD dwWin32ExitCode, DWORD dwWaitHint); diff --git a/src/zenutil/service.cpp b/src/zenutil/service.cpp new file mode 100644 index 000000000..e4a9a951e --- /dev/null +++ b/src/zenutil/service.cpp @@ -0,0 +1,1120 @@ +// Copyright Epic Games, Inc. All Rights Reserved. + +#include <zenutil/service.h> + +#include <zencore/except.h> +#include <zencore/process.h> +#include <zencore/scopeguard.h> +#include <zencore/zencore.h> +#include <string_view> + +#if ZEN_PLATFORM_WINDOWS +# include <zencore/windows.h> +# include <zenutil/windows/service.h> +#endif +#if ZEN_PLATFORM_MAC +# include <zencore/filesystem.h> +# include <zencore/fmtutils.h> + +# include <unistd.h> +# include <sys/stat.h> +#endif +#if ZEN_PLATFORM_LINUX +# include <zencore/filesystem.h> +# include <zencore/fmtutils.h> + +# include <unistd.h> +# include <sys/stat.h> +# include <regex> + +ZEN_THIRD_PARTY_INCLUDES_START +# include <systemd/sd-daemon.h> +ZEN_THIRD_PARTY_INCLUDES_END + +#endif + +namespace zen { +using namespace std::literals; + +void +ReportServiceStatus(ServiceStatus Status) +{ +#if ZEN_PLATFORM_WINDOWS + switch (Status) + { + case ServiceStatus::Starting: + ReportSvcStatus(SERVICE_START_PENDING, NO_ERROR, 3000); + break; + case ServiceStatus::Running: + ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); + break; + case ServiceStatus::Stopping: + ReportSvcStatus(SERVICE_STOP_PENDING, NO_ERROR, 0); + break; + case ServiceStatus::Stopped: + ReportSvcStatus(SERVICE_STOPPED, (DWORD)ApplicationExitCode(), 0); + break; + default: + break; + } +#elif ZEN_PLATFORM_LINUX + switch (Status) + { + case ServiceStatus::Running: + sd_notify(0, "READY=1"); + break; + case ServiceStatus::Stopping: + sd_notify(0, "STOPPING=1"); + break; + case ServiceStatus::Stopped: + sd_notifyf(0, "EXIT_STATUS=%d", ApplicationExitCode()); + break; + } +#endif + (void)Status; +} + +namespace { +#if ZEN_PLATFORM_WINDOWS + + bool SplitExecutableAndArgs(const std::wstring& ExeAndArgs, std::filesystem::path& OutExecutablePath, std::string& OutArguments) + { + if (ExeAndArgs.size()) + { + if (ExeAndArgs[0] == '"') + { + std::wstring::size_type ExecutableEnd = ExeAndArgs.find('"', 1); + if (ExecutableEnd == std::wstring::npos) + { + OutExecutablePath = ExeAndArgs; + return true; + } + else + { + OutExecutablePath = ExeAndArgs.substr(0, ExecutableEnd + 1); + OutArguments = WideToUtf8(ExeAndArgs.substr(ExecutableEnd + 1 + ExeAndArgs[ExecutableEnd + 1] == ' ' ? 1 : 0)); + return true; + } + } + else + { + std::wstring::size_type ExecutableEnd = ExeAndArgs.find(' ', 1); + if (ExecutableEnd == std::wstring::npos) + { + OutExecutablePath = ExeAndArgs; + return true; + } + else + { + OutExecutablePath = ExeAndArgs.substr(0, ExecutableEnd); + OutArguments = WideToUtf8(ExeAndArgs.substr(ExecutableEnd + 1)); + return true; + } + } + } + return false; + } + +#endif // ZEN_PLATFORM_WINDOWS + +#if ZEN_PLATFORM_MAC + std::vector<std::string_view> SplitArguments(std::string_view Arguments) + { + bool IsQuote = false; + size_t Start = 0; + size_t Offset = 0; + std::vector<std::string_view> Result; + for (; Offset < Arguments.length(); Offset++) + { + switch (Arguments[Offset]) + { + case ' ': + if (IsQuote) + { + continue; + } + else if (Offset > Start) + { + Result.push_back(Arguments.substr(Start, Offset - Start)); + Start = Offset + 1; + } + break; + case '"': + if (IsQuote) + { + IsQuote = false; + if (Offset - Start > 1) + { + Result.push_back(Arguments.substr(Start + 1, Offset - (Start + 1))); + } + Start = Offset + 1; + } + else + { + IsQuote = true; + } + break; + case '=': + if (IsQuote) + { + continue; + } + else if (Offset > Start) + { + Result.push_back(Arguments.substr(Start, Offset - Start)); + Start = Offset + 1; + } + break; + default: + break; + } + } + ZEN_ASSERT(!IsQuote); + if (Offset > Start) + { + Result.push_back(Arguments.substr(Start, Offset - Start)); + } + return Result; + } + + // Needs special character escaping + void AppendEscaped(std::string_view String, StringBuilderBase& SB) + { + size_t Offset = 0; + while (Offset < String.length()) + { + size_t NextEscapeCharacter = String.find_first_of("\"'<>&", Offset); + if (NextEscapeCharacter == std::string_view::npos) + { + break; + } + if (NextEscapeCharacter > Offset) + { + SB.Append(String.substr(Offset, NextEscapeCharacter - Offset)); + } + switch (String[NextEscapeCharacter]) + { + case '"': + SB.Append("""); + break; + case '\'': + SB.Append("&apos"); + break; + case '<': + SB.Append("<"); + break; + case '>': + SB.Append(">"); + break; + case '&': + SB.Append("&"); + break; + default: + ZEN_ASSERT(false); + break; + } + Offset = NextEscapeCharacter + 1; + } + if (Offset == 0) + { + SB.Append(String); + } + else if (String.length() > Offset) + { + SB.Append(String.substr(Offset)); + } + } + + std::string GetDaemonName(std::string_view ServiceName) { return fmt::format("com.epicgames.unreal.{}", ServiceName); } + + std::filesystem::path GetPListPath(const std::string& DaemonName) + { + const std::filesystem::path PListFolder = "/Library/LaunchDaemons"; + return PListFolder / (DaemonName + ".plist"); + } + + std::string BuildPlist(std::string_view ServiceName, + const std::filesystem::path& ExecutablePath, + std::string_view CommandLineOptions, + std::string_view DaemonName, + bool Debug) + { + std::vector<std::string_view> Arguments = SplitArguments(CommandLineOptions); + ExtendableStringBuilder<256> ProgramArguments; + for (const std::string_view Argument : Arguments) + { + ProgramArguments.Append(" <string>"); + AppendEscaped(Argument, ProgramArguments); + ProgramArguments.Append("</string>\n"); + } + + return fmt::format( + "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n" + "<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n" + "<plist version=\"1.0\">\n" + "<dict>\n" + " <key>Label</key>\n" + " <string>{}</string>\n" // DaemonName + " \n" + " <key>ProgramArguments</key>\n" + " <array>\n" + " <string>{}</string>\n" // Program name + "{}" // "<string>arg</string>\n" * number of arguments + " </array>\n" + " \n" + " <key>RunAtLoad</key>\n" + " <true/>\n" + " \n" + // " <key>KeepAlive</key>\n" + // " <true/>\n" + // " \n" + " <key>StandardOutPath</key>\n" + " <string>/var/log/{}.log</string>\n" + " \n" + " <key>StandardErrorPath</key>\n" + " <string>/var/log/{}.err.log</string>\n" + " \n" + " <key>Debug</key>\n" + " <{}/>\n" + " \n" + "</dict>\n" + "</plist>\n", + DaemonName, + ExecutablePath, + ProgramArguments.ToView(), + ServiceName, + ServiceName, + Debug ? "true"sv : "false"sv); + + // "<key>Sockets</key>" + // "<dict>" + // "<key>Listeners</key>" + // "<dict>" + // "<key>SockServiceName</key>" + // "<string>{}</string>" // Listen socket + // "<key>SockType</key>" + // "<string>tcp</string>" + // "<key>SockFamily</key>" + // "<string>IPv4</string>" + // "</dict>" + // "</dict>" + } + +#endif // ZEN_PLATFORM_MAC + +#if ZEN_PLATFORM_MAC || ZEN_PLATFORM_LINUX + + std::pair<int, std::string> ExecuteProgram(std::string_view Cmd) + { + std::string Data; + const int BufferSize = 256; + char Buffer[BufferSize]; + std::string Command(Cmd); + Command.append(" 2>&1"); + + ZEN_DEBUG("Running: '{}'", Command); + + FILE* Stream = popen(Command.c_str(), "r"); + if (Stream) + { + while (!feof(Stream)) + { + if (fgets(Buffer, BufferSize, Stream) != NULL) + { + Data.append(Buffer); + } + } + + while (!Data.empty() && isspace(Data[Data.length() - 1])) + { + Data.pop_back(); + } + + int Res = -1; + int Status = pclose(Stream); + if (Status < 0) + { + ZEN_DEBUG("Command {} returned {}, errno {}", Command, Status, errno); + return {Status, Data}; + } + uint64_t WaitMS = 100; + if (WIFEXITED(Status)) + { + Res = WEXITSTATUS(Status); + } + if (Res != 0 && Res != (128 + 13)) + { + return {Res, Data}; + } + return {0, Data}; + } + return {errno, ""}; + } + +#endif // ZEN_PLATFORM_MAC || ZEN_PLATFORM_LINUX + +#if ZEN_PLATFORM_LINUX + std::string GetUnitName(std::string_view ServiceName) { return fmt::format("com.epicgames.unreal.{}", ServiceName); } + + std::filesystem::path GetServiceUnitPath(const std::string& UnitName) + { + const std::filesystem::path SystemUnitFolder = "/etc/systemd/system/"; + return SystemUnitFolder / (UnitName + ".service"); + } + + std::string BuildUnitFile(std::string_view ServiceName, + const std::filesystem::path& ExecutablePath, + std::string_view CommandLineOptions, + std::string_view UserName) + { + return fmt::format( + "[Unit]\n" + "Description={}\n" + "Documentation=https://github.com/epicgames/zen\n" + "\n" + "DefaultDependencies=no\n" + "After=network.target\n" + "StartLimitIntervalSec=0\n" + "\n" + "[Service]\n" + "Type=notify\n" + "Restart=always\n" + "RestartSec=1\n" + "User={}\n" + "ExecStart={} {}\n" + "RuntimeDirectory={}\n" + "[Install]\n" + "WantedBy=multi-user.target", + ServiceName, + UserName, + ExecutablePath, + CommandLineOptions, + ExecutablePath.parent_path()); + } + +#endif // ZEN_PLATFORM_LINUX +} // namespace + +std::string_view +ToString(ServiceStatus Status) +{ + switch (Status) + { + case ServiceStatus::NotInstalled: + return "Not installed"sv; + case ServiceStatus::Starting: + return "Starting"sv; + case ServiceStatus::Running: + return "Running"sv; + case ServiceStatus::Stopping: + return "Stopping"sv; + case ServiceStatus::Stopped: + return "Stopped"sv; + case ServiceStatus::Pausing: + return "Pausing"sv; + case ServiceStatus::Paused: + return "Paused"sv; + case ServiceStatus::Resuming: + return "Resuming"sv; + default: + ZEN_ASSERT(false); + return ""sv; + } +} + +#if ZEN_PLATFORM_WINDOWS + +std::error_code +InstallService(std::string_view ServiceName, const ServiceSpec& Spec) +{ + // TODO: Is "LocalService account" the correct account? + // TODO: Is ther eother parameters/security settings that we need to set up properly? + + // Get a handle to the SCM database. + SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer + NULL, // ServicesActive database + SC_MANAGER_ALL_ACCESS); // full access rights + + if (NULL == schSCManager) + { + return MakeErrorCodeFromLastError(); + } + + auto _ = MakeGuard([schSCManager]() { CloseServiceHandle(schSCManager); }); + + // Create the service + + ExtendableWideStringBuilder<128> Name; + Utf8ToWide(ServiceName, Name); + + ExtendableWideStringBuilder<128> DisplayName; + Utf8ToWide(Spec.DisplayName, DisplayName); + + ExtendableWideStringBuilder<128> Path; + Path.Append(Spec.ExecutablePath.c_str()); + if (!Spec.CommandLineOptions.empty()) + { + Path.AppendAscii(" "); + Utf8ToWide(Spec.CommandLineOptions, Path); + } + + SC_HANDLE schService = CreateService(schSCManager, // SCM database + Name.c_str(), // name of service + DisplayName.c_str(), // service name to display + SERVICE_ALL_ACCESS, // desired access + SERVICE_WIN32_OWN_PROCESS, // service type + SERVICE_AUTO_START, // start type + SERVICE_ERROR_NORMAL, // error control type + Path.c_str(), // path to service's binary + NULL, // no load ordering group + NULL, // no tag identifier + NULL, // no dependencies + TEXT("NT AUTHORITY\\LocalService"), // LocalService account + NULL); // no password + + if (schService == NULL) + { + return MakeErrorCodeFromLastError(); + } + + auto __ = MakeGuard([schService]() { CloseServiceHandle(schService); }); + + if (!Spec.Description.empty()) + { + ExtendableWideStringBuilder<128> DescriptionBuilder; + Utf8ToWide(Spec.Description, DescriptionBuilder); + + SERVICE_DESCRIPTION Description; + Description.lpDescription = const_cast<wchar_t*>(DescriptionBuilder.c_str()); + if (!ChangeServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, &Description)) + { + return MakeErrorCodeFromLastError(); + } + } + + // Actions defining what the service manager should do in the event of a zenserver crash. + // Attempt an immediate restart twice. If both restarts fail, stop trying. + // The attempt count will be reset based on the timeout specified in SERVICE_FAILURE_ACTIONS. + // If the service manages to survive for the length of that timeout, the reset attempt count + // will be reset and we will try restarting if we fail again. + SC_ACTION Actions[] = {{SC_ACTION_RESTART, 0}, {SC_ACTION_RESTART, 0}, {SC_ACTION_NONE, 0}}; + + SERVICE_FAILURE_ACTIONS FailureAction = { + 60, // if we haven't failed for one minute, assume the service is healthy and reset the failure count + NULL, // no reboot message - we don't want to reboot the whole system if zen dies + NULL, // no command to run on failure - just attempt restarting the service + ZEN_ARRAY_COUNT(Actions), + Actions}; + + if (!ChangeServiceConfig2(schService, SERVICE_CONFIG_FAILURE_ACTIONS, &FailureAction)) + { + return MakeErrorCodeFromLastError(); + } + + return {}; +} + +std::error_code +UninstallService(std::string_view ServiceName) +{ + // Get a handle to the SCM database. + SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer + NULL, // ServicesActive database + SC_MANAGER_ALL_ACCESS); // full access rights + + if (NULL == schSCManager) + { + return MakeErrorCodeFromLastError(); + } + + auto _ = MakeGuard([schSCManager]() { CloseServiceHandle(schSCManager); }); + + // Get a handle to the service. + + ExtendableWideStringBuilder<128> Name; + Utf8ToWide(ServiceName, Name); + + SC_HANDLE schService = OpenService(schSCManager, // SCM database + Name.c_str(), // name of service + DELETE); // need delete access + + if (schService == NULL) + { + DWORD Error = ::GetLastError(); + if (Error == ERROR_SERVICE_DOES_NOT_EXIST) + { + return {}; + } + return MakeErrorCode(Error); + } + auto __ = MakeGuard([schService]() { CloseServiceHandle(schService); }); + + // Delete the service. + + if (!DeleteService(schService)) + { + return MakeErrorCodeFromLastError(); + } + + return {}; +} + +std::error_code +QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo) +{ + // Get a handle to the SCM database. + SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer + NULL, // ServicesActive database + SC_MANAGER_CONNECT); // standard access rights + + if (NULL == schSCManager) + { + return MakeErrorCodeFromLastError(); + } + + auto _ = MakeGuard([schSCManager]() { CloseServiceHandle(schSCManager); }); + + // Get a handle to the service. + + ExtendableWideStringBuilder<128> Name; + Utf8ToWide(ServiceName, Name); + + SC_HANDLE schService = OpenService(schSCManager, // SCM database + Name.c_str(), // name of service + SERVICE_QUERY_STATUS | SERVICE_QUERY_CONFIG); // need delete access + + if (schService == NULL) + { + DWORD Error = ::GetLastError(); + if (Error == ERROR_SERVICE_DOES_NOT_EXIST) + { + OutInfo.Status = ServiceStatus::NotInstalled; + return {}; + } + return MakeErrorCode(Error); + } + auto __ = MakeGuard([schService]() { CloseServiceHandle(schService); }); + + std::vector<std::uint8_t> Buffer(8192); + QUERY_SERVICE_CONFIG* ServiceConfig = reinterpret_cast<QUERY_SERVICE_CONFIG*>(Buffer.data()); + DWORD BytesNeeded = 0; + if (!QueryServiceConfig(schService, ServiceConfig, (DWORD)Buffer.size(), &BytesNeeded)) + { + return MakeErrorCodeFromLastError(); + } + + std::wstring BinaryWithArguments(ServiceConfig->lpBinaryPathName); + (void)SplitExecutableAndArgs(BinaryWithArguments, OutInfo.Spec.ExecutablePath, OutInfo.Spec.CommandLineOptions); + OutInfo.Spec.DisplayName = WideToUtf8(ServiceConfig->lpDisplayName); + + SERVICE_STATUS ServiceStatus; + if (!::QueryServiceStatus(schService, &ServiceStatus)) + { + return MakeErrorCodeFromLastError(); + } + + switch (ServiceStatus.dwCurrentState) + { + case SERVICE_STOPPED: + OutInfo.Status = ServiceStatus::Stopped; + break; + case SERVICE_START_PENDING: + OutInfo.Status = ServiceStatus::Starting; + break; + case SERVICE_STOP_PENDING: + OutInfo.Status = ServiceStatus::Stopping; + break; + case SERVICE_RUNNING: + OutInfo.Status = ServiceStatus::Running; + break; + case SERVICE_CONTINUE_PENDING: + OutInfo.Status = ServiceStatus::Resuming; + break; + case SERVICE_PAUSE_PENDING: + OutInfo.Status = ServiceStatus::Pausing; + break; + case SERVICE_PAUSED: + OutInfo.Status = ServiceStatus::Paused; + break; + default: + throw std::runtime_error(fmt::format("Unknown service status for '{}': {}", ServiceName, ServiceStatus.dwCurrentState)); + } + + if (!QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, Buffer.data(), (DWORD)Buffer.size(), &BytesNeeded)) + { + DWORD Error = ::GetLastError(); + if (Error == ERROR_INSUFFICIENT_BUFFER) + { + Buffer.resize((size_t)BytesNeeded); + if (!QueryServiceConfig2(schService, SERVICE_CONFIG_DESCRIPTION, Buffer.data(), (DWORD)Buffer.size(), &BytesNeeded)) + { + return MakeErrorCodeFromLastError(); + } + } + else + { + return MakeErrorCode(Error); + } + } + SERVICE_DESCRIPTION* Description = (SERVICE_DESCRIPTION*)Buffer.data(); + if (Description->lpDescription != NULL) + { + OutInfo.Spec.Description = WideToUtf8(std::wstring(Description->lpDescription)); + } + + return {}; +} + +std::error_code +StartService(std::string_view ServiceName) +{ + // Get a handle to the SCM database. + SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer + NULL, // ServicesActive database + SC_MANAGER_CONNECT); // default access rights + + if (NULL == schSCManager) + { + return MakeErrorCodeFromLastError(); + } + + auto _ = MakeGuard([schSCManager]() { CloseServiceHandle(schSCManager); }); + + // Get a handle to the service. + + ExtendableWideStringBuilder<128> Name; + Utf8ToWide(ServiceName, Name); + + SC_HANDLE schService = OpenService(schSCManager, // SCM database + Name.c_str(), // name of service + SERVICE_START); // need start access + + if (schService == NULL) + { + return MakeErrorCodeFromLastError(); + } + auto __ = MakeGuard([schService]() { CloseServiceHandle(schService); }); + + // Start the service. + + if (!::StartService(schService, 0, NULL)) + { + return MakeErrorCodeFromLastError(); + } + + return {}; +} + +std::error_code +StopService(std::string_view ServiceName) +{ + // Get a handle to the SCM database. + SC_HANDLE schSCManager = OpenSCManager(NULL, // local computer + NULL, // ServicesActive database + SC_MANAGER_CONNECT); // default access rights + + if (NULL == schSCManager) + { + return MakeErrorCodeFromLastError(); + } + + auto _ = MakeGuard([schSCManager]() { CloseServiceHandle(schSCManager); }); + + // Get a handle to the service. + + ExtendableWideStringBuilder<128> Name; + Utf8ToWide(ServiceName, Name); + + SC_HANDLE schService = OpenService(schSCManager, // SCM database + Name.c_str(), // name of service + SERVICE_STOP); // need start access + + if (schService == NULL) + { + return MakeErrorCodeFromLastError(); + } + auto __ = MakeGuard([schService]() { CloseServiceHandle(schService); }); + + // Stop the service. + SERVICE_STATUS ServiceStatus; + if (!::ControlService(schService, SERVICE_CONTROL_STOP, &ServiceStatus)) + { + return MakeErrorCodeFromLastError(); + } + + return {}; +} + +#endif + +#if ZEN_PLATFORM_MAC + +std::error_code +InstallService(std::string_view ServiceName, const ServiceSpec& Spec) +{ + // TODO: Do we need to create a separate user for the service or is running as the default service user OK? + const std::string DaemonName = GetDaemonName(ServiceName); + std::string PList = BuildPlist(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, DaemonName, true); + + const std::filesystem::path PListPath = GetPListPath(DaemonName); + ZEN_INFO("Writing launchd plist to {}", PListPath.string()); + try + { + zen::WriteFile(PListPath, IoBuffer(IoBuffer::Wrap, PList.data(), PList.size())); + } + catch (const std::system_error& Ex) + { + return MakeErrorCode(Ex.code().value()); + } + + ZEN_INFO("Changing permissions to 644 for {}", PListPath.string()); + if (chmod(PListPath.string().c_str(), 0644) == -1) + { + return MakeErrorCodeFromLastError(); + } + return {}; +} + +std::error_code +UninstallService(std::string_view ServiceName) +{ + const std::string DaemonName = GetDaemonName(ServiceName); + const std::filesystem::path PListPath = GetPListPath(DaemonName); + ZEN_INFO("Attempting to remove launchd plist from {}", PListPath.string()); + std::error_code Ec; + std::filesystem::remove(PListPath, Ec); + return Ec; +} + +std::error_code +QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo) +{ + OutInfo.Status = ServiceStatus::NotInstalled; + const std::string DaemonName = GetDaemonName(ServiceName); + + const std::filesystem::path PListPath = GetPListPath(DaemonName); + if (std::filesystem::is_regular_file(PListPath)) + { + OutInfo.Status = ServiceStatus::Stopped; + + { + // Parse plist :( + IoBuffer Buffer = ReadFile(PListPath).Flatten(); + MemoryView Data = Buffer.GetView(); + std::string PList((const char*)Data.GetData(), Data.GetSize()); + + enum class ParseMode + { + None, + ExpectingProgramArgumentsArray, + ExpectingProgramExecutablePath, + ExpectingCommandLineOption + }; + + ParseMode Mode = ParseMode::None; + + ForEachStrTok(PList, '\n', [&](std::string_view Line) { + switch (Mode) + { + case ParseMode::None: + { + if (Line.find("<key>ProgramArguments</key>") != std::string_view::npos) + { + Mode = ParseMode::ExpectingProgramArgumentsArray; + return true; + } + } + break; + case ParseMode::ExpectingProgramArgumentsArray: + { + if (Line.find("<array>") != std::string_view::npos) + { + Mode = ParseMode::ExpectingProgramExecutablePath; + return true; + } + Mode = ParseMode::None; + } + break; + case ParseMode::ExpectingProgramExecutablePath: + { + if (std::string_view::size_type ArgStart = Line.find("<string>"); ArgStart != std::string_view::npos) + { + ArgStart += 8; + if (std::string_view::size_type ArgEnd = Line.find("</string>", ArgStart); ArgEnd != std::string_view::npos) + { + std::string_view ProgramString = Line.substr(ArgStart, ArgEnd - ArgStart); + OutInfo.Spec.ExecutablePath = ProgramString; + Mode = ParseMode::ExpectingCommandLineOption; + return true; + } + } + Mode = ParseMode::None; + } + break; + case ParseMode::ExpectingCommandLineOption: + { + if (std::string_view::size_type ArgStart = Line.find("</array>"); ArgStart != std::string_view::npos) + { + Mode = ParseMode::None; + return true; + } + else if (std::string_view::size_type ArgStart = Line.find("<string>"); ArgStart != std::string_view::npos) + { + ArgStart += 8; + if (std::string_view::size_type ArgEnd = Line.find("</string>", ArgStart); ArgEnd != std::string_view::npos) + { + std::string_view ArgumentString = Line.substr(ArgStart, ArgEnd - ArgStart); + if (!OutInfo.Spec.CommandLineOptions.empty()) + { + OutInfo.Spec.CommandLineOptions += " "; + } + OutInfo.Spec.CommandLineOptions += ArgumentString; + return true; + } + } + Mode = ParseMode::None; + } + break; + } + return true; + }); + } + { + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl list {}", DaemonName)); + if (Res.first == 0 && !Res.second.empty()) + { + ForEachStrTok(Res.second, '\n', [&](std::string_view Line) { + if (Line.find("\"PID\"") != std::string_view::npos) + { + std::string_view::size_type PidStart = Line.find('='); + std::string_view::size_type PidEnd = Line.find(';'); + std::string_view PidString = Line.substr(PidStart + 2, PidEnd - (PidStart + 2)); + if (ParseInt<int>(PidString).has_value()) + { + OutInfo.Status = ServiceStatus::Running; + } + return false; + } + return true; + }); + // Parse installed info + } + } + } + + return {}; +} + +std::error_code +StartService(std::string_view ServiceName) +{ + const std::string DaemonName = GetDaemonName(ServiceName); + const std::filesystem::path PListPath = GetPListPath(DaemonName); + + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootstrap system {}", PListPath)); + if (Res.first != 0) + { + return MakeErrorCode(Res.first); + } + + return {}; +} + +std::error_code +StopService(std::string_view ServiceName) +{ + const std::string DaemonName = GetDaemonName(ServiceName); + const std::filesystem::path PListPath = GetPListPath(DaemonName); + + /* + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("launchctl bootout system ", PListPath.)); + if (Res.first != 0) + { + return MakeErrorCode(Res.first); + } + */ + + return {}; +} + +#endif // ZEN_PLATFORM_MAC + +#if ZEN_PLATFORM_LINUX + +std::error_code +InstallService(std::string_view ServiceName, const ServiceSpec& Spec) +{ + const std::string UnitName = GetUnitName(ServiceName); + const std::filesystem::path ServiceUnitPath = GetServiceUnitPath(UnitName); + std::string UserName = Spec.UserName; + + if (UserName == "") + { + std::pair<int, std::string> UserResult = ExecuteProgram("echo $SUDO_USER"); + if (UserResult.first != 0 || UserResult.second.empty()) + { + ZEN_ERROR("Unable to determine current user"); + return MakeErrorCode(UserResult.first); + } + + UserName = UserResult.second; + } + + std::string UnitFile = BuildUnitFile(ServiceName, Spec.ExecutablePath, Spec.CommandLineOptions, UserName); + ZEN_DEBUG("Writing systemd unit file to {}", ServiceUnitPath.string()); + try + { + zen::WriteFile(ServiceUnitPath, IoBuffer(IoBuffer::Wrap, UnitFile.data(), UnitFile.size())); + } + catch (const std::system_error& Ex) + { + return MakeErrorCode(Ex.code().value()); + } + + ZEN_DEBUG("Changing permissions to 644 for {}", ServiceUnitPath.string()); + if (chmod(ServiceUnitPath.string().c_str(), 0644) == -1) + { + return MakeErrorCodeFromLastError(); + } + + std::pair<int, std::string> Res = ExecuteProgram("systemctl daemon-reload"); + if (Res.first != 0 && Res.first != -1) + { + ZEN_ERROR("systemctl daemon-reload failed with {}: '{}'", Res.first, Res.second); + return MakeErrorCode(Res.first); + } + + Res = ExecuteProgram(fmt::format("systemctl enable {}", UnitName)); + if (Res.first != 0 && Res.first != -1) + { + ZEN_ERROR("systemctl enable failed with {}: '{}'", Res.first, Res.second); + return MakeErrorCode(Res.first); + } + + return {}; +} + +std::error_code +UninstallService(std::string_view ServiceName) +{ + const std::string UnitName = GetUnitName(ServiceName); + const std::filesystem::path ServiceUnitPath = GetServiceUnitPath(UnitName); + + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("systemctl disable {}", UnitName)); + if (Res.first != 0 && Res.first != -1) + { + ZEN_ERROR("systemctl disable failed with {}: '{}'", Res.first, Res.second); + return MakeErrorCode(Res.first); + } + + ZEN_DEBUG("Attempting to remove systemd unit file from {}", ServiceUnitPath.string()); + std::error_code Ec; + std::filesystem::remove(ServiceUnitPath, Ec); + if (Ec) + { + ZEN_ERROR("failed to remove {}: '{}'", ServiceUnitPath, Ec.message()); + return Ec; + } + + Res = ExecuteProgram("systemctl daemon-reload"); + if (Res.first != 0 && Res.first != -1) + { + ZEN_ERROR("systemctl daemon-reload failed with {}: '{}'", Res.first, Res.second); + return MakeErrorCode(Res.first); + } + + return {}; +} + +std::error_code +QueryInstalledService(std::string_view ServiceName, ServiceInfo& OutInfo) +{ + const std::string UnitName = GetUnitName(ServiceName); + const std::filesystem::path ServiceUnitPath = GetServiceUnitPath(UnitName); + + OutInfo.Status = ServiceStatus::NotInstalled; + + if (std::filesystem::is_regular_file(ServiceUnitPath)) + { + OutInfo.Status = ServiceStatus::Stopped; + + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("systemctl is-active --quiet {}", UnitName)); + if (Res.first == 0) + { + OutInfo.Status = ServiceStatus::Running; + + std::pair<int, std::string> ShowResult = ExecuteProgram(fmt::format("systemctl show -p ExecStart {}", UnitName)); + if (ShowResult.first == 0) + { + std::regex Regex(R"~(ExecStart=\{ path=(.*?) ; argv\[\]=(.*?) ;)~"); + std::smatch Match; + + if (std::regex_search(ShowResult.second, Match, Regex)) + { + std::string Executable = Match[1].str(); + std::string CommandLine = Match[2].str(); + OutInfo.Spec.ExecutablePath = Executable; + OutInfo.Spec.CommandLineOptions = CommandLine.substr(Executable.size(), CommandLine.size()); + } + else + { + ZEN_WARN("Failed to parse output of systemctl show: {}", ShowResult.second); + } + } + else + { + ZEN_WARN("Failed to read start info from systemctl: error code {}", ShowResult.first); + } + } + else + { + ZEN_DEBUG("systemctl status failed with '{}'({})", Res.second, Res.first); + } + } + + return {}; +} + +std::error_code +StartService(std::string_view ServiceName) +{ + // TODO: Starting the service returns -1 from ExecuteProgram, so the service won't start + // TODO: Running start from command line gives no output but the service does not start - not sure what is wrong. + // Starting the same command line for the service using `sudo` *will* start the service sucessfully so I + // assume that the Unit file or some config is wrong/missing. + + const std::string UnitName = GetUnitName(ServiceName); + const std::filesystem::path ServiceUnitPath = GetServiceUnitPath(UnitName); + + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("systemctl start {}", UnitName)); + if (Res.first != 0) + { + ZEN_ERROR("service start failed with {}: '{}'", Res.first, Res.second); + return MakeErrorCode(Res.first); + } + + return {}; +} + +std::error_code +StopService(std::string_view ServiceName) +{ + // TODO: Stopping the service returns -1 from ExecuteProgram, maybe this ie expected as I have yet to successfully start the service + // using systemctl start + + const std::string UnitName = GetUnitName(ServiceName); + const std::filesystem::path ServiceUnitPath = GetServiceUnitPath(UnitName); + + std::pair<int, std::string> Res = ExecuteProgram(fmt::format("systemctl stop {}", UnitName)); + if (Res.first != 0) + { + ZEN_ERROR("service stop failed with {}: '{}'", Res.first, Res.second); + return MakeErrorCode(Res.first); + } + + return {}; +} + +#endif // ZEN_PLATFORM_LINUX + +} // namespace zen diff --git a/src/zenserver/windows/service.cpp b/src/zenutil/windows/service.cpp index cb87df1f6..b76ed7a66 100644 --- a/src/zenserver/windows/service.cpp +++ b/src/zenutil/windows/service.cpp @@ -1,10 +1,9 @@ // Copyright Epic Games, Inc. All Rights Reserved. -#include "service.h" - #include <zencore/zencore.h> #if ZEN_PLATFORM_WINDOWS +# include <zenutil/windows/service.h> # include <zencore/except.h> # include <zencore/thread.h> @@ -21,7 +20,6 @@ HANDLE ghSvcStopEvent = NULL; void SvcInstall(void); -void ReportSvcStatus(DWORD, DWORD, DWORD); void SvcReportEvent(LPTSTR); WindowsService::WindowsService() @@ -222,14 +220,7 @@ WindowsService::SvcMain() return 1; } - // Report running status when initialization is complete. - - ReportSvcStatus(SERVICE_RUNNING, NO_ERROR, 0); - int ReturnCode = Run(); - - ReportSvcStatus(SERVICE_STOPPED, NO_ERROR, 0); - return ReturnCode; } diff --git a/src/zenutil/xmake.lua b/src/zenutil/xmake.lua index 3d95651f2..6d87aefcc 100644 --- a/src/zenutil/xmake.lua +++ b/src/zenutil/xmake.lua @@ -8,3 +8,11 @@ target('zenutil') add_includedirs("include", {public=true}) add_deps("zencore", "zenhttp") add_packages("vcpkg::robin-map", "vcpkg::spdlog") + + if is_plat("linux") then + add_includedirs("$(projectdir)/thirdparty/systemd/include") + add_linkdirs("$(projectdir)/thirdparty/systemd/lib") + add_links("systemd") + add_links("cap") + end + diff --git a/src/zenutil/zenserverprocess.cpp b/src/zenutil/zenserverprocess.cpp index a5b342cb0..4fd1cef9a 100644 --- a/src/zenutil/zenserverprocess.cpp +++ b/src/zenutil/zenserverprocess.cpp @@ -167,10 +167,23 @@ ZenServerState::Initialize() ThrowLastError("Could not map view of Zen server state"); } #else - int Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT | O_CLOEXEC, 0666); + ZEN_INFO("{}", S_IRUSR | S_IWUSR | S_IXUSR); + ZEN_INFO("{}", geteuid()); + int Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT | O_CLOEXEC, geteuid() == 0 ? 0766 : 0666); if (Fd < 0) { - ThrowLastError("Could not open a shared memory object"); + // Work around a potential issue if the service user is changed in certain configurations. + // If the sysctl 'fs.protected_regular' is set to 1 or 2 (default on many distros), + // we will be unable to open an existing shared memory object created by another user using O_CREAT, + // even if we have the correct permissions, or are running as root. If we destroy the existing + // shared memory object and retry, we'll be able to get past shm_open() so long as we have + // the appropriate permissions to create the shared memory object. + shm_unlink("/UnrealEngineZen"); + Fd = shm_open("/UnrealEngineZen", O_RDWR | O_CREAT | O_CLOEXEC, geteuid() == 0 ? 0766 : 0666); + if (Fd < 0) + { + ThrowLastError("Could not open a shared memory object"); + } } fchmod(Fd, 0666); void* hMap = (void*)intptr_t(Fd); diff --git a/thirdparty/systemd/include/systemd/_sd-common.h b/thirdparty/systemd/include/systemd/_sd-common.h new file mode 100644 index 000000000..d4381d90f --- /dev/null +++ b/thirdparty/systemd/include/systemd/_sd-common.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdcommonhfoo +#define foosdcommonhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +/* This is a private header; never even think of including this directly! */ + +#if defined(__INCLUDE_LEVEL__) && __INCLUDE_LEVEL__ <= 1 && !defined(__COVERITY__) +# error "Do not include _sd-common.h directly; it is a private header." +#endif + +typedef void (*_sd_destroy_t)(void *userdata); + +#ifndef _sd_printf_ +# if __GNUC__ >= 4 +# define _sd_printf_(a,b) __attribute__((__format__(printf, a, b))) +# else +# define _sd_printf_(a,b) +# endif +#endif + +#ifndef _sd_sentinel_ +# define _sd_sentinel_ __attribute__((__sentinel__)) +#endif + +#ifndef _sd_packed_ +# define _sd_packed_ __attribute__((__packed__)) +#endif + +#ifndef _sd_pure_ +# define _sd_pure_ __attribute__((__pure__)) +#endif + +/* Note that strictly speaking __deprecated__ has been available before GCC 6. However, starting with GCC 6 + * it also works on enum values, which we are interested in. Since this is a developer-facing feature anyway + * (as opposed to build engineer-facing), let's hence conditionalize this to gcc 6, given that the developers + * are probably going to use something newer anyway. */ +#ifndef _sd_deprecated_ +# if __GNUC__ >= 6 +# define _sd_deprecated_ __attribute__((__deprecated__)) +# else +# define _sd_deprecated_ +# endif +#endif + +#ifndef _SD_STRINGIFY +# define _SD_XSTRINGIFY(x) #x +# define _SD_STRINGIFY(x) _SD_XSTRINGIFY(x) +#endif + +#ifndef _SD_BEGIN_DECLARATIONS +# ifdef __cplusplus +# define _SD_BEGIN_DECLARATIONS \ + extern "C" { \ + struct _sd_useless_struct_to_allow_trailing_semicolon_ +# else +# define _SD_BEGIN_DECLARATIONS \ + struct _sd_useless_struct_to_allow_trailing_semicolon_ +# endif +#endif + +#ifndef _SD_END_DECLARATIONS +# ifdef __cplusplus +# define _SD_END_DECLARATIONS \ + } \ + struct _sd_useless_cpp_struct_to_allow_trailing_semicolon_ +# else +# define _SD_END_DECLARATIONS \ + struct _sd_useless_struct_to_allow_trailing_semicolon_ +# endif +#endif + +#ifndef _SD_ARRAY_STATIC +# if __STDC_VERSION__ >= 199901L && !defined(__cplusplus) +# define _SD_ARRAY_STATIC static +# else +# define _SD_ARRAY_STATIC +# endif +#endif + +#define _SD_DEFINE_POINTER_CLEANUP_FUNC(type, func) \ + static __inline__ void func##p(type **p) { \ + if (*p) \ + func(*p); \ + } \ + struct _sd_useless_struct_to_allow_trailing_semicolon_ + +/* The following macro should be used in all public enums, to force 64-bit wideness on them, so that we can + * freely extend them later on, without breaking compatibility. */ +#define _SD_ENUM_FORCE_S64(id) \ + _SD_##id##_INT64_MIN = INT64_MIN, \ + _SD_##id##_INT64_MAX = INT64_MAX + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-bus-protocol.h b/thirdparty/systemd/include/systemd/sd-bus-protocol.h new file mode 100644 index 000000000..25c9ab335 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-bus-protocol.h @@ -0,0 +1,108 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdbusprotocolhfoo +#define foosdbusprotocolhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +/* Types of message */ + +enum { + _SD_BUS_MESSAGE_TYPE_INVALID = 0, + SD_BUS_MESSAGE_METHOD_CALL, + SD_BUS_MESSAGE_METHOD_RETURN, + SD_BUS_MESSAGE_METHOD_ERROR, + SD_BUS_MESSAGE_SIGNAL, + _SD_BUS_MESSAGE_TYPE_MAX +}; + +/* Primitive types */ + +enum { + _SD_BUS_TYPE_INVALID = 0, + SD_BUS_TYPE_BYTE = 'y', + SD_BUS_TYPE_BOOLEAN = 'b', + SD_BUS_TYPE_INT16 = 'n', + SD_BUS_TYPE_UINT16 = 'q', + SD_BUS_TYPE_INT32 = 'i', + SD_BUS_TYPE_UINT32 = 'u', + SD_BUS_TYPE_INT64 = 'x', + SD_BUS_TYPE_UINT64 = 't', + SD_BUS_TYPE_DOUBLE = 'd', + SD_BUS_TYPE_STRING = 's', + SD_BUS_TYPE_OBJECT_PATH = 'o', + SD_BUS_TYPE_SIGNATURE = 'g', + SD_BUS_TYPE_UNIX_FD = 'h', + SD_BUS_TYPE_ARRAY = 'a', + SD_BUS_TYPE_VARIANT = 'v', + SD_BUS_TYPE_STRUCT = 'r', /* not actually used in signatures */ + SD_BUS_TYPE_STRUCT_BEGIN = '(', + SD_BUS_TYPE_STRUCT_END = ')', + SD_BUS_TYPE_DICT_ENTRY = 'e', /* not actually used in signatures */ + SD_BUS_TYPE_DICT_ENTRY_BEGIN = '{', + SD_BUS_TYPE_DICT_ENTRY_END = '}' +}; + +/* Well-known errors. Note that this is only a sanitized subset of the + * errors that the reference implementation generates. */ + +#define SD_BUS_ERROR_FAILED "org.freedesktop.DBus.Error.Failed" +#define SD_BUS_ERROR_NO_MEMORY "org.freedesktop.DBus.Error.NoMemory" +#define SD_BUS_ERROR_SERVICE_UNKNOWN "org.freedesktop.DBus.Error.ServiceUnknown" +#define SD_BUS_ERROR_NAME_HAS_NO_OWNER "org.freedesktop.DBus.Error.NameHasNoOwner" +#define SD_BUS_ERROR_NO_REPLY "org.freedesktop.DBus.Error.NoReply" +#define SD_BUS_ERROR_IO_ERROR "org.freedesktop.DBus.Error.IOError" +#define SD_BUS_ERROR_BAD_ADDRESS "org.freedesktop.DBus.Error.BadAddress" +#define SD_BUS_ERROR_NOT_SUPPORTED "org.freedesktop.DBus.Error.NotSupported" +#define SD_BUS_ERROR_LIMITS_EXCEEDED "org.freedesktop.DBus.Error.LimitsExceeded" +#define SD_BUS_ERROR_ACCESS_DENIED "org.freedesktop.DBus.Error.AccessDenied" +#define SD_BUS_ERROR_AUTH_FAILED "org.freedesktop.DBus.Error.AuthFailed" +#define SD_BUS_ERROR_NO_SERVER "org.freedesktop.DBus.Error.NoServer" +#define SD_BUS_ERROR_TIMEOUT "org.freedesktop.DBus.Error.Timeout" +#define SD_BUS_ERROR_NO_NETWORK "org.freedesktop.DBus.Error.NoNetwork" +#define SD_BUS_ERROR_ADDRESS_IN_USE "org.freedesktop.DBus.Error.AddressInUse" +#define SD_BUS_ERROR_DISCONNECTED "org.freedesktop.DBus.Error.Disconnected" +#define SD_BUS_ERROR_INVALID_ARGS "org.freedesktop.DBus.Error.InvalidArgs" +#define SD_BUS_ERROR_FILE_NOT_FOUND "org.freedesktop.DBus.Error.FileNotFound" +#define SD_BUS_ERROR_FILE_EXISTS "org.freedesktop.DBus.Error.FileExists" +#define SD_BUS_ERROR_UNKNOWN_METHOD "org.freedesktop.DBus.Error.UnknownMethod" +#define SD_BUS_ERROR_UNKNOWN_OBJECT "org.freedesktop.DBus.Error.UnknownObject" +#define SD_BUS_ERROR_UNKNOWN_INTERFACE "org.freedesktop.DBus.Error.UnknownInterface" +#define SD_BUS_ERROR_UNKNOWN_PROPERTY "org.freedesktop.DBus.Error.UnknownProperty" +#define SD_BUS_ERROR_PROPERTY_READ_ONLY "org.freedesktop.DBus.Error.PropertyReadOnly" +#define SD_BUS_ERROR_UNIX_PROCESS_ID_UNKNOWN "org.freedesktop.DBus.Error.UnixProcessIdUnknown" +#define SD_BUS_ERROR_INVALID_SIGNATURE "org.freedesktop.DBus.Error.InvalidSignature" +#define SD_BUS_ERROR_INCONSISTENT_MESSAGE "org.freedesktop.DBus.Error.InconsistentMessage" +#define SD_BUS_ERROR_TIMED_OUT "org.freedesktop.DBus.Error.TimedOut" +#define SD_BUS_ERROR_MATCH_RULE_NOT_FOUND "org.freedesktop.DBus.Error.MatchRuleNotFound" +#define SD_BUS_ERROR_MATCH_RULE_INVALID "org.freedesktop.DBus.Error.MatchRuleInvalid" +#define SD_BUS_ERROR_INTERACTIVE_AUTHORIZATION_REQUIRED "org.freedesktop.DBus.Error.InteractiveAuthorizationRequired" +#define SD_BUS_ERROR_INVALID_FILE_CONTENT "org.freedesktop.DBus.Error.InvalidFileContent" +#define SD_BUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN "org.freedesktop.DBus.Error.SELinuxSecurityContextUnknown" +#define SD_BUS_ERROR_OBJECT_PATH_IN_USE "org.freedesktop.DBus.Error.ObjectPathInUse" + +/* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-marshaling-signature */ +#define SD_BUS_MAXIMUM_SIGNATURE_LENGTH 255 + +/* https://dbus.freedesktop.org/doc/dbus-specification.html#message-protocol-names */ +#define SD_BUS_MAXIMUM_NAME_LENGTH 255 + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-bus-vtable.h b/thirdparty/systemd/include/systemd/sd-bus-vtable.h new file mode 100644 index 000000000..d06c5c301 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-bus-vtable.h @@ -0,0 +1,357 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdbusvtablehfoo +#define foosdbusvtablehfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +typedef struct sd_bus_vtable sd_bus_vtable; + +#include "sd-bus.h" + +enum { + _SD_BUS_VTABLE_START = '<', + _SD_BUS_VTABLE_END = '>', + _SD_BUS_VTABLE_METHOD = 'M', + _SD_BUS_VTABLE_SIGNAL = 'S', + _SD_BUS_VTABLE_PROPERTY = 'P', + _SD_BUS_VTABLE_WRITABLE_PROPERTY = 'W' +}; + +__extension__ enum { + SD_BUS_VTABLE_DEPRECATED = 1ULL << 0, + SD_BUS_VTABLE_HIDDEN = 1ULL << 1, + SD_BUS_VTABLE_UNPRIVILEGED = 1ULL << 2, + SD_BUS_VTABLE_METHOD_NO_REPLY = 1ULL << 3, + SD_BUS_VTABLE_PROPERTY_CONST = 1ULL << 4, + SD_BUS_VTABLE_PROPERTY_EMITS_CHANGE = 1ULL << 5, + SD_BUS_VTABLE_PROPERTY_EMITS_INVALIDATION = 1ULL << 6, + SD_BUS_VTABLE_PROPERTY_EXPLICIT = 1ULL << 7, + SD_BUS_VTABLE_SENSITIVE = 1ULL << 8, /* covers both directions: method call + reply */ + SD_BUS_VTABLE_ABSOLUTE_OFFSET = 1ULL << 9, + _SD_BUS_VTABLE_CAPABILITY_MASK = 0xFFFFULL << 40 +}; + +#define SD_BUS_VTABLE_CAPABILITY(x) ((uint64_t) (((x)+1) & 0xFFFF) << 40) + +enum { + _SD_BUS_VTABLE_PARAM_NAMES = 1 << 0 +}; + +extern const unsigned sd_bus_object_vtable_format; + +/* Note: unused areas in the sd_bus_vtable[] array must be initialized to 0. The structure contains an embedded + * union, and the compiler is NOT required to initialize the unused areas of the union when the rest of the + * structure is initialized. Normally the array is defined as read-only data, in which case the linker places + * it in the BSS section, which is always fully initialized, so this is not a concern. But if the array is + * created on the stack or on the heap, care must be taken to initialize the unused areas, for examply by + * first memsetting the whole region to zero before filling the data in. */ + +struct sd_bus_vtable { + /* Please do not initialize this structure directly, use the + * macros below instead */ + + __extension__ uint8_t type:8; + __extension__ uint64_t flags:56; + union { + struct { + size_t element_size; + uint64_t features; + const unsigned *vtable_format_reference; + } start; + struct { + /* This field exists only to make sure we have something to initialize in + * SD_BUS_VTABLE_END in a way that is both compatible with pedantic versions of C and + * C++. It's unused otherwise. */ + size_t _reserved; + } end; + struct { + const char *member; + const char *signature; + const char *result; + sd_bus_message_handler_t handler; + size_t offset; + const char *names; + } method; + struct { + const char *member; + const char *signature; + const char *names; + } signal; + struct { + const char *member; + const char *signature; + sd_bus_property_get_t get; + sd_bus_property_set_t set; + size_t offset; + } property; + } x; +}; + +#define SD_BUS_VTABLE_START(_flags) \ + { \ + .type = _SD_BUS_VTABLE_START, \ + .flags = _flags, \ + .x = { \ + .start = { \ + .element_size = sizeof(sd_bus_vtable), \ + .features = _SD_BUS_VTABLE_PARAM_NAMES, \ + .vtable_format_reference = &sd_bus_object_vtable_format, \ + }, \ + }, \ + } + +/* helper macro to format method and signal parameters, one at a time */ +#define SD_BUS_PARAM(x) #x "\0" + +#define SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, _offset, _flags) \ + { \ + .type = _SD_BUS_VTABLE_METHOD, \ + .flags = _flags, \ + .x = { \ + .method = { \ + .member = _member, \ + .signature = _signature, \ + .result = _result, \ + .handler = _handler, \ + .offset = _offset, \ + .names = _in_names _out_names, \ + }, \ + }, \ + } +#define SD_BUS_METHOD_WITH_OFFSET(_member, _signature, _result, _handler, _offset, _flags) \ + SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, _offset, _flags) +#define SD_BUS_METHOD_WITH_NAMES(_member, _signature, _in_names, _result, _out_names, _handler, _flags) \ + SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, _in_names, _result, _out_names, _handler, 0, _flags) +#define SD_BUS_METHOD(_member, _signature, _result, _handler, _flags) \ + SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, _signature, "", _result, "", _handler, 0, _flags) + +#define SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, _out_names, _flags) \ + { \ + .type = _SD_BUS_VTABLE_SIGNAL, \ + .flags = _flags, \ + .x = { \ + .signal = { \ + .member = _member, \ + .signature = _signature, \ + .names = _out_names, \ + }, \ + }, \ + } +#define SD_BUS_SIGNAL(_member, _signature, _flags) \ + SD_BUS_SIGNAL_WITH_NAMES(_member, _signature, "", _flags) + +#define SD_BUS_PROPERTY(_member, _signature, _get, _offset, _flags) \ + { \ + .type = _SD_BUS_VTABLE_PROPERTY, \ + .flags = _flags, \ + .x = { \ + .property = { \ + .member = _member, \ + .signature = _signature, \ + .get = _get, \ + .set = NULL, \ + .offset = _offset, \ + }, \ + }, \ + } + +#define SD_BUS_WRITABLE_PROPERTY(_member, _signature, _get, _set, _offset, _flags) \ + { \ + .type = _SD_BUS_VTABLE_WRITABLE_PROPERTY, \ + .flags = _flags, \ + .x = { \ + .property = { \ + .member = _member, \ + .signature = _signature, \ + .get = _get, \ + .set = _set, \ + .offset = _offset, \ + }, \ + }, \ + } + +#define SD_BUS_VTABLE_END \ + { \ + .type = _SD_BUS_VTABLE_END, \ + .flags = 0, \ + .x = { \ + .end = { \ + ._reserved = 0, \ + }, \ + }, \ + } + +#define _SD_ECHO(X) X +#define _SD_CONCAT(X) #X "\0" + +#define _SD_VARARGS_FOREACH_SEQ(_01, _02, _03, _04, _05, _06, _07, _08, _09, _10, \ + _11, _12, _13, _14, _15, _16, _17, _18, _19, _20, \ + _21, _22, _23, _24, _25, _26, _27, _28, _29, _30, \ + _31, _32, _33, _34, _35, _36, _37, _38, _39, _40, \ + _41, _42, _43, _44, _45, _46, _47, _48, _49, _50, \ + NAME, ...) NAME + +#define _SD_VARARGS_FOREACH_EVEN_00(FN) +#define _SD_VARARGS_FOREACH_EVEN_01(FN, X) FN(X) +#define _SD_VARARGS_FOREACH_EVEN_02(FN, X, Y) FN(X) +#define _SD_VARARGS_FOREACH_EVEN_04(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_02(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_06(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_04(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_08(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_06(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_10(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_08(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_12(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_10(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_14(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_12(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_16(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_14(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_18(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_16(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_20(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_18(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_22(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_20(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_24(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_22(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_26(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_24(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_28(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_26(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_30(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_28(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_32(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_30(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_34(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_32(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_36(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_34(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_38(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_36(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_40(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_38(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_42(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_40(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_44(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_42(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_46(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_44(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_48(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_46(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_EVEN_50(FN, X, Y, ...) FN(X) _SD_VARARGS_FOREACH_EVEN_48(FN, __VA_ARGS__) + +#define _SD_VARARGS_FOREACH_EVEN(FN, ...) \ + _SD_VARARGS_FOREACH_SEQ(__VA_ARGS__, \ + _SD_VARARGS_FOREACH_EVEN_50, _SD_VARARGS_FOREACH_EVEN_49, \ + _SD_VARARGS_FOREACH_EVEN_48, _SD_VARARGS_FOREACH_EVEN_47, \ + _SD_VARARGS_FOREACH_EVEN_46, _SD_VARARGS_FOREACH_EVEN_45, \ + _SD_VARARGS_FOREACH_EVEN_44, _SD_VARARGS_FOREACH_EVEN_43, \ + _SD_VARARGS_FOREACH_EVEN_42, _SD_VARARGS_FOREACH_EVEN_41, \ + _SD_VARARGS_FOREACH_EVEN_40, _SD_VARARGS_FOREACH_EVEN_39, \ + _SD_VARARGS_FOREACH_EVEN_38, _SD_VARARGS_FOREACH_EVEN_37, \ + _SD_VARARGS_FOREACH_EVEN_36, _SD_VARARGS_FOREACH_EVEN_35, \ + _SD_VARARGS_FOREACH_EVEN_34, _SD_VARARGS_FOREACH_EVEN_33, \ + _SD_VARARGS_FOREACH_EVEN_32, _SD_VARARGS_FOREACH_EVEN_31, \ + _SD_VARARGS_FOREACH_EVEN_30, _SD_VARARGS_FOREACH_EVEN_29, \ + _SD_VARARGS_FOREACH_EVEN_28, _SD_VARARGS_FOREACH_EVEN_27, \ + _SD_VARARGS_FOREACH_EVEN_26, _SD_VARARGS_FOREACH_EVEN_25, \ + _SD_VARARGS_FOREACH_EVEN_24, _SD_VARARGS_FOREACH_EVEN_23, \ + _SD_VARARGS_FOREACH_EVEN_22, _SD_VARARGS_FOREACH_EVEN_21, \ + _SD_VARARGS_FOREACH_EVEN_20, _SD_VARARGS_FOREACH_EVEN_19, \ + _SD_VARARGS_FOREACH_EVEN_18, _SD_VARARGS_FOREACH_EVEN_17, \ + _SD_VARARGS_FOREACH_EVEN_16, _SD_VARARGS_FOREACH_EVEN_15, \ + _SD_VARARGS_FOREACH_EVEN_14, _SD_VARARGS_FOREACH_EVEN_13, \ + _SD_VARARGS_FOREACH_EVEN_12, _SD_VARARGS_FOREACH_EVEN_11, \ + _SD_VARARGS_FOREACH_EVEN_10, _SD_VARARGS_FOREACH_EVEN_09, \ + _SD_VARARGS_FOREACH_EVEN_08, _SD_VARARGS_FOREACH_EVEN_07, \ + _SD_VARARGS_FOREACH_EVEN_06, _SD_VARARGS_FOREACH_EVEN_05, \ + _SD_VARARGS_FOREACH_EVEN_04, _SD_VARARGS_FOREACH_EVEN_03, \ + _SD_VARARGS_FOREACH_EVEN_02, _SD_VARARGS_FOREACH_EVEN_01, \ + _SD_VARARGS_FOREACH_EVEN_00) \ + (FN, __VA_ARGS__) + +#define _SD_VARARGS_FOREACH_ODD_00(FN) +#define _SD_VARARGS_FOREACH_ODD_01(FN, X) +#define _SD_VARARGS_FOREACH_ODD_02(FN, X, Y) FN(Y) +#define _SD_VARARGS_FOREACH_ODD_04(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_02(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_06(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_04(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_08(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_06(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_10(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_08(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_12(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_10(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_14(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_12(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_16(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_14(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_18(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_16(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_20(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_18(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_22(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_20(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_24(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_22(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_26(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_24(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_28(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_26(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_30(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_28(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_32(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_30(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_34(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_32(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_36(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_34(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_38(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_36(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_40(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_38(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_42(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_40(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_44(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_42(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_46(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_44(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_48(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_46(FN, __VA_ARGS__) +#define _SD_VARARGS_FOREACH_ODD_50(FN, X, Y, ...) FN(Y) _SD_VARARGS_FOREACH_ODD_48(FN, __VA_ARGS__) + +#define _SD_VARARGS_FOREACH_ODD(FN, ...) \ + _SD_VARARGS_FOREACH_SEQ(__VA_ARGS__, \ + _SD_VARARGS_FOREACH_ODD_50, _SD_VARARGS_FOREACH_ODD_49, \ + _SD_VARARGS_FOREACH_ODD_48, _SD_VARARGS_FOREACH_ODD_47, \ + _SD_VARARGS_FOREACH_ODD_46, _SD_VARARGS_FOREACH_ODD_45, \ + _SD_VARARGS_FOREACH_ODD_44, _SD_VARARGS_FOREACH_ODD_43, \ + _SD_VARARGS_FOREACH_ODD_42, _SD_VARARGS_FOREACH_ODD_41, \ + _SD_VARARGS_FOREACH_ODD_40, _SD_VARARGS_FOREACH_ODD_39, \ + _SD_VARARGS_FOREACH_ODD_38, _SD_VARARGS_FOREACH_ODD_37, \ + _SD_VARARGS_FOREACH_ODD_36, _SD_VARARGS_FOREACH_ODD_35, \ + _SD_VARARGS_FOREACH_ODD_34, _SD_VARARGS_FOREACH_ODD_33, \ + _SD_VARARGS_FOREACH_ODD_32, _SD_VARARGS_FOREACH_ODD_31, \ + _SD_VARARGS_FOREACH_ODD_30, _SD_VARARGS_FOREACH_ODD_29, \ + _SD_VARARGS_FOREACH_ODD_28, _SD_VARARGS_FOREACH_ODD_27, \ + _SD_VARARGS_FOREACH_ODD_26, _SD_VARARGS_FOREACH_ODD_25, \ + _SD_VARARGS_FOREACH_ODD_24, _SD_VARARGS_FOREACH_ODD_23, \ + _SD_VARARGS_FOREACH_ODD_22, _SD_VARARGS_FOREACH_ODD_21, \ + _SD_VARARGS_FOREACH_ODD_20, _SD_VARARGS_FOREACH_ODD_19, \ + _SD_VARARGS_FOREACH_ODD_18, _SD_VARARGS_FOREACH_ODD_17, \ + _SD_VARARGS_FOREACH_ODD_16, _SD_VARARGS_FOREACH_ODD_15, \ + _SD_VARARGS_FOREACH_ODD_14, _SD_VARARGS_FOREACH_ODD_13, \ + _SD_VARARGS_FOREACH_ODD_12, _SD_VARARGS_FOREACH_ODD_11, \ + _SD_VARARGS_FOREACH_ODD_10, _SD_VARARGS_FOREACH_ODD_09, \ + _SD_VARARGS_FOREACH_ODD_08, _SD_VARARGS_FOREACH_ODD_07, \ + _SD_VARARGS_FOREACH_ODD_06, _SD_VARARGS_FOREACH_ODD_05, \ + _SD_VARARGS_FOREACH_ODD_04, _SD_VARARGS_FOREACH_ODD_03, \ + _SD_VARARGS_FOREACH_ODD_02, _SD_VARARGS_FOREACH_ODD_01, \ + _SD_VARARGS_FOREACH_ODD_00) \ + (FN, __VA_ARGS__) + +#define SD_BUS_ARGS(...) __VA_ARGS__ +#define SD_BUS_RESULT(...) __VA_ARGS__ + +#define SD_BUS_NO_ARGS SD_BUS_ARGS(NULL) +#define SD_BUS_NO_RESULT SD_BUS_RESULT(NULL) + +#define SD_BUS_METHOD_WITH_ARGS(_member, _args, _result, _handler, _flags) \ + SD_BUS_METHOD_WITH_NAMES(_member, \ + _SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \ + _SD_VARARGS_FOREACH_ODD(_SD_CONCAT, _args), \ + _SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \ + _SD_VARARGS_FOREACH_ODD(_SD_CONCAT, _result) "\0", \ + _handler, _flags) + +#define SD_BUS_METHOD_WITH_ARGS_OFFSET(_member, _args, _result, _handler, _offset, _flags) \ + SD_BUS_METHOD_WITH_NAMES_OFFSET(_member, \ + _SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \ + _SD_VARARGS_FOREACH_ODD(_SD_CONCAT, _args), \ + _SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _result), \ + _SD_VARARGS_FOREACH_ODD(_SD_CONCAT, _result) "\0", \ + _handler, _offset, _flags) + +#define SD_BUS_SIGNAL_WITH_ARGS(_member, _args, _flags) \ + SD_BUS_SIGNAL_WITH_NAMES(_member, \ + _SD_VARARGS_FOREACH_EVEN(_SD_ECHO, _args), \ + _SD_VARARGS_FOREACH_ODD(_SD_CONCAT, _args) "\0", \ + _flags) + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-bus.h b/thirdparty/systemd/include/systemd/sd-bus.h new file mode 100644 index 000000000..f1a331199 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-bus.h @@ -0,0 +1,544 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdbushfoo +#define foosdbushfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <stdarg.h> +#include <stdio.h> +#include <sys/types.h> +#include <sys/uio.h> + +#include "sd-event.h" +#include "sd-id128.h" + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +#define SD_BUS_DEFAULT ((sd_bus *) 1) +#define SD_BUS_DEFAULT_USER ((sd_bus *) 2) +#define SD_BUS_DEFAULT_SYSTEM ((sd_bus *) 3) + +/* Types */ + +typedef struct sd_bus sd_bus; +typedef struct sd_bus_message sd_bus_message; +typedef struct sd_bus_slot sd_bus_slot; +typedef struct sd_bus_creds sd_bus_creds; +typedef struct sd_bus_track sd_bus_track; + +typedef struct { + const char *name; + const char *message; + int _need_free; +} sd_bus_error; + +typedef struct { + const char *name; + int code; +} sd_bus_error_map; + +/* Flags */ + +__extension__ enum { + SD_BUS_CREDS_PID = 1ULL << 0, + SD_BUS_CREDS_TID = 1ULL << 1, + SD_BUS_CREDS_PPID = 1ULL << 2, + SD_BUS_CREDS_UID = 1ULL << 3, + SD_BUS_CREDS_EUID = 1ULL << 4, + SD_BUS_CREDS_SUID = 1ULL << 5, + SD_BUS_CREDS_FSUID = 1ULL << 6, + SD_BUS_CREDS_GID = 1ULL << 7, + SD_BUS_CREDS_EGID = 1ULL << 8, + SD_BUS_CREDS_SGID = 1ULL << 9, + SD_BUS_CREDS_FSGID = 1ULL << 10, + SD_BUS_CREDS_SUPPLEMENTARY_GIDS = 1ULL << 11, + SD_BUS_CREDS_COMM = 1ULL << 12, + SD_BUS_CREDS_TID_COMM = 1ULL << 13, + SD_BUS_CREDS_EXE = 1ULL << 14, + SD_BUS_CREDS_CMDLINE = 1ULL << 15, + SD_BUS_CREDS_CGROUP = 1ULL << 16, + SD_BUS_CREDS_UNIT = 1ULL << 17, + SD_BUS_CREDS_SLICE = 1ULL << 18, + SD_BUS_CREDS_USER_UNIT = 1ULL << 19, + SD_BUS_CREDS_USER_SLICE = 1ULL << 20, + SD_BUS_CREDS_SESSION = 1ULL << 21, + SD_BUS_CREDS_OWNER_UID = 1ULL << 22, + SD_BUS_CREDS_EFFECTIVE_CAPS = 1ULL << 23, + SD_BUS_CREDS_PERMITTED_CAPS = 1ULL << 24, + SD_BUS_CREDS_INHERITABLE_CAPS = 1ULL << 25, + SD_BUS_CREDS_BOUNDING_CAPS = 1ULL << 26, + SD_BUS_CREDS_SELINUX_CONTEXT = 1ULL << 27, + SD_BUS_CREDS_AUDIT_SESSION_ID = 1ULL << 28, + SD_BUS_CREDS_AUDIT_LOGIN_UID = 1ULL << 29, + SD_BUS_CREDS_TTY = 1ULL << 30, + SD_BUS_CREDS_UNIQUE_NAME = 1ULL << 31, + SD_BUS_CREDS_WELL_KNOWN_NAMES = 1ULL << 32, + SD_BUS_CREDS_DESCRIPTION = 1ULL << 33, + SD_BUS_CREDS_PIDFD = 1ULL << 34, + SD_BUS_CREDS_AUGMENT = 1ULL << 63, /* special flag, if on sd-bus will augment creds struct, in a potentially race-full way. */ + _SD_BUS_CREDS_ALL = (1ULL << 35) -1 +}; + +__extension__ enum { + SD_BUS_NAME_REPLACE_EXISTING = 1ULL << 0, + SD_BUS_NAME_ALLOW_REPLACEMENT = 1ULL << 1, + SD_BUS_NAME_QUEUE = 1ULL << 2 +}; + +__extension__ enum { + SD_BUS_MESSAGE_DUMP_WITH_HEADER = 1ULL << 0, + SD_BUS_MESSAGE_DUMP_SUBTREE_ONLY = 1ULL << 1, + _SD_BUS_MESSAGE_DUMP_KNOWN_FLAGS = SD_BUS_MESSAGE_DUMP_WITH_HEADER | SD_BUS_MESSAGE_DUMP_SUBTREE_ONLY +}; + +/* Callbacks */ + +typedef int (*sd_bus_message_handler_t)(sd_bus_message *m, void *userdata, sd_bus_error *ret_error); +typedef int (*sd_bus_property_get_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *reply, void *userdata, sd_bus_error *ret_error); +typedef int (*sd_bus_property_set_t) (sd_bus *bus, const char *path, const char *interface, const char *property, sd_bus_message *value, void *userdata, sd_bus_error *ret_error); +typedef int (*sd_bus_object_find_t) (sd_bus *bus, const char *path, const char *interface, void *userdata, void **ret_found, sd_bus_error *ret_error); +typedef int (*sd_bus_node_enumerator_t) (sd_bus *bus, const char *prefix, void *userdata, char ***ret_nodes, sd_bus_error *ret_error); +typedef int (*sd_bus_track_handler_t) (sd_bus_track *track, void *userdata); +typedef _sd_destroy_t sd_bus_destroy_t; + +#include "sd-bus-protocol.h" +#include "sd-bus-vtable.h" + +/* Naming */ + +int sd_bus_interface_name_is_valid(const char *p); +int sd_bus_service_name_is_valid(const char *p); +int sd_bus_member_name_is_valid(const char *p); +int sd_bus_object_path_is_valid(const char *p); + +/* Connections */ + +int sd_bus_default(sd_bus **ret); +int sd_bus_default_user(sd_bus **ret); +int sd_bus_default_system(sd_bus **ret); + +int sd_bus_open(sd_bus **ret); +int sd_bus_open_with_description(sd_bus **ret, const char *description); +int sd_bus_open_user(sd_bus **ret); +int sd_bus_open_user_with_description(sd_bus **ret, const char *description); +int sd_bus_open_user_machine(sd_bus **ret, const char *machine); +int sd_bus_open_system(sd_bus **ret); +int sd_bus_open_system_with_description(sd_bus **ret, const char *description); +int sd_bus_open_system_remote(sd_bus **ret, const char *host); +int sd_bus_open_system_machine(sd_bus **ret, const char *machine); + +int sd_bus_new(sd_bus **ret); + +int sd_bus_set_address(sd_bus *bus, const char *address); +int sd_bus_set_fd(sd_bus *bus, int input_fd, int output_fd); +int sd_bus_set_exec(sd_bus *bus, const char *path, char *const *argv); +int sd_bus_get_address(sd_bus *bus, const char **address); +int sd_bus_set_bus_client(sd_bus *bus, int b); +int sd_bus_is_bus_client(sd_bus *bus); +int sd_bus_set_server(sd_bus *bus, int b, sd_id128_t bus_id); +int sd_bus_is_server(sd_bus *bus); +int sd_bus_set_anonymous(sd_bus *bus, int b); +int sd_bus_is_anonymous(sd_bus *bus); +int sd_bus_set_trusted(sd_bus *bus, int b); +int sd_bus_is_trusted(sd_bus *bus); +int sd_bus_set_monitor(sd_bus *bus, int b); +int sd_bus_is_monitor(sd_bus *bus); +int sd_bus_set_description(sd_bus *bus, const char *description); +int sd_bus_get_description(sd_bus *bus, const char **description); +int sd_bus_negotiate_creds(sd_bus *bus, int b, uint64_t creds_mask); +int sd_bus_negotiate_timestamp(sd_bus *bus, int b); +int sd_bus_negotiate_fds(sd_bus *bus, int b); +int sd_bus_can_send(sd_bus *bus, char type); +int sd_bus_get_creds_mask(sd_bus *bus, uint64_t *creds_mask); +int sd_bus_set_allow_interactive_authorization(sd_bus *bus, int b); +int sd_bus_get_allow_interactive_authorization(sd_bus *bus); +int sd_bus_set_exit_on_disconnect(sd_bus *bus, int b); +int sd_bus_get_exit_on_disconnect(sd_bus *bus); +int sd_bus_set_close_on_exit(sd_bus *bus, int b); +int sd_bus_get_close_on_exit(sd_bus *bus); +int sd_bus_set_watch_bind(sd_bus *bus, int b); +int sd_bus_get_watch_bind(sd_bus *bus); +int sd_bus_set_connected_signal(sd_bus *bus, int b); +int sd_bus_get_connected_signal(sd_bus *bus); +int sd_bus_set_sender(sd_bus *bus, const char *sender); +int sd_bus_get_sender(sd_bus *bus, const char **ret); + +int sd_bus_start(sd_bus *bus); + +int sd_bus_try_close(sd_bus *bus) _sd_deprecated_; +void sd_bus_close(sd_bus *bus); + +sd_bus* sd_bus_ref(sd_bus *bus); +sd_bus* sd_bus_unref(sd_bus *bus); +sd_bus* sd_bus_close_unref(sd_bus *bus); +sd_bus* sd_bus_flush_close_unref(sd_bus *bus); + +void sd_bus_default_flush_close(void); + +int sd_bus_is_open(sd_bus *bus); +int sd_bus_is_ready(sd_bus *bus); + +int sd_bus_get_bus_id(sd_bus *bus, sd_id128_t *id); +int sd_bus_get_scope(sd_bus *bus, const char **scope); +int sd_bus_get_tid(sd_bus *bus, pid_t *tid); +int sd_bus_get_owner_creds(sd_bus *bus, uint64_t creds_mask, sd_bus_creds **ret); + +int sd_bus_send(sd_bus *bus, sd_bus_message *m, uint64_t *cookie); +int sd_bus_send_to(sd_bus *bus, sd_bus_message *m, const char *destination, uint64_t *cookie); +int sd_bus_call(sd_bus *bus, sd_bus_message *m, uint64_t usec, sd_bus_error *ret_error, sd_bus_message **reply); +int sd_bus_call_async(sd_bus *bus, sd_bus_slot **slot, sd_bus_message *m, sd_bus_message_handler_t callback, void *userdata, uint64_t usec); + +int sd_bus_get_fd(sd_bus *bus); +int sd_bus_get_events(sd_bus *bus); +int sd_bus_get_timeout(sd_bus *bus, uint64_t *timeout_usec); +int sd_bus_process(sd_bus *bus, sd_bus_message **r); +int sd_bus_process_priority(sd_bus *bus, int64_t max_priority, sd_bus_message **r) _sd_deprecated_; +int sd_bus_wait(sd_bus *bus, uint64_t timeout_usec); +int sd_bus_flush(sd_bus *bus); +int sd_bus_enqueue_for_read(sd_bus *bus, sd_bus_message *m); + +sd_bus_slot* sd_bus_get_current_slot(sd_bus *bus); +sd_bus_message* sd_bus_get_current_message(sd_bus *bus); +sd_bus_message_handler_t sd_bus_get_current_handler(sd_bus *bus); +void* sd_bus_get_current_userdata(sd_bus *bus); + +int sd_bus_attach_event(sd_bus *bus, sd_event *e, int priority); +int sd_bus_detach_event(sd_bus *bus); +sd_event* sd_bus_get_event(sd_bus *bus); + +int sd_bus_get_n_queued_read(sd_bus *bus, uint64_t *ret); +int sd_bus_get_n_queued_write(sd_bus *bus, uint64_t *ret); + +int sd_bus_set_method_call_timeout(sd_bus *bus, uint64_t usec); +int sd_bus_get_method_call_timeout(sd_bus *bus, uint64_t *ret); + +int sd_bus_add_filter(sd_bus *bus, sd_bus_slot **slot, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_add_match(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_add_match_async(sd_bus *bus, sd_bus_slot **slot, const char *match, sd_bus_message_handler_t callback, sd_bus_message_handler_t install_callback, void *userdata); +int sd_bus_add_object(sd_bus *bus, sd_bus_slot **slot, const char *path, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_add_fallback(sd_bus *bus, sd_bus_slot **slot, const char *prefix, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_add_object_vtable(sd_bus *bus, sd_bus_slot **slot, const char *path, const char *interface, const sd_bus_vtable *vtable, void *userdata); +int sd_bus_add_fallback_vtable(sd_bus *bus, sd_bus_slot **slot, const char *prefix, const char *interface, const sd_bus_vtable *vtable, sd_bus_object_find_t find, void *userdata); +int sd_bus_add_node_enumerator(sd_bus *bus, sd_bus_slot **slot, const char *path, sd_bus_node_enumerator_t callback, void *userdata); +int sd_bus_add_object_manager(sd_bus *bus, sd_bus_slot **slot, const char *path); + +/* Slot object */ + +sd_bus_slot* sd_bus_slot_ref(sd_bus_slot *slot); +sd_bus_slot* sd_bus_slot_unref(sd_bus_slot *slot); + +sd_bus* sd_bus_slot_get_bus(sd_bus_slot *slot); +void* sd_bus_slot_get_userdata(sd_bus_slot *slot); +void* sd_bus_slot_set_userdata(sd_bus_slot *slot, void *userdata); +int sd_bus_slot_set_description(sd_bus_slot *slot, const char *description); +int sd_bus_slot_get_description(sd_bus_slot *slot, const char **description); +int sd_bus_slot_get_floating(sd_bus_slot *slot); +int sd_bus_slot_set_floating(sd_bus_slot *slot, int b); +int sd_bus_slot_set_destroy_callback(sd_bus_slot *s, sd_bus_destroy_t callback); +int sd_bus_slot_get_destroy_callback(sd_bus_slot *s, sd_bus_destroy_t *callback); + +sd_bus_message* sd_bus_slot_get_current_message(sd_bus_slot *slot); +sd_bus_message_handler_t sd_bus_slot_get_current_handler(sd_bus_slot *slot); +void* sd_bus_slot_get_current_userdata(sd_bus_slot *slot); + +/* Message object */ + +int sd_bus_message_new(sd_bus *bus, sd_bus_message **m, uint8_t type); +int sd_bus_message_new_signal(sd_bus *bus, sd_bus_message **m, const char *path, const char *interface, const char *member); +int sd_bus_message_new_signal_to(sd_bus *bus, sd_bus_message **m, const char *destination, const char *path, const char *interface, const char *member); +int sd_bus_message_new_method_call(sd_bus *bus, sd_bus_message **m, const char *destination, const char *path, const char *interface, const char *member); +int sd_bus_message_new_method_return(sd_bus_message *call, sd_bus_message **m); +int sd_bus_message_new_method_error(sd_bus_message *call, sd_bus_message **m, const sd_bus_error *e); +int sd_bus_message_new_method_errorf(sd_bus_message *call, sd_bus_message **m, const char *name, const char *format, ...) _sd_printf_(4, 5); +int sd_bus_message_new_method_errno(sd_bus_message *call, sd_bus_message **m, int error, const sd_bus_error *e); +int sd_bus_message_new_method_errnof(sd_bus_message *call, sd_bus_message **m, int error, const char *format, ...) _sd_printf_(4, 5); + +sd_bus_message* sd_bus_message_ref(sd_bus_message *m); +sd_bus_message* sd_bus_message_unref(sd_bus_message *m); + +int sd_bus_message_seal(sd_bus_message *m, uint64_t cookie, uint64_t timeout_usec); + +int sd_bus_message_get_type(sd_bus_message *m, uint8_t *type); +int sd_bus_message_get_cookie(sd_bus_message *m, uint64_t *cookie); +int sd_bus_message_get_reply_cookie(sd_bus_message *m, uint64_t *cookie); +int sd_bus_message_get_priority(sd_bus_message *m, int64_t *priority) _sd_deprecated_; + +int sd_bus_message_get_expect_reply(sd_bus_message *m); +int sd_bus_message_get_auto_start(sd_bus_message *m); +int sd_bus_message_get_allow_interactive_authorization(sd_bus_message *m); + +const char* sd_bus_message_get_signature(sd_bus_message *m, int complete); +const char* sd_bus_message_get_path(sd_bus_message *m); +const char* sd_bus_message_get_interface(sd_bus_message *m); +const char* sd_bus_message_get_member(sd_bus_message *m); +const char* sd_bus_message_get_destination(sd_bus_message *m); +const char* sd_bus_message_get_sender(sd_bus_message *m); +const sd_bus_error* sd_bus_message_get_error(sd_bus_message *m); +int sd_bus_message_get_errno(sd_bus_message *m); + +int sd_bus_message_get_monotonic_usec(sd_bus_message *m, uint64_t *usec); +int sd_bus_message_get_realtime_usec(sd_bus_message *m, uint64_t *usec); +int sd_bus_message_get_seqnum(sd_bus_message *m, uint64_t *seqnum); + +sd_bus* sd_bus_message_get_bus(sd_bus_message *m); +sd_bus_creds* sd_bus_message_get_creds(sd_bus_message *m); /* do not unref the result */ + +int sd_bus_message_is_signal(sd_bus_message *m, const char *interface, const char *member); +int sd_bus_message_is_method_call(sd_bus_message *m, const char *interface, const char *member); +int sd_bus_message_is_method_error(sd_bus_message *m, const char *name); +int sd_bus_message_is_empty(sd_bus_message *m); +int sd_bus_message_has_signature(sd_bus_message *m, const char *signature); + +int sd_bus_message_set_expect_reply(sd_bus_message *m, int b); +int sd_bus_message_set_auto_start(sd_bus_message *m, int b); +int sd_bus_message_set_allow_interactive_authorization(sd_bus_message *m, int b); + +int sd_bus_message_set_destination(sd_bus_message *m, const char *destination); +int sd_bus_message_set_sender(sd_bus_message *m, const char *sender); +int sd_bus_message_set_priority(sd_bus_message *m, int64_t priority) _sd_deprecated_; + +int sd_bus_message_append(sd_bus_message *m, const char *types, ...); +int sd_bus_message_appendv(sd_bus_message *m, const char *types, va_list ap); +int sd_bus_message_append_basic(sd_bus_message *m, char type, const void *p); +int sd_bus_message_append_array(sd_bus_message *m, char type, const void *ptr, size_t size); +int sd_bus_message_append_array_space(sd_bus_message *m, char type, size_t size, void **ptr); +int sd_bus_message_append_array_iovec(sd_bus_message *m, char type, const struct iovec *iov, unsigned n); +int sd_bus_message_append_array_memfd(sd_bus_message *m, char type, int memfd, uint64_t offset, uint64_t size); +int sd_bus_message_append_string_space(sd_bus_message *m, size_t size, char **s); +int sd_bus_message_append_string_iovec(sd_bus_message *m, const struct iovec *iov, unsigned n); +int sd_bus_message_append_string_memfd(sd_bus_message *m, int memfd, uint64_t offset, uint64_t size); +int sd_bus_message_append_strv(sd_bus_message *m, char **l); +int sd_bus_message_open_container(sd_bus_message *m, char type, const char *contents); +int sd_bus_message_close_container(sd_bus_message *m); +int sd_bus_message_copy(sd_bus_message *m, sd_bus_message *source, int all); + +int sd_bus_message_read(sd_bus_message *m, const char *types, ...); +int sd_bus_message_readv(sd_bus_message *m, const char *types, va_list ap); +int sd_bus_message_read_basic(sd_bus_message *m, char type, void *p); +int sd_bus_message_read_array(sd_bus_message *m, char type, const void **ptr, size_t *size); +int sd_bus_message_read_strv(sd_bus_message *m, char ***l); /* free the result! */ +int sd_bus_message_read_strv_extend(sd_bus_message *m, char ***l); +int sd_bus_message_skip(sd_bus_message *m, const char *types); +int sd_bus_message_enter_container(sd_bus_message *m, char type, const char *contents); +int sd_bus_message_exit_container(sd_bus_message *m); +int sd_bus_message_peek_type(sd_bus_message *m, char *type, const char **contents); +int sd_bus_message_verify_type(sd_bus_message *m, char type, const char *contents); +int sd_bus_message_at_end(sd_bus_message *m, int complete); +int sd_bus_message_rewind(sd_bus_message *m, int complete); +int sd_bus_message_sensitive(sd_bus_message *m); + +int sd_bus_message_dump(sd_bus_message *m, FILE *f, uint64_t flags); + +/* Bus management */ + +int sd_bus_get_unique_name(sd_bus *bus, const char **unique); +int sd_bus_request_name(sd_bus *bus, const char *name, uint64_t flags); +int sd_bus_request_name_async(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, uint64_t flags, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_release_name(sd_bus *bus, const char *name); +int sd_bus_release_name_async(sd_bus *bus, sd_bus_slot **ret_slot, const char *name, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_list_names(sd_bus *bus, char ***acquired, char ***activatable); /* free the results */ +int sd_bus_get_name_creds(sd_bus *bus, const char *name, uint64_t mask, sd_bus_creds **creds); /* unref the result! */ +int sd_bus_get_name_machine_id(sd_bus *bus, const char *name, sd_id128_t *machine); + +/* Convenience calls */ + +int sd_bus_message_send(sd_bus_message *m); +int sd_bus_call_methodv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, va_list ap); +int sd_bus_call_method(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *types, ...); +int sd_bus_call_method_asyncv(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, va_list ap); +int sd_bus_call_method_async(sd_bus *bus, sd_bus_slot **slot, const char *destination, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata, const char *types, ...); +int sd_bus_get_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, sd_bus_message **reply, const char *type); +int sd_bus_get_property_trivial(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char type, void *ret_ptr); +int sd_bus_get_property_string(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char **ret); /* free the result! */ +int sd_bus_get_property_strv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, char ***ret); /* free the result! */ +int sd_bus_set_propertyv(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, const char *type, va_list ap); +int sd_bus_set_property(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, sd_bus_error *ret_error, const char *type, ...); + +int sd_bus_reply_method_returnv(sd_bus_message *call, const char *types, va_list ap); +int sd_bus_reply_method_return(sd_bus_message *call, const char *types, ...); +int sd_bus_reply_method_error(sd_bus_message *call, const sd_bus_error *e); +int sd_bus_reply_method_errorfv(sd_bus_message *call, const char *name, const char *format, va_list ap) _sd_printf_(3, 0); +int sd_bus_reply_method_errorf(sd_bus_message *call, const char *name, const char *format, ...) _sd_printf_(3, 4); +int sd_bus_reply_method_errno(sd_bus_message *call, int error, const sd_bus_error *e); +int sd_bus_reply_method_errnofv(sd_bus_message *call, int error, const char *format, va_list ap) _sd_printf_(3, 0); +int sd_bus_reply_method_errnof(sd_bus_message *call, int error, const char *format, ...) _sd_printf_(3, 4); + +int sd_bus_emit_signalv(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, va_list ap); +int sd_bus_emit_signal(sd_bus *bus, const char *path, const char *interface, const char *member, const char *types, ...); +int sd_bus_emit_signal_tov(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, const char *types, va_list ap); +int sd_bus_emit_signal_to(sd_bus *bus, const char *destination, const char *path, const char *interface, const char *member, const char *types, ...); + +int sd_bus_emit_properties_changed_strv(sd_bus *bus, const char *path, const char *interface, char **names); +int sd_bus_emit_properties_changed(sd_bus *bus, const char *path, const char *interface, const char *name, ...) _sd_sentinel_; + +int sd_bus_emit_object_added(sd_bus *bus, const char *path); +int sd_bus_emit_object_removed(sd_bus *bus, const char *path); +int sd_bus_emit_interfaces_added_strv(sd_bus *bus, const char *path, char **interfaces); +int sd_bus_emit_interfaces_added(sd_bus *bus, const char *path, const char *interface, ...) _sd_sentinel_; +int sd_bus_emit_interfaces_removed_strv(sd_bus *bus, const char *path, char **interfaces); +int sd_bus_emit_interfaces_removed(sd_bus *bus, const char *path, const char *interface, ...) _sd_sentinel_; + +int sd_bus_query_sender_creds(sd_bus_message *m, uint64_t mask, sd_bus_creds **creds); +int sd_bus_query_sender_privilege(sd_bus_message *m, int capability); + +int sd_bus_match_signal(sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t callback, void *userdata); +int sd_bus_match_signal_async(sd_bus *bus, sd_bus_slot **ret, const char *sender, const char *path, const char *interface, const char *member, sd_bus_message_handler_t match_callback, sd_bus_message_handler_t add_callback, void *userdata); + +/* Credential handling */ + +int sd_bus_creds_new_from_pid(sd_bus_creds **ret, pid_t pid, uint64_t creds_mask); +int sd_bus_creds_new_from_pidfd(sd_bus_creds **ret, int pidfd, uint64_t creds_mask); +sd_bus_creds* sd_bus_creds_ref(sd_bus_creds *c); +sd_bus_creds* sd_bus_creds_unref(sd_bus_creds *c); +uint64_t sd_bus_creds_get_mask(const sd_bus_creds *c); +uint64_t sd_bus_creds_get_augmented_mask(const sd_bus_creds *c); + +int sd_bus_creds_get_pid(sd_bus_creds *c, pid_t *pid); +int sd_bus_creds_get_pidfd_dup(sd_bus_creds *c, int *ret_fd); +int sd_bus_creds_get_ppid(sd_bus_creds *c, pid_t *ppid); +int sd_bus_creds_get_tid(sd_bus_creds *c, pid_t *tid); +int sd_bus_creds_get_uid(sd_bus_creds *c, uid_t *uid); +int sd_bus_creds_get_euid(sd_bus_creds *c, uid_t *euid); +int sd_bus_creds_get_suid(sd_bus_creds *c, uid_t *suid); +int sd_bus_creds_get_fsuid(sd_bus_creds *c, uid_t *fsuid); +int sd_bus_creds_get_gid(sd_bus_creds *c, gid_t *gid); +int sd_bus_creds_get_egid(sd_bus_creds *c, gid_t *egid); +int sd_bus_creds_get_sgid(sd_bus_creds *c, gid_t *sgid); +int sd_bus_creds_get_fsgid(sd_bus_creds *c, gid_t *fsgid); +int sd_bus_creds_get_supplementary_gids(sd_bus_creds *c, const gid_t **gids); +int sd_bus_creds_get_comm(sd_bus_creds *c, const char **comm); +int sd_bus_creds_get_tid_comm(sd_bus_creds *c, const char **comm); +int sd_bus_creds_get_exe(sd_bus_creds *c, const char **exe); +int sd_bus_creds_get_cmdline(sd_bus_creds *c, char ***cmdline); +int sd_bus_creds_get_cgroup(sd_bus_creds *c, const char **cgroup); +int sd_bus_creds_get_unit(sd_bus_creds *c, const char **unit); +int sd_bus_creds_get_slice(sd_bus_creds *c, const char **slice); +int sd_bus_creds_get_user_unit(sd_bus_creds *c, const char **unit); +int sd_bus_creds_get_user_slice(sd_bus_creds *c, const char **slice); +int sd_bus_creds_get_session(sd_bus_creds *c, const char **session); +int sd_bus_creds_get_owner_uid(sd_bus_creds *c, uid_t *uid); +int sd_bus_creds_has_effective_cap(sd_bus_creds *c, int capability); +int sd_bus_creds_has_permitted_cap(sd_bus_creds *c, int capability); +int sd_bus_creds_has_inheritable_cap(sd_bus_creds *c, int capability); +int sd_bus_creds_has_bounding_cap(sd_bus_creds *c, int capability); +int sd_bus_creds_get_selinux_context(sd_bus_creds *c, const char **context); +int sd_bus_creds_get_audit_session_id(sd_bus_creds *c, uint32_t *sessionid); +int sd_bus_creds_get_audit_login_uid(sd_bus_creds *c, uid_t *loginuid); +int sd_bus_creds_get_tty(sd_bus_creds *c, const char **tty); +int sd_bus_creds_get_unique_name(sd_bus_creds *c, const char **name); +int sd_bus_creds_get_well_known_names(sd_bus_creds *c, char ***names); +int sd_bus_creds_get_description(sd_bus_creds *c, const char **name); + +/* Error structures */ + +#define SD_BUS_ERROR_MAKE_CONST(name, message) ((const sd_bus_error) {(name), (message), 0}) +#define SD_BUS_ERROR_NULL SD_BUS_ERROR_MAKE_CONST(NULL, NULL) + +void sd_bus_error_free(sd_bus_error *e); +int sd_bus_error_set(sd_bus_error *e, const char *name, const char *message); +int sd_bus_error_setf(sd_bus_error *e, const char *name, const char *format, ...) _sd_printf_(3, 4); +int sd_bus_error_setfv(sd_bus_error *e, const char *name, const char *format, va_list ap) _sd_printf_(3,0); + +int sd_bus_error_set_const(sd_bus_error *e, const char *name, const char *message); +int sd_bus_error_set_errno(sd_bus_error *e, int error); +int sd_bus_error_set_errnof(sd_bus_error *e, int error, const char *format, ...) _sd_printf_(3, 4); +int sd_bus_error_set_errnofv(sd_bus_error *e, int error, const char *format, va_list ap) _sd_printf_(3,0); +int sd_bus_error_get_errno(const sd_bus_error *e); +int sd_bus_error_copy(sd_bus_error *dest, const sd_bus_error *e); +int sd_bus_error_move(sd_bus_error *dest, sd_bus_error *e); +int sd_bus_error_is_set(const sd_bus_error *e); +int sd_bus_error_has_name(const sd_bus_error *e, const char *name); +int sd_bus_error_has_names_sentinel(const sd_bus_error *e, ...) _sd_sentinel_; +#define sd_bus_error_has_names(e, ...) sd_bus_error_has_names_sentinel(e, __VA_ARGS__, NULL) + +#define SD_BUS_ERROR_MAP(_name, _code) \ + { \ + .name = _name, \ + .code = _code, \ + } +#define SD_BUS_ERROR_MAP_END \ + { \ + .name = NULL, \ + .code = - 'x', \ + } + +int sd_bus_error_add_map(const sd_bus_error_map *map); + +/* Auxiliary macros */ + +#define SD_BUS_MESSAGE_APPEND_ID128(x) 16, \ + (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], \ + (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], \ + (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], \ + (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] + +#define SD_BUS_MESSAGE_READ_ID128(x) 16, \ + &(x).bytes[0], &(x).bytes[1], &(x).bytes[2], &(x).bytes[3], \ + &(x).bytes[4], &(x).bytes[5], &(x).bytes[6], &(x).bytes[7], \ + &(x).bytes[8], &(x).bytes[9], &(x).bytes[10], &(x).bytes[11], \ + &(x).bytes[12], &(x).bytes[13], &(x).bytes[14], &(x).bytes[15] + +/* Label escaping */ + +int sd_bus_path_encode(const char *prefix, const char *external_id, char **ret_path); +int sd_bus_path_encode_many(char **out, const char *path_template, ...); +int sd_bus_path_decode(const char *path, const char *prefix, char **ret_external_id); +int sd_bus_path_decode_many(const char *path, const char *path_template, ...); + +/* Tracking peers */ + +int sd_bus_track_new(sd_bus *bus, sd_bus_track **track, sd_bus_track_handler_t handler, void *userdata); +sd_bus_track* sd_bus_track_ref(sd_bus_track *track); +sd_bus_track* sd_bus_track_unref(sd_bus_track *track); + +sd_bus* sd_bus_track_get_bus(sd_bus_track *track); +void* sd_bus_track_get_userdata(sd_bus_track *track); +void* sd_bus_track_set_userdata(sd_bus_track *track, void *userdata); + +int sd_bus_track_add_sender(sd_bus_track *track, sd_bus_message *m); +int sd_bus_track_remove_sender(sd_bus_track *track, sd_bus_message *m); +int sd_bus_track_add_name(sd_bus_track *track, const char *name); +int sd_bus_track_remove_name(sd_bus_track *track, const char *name); + +int sd_bus_track_set_recursive(sd_bus_track *track, int b); +int sd_bus_track_get_recursive(sd_bus_track *track); + +unsigned sd_bus_track_count(sd_bus_track *track); +int sd_bus_track_count_sender(sd_bus_track *track, sd_bus_message *m); +int sd_bus_track_count_name(sd_bus_track *track, const char *name); + +const char* sd_bus_track_contains(sd_bus_track *track, const char *name); +const char* sd_bus_track_first(sd_bus_track *track); +const char* sd_bus_track_next(sd_bus_track *track); + +int sd_bus_track_set_destroy_callback(sd_bus_track *s, sd_bus_destroy_t callback); +int sd_bus_track_get_destroy_callback(sd_bus_track *s, sd_bus_destroy_t *ret); + +/* Define helpers so that __attribute__((cleanup(sd_bus_unrefp))) and similar may be used. */ +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus, sd_bus_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus, sd_bus_close_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus, sd_bus_flush_close_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus_slot, sd_bus_slot_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus_message, sd_bus_message_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus_creds, sd_bus_creds_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_bus_track, sd_bus_track_unref); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-daemon.h b/thirdparty/systemd/include/systemd/sd-daemon.h new file mode 100644 index 000000000..595b6f337 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-daemon.h @@ -0,0 +1,347 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosddaemonhfoo +#define foosddaemonhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <sys/types.h> +#include <sys/socket.h> + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +/* + The following functionality is provided: + + - Support for logging with log levels on stderr + - File descriptor passing for socket-based activation + - Daemon startup and status notification + - Detection of systemd boots + + See sd-daemon(3) for more information. +*/ + +/* + Log levels for usage on stderr: + + fprintf(stderr, SD_NOTICE "Hello World!\n"); + + This is similar to printk() usage in the kernel. +*/ +#define SD_EMERG "<0>" /* system is unusable */ +#define SD_ALERT "<1>" /* action must be taken immediately */ +#define SD_CRIT "<2>" /* critical conditions */ +#define SD_ERR "<3>" /* error conditions */ +#define SD_WARNING "<4>" /* warning conditions */ +#define SD_NOTICE "<5>" /* normal but significant condition */ +#define SD_INFO "<6>" /* informational */ +#define SD_DEBUG "<7>" /* debug-level messages */ + +/* The first passed file descriptor is fd 3 */ +#define SD_LISTEN_FDS_START 3 + +/* + Returns how many file descriptors have been passed, or a negative + errno code on failure. Optionally, removes the $LISTEN_FDS and + $LISTEN_PID file descriptors from the environment (recommended, but + problematic in threaded environments). If r is the return value of + this function you'll find the file descriptors passed as fds + SD_LISTEN_FDS_START to SD_LISTEN_FDS_START+r-1. Returns a negative + errno style error code on failure. This function call ensures that + the FD_CLOEXEC flag is set for the passed file descriptors, to make + sure they are not passed on to child processes. If FD_CLOEXEC shall + not be set, the caller needs to unset it after this call for all file + descriptors that are used. + + See sd_listen_fds(3) for more information. +*/ +int sd_listen_fds(int unset_environment); + +int sd_listen_fds_with_names(int unset_environment, char ***names); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a FIFO in the file system stored under the + specified path, 0 otherwise. If path is NULL a path name check will + not be done and the call only verifies if the file descriptor + refers to a FIFO. Returns a negative errno style error code on + failure. + + See sd_is_fifo(3) for more information. +*/ +int sd_is_fifo(int fd, const char *path); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a special character device on the file + system stored under the specified path, 0 otherwise. + If path is NULL a path name check will not be done and the call + only verifies if the file descriptor refers to a special character. + Returns a negative errno style error code on failure. + + See sd_is_special(3) for more information. +*/ +int sd_is_special(int fd, const char *path); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a socket of the specified family (AF_INET, + ...) and type (SOCK_DGRAM, SOCK_STREAM, ...), 0 otherwise. If + family is 0 a socket family check will not be done. If type is 0 a + socket type check will not be done and the call only verifies if + the file descriptor refers to a socket. If listening is > 0 it is + verified that the socket is in listening mode. (i.e. listen() has + been called) If listening is == 0 it is verified that the socket is + not in listening mode. If listening is < 0 no listening mode check + is done. Returns a negative errno style error code on failure. + + See sd_is_socket(3) for more information. +*/ +int sd_is_socket(int fd, int family, int type, int listening); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an Internet socket, of the specified family + (either AF_INET or AF_INET6) and the specified type (SOCK_DGRAM, + SOCK_STREAM, ...), 0 otherwise. If version is 0 a protocol version + check is not done. If type is 0 a socket type check will not be + done. If port is 0 a socket port check will not be done. The + listening flag is used the same way as in sd_is_socket(). Returns a + negative errno style error code on failure. + + See sd_is_socket_inet(3) for more information. +*/ +int sd_is_socket_inet(int fd, int family, int type, int listening, uint16_t port); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if the + file descriptor is an Internet socket of the specified type + (SOCK_DGRAM, SOCK_STREAM, ...), and if the address of the socket is + the same as the address specified by addr. The listening flag is used + the same way as in sd_is_socket(). Returns a negative errno style + error code on failure. + + See sd_is_socket_sockaddr(3) for more information. +*/ +int sd_is_socket_sockaddr(int fd, int type, const struct sockaddr* addr, unsigned addr_len, int listening); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is an AF_UNIX socket of the specified type + (SOCK_DGRAM, SOCK_STREAM, ...) and path, 0 otherwise. If type is 0 + a socket type check will not be done. If path is NULL a socket path + check will not be done. For normal AF_UNIX sockets set length to + 0. For abstract namespace sockets set length to the length of the + socket name (including the initial 0 byte), and pass the full + socket path in path (including the initial 0 byte). The listening + flag is used the same way as in sd_is_socket(). Returns a negative + errno style error code on failure. + + See sd_is_socket_unix(3) for more information. +*/ +int sd_is_socket_unix(int fd, int type, int listening, const char *path, size_t length); + +/* + Helper call for identifying a passed file descriptor. Returns 1 if + the file descriptor is a POSIX Message Queue of the specified name, + 0 otherwise. If path is NULL a message queue name check is not + done. Returns a negative errno style error code on failure. + + See sd_is_mq(3) for more information. +*/ +int sd_is_mq(int fd, const char *path); + +/* + Informs systemd about changed daemon state. This takes a number of + newline separated environment-style variable assignments in a + string. The following variables are known: + + MAINPID=... The main PID of a daemon, in case systemd did not + fork off the process itself. Example: "MAINPID=4711" + + READY=1 Tells systemd that daemon startup or daemon reload + is finished (only relevant for services of Type=notify). + The passed argument is a boolean "1" or "0". Since there + is little value in signaling non-readiness the only + value daemons should send is "READY=1". + + RELOADING=1 Tell systemd that the daemon began reloading its + configuration. When the configuration has been + reloaded completely, READY=1 should be sent to inform + systemd about this. + + STOPPING=1 Tells systemd that the daemon is about to go down. + + STATUS=... Passes a single-line status string back to systemd + that describes the daemon state. This is free-form + and can be used for various purposes: general state + feedback, fsck-like programs could pass completion + percentages and failing programs could pass a human + readable error message. Example: "STATUS=Completed + 66% of file system check..." + + NOTIFYACCESS=... + Reset the access to the service status notification socket. + Example: "NOTIFYACCESS=main" + + ERRNO=... If a daemon fails, the errno-style error code, + formatted as string. Example: "ERRNO=2" for ENOENT. + + BUSERROR=... If a daemon fails, the D-Bus error-style error + code. Example: "BUSERROR=org.freedesktop.DBus.Error.TimedOut" + + WATCHDOG=1 Tells systemd to update the watchdog timestamp. + Services using this feature should do this in + regular intervals. A watchdog framework can use the + timestamps to detect failed services. Also see + sd_watchdog_enabled() below. + + WATCHDOG_USEC=... + Reset watchdog_usec value during runtime. + To reset watchdog_usec value, start the service again. + Example: "WATCHDOG_USEC=20000000" + + FDSTORE=1 Store the file descriptors passed along with the + message in the per-service file descriptor store, + and pass them to the main process again on next + invocation. This variable is only supported with + sd_pid_notify_with_fds(). + + FDSTOREREMOVE=1 + Remove one or more file descriptors from the file + descriptor store, identified by the name specified + in FDNAME=, see below. + + FDNAME= A name to assign to new file descriptors stored in the + file descriptor store, or the name of the file descriptors + to remove in case of FDSTOREREMOVE=1. + + Daemons can choose to send additional variables. However, it is + recommended to prefix variable names not listed above with X_. + + Returns a negative errno-style error code on failure. Returns > 0 + if systemd could be notified, 0 if it couldn't possibly because + systemd is not running. + + Example: When a daemon finished starting up, it could issue this + call to notify systemd about it: + + sd_notify(0, "READY=1"); + + See sd_notifyf() for more complete examples. + + See sd_notify(3) for more information. +*/ +int sd_notify(int unset_environment, const char *state); + +/* + Similar to sd_notify() but takes a format string. + + Example 1: A daemon could send the following after initialization: + + sd_notifyf(0, "READY=1\n" + "STATUS=Processing requests...\n" + "MAINPID=%lu", + (unsigned long) getpid()); + + Example 2: A daemon could send the following shortly before + exiting, on failure: + + sd_notifyf(0, "STATUS=Failed to start up: %s\n" + "ERRNO=%i", + strerror_r(errnum, (char[1024]){}, 1024), + errnum); + + See sd_notifyf(3) for more information. +*/ +int sd_notifyf(int unset_environment, const char *format, ...) _sd_printf_(2,3); + +/* + Similar to sd_notify(), but send the message on behalf of another + process, if the appropriate permissions are available. +*/ +int sd_pid_notify(pid_t pid, int unset_environment, const char *state); + +/* + Similar to sd_notifyf(), but send the message on behalf of another + process, if the appropriate permissions are available. +*/ +int sd_pid_notifyf(pid_t pid, int unset_environment, const char *format, ...) _sd_printf_(3,4); + +/* + Similar to sd_pid_notify(), but also passes the specified fd array + to the service manager for storage. This is particularly useful for + FDSTORE=1 messages. +*/ +int sd_pid_notify_with_fds(pid_t pid, int unset_environment, const char *state, const int *fds, unsigned n_fds); + +/* + Combination of sd_pid_notifyf() and sd_pid_notify_with_fds() +*/ +int sd_pid_notifyf_with_fds(pid_t pid, int unset_environment, const int *fds, size_t n_fds, const char *format, ...) _sd_printf_(5,6); + +/* + Returns > 0 if synchronization with systemd succeeded. Returns < 0 + on error. Returns 0 if $NOTIFY_SOCKET was not set. Note that the + timeout parameter of this function call takes the timeout in μs, and + will be passed to ppoll(2), hence the behaviour will be similar to + ppoll(2). This function can be called after sending a status message + to systemd, if one needs to synchronize against reception of the + status messages sent before this call is made. Therefore, this + cannot be used to know if the status message was processed + successfully, but to only synchronize against its consumption. +*/ +int sd_notify_barrier(int unset_environment, uint64_t timeout); + +/* + Just like sd_notify_barrier() but also takes a PID to send the barrier message from. +*/ +int sd_pid_notify_barrier(pid_t pid, int unset_environment, uint64_t timeout); + +/* + Returns > 0 if the system was booted with systemd. Returns < 0 on + error. Returns 0 if the system was not booted with systemd. Note + that all of the functions above handle non-systemd boots just + fine. You should NOT protect them with a call to this function. Also + note that this function checks whether the system, not the user + session is controlled by systemd. However the functions above work + for both user and system services. + + See sd_booted(3) for more information. +*/ +int sd_booted(void); + +/* + Returns > 0 if the service manager expects watchdog keep-alive + events to be sent regularly via sd_notify(0, "WATCHDOG=1"). Returns + 0 if it does not expect this. If the usec argument is non-NULL + returns the watchdog timeout in μs after which the service manager + will act on a process that has not sent a watchdog keep alive + message. This function is useful to implement services that + recognize automatically if they are being run under supervision of + systemd with WatchdogSec= set. It is recommended for clients to + generate keep-alive pings via sd_notify(0, "WATCHDOG=1") every half + of the returned time. + + See sd_watchdog_enabled(3) for more information. +*/ +int sd_watchdog_enabled(int unset_environment, uint64_t *usec); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-device.h b/thirdparty/systemd/include/systemd/sd-device.h new file mode 100644 index 000000000..b67ec0f34 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-device.h @@ -0,0 +1,168 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosddevicehfoo +#define foosddevicehfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <errno.h> +#include <inttypes.h> +#include <sys/stat.h> +#include <sys/sysmacros.h> +#include <sys/types.h> + +#include "sd-event.h" +#include "sd-id128.h" + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +typedef struct sd_device sd_device; +typedef struct sd_device_enumerator sd_device_enumerator; +typedef struct sd_device_monitor sd_device_monitor; + +__extension__ typedef enum sd_device_action_t { + SD_DEVICE_ADD, + SD_DEVICE_REMOVE, + SD_DEVICE_CHANGE, + SD_DEVICE_MOVE, + SD_DEVICE_ONLINE, + SD_DEVICE_OFFLINE, + SD_DEVICE_BIND, + SD_DEVICE_UNBIND, + _SD_DEVICE_ACTION_MAX, + _SD_DEVICE_ACTION_INVALID = -EINVAL, + _SD_ENUM_FORCE_S64(DEVICE_ACTION) +} sd_device_action_t; + +/* callback */ + +typedef int (*sd_device_monitor_handler_t)(sd_device_monitor *m, sd_device *device, void *userdata); + +/* device */ + +sd_device *sd_device_ref(sd_device *device); +sd_device *sd_device_unref(sd_device *device); + +int sd_device_new_from_syspath(sd_device **ret, const char *syspath); +int sd_device_new_from_devnum(sd_device **ret, char type, dev_t devnum); +int sd_device_new_from_subsystem_sysname(sd_device **ret, const char *subsystem, const char *sysname); +int sd_device_new_from_device_id(sd_device **ret, const char *id); +int sd_device_new_from_stat_rdev(sd_device **ret, const struct stat *st); +int sd_device_new_from_devname(sd_device **ret, const char *devname); +int sd_device_new_from_path(sd_device **ret, const char *path); +int sd_device_new_from_ifname(sd_device **ret, const char *ifname); +int sd_device_new_from_ifindex(sd_device **ret, int ifindex); + +int sd_device_new_child(sd_device **ret, sd_device *device, const char *suffix); + +int sd_device_get_parent(sd_device *child, sd_device **ret); +int sd_device_get_parent_with_subsystem_devtype(sd_device *child, const char *subsystem, const char *devtype, sd_device **ret); + +int sd_device_get_syspath(sd_device *device, const char **ret); +int sd_device_get_subsystem(sd_device *device, const char **ret); +int sd_device_get_devtype(sd_device *device, const char **ret); +int sd_device_get_devnum(sd_device *device, dev_t *devnum); +int sd_device_get_ifindex(sd_device *device, int *ifindex); +int sd_device_get_driver(sd_device *device, const char **ret); +int sd_device_get_devpath(sd_device *device, const char **ret); +int sd_device_get_devname(sd_device *device, const char **ret); +int sd_device_get_sysname(sd_device *device, const char **ret); +int sd_device_get_sysnum(sd_device *device, const char **ret); +int sd_device_get_action(sd_device *device, sd_device_action_t *ret); +int sd_device_get_seqnum(sd_device *device, uint64_t *ret); +int sd_device_get_diskseq(sd_device *device, uint64_t *ret); + +int sd_device_get_is_initialized(sd_device *device); +int sd_device_get_usec_initialized(sd_device *device, uint64_t *ret); +int sd_device_get_usec_since_initialized(sd_device *device, uint64_t *ret); + +const char *sd_device_get_tag_first(sd_device *device); +const char *sd_device_get_tag_next(sd_device *device); +const char *sd_device_get_current_tag_first(sd_device *device); +const char *sd_device_get_current_tag_next(sd_device *device); +const char *sd_device_get_devlink_first(sd_device *device); +const char *sd_device_get_devlink_next(sd_device *device); +const char *sd_device_get_property_first(sd_device *device, const char **value); +const char *sd_device_get_property_next(sd_device *device, const char **value); +const char *sd_device_get_sysattr_first(sd_device *device); +const char *sd_device_get_sysattr_next(sd_device *device); +sd_device *sd_device_get_child_first(sd_device *device, const char **ret_suffix); +sd_device *sd_device_get_child_next(sd_device *device, const char **ret_suffix); + +int sd_device_has_tag(sd_device *device, const char *tag); +int sd_device_has_current_tag(sd_device *device, const char *tag); +int sd_device_get_property_value(sd_device *device, const char *key, const char **value); +int sd_device_get_trigger_uuid(sd_device *device, sd_id128_t *ret); +int sd_device_get_sysattr_value(sd_device *device, const char *sysattr, const char **_value); + +int sd_device_set_sysattr_value(sd_device *device, const char *sysattr, const char *value); +int sd_device_set_sysattr_valuef(sd_device *device, const char *sysattr, const char *format, ...) _sd_printf_(3, 4); +int sd_device_trigger(sd_device *device, sd_device_action_t action); +int sd_device_trigger_with_uuid(sd_device *device, sd_device_action_t action, sd_id128_t *ret_uuid); +int sd_device_open(sd_device *device, int flags); + +/* device enumerator */ + +int sd_device_enumerator_new(sd_device_enumerator **ret); +sd_device_enumerator *sd_device_enumerator_ref(sd_device_enumerator *enumerator); +sd_device_enumerator *sd_device_enumerator_unref(sd_device_enumerator *enumerator); + +sd_device *sd_device_enumerator_get_device_first(sd_device_enumerator *enumerator); +sd_device *sd_device_enumerator_get_device_next(sd_device_enumerator *enumerator); +sd_device *sd_device_enumerator_get_subsystem_first(sd_device_enumerator *enumerator); +sd_device *sd_device_enumerator_get_subsystem_next(sd_device_enumerator *enumerator); + +int sd_device_enumerator_add_match_subsystem(sd_device_enumerator *enumerator, const char *subsystem, int match); +int sd_device_enumerator_add_match_sysattr(sd_device_enumerator *enumerator, const char *sysattr, const char *value, int match); +int sd_device_enumerator_add_match_property(sd_device_enumerator *enumerator, const char *property, const char *value); +int sd_device_enumerator_add_match_property_required(sd_device_enumerator *enumerator, const char *property, const char *value); +int sd_device_enumerator_add_match_sysname(sd_device_enumerator *enumerator, const char *sysname); +int sd_device_enumerator_add_nomatch_sysname(sd_device_enumerator *enumerator, const char *sysname); +int sd_device_enumerator_add_match_tag(sd_device_enumerator *enumerator, const char *tag); +int sd_device_enumerator_add_match_parent(sd_device_enumerator *enumerator, sd_device *parent); +int sd_device_enumerator_allow_uninitialized(sd_device_enumerator *enumerator); + +/* device monitor */ + +int sd_device_monitor_new(sd_device_monitor **ret); +sd_device_monitor *sd_device_monitor_ref(sd_device_monitor *m); +sd_device_monitor *sd_device_monitor_unref(sd_device_monitor *m); + +int sd_device_monitor_set_receive_buffer_size(sd_device_monitor *m, size_t size); +int sd_device_monitor_attach_event(sd_device_monitor *m, sd_event *event); +int sd_device_monitor_detach_event(sd_device_monitor *m); +sd_event *sd_device_monitor_get_event(sd_device_monitor *m); +sd_event_source *sd_device_monitor_get_event_source(sd_device_monitor *m); +int sd_device_monitor_set_description(sd_device_monitor *m, const char *description); +int sd_device_monitor_get_description(sd_device_monitor *m, const char **ret); +int sd_device_monitor_start(sd_device_monitor *m, sd_device_monitor_handler_t callback, void *userdata); +int sd_device_monitor_stop(sd_device_monitor *m); + +int sd_device_monitor_filter_add_match_subsystem_devtype(sd_device_monitor *m, const char *subsystem, const char *devtype); +int sd_device_monitor_filter_add_match_tag(sd_device_monitor *m, const char *tag); +int sd_device_monitor_filter_add_match_sysattr(sd_device_monitor *m, const char *sysattr, const char *value, int match); +int sd_device_monitor_filter_add_match_parent(sd_device_monitor *m, sd_device *device, int match); +int sd_device_monitor_filter_update(sd_device_monitor *m); +int sd_device_monitor_filter_remove(sd_device_monitor *m); + +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_device, sd_device_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_device_enumerator, sd_device_enumerator_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_device_monitor, sd_device_monitor_unref); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-event.h b/thirdparty/systemd/include/systemd/sd-event.h new file mode 100644 index 000000000..a876add00 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-event.h @@ -0,0 +1,188 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdeventhfoo +#define foosdeventhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <signal.h> +#include <sys/epoll.h> +#include <sys/inotify.h> +#include <sys/signalfd.h> +#include <sys/types.h> +#include <sys/wait.h> +#include <time.h> + +#include "_sd-common.h" + +/* + Why is this better than pure epoll? + + - Supports event source prioritization + - Scales better with a large number of time events because it does not require one timerfd each + - Automatically tries to coalesce timer events system-wide + - Handles signals, child PIDs, inotify events + - Supports systemd-style automatic watchdog event generation +*/ + +_SD_BEGIN_DECLARATIONS; + +#define SD_EVENT_DEFAULT ((sd_event *) 1) + +typedef struct sd_event sd_event; +typedef struct sd_event_source sd_event_source; + +enum { + SD_EVENT_OFF = 0, + SD_EVENT_ON = 1, + SD_EVENT_ONESHOT = -1 +}; + +enum { + SD_EVENT_INITIAL, + SD_EVENT_ARMED, + SD_EVENT_PENDING, + SD_EVENT_RUNNING, + SD_EVENT_EXITING, + SD_EVENT_FINISHED, + SD_EVENT_PREPARING +}; + +enum { + /* And everything in-between and outside is good too */ + SD_EVENT_PRIORITY_IMPORTANT = -100, + SD_EVENT_PRIORITY_NORMAL = 0, + SD_EVENT_PRIORITY_IDLE = 100 +}; + +#define SD_EVENT_SIGNAL_PROCMASK (1 << 30) + +typedef int (*sd_event_handler_t)(sd_event_source *s, void *userdata); +typedef int (*sd_event_io_handler_t)(sd_event_source *s, int fd, uint32_t revents, void *userdata); +typedef int (*sd_event_time_handler_t)(sd_event_source *s, uint64_t usec, void *userdata); +typedef int (*sd_event_signal_handler_t)(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata); +#if defined _GNU_SOURCE || (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 199309L) +typedef int (*sd_event_child_handler_t)(sd_event_source *s, const siginfo_t *si, void *userdata); +#else +typedef void* sd_event_child_handler_t; +#endif +typedef int (*sd_event_inotify_handler_t)(sd_event_source *s, const struct inotify_event *event, void *userdata); +typedef _sd_destroy_t sd_event_destroy_t; + +int sd_event_default(sd_event **e); + +int sd_event_new(sd_event **e); +sd_event* sd_event_ref(sd_event *e); +sd_event* sd_event_unref(sd_event *e); + +int sd_event_add_io(sd_event *e, sd_event_source **s, int fd, uint32_t events, sd_event_io_handler_t callback, void *userdata); +int sd_event_add_time(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); +int sd_event_add_time_relative(sd_event *e, sd_event_source **s, clockid_t clock, uint64_t usec, uint64_t accuracy, sd_event_time_handler_t callback, void *userdata); +int sd_event_add_signal(sd_event *e, sd_event_source **s, int sig, sd_event_signal_handler_t callback, void *userdata); +int sd_event_add_child(sd_event *e, sd_event_source **s, pid_t pid, int options, sd_event_child_handler_t callback, void *userdata); +int sd_event_add_child_pidfd(sd_event *e, sd_event_source **s, int pidfd, int options, sd_event_child_handler_t callback, void *userdata); +int sd_event_add_inotify(sd_event *e, sd_event_source **s, const char *path, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); +int sd_event_add_inotify_fd(sd_event *e, sd_event_source **s, int fd, uint32_t mask, sd_event_inotify_handler_t callback, void *userdata); +int sd_event_add_defer(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); +int sd_event_add_post(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); +int sd_event_add_exit(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); +int sd_event_add_memory_pressure(sd_event *e, sd_event_source **s, sd_event_handler_t callback, void *userdata); + +int sd_event_prepare(sd_event *e); +int sd_event_wait(sd_event *e, uint64_t usec); +int sd_event_dispatch(sd_event *e); +int sd_event_run(sd_event *e, uint64_t usec); +int sd_event_loop(sd_event *e); +int sd_event_exit(sd_event *e, int code); + +int sd_event_now(sd_event *e, clockid_t clock, uint64_t *usec); + +int sd_event_get_fd(sd_event *e); +int sd_event_get_state(sd_event *e); +int sd_event_get_tid(sd_event *e, pid_t *tid); +int sd_event_get_exit_code(sd_event *e, int *code); +int sd_event_set_watchdog(sd_event *e, int b); +int sd_event_get_watchdog(sd_event *e); +int sd_event_get_iteration(sd_event *e, uint64_t *ret); +int sd_event_set_signal_exit(sd_event *e, int b); + +sd_event_source* sd_event_source_ref(sd_event_source *s); +sd_event_source* sd_event_source_unref(sd_event_source *s); +sd_event_source* sd_event_source_disable_unref(sd_event_source *s); + +sd_event *sd_event_source_get_event(sd_event_source *s); +void* sd_event_source_get_userdata(sd_event_source *s); +void* sd_event_source_set_userdata(sd_event_source *s, void *userdata); + +int sd_event_source_set_description(sd_event_source *s, const char *description); +int sd_event_source_get_description(sd_event_source *s, const char **description); +int sd_event_source_set_prepare(sd_event_source *s, sd_event_handler_t callback); +int sd_event_source_get_pending(sd_event_source *s); +int sd_event_source_get_priority(sd_event_source *s, int64_t *priority); +int sd_event_source_set_priority(sd_event_source *s, int64_t priority); +int sd_event_source_get_enabled(sd_event_source *s, int *enabled); +int sd_event_source_set_enabled(sd_event_source *s, int enabled); +int sd_event_source_get_io_fd(sd_event_source *s); +int sd_event_source_set_io_fd(sd_event_source *s, int fd); +int sd_event_source_get_io_fd_own(sd_event_source *s); +int sd_event_source_set_io_fd_own(sd_event_source *s, int own); +int sd_event_source_get_io_events(sd_event_source *s, uint32_t* events); +int sd_event_source_set_io_events(sd_event_source *s, uint32_t events); +int sd_event_source_get_io_revents(sd_event_source *s, uint32_t* revents); +int sd_event_source_get_time(sd_event_source *s, uint64_t *usec); +int sd_event_source_set_time(sd_event_source *s, uint64_t usec); +int sd_event_source_set_time_relative(sd_event_source *s, uint64_t usec); +int sd_event_source_get_time_accuracy(sd_event_source *s, uint64_t *usec); +int sd_event_source_set_time_accuracy(sd_event_source *s, uint64_t usec); +int sd_event_source_get_time_clock(sd_event_source *s, clockid_t *clock); +int sd_event_source_get_signal(sd_event_source *s); +int sd_event_source_get_child_pid(sd_event_source *s, pid_t *pid); +int sd_event_source_get_child_pidfd(sd_event_source *s); +int sd_event_source_get_child_pidfd_own(sd_event_source *s); +int sd_event_source_set_child_pidfd_own(sd_event_source *s, int own); +int sd_event_source_get_child_process_own(sd_event_source *s); +int sd_event_source_set_child_process_own(sd_event_source *s, int own); +#if defined _GNU_SOURCE || (defined _POSIX_C_SOURCE && _POSIX_C_SOURCE >= 199309L) +int sd_event_source_send_child_signal(sd_event_source *s, int sig, const siginfo_t *si, unsigned flags); +#else +int sd_event_source_send_child_signal(sd_event_source *s, int sig, const void *si, unsigned flags); +#endif +int sd_event_source_get_inotify_mask(sd_event_source *s, uint32_t *ret); +int sd_event_source_get_inotify_path(sd_event_source *s, const char **ret); +int sd_event_source_set_memory_pressure_type(sd_event_source *e, const char *ty); +int sd_event_source_set_memory_pressure_period(sd_event_source *s, uint64_t threshold_usec, uint64_t window_usec); +int sd_event_source_set_destroy_callback(sd_event_source *s, sd_event_destroy_t callback); +int sd_event_source_get_destroy_callback(sd_event_source *s, sd_event_destroy_t *ret); +int sd_event_source_get_floating(sd_event_source *s); +int sd_event_source_set_floating(sd_event_source *s, int b); +int sd_event_source_get_exit_on_failure(sd_event_source *s); +int sd_event_source_set_exit_on_failure(sd_event_source *s, int b); +int sd_event_source_set_ratelimit(sd_event_source *s, uint64_t interval_usec, unsigned burst); +int sd_event_source_get_ratelimit(sd_event_source *s, uint64_t *ret_interval_usec, unsigned *ret_burst); +int sd_event_source_is_ratelimited(sd_event_source *s); +int sd_event_source_set_ratelimit_expire_callback(sd_event_source *s, sd_event_handler_t callback); +int sd_event_source_leave_ratelimit(sd_event_source *s); + +int sd_event_trim_memory(void); + +/* Define helpers so that __attribute__((cleanup(sd_event_unrefp))) and similar may be used. */ +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event, sd_event_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event_source, sd_event_source_unref); +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_event_source, sd_event_source_disable_unref); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-gpt.h b/thirdparty/systemd/include/systemd/sd-gpt.h new file mode 100644 index 000000000..7ffa57a94 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-gpt.h @@ -0,0 +1,369 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdgpthfoo +#define foosdgpthfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include "sd-id128.h" + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +#define SD_GPT_ROOT_ALPHA SD_ID128_MAKE(65,23,f8,ae,3e,b1,4e,2a,a0,5a,18,b6,95,ae,65,6f) +#define SD_GPT_ROOT_ARC SD_ID128_MAKE(d2,7f,46,ed,29,19,4c,b8,bd,25,95,31,f3,c1,65,34) +#define SD_GPT_ROOT_ARM SD_ID128_MAKE(69,da,d7,10,2c,e4,4e,3c,b1,6c,21,a1,d4,9a,be,d3) +#define SD_GPT_ROOT_ARM64 SD_ID128_MAKE(b9,21,b0,45,1d,f0,41,c3,af,44,4c,6f,28,0d,3f,ae) +#define SD_GPT_ROOT_IA64 SD_ID128_MAKE(99,3d,8d,3d,f8,0e,42,25,85,5a,9d,af,8e,d7,ea,97) +#define SD_GPT_ROOT_LOONGARCH64 SD_ID128_MAKE(77,05,58,00,79,2c,4f,94,b3,9a,98,c9,1b,76,2b,b6) +#define SD_GPT_ROOT_MIPS SD_ID128_MAKE(e9,43,45,44,6e,2c,47,cc,ba,e2,12,d6,de,af,b4,4c) +#define SD_GPT_ROOT_MIPS64 SD_ID128_MAKE(d1,13,af,76,80,ef,41,b4,bd,b6,0c,ff,4d,3d,4a,25) +#define SD_GPT_ROOT_MIPS_LE SD_ID128_MAKE(37,c5,8c,8a,d9,13,41,56,a2,5f,48,b1,b6,4e,07,f0) +#define SD_GPT_ROOT_MIPS64_LE SD_ID128_MAKE(70,0b,da,43,7a,34,45,07,b1,79,ee,b9,3d,7a,7c,a3) +#define SD_GPT_ROOT_PARISC SD_ID128_MAKE(1a,ac,db,3b,54,44,41,38,bd,9e,e5,c2,23,9b,23,46) +#define SD_GPT_ROOT_PPC SD_ID128_MAKE(1d,e3,f1,ef,fa,98,47,b5,8d,cd,4a,86,0a,65,4d,78) +#define SD_GPT_ROOT_PPC64 SD_ID128_MAKE(91,2a,de,1d,a8,39,49,13,89,64,a1,0e,ee,08,fb,d2) +#define SD_GPT_ROOT_PPC64_LE SD_ID128_MAKE(c3,1c,45,e6,3f,39,41,2e,80,fb,48,09,c4,98,05,99) +#define SD_GPT_ROOT_RISCV32 SD_ID128_MAKE(60,d5,a7,fe,8e,7d,43,5c,b7,14,3d,d8,16,21,44,e1) +#define SD_GPT_ROOT_RISCV64 SD_ID128_MAKE(72,ec,70,a6,cf,74,40,e6,bd,49,4b,da,08,e8,f2,24) +#define SD_GPT_ROOT_S390 SD_ID128_MAKE(08,a7,ac,ea,62,4c,4a,20,91,e8,6e,0f,a6,7d,23,f9) +#define SD_GPT_ROOT_S390X SD_ID128_MAKE(5e,ea,d9,a9,fe,09,4a,1e,a1,d7,52,0d,00,53,13,06) +#define SD_GPT_ROOT_TILEGX SD_ID128_MAKE(c5,0c,dd,70,38,62,4c,c3,90,e1,80,9a,8c,93,ee,2c) +#define SD_GPT_ROOT_X86 SD_ID128_MAKE(44,47,95,40,f2,97,41,b2,9a,f7,d1,31,d5,f0,45,8a) +#define SD_GPT_ROOT_X86_64 SD_ID128_MAKE(4f,68,bc,e3,e8,cd,4d,b1,96,e7,fb,ca,f9,84,b7,09) +#define SD_GPT_USR_ALPHA SD_ID128_MAKE(e1,8c,f0,8c,33,ec,4c,0d,82,46,c6,c6,fb,3d,a0,24) +#define SD_GPT_USR_ARC SD_ID128_MAKE(79,78,a6,83,63,16,49,22,bb,ee,38,bf,f5,a2,fe,cc) +#define SD_GPT_USR_ARM SD_ID128_MAKE(7d,03,59,a3,02,b3,4f,0a,86,5c,65,44,03,e7,06,25) +#define SD_GPT_USR_ARM64 SD_ID128_MAKE(b0,e0,10,50,ee,5f,43,90,94,9a,91,01,b1,71,04,e9) +#define SD_GPT_USR_IA64 SD_ID128_MAKE(43,01,d2,a6,4e,3b,4b,2a,bb,94,9e,0b,2c,42,25,ea) +#define SD_GPT_USR_LOONGARCH64 SD_ID128_MAKE(e6,11,c7,02,57,5c,4c,be,9a,46,43,4f,a0,bf,7e,3f) +#define SD_GPT_USR_MIPS SD_ID128_MAKE(77,3b,2a,bc,2a,99,43,98,8b,f5,03,ba,ac,40,d0,2b) +#define SD_GPT_USR_MIPS64 SD_ID128_MAKE(57,e1,39,58,73,31,43,65,8e,6e,35,ee,ee,17,c6,1b) +#define SD_GPT_USR_MIPS_LE SD_ID128_MAKE(0f,48,68,e9,99,52,47,06,97,9f,3e,d3,a4,73,e9,47) +#define SD_GPT_USR_MIPS64_LE SD_ID128_MAKE(c9,7c,1f,32,ba,06,40,b4,9f,22,23,60,61,b0,8a,a8) +#define SD_GPT_USR_PARISC SD_ID128_MAKE(dc,4a,44,80,69,17,42,62,a4,ec,db,93,84,94,9f,25) +#define SD_GPT_USR_PPC SD_ID128_MAKE(7d,14,fe,c5,cc,71,41,5d,9d,6c,06,bf,0b,3c,3e,af) +#define SD_GPT_USR_PPC64 SD_ID128_MAKE(2c,97,39,e2,f0,68,46,b3,9f,d0,01,c5,a9,af,bc,ca) +#define SD_GPT_USR_PPC64_LE SD_ID128_MAKE(15,bb,03,af,77,e7,4d,4a,b1,2b,c0,d0,84,f7,49,1c) +#define SD_GPT_USR_RISCV32 SD_ID128_MAKE(b9,33,fb,22,5c,3f,4f,91,af,90,e2,bb,0f,a5,07,02) +#define SD_GPT_USR_RISCV64 SD_ID128_MAKE(be,ae,c3,4b,84,42,43,9b,a4,0b,98,43,81,ed,09,7d) +#define SD_GPT_USR_S390 SD_ID128_MAKE(cd,0f,86,9b,d0,fb,4c,a0,b1,41,9e,a8,7c,c7,8d,66) +#define SD_GPT_USR_S390X SD_ID128_MAKE(8a,4f,57,70,50,aa,4e,d3,87,4a,99,b7,10,db,6f,ea) +#define SD_GPT_USR_TILEGX SD_ID128_MAKE(55,49,70,29,c7,c1,44,cc,aa,39,81,5e,d1,55,86,30) +#define SD_GPT_USR_X86 SD_ID128_MAKE(75,25,0d,76,8c,c6,45,8e,bd,66,bd,47,cc,81,a8,12) +#define SD_GPT_USR_X86_64 SD_ID128_MAKE(84,84,68,0c,95,21,48,c6,9c,11,b0,72,06,56,f6,9e) + +/* Verity partitions for the root partitions above (we only define them for the root and /usr partitions, + * because only they are commonly read-only and hence suitable for verity). */ +#define SD_GPT_ROOT_ALPHA_VERITY SD_ID128_MAKE(fc,56,d9,e9,e6,e5,4c,06,be,32,e7,44,07,ce,09,a5) +#define SD_GPT_ROOT_ARC_VERITY SD_ID128_MAKE(24,b2,d9,75,0f,97,45,21,af,a1,cd,53,1e,42,1b,8d) +#define SD_GPT_ROOT_ARM_VERITY SD_ID128_MAKE(73,86,cd,f2,20,3c,47,a9,a4,98,f2,ec,ce,45,a2,d6) +#define SD_GPT_ROOT_ARM64_VERITY SD_ID128_MAKE(df,33,00,ce,d6,9f,4c,92,97,8c,9b,fb,0f,38,d8,20) +#define SD_GPT_ROOT_IA64_VERITY SD_ID128_MAKE(86,ed,10,d5,b6,07,45,bb,89,57,d3,50,f2,3d,05,71) +#define SD_GPT_ROOT_LOONGARCH64_VERITY SD_ID128_MAKE(f3,39,3b,22,e9,af,46,13,a9,48,9d,3b,fb,d0,c5,35) +#define SD_GPT_ROOT_MIPS_VERITY SD_ID128_MAKE(7a,43,07,99,f7,11,4c,7e,8e,5b,1d,68,5b,d4,86,07) +#define SD_GPT_ROOT_MIPS64_VERITY SD_ID128_MAKE(57,95,36,f8,6a,33,40,55,a9,5a,df,2d,5e,2c,42,a8) +#define SD_GPT_ROOT_MIPS_LE_VERITY SD_ID128_MAKE(d7,d1,50,d2,2a,04,4a,33,8f,12,16,65,12,05,ff,7b) +#define SD_GPT_ROOT_MIPS64_LE_VERITY SD_ID128_MAKE(16,b4,17,f8,3e,06,4f,57,8d,d2,9b,52,32,f4,1a,a6) +#define SD_GPT_ROOT_PARISC_VERITY SD_ID128_MAKE(d2,12,a4,30,fb,c5,49,f9,a9,83,a7,fe,ef,2b,8d,0e) +#define SD_GPT_ROOT_PPC64_LE_VERITY SD_ID128_MAKE(90,6b,d9,44,45,89,4a,ae,a4,e4,dd,98,39,17,44,6a) +#define SD_GPT_ROOT_PPC64_VERITY SD_ID128_MAKE(92,25,a9,a3,3c,19,4d,89,b4,f6,ee,ff,88,f1,76,31) +#define SD_GPT_ROOT_PPC_VERITY SD_ID128_MAKE(98,cf,e6,49,15,88,46,dc,b2,f0,ad,d1,47,42,49,25) +#define SD_GPT_ROOT_RISCV32_VERITY SD_ID128_MAKE(ae,02,53,be,11,67,40,07,ac,68,43,92,6c,14,c5,de) +#define SD_GPT_ROOT_RISCV64_VERITY SD_ID128_MAKE(b6,ed,55,82,44,0b,42,09,b8,da,5f,f7,c4,19,ea,3d) +#define SD_GPT_ROOT_S390_VERITY SD_ID128_MAKE(7a,c6,3b,47,b2,5c,46,3b,8d,f8,b4,a9,4e,6c,90,e1) +#define SD_GPT_ROOT_S390X_VERITY SD_ID128_MAKE(b3,25,bf,be,c7,be,4a,b8,83,57,13,9e,65,2d,2f,6b) +#define SD_GPT_ROOT_TILEGX_VERITY SD_ID128_MAKE(96,60,61,ec,28,e4,4b,2e,b4,a5,1f,0a,82,5a,1d,84) +#define SD_GPT_ROOT_X86_64_VERITY SD_ID128_MAKE(2c,73,57,ed,eb,d2,46,d9,ae,c1,23,d4,37,ec,2b,f5) +#define SD_GPT_ROOT_X86_VERITY SD_ID128_MAKE(d1,3c,5d,3b,b5,d1,42,2a,b2,9f,94,54,fd,c8,9d,76) +#define SD_GPT_USR_ALPHA_VERITY SD_ID128_MAKE(8c,ce,0d,25,c0,d0,4a,44,bd,87,46,33,1b,f1,df,67) +#define SD_GPT_USR_ARC_VERITY SD_ID128_MAKE(fc,a0,59,8c,d8,80,45,91,8c,16,4e,da,05,c7,34,7c) +#define SD_GPT_USR_ARM_VERITY SD_ID128_MAKE(c2,15,d7,51,7b,cd,46,49,be,90,66,27,49,0a,4c,05) +#define SD_GPT_USR_ARM64_VERITY SD_ID128_MAKE(6e,11,a4,e7,fb,ca,4d,ed,b9,e9,e1,a5,12,bb,66,4e) +#define SD_GPT_USR_IA64_VERITY SD_ID128_MAKE(6a,49,1e,03,3b,e7,45,45,8e,38,83,32,0e,0e,a8,80) +#define SD_GPT_USR_LOONGARCH64_VERITY SD_ID128_MAKE(f4,6b,2c,26,59,ae,48,f0,91,06,c5,0e,d4,7f,67,3d) +#define SD_GPT_USR_MIPS_VERITY SD_ID128_MAKE(6e,5a,1b,c8,d2,23,49,b7,bc,a8,37,a5,fc,ce,b9,96) +#define SD_GPT_USR_MIPS64_VERITY SD_ID128_MAKE(81,cf,9d,90,74,58,4d,f4,8d,cf,c8,a3,a4,04,f0,9b) +#define SD_GPT_USR_MIPS_LE_VERITY SD_ID128_MAKE(46,b9,8d,8d,b5,5c,4e,8f,aa,b3,37,fc,a7,f8,07,52) +#define SD_GPT_USR_MIPS64_LE_VERITY SD_ID128_MAKE(3c,3d,61,fe,b5,f3,41,4d,bb,71,87,39,a6,94,a4,ef) +#define SD_GPT_USR_PARISC_VERITY SD_ID128_MAKE(58,43,d6,18,ec,37,48,d7,9f,12,ce,a8,e0,87,68,b2) +#define SD_GPT_USR_PPC64_LE_VERITY SD_ID128_MAKE(ee,2b,99,83,21,e8,41,53,86,d9,b6,90,1a,54,d1,ce) +#define SD_GPT_USR_PPC64_VERITY SD_ID128_MAKE(bd,b5,28,a5,a2,59,47,5f,a8,7d,da,53,fa,73,6a,07) +#define SD_GPT_USR_PPC_VERITY SD_ID128_MAKE(df,76,5d,00,27,0e,49,e5,bc,75,f4,7b,b2,11,8b,09) +#define SD_GPT_USR_RISCV32_VERITY SD_ID128_MAKE(cb,1e,e4,e3,8c,d0,41,36,a0,a4,aa,61,a3,2e,87,30) +#define SD_GPT_USR_RISCV64_VERITY SD_ID128_MAKE(8f,10,56,be,9b,05,47,c4,81,d6,be,53,12,8e,5b,54) +#define SD_GPT_USR_S390_VERITY SD_ID128_MAKE(b6,63,c6,18,e7,bc,4d,6d,90,aa,11,b7,56,bb,17,97) +#define SD_GPT_USR_S390X_VERITY SD_ID128_MAKE(31,74,1c,c4,1a,2a,41,11,a5,81,e0,0b,44,7d,2d,06) +#define SD_GPT_USR_TILEGX_VERITY SD_ID128_MAKE(2f,b4,bf,56,07,fa,42,da,81,32,6b,13,9f,20,26,ae) +#define SD_GPT_USR_X86_64_VERITY SD_ID128_MAKE(77,ff,5f,63,e7,b6,46,33,ac,f4,15,65,b8,64,c0,e6) +#define SD_GPT_USR_X86_VERITY SD_ID128_MAKE(8f,46,1b,0d,14,ee,4e,81,9a,a9,04,9b,6f,b9,7a,bd) + +/* PKCS#7 Signatures for the Verity Root Hashes */ +#define SD_GPT_ROOT_ALPHA_VERITY_SIG SD_ID128_MAKE(d4,64,95,b7,a0,53,41,4f,80,f7,70,0c,99,92,1e,f8) +#define SD_GPT_ROOT_ARC_VERITY_SIG SD_ID128_MAKE(14,3a,70,ba,cb,d3,4f,06,91,9f,6c,05,68,3a,78,bc) +#define SD_GPT_ROOT_ARM_VERITY_SIG SD_ID128_MAKE(42,b0,45,5f,eb,11,49,1d,98,d3,56,14,5b,a9,d0,37) +#define SD_GPT_ROOT_ARM64_VERITY_SIG SD_ID128_MAKE(6d,b6,9d,e6,29,f4,47,58,a7,a5,96,21,90,f0,0c,e3) +#define SD_GPT_ROOT_IA64_VERITY_SIG SD_ID128_MAKE(e9,8b,36,ee,32,ba,48,82,9b,12,0c,e1,46,55,f4,6a) +#define SD_GPT_ROOT_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(5a,fb,67,eb,ec,c8,4f,85,ae,8e,ac,1e,7c,50,e7,d0) +#define SD_GPT_ROOT_MIPS_VERITY_SIG SD_ID128_MAKE(bb,a2,10,a2,9c,5d,45,ee,9e,87,ff,2c,cb,d0,02,d0) +#define SD_GPT_ROOT_MIPS64_VERITY_SIG SD_ID128_MAKE(43,ce,94,d4,0f,3d,49,99,82,50,b9,de,af,d9,8e,6e) +#define SD_GPT_ROOT_MIPS_LE_VERITY_SIG SD_ID128_MAKE(c9,19,cc,1f,44,56,4e,ff,91,8c,f7,5e,94,52,5c,a5) +#define SD_GPT_ROOT_MIPS64_LE_VERITY_SIG SD_ID128_MAKE(90,4e,58,ef,5c,65,4a,31,9c,57,6a,f5,fc,7c,5d,e7) +#define SD_GPT_ROOT_PARISC_VERITY_SIG SD_ID128_MAKE(15,de,61,70,65,d3,43,1c,91,6e,b0,dc,d8,39,3f,25) +#define SD_GPT_ROOT_PPC64_LE_VERITY_SIG SD_ID128_MAKE(d4,a2,36,e7,e8,73,4c,07,bf,1d,bf,6c,f7,f1,c3,c6) +#define SD_GPT_ROOT_PPC64_VERITY_SIG SD_ID128_MAKE(f5,e2,c2,0c,45,b2,4f,fa,bc,e9,2a,60,73,7e,1a,af) +#define SD_GPT_ROOT_PPC_VERITY_SIG SD_ID128_MAKE(1b,31,b5,aa,ad,d9,46,3a,b2,ed,bd,46,7f,c8,57,e7) +#define SD_GPT_ROOT_RISCV32_VERITY_SIG SD_ID128_MAKE(3a,11,2a,75,87,29,43,80,b4,cf,76,4d,79,93,44,48) +#define SD_GPT_ROOT_RISCV64_VERITY_SIG SD_ID128_MAKE(ef,e0,f0,87,ea,8d,44,69,82,1a,4c,2a,96,a8,38,6a) +#define SD_GPT_ROOT_S390_VERITY_SIG SD_ID128_MAKE(34,82,38,8e,42,54,43,5a,a2,41,76,6a,06,5f,99,60) +#define SD_GPT_ROOT_S390X_VERITY_SIG SD_ID128_MAKE(c8,01,87,a5,73,a3,49,1a,90,1a,01,7c,3f,a9,53,e9) +#define SD_GPT_ROOT_TILEGX_VERITY_SIG SD_ID128_MAKE(b3,67,14,39,97,b0,4a,53,90,f7,2d,5a,8f,3a,d4,7b) +#define SD_GPT_ROOT_X86_64_VERITY_SIG SD_ID128_MAKE(41,09,2b,05,9f,c8,45,23,99,4f,2d,ef,04,08,b1,76) +#define SD_GPT_ROOT_X86_VERITY_SIG SD_ID128_MAKE(59,96,fc,05,10,9c,48,de,80,8b,23,fa,08,30,b6,76) +#define SD_GPT_USR_ALPHA_VERITY_SIG SD_ID128_MAKE(5c,6e,1c,76,07,6a,45,7a,a0,fe,f3,b4,cd,21,ce,6e) +#define SD_GPT_USR_ARC_VERITY_SIG SD_ID128_MAKE(94,f9,a9,a1,99,71,42,7a,a4,00,50,cb,29,7f,0f,35) +#define SD_GPT_USR_ARM_VERITY_SIG SD_ID128_MAKE(d7,ff,81,2f,37,d1,49,02,a8,10,d7,6b,a5,7b,97,5a) +#define SD_GPT_USR_ARM64_VERITY_SIG SD_ID128_MAKE(c2,3c,e4,ff,44,bd,4b,00,b2,d4,b4,1b,34,19,e0,2a) +#define SD_GPT_USR_IA64_VERITY_SIG SD_ID128_MAKE(8d,e5,8b,c2,2a,43,46,0d,b1,4e,a7,6e,4a,17,b4,7f) +#define SD_GPT_USR_LOONGARCH64_VERITY_SIG SD_ID128_MAKE(b0,24,f3,15,d3,30,44,4c,84,61,44,bb,de,52,4e,99) +#define SD_GPT_USR_MIPS_VERITY_SIG SD_ID128_MAKE(97,ae,15,8d,f2,16,49,7b,80,57,f7,f9,05,77,0f,54) +#define SD_GPT_USR_MIPS64_VERITY_SIG SD_ID128_MAKE(05,81,6c,e2,dd,40,4a,c6,a6,1d,37,d3,2d,c1,ba,7d) +#define SD_GPT_USR_MIPS_LE_VERITY_SIG SD_ID128_MAKE(3e,23,ca,0b,a4,bc,4b,4e,80,87,5a,b6,a2,6a,a8,a9) +#define SD_GPT_USR_MIPS64_LE_VERITY_SIG SD_ID128_MAKE(f2,c2,c7,ee,ad,cc,43,51,b5,c6,ee,98,16,b6,6e,16) +#define SD_GPT_USR_PARISC_VERITY_SIG SD_ID128_MAKE(45,0d,d7,d1,32,24,45,ec,9c,f2,a4,3a,34,6d,71,ee) +#define SD_GPT_USR_PPC64_LE_VERITY_SIG SD_ID128_MAKE(c8,bf,bd,1e,26,8e,45,21,8b,ba,bf,31,4c,39,95,57) +#define SD_GPT_USR_PPC64_VERITY_SIG SD_ID128_MAKE(0b,88,88,63,d7,f8,4d,9e,97,66,23,9f,ce,4d,58,af) +#define SD_GPT_USR_PPC_VERITY_SIG SD_ID128_MAKE(70,07,89,1d,d3,71,4a,80,86,a4,5c,b8,75,b9,30,2e) +#define SD_GPT_USR_RISCV32_VERITY_SIG SD_ID128_MAKE(c3,83,6a,13,31,37,45,ba,b5,83,b1,6c,50,fe,5e,b4) +#define SD_GPT_USR_RISCV64_VERITY_SIG SD_ID128_MAKE(d2,f9,00,0a,7a,18,45,3f,b5,cd,4d,32,f7,7a,7b,32) +#define SD_GPT_USR_S390_VERITY_SIG SD_ID128_MAKE(17,44,0e,4f,a8,d0,46,7f,a4,6e,39,12,ae,6e,f2,c5) +#define SD_GPT_USR_S390X_VERITY_SIG SD_ID128_MAKE(3f,32,48,16,66,7b,46,ae,86,ee,9b,0c,0c,6c,11,b4) +#define SD_GPT_USR_TILEGX_VERITY_SIG SD_ID128_MAKE(4e,de,75,e2,6c,cc,4c,c8,b9,c7,70,33,4b,08,75,10) +#define SD_GPT_USR_X86_64_VERITY_SIG SD_ID128_MAKE(e7,bb,33,fb,06,cf,4e,81,82,73,e5,43,b4,13,e2,e2) +#define SD_GPT_USR_X86_VERITY_SIG SD_ID128_MAKE(97,4a,71,c0,de,41,43,c3,be,5d,5c,5c,cd,1a,d2,c0) + +#define SD_GPT_ESP SD_ID128_MAKE(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b) +#define SD_GPT_ESP_STR SD_ID128_MAKE_UUID_STR(c1,2a,73,28,f8,1f,11,d2,ba,4b,00,a0,c9,3e,c9,3b) +#define SD_GPT_XBOOTLDR SD_ID128_MAKE(bc,13,c2,ff,59,e6,42,62,a3,52,b2,75,fd,6f,71,72) +#define SD_GPT_XBOOTLDR_STR SD_ID128_MAKE_UUID_STR(bc,13,c2,ff,59,e6,42,62,a3,52,b2,75,fd,6f,71,72) +#define SD_GPT_SWAP SD_ID128_MAKE(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f) +#define SD_GPT_SWAP_STR SD_ID128_MAKE_UUID_STR(06,57,fd,6d,a4,ab,43,c4,84,e5,09,33,c8,4b,4f,4f) +#define SD_GPT_HOME SD_ID128_MAKE(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15) +#define SD_GPT_HOME_STR SD_ID128_MAKE_UUID_STR(93,3a,c7,e1,2e,b4,4f,13,b8,44,0e,14,e2,ae,f9,15) +#define SD_GPT_SRV SD_ID128_MAKE(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8) +#define SD_GPT_SRV_STR SD_ID128_MAKE_UUID_STR(3b,8f,84,25,20,e0,4f,3b,90,7f,1a,25,a7,6f,98,e8) +#define SD_GPT_VAR SD_ID128_MAKE(4d,21,b0,16,b5,34,45,c2,a9,fb,5c,16,e0,91,fd,2d) +#define SD_GPT_VAR_STR SD_ID128_MAKE_UUID_STR(4d,21,b0,16,b5,34,45,c2,a9,fb,5c,16,e0,91,fd,2d) +#define SD_GPT_TMP SD_ID128_MAKE(7e,c6,f5,57,3b,c5,4a,ca,b2,93,16,ef,5d,f6,39,d1) +#define SD_GPT_TMP_STR SD_ID128_MAKE_UUID_STR(7e,c6,f5,57,3b,c5,4a,ca,b2,93,16,ef,5d,f6,39,d1) +#define SD_GPT_USER_HOME SD_ID128_MAKE(77,3f,91,ef,66,d4,49,b5,bd,83,d6,83,bf,40,ad,16) +#define SD_GPT_USER_HOME_STR SD_ID128_MAKE_UUID_STR(77,3f,91,ef,66,d4,49,b5,bd,83,d6,83,bf,40,ad,16) +#define SD_GPT_LINUX_GENERIC SD_ID128_MAKE(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4) +#define SD_GPT_LINUX_GENERIC_STR SD_ID128_MAKE_UUID_STR(0f,c6,3d,af,84,83,47,72,8e,79,3d,69,d8,47,7d,e4) + +/* Maintain same order as above */ +#if defined(__alpha__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ALPHA +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ALPHA_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ALPHA_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_ALPHA +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ALPHA_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ALPHA_VERITY_SIG + +#elif defined(__arc__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARC +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARC_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARC_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_ARC +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARC_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARC_VERITY_SIG + +#elif defined(__aarch64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARM64 +# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_ARM +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARM64_VERITY +# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_ARM_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARM64_VERITY_SIG +# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_ARM64 +# define SD_GPT_USR_SECONDARY SD_GPT_USR_ARM +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARM64_VERITY +# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_ARM_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARM64_VERITY_SIG +# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG +#elif defined(__arm__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_ARM +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_ARM_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_ARM_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_ARM +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_ARM_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_ARM_VERITY_SIG + +#elif defined(__ia64__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_IA64 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_IA64_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_IA64_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_IA64 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_IA64_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_IA64_VERITY_SIG + +#elif defined(__loongarch_lp64) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_LOONGARCH64 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_LOONGARCH64_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_LOONGARCH64_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_LOONGARCH64 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_LOONGARCH64_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_LOONGARCH64_VERITY_SIG + +#elif defined(__mips__) && !defined(__mips64) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_MIPS +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_MIPS_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_MIPS_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_MIPS +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_MIPS_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_MIPS_VERITY_SIG +#elif defined(__mips64) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_MIPS64 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_MIPS64_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_MIPS64_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_MIPS64 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_MIPS64_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_MIPS64_VERITY_SIG + +#elif defined(__mips__) && !defined(__mips64) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_MIPS_LE +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_MIPS_LE_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_MIPS_LE_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_MIPS_LE +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_MIPS_LE_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_MIPS_LE_VERITY_SIG +#elif defined(__mips64) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_MIPS64_LE +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_MIPS64_LE_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_MIPS64_LE_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_MIPS64_LE +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_MIPS64_LE_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_MIPS64_LE_VERITY_SIG + +#elif defined(__parisc__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_PARISC +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_PARISC_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_PARISC_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_PARISC +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_PARISC_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_PARISC_VERITY_SIG + +#elif defined(__powerpc__) && defined(__PPC64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_PPC64_LE +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_PPC64_LE_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_PPC64_LE_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_PPC64_LE +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_PPC64_LE_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_PPC64_LE_VERITY_SIG +#elif defined(__powerpc__) && defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_PPC64 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_PPC64_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_PPC64_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_PPC64 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_PPC64_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_PPC64_VERITY_SIG +#elif defined(__powerpc__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_PPC +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_PPC_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_PPC_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_PPC +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_PPC_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_PPC_VERITY_SIG + +#elif defined(__riscv) && __riscv_xlen == 32 +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_RISCV32 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_RISCV32_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_RISCV32_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_RISCV32 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_RISCV32_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_RISCV32_VERITY_SIG +#elif defined(__riscv) && __riscv_xlen == 64 +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_RISCV64 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_RISCV64_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_RISCV64_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_RISCV64 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_RISCV64_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_RISCV64_VERITY_SIG + +#elif defined(__s390__) && !defined(__s390x__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_S390 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_S390_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_S390_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_S390 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_S390_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_S390_VERITY_SIG + +#elif defined(__s390x__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_S390X +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_S390X_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_S390X_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_S390X +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_S390X_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_S390X_VERITY_SIG + +#elif defined(__tilegx__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_TILEGX +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_TILEGX_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_TILEGX_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_TILEGX +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_TILEGX_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_TILEGX_VERITY_SIG + +#elif defined(__x86_64__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_X86_64 +# define SD_GPT_ROOT_SECONDARY SD_GPT_ROOT_X86 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_X86_64_VERITY +# define SD_GPT_ROOT_SECONDARY_VERITY SD_GPT_ROOT_X86_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_X86_64_VERITY_SIG +# define SD_GPT_ROOT_SECONDARY_VERITY_SIG SD_GPT_ROOT_X86_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_X86_64 +# define SD_GPT_USR_SECONDARY SD_GPT_USR_X86 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_X86_64_VERITY +# define SD_GPT_USR_SECONDARY_VERITY SD_GPT_USR_X86_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_X86_64_VERITY_SIG +# define SD_GPT_USR_SECONDARY_VERITY_SIG SD_GPT_USR_X86_VERITY_SIG +#elif defined(__i386__) +# define SD_GPT_ROOT_NATIVE SD_GPT_ROOT_X86 +# define SD_GPT_ROOT_NATIVE_VERITY SD_GPT_ROOT_X86_VERITY +# define SD_GPT_ROOT_NATIVE_VERITY_SIG SD_GPT_ROOT_X86_VERITY_SIG +# define SD_GPT_USR_NATIVE SD_GPT_USR_X86 +# define SD_GPT_USR_NATIVE_VERITY SD_GPT_USR_X86_VERITY +# define SD_GPT_USR_NATIVE_VERITY_SIG SD_GPT_USR_X86_VERITY_SIG +#endif + +/* Partition attributes defined by the UEFI specification. */ +#define SD_GPT_FLAG_REQUIRED_PARTITION (UINT64_C(1) << 0) +#define SD_GPT_FLAG_NO_BLOCK_IO_PROTOCOL (UINT64_C(1) << 1) +#define SD_GPT_FLAG_LEGACY_BIOS_BOOTABLE (UINT64_C(1) << 2) + +/* Flags we recognize on the root, usr, xbootldr, swap, home, srv, var, tmp partitions when doing + * auto-discovery. + * + * The first two happen to be identical to what Microsoft defines for its own Basic Data Partitions + * in "winioctl.h": GPT_BASIC_DATA_ATTRIBUTE_READ_ONLY, GPT_BASIC_DATA_ATTRIBUTE_NO_DRIVE_LETTER. + */ +#define SD_GPT_FLAG_READ_ONLY (UINT64_C(1) << 60) +#define SD_GPT_FLAG_NO_AUTO (UINT64_C(1) << 63) +#define SD_GPT_FLAG_GROWFS (UINT64_C(1) << 59) + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-hwdb.h b/thirdparty/systemd/include/systemd/sd-hwdb.h new file mode 100644 index 000000000..ff880f15d --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-hwdb.h @@ -0,0 +1,46 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdhwdbhfoo +#define foosdhwdbhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +typedef struct sd_hwdb sd_hwdb; + +sd_hwdb *sd_hwdb_ref(sd_hwdb *hwdb); +sd_hwdb *sd_hwdb_unref(sd_hwdb *hwdb); + +int sd_hwdb_new(sd_hwdb **ret); +int sd_hwdb_new_from_path(const char *path, sd_hwdb **ret); + +int sd_hwdb_get(sd_hwdb *hwdb, const char *modalias, const char *key, const char **value); + +int sd_hwdb_seek(sd_hwdb *hwdb, const char *modalias); +int sd_hwdb_enumerate(sd_hwdb *hwdb, const char **key, const char **value); + +/* the inverse condition avoids ambiguity of dangling 'else' after the macro */ +#define SD_HWDB_FOREACH_PROPERTY(hwdb, modalias, key, value) \ + if (sd_hwdb_seek(hwdb, modalias) < 0) { } \ + else while (sd_hwdb_enumerate(hwdb, &(key), &(value)) > 0) + +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_hwdb, sd_hwdb_unref); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-id128.h b/thirdparty/systemd/include/systemd/sd-id128.h new file mode 100644 index 000000000..a9210526b --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-id128.h @@ -0,0 +1,165 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdid128hfoo +#define foosdid128hfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <stdarg.h> +#include <string.h> + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +/* 128-bit ID APIs. See sd-id128(3) for more information. */ + +typedef union sd_id128 sd_id128_t; + +union sd_id128 { + uint8_t bytes[16]; + uint64_t qwords[2]; +}; + +#define SD_ID128_STRING_MAX 33U +#define SD_ID128_UUID_STRING_MAX 37U + +char *sd_id128_to_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_STRING_MAX]); +char *sd_id128_to_uuid_string(sd_id128_t id, char s[_SD_ARRAY_STATIC SD_ID128_UUID_STRING_MAX]); +int sd_id128_from_string(const char *s, sd_id128_t *ret); + +#define SD_ID128_TO_STRING(id) sd_id128_to_string((id), (char[SD_ID128_STRING_MAX]) {}) +#define SD_ID128_TO_UUID_STRING(id) sd_id128_to_uuid_string((id), (char[SD_ID128_UUID_STRING_MAX]) {}) + +int sd_id128_randomize(sd_id128_t *ret); + +int sd_id128_get_machine(sd_id128_t *ret); +int sd_id128_get_boot(sd_id128_t *ret); +int sd_id128_get_invocation(sd_id128_t *ret); + +int sd_id128_get_app_specific(sd_id128_t base, sd_id128_t app_id, sd_id128_t *ret); +int sd_id128_get_machine_app_specific(sd_id128_t app_id, sd_id128_t *ret); +int sd_id128_get_boot_app_specific(sd_id128_t app_id, sd_id128_t *ret); +int sd_id128_get_invocation_app_specific(sd_id128_t app_id, sd_id128_t *ret); + +#define SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ + { .bytes = { 0x##v0, 0x##v1, 0x##v2, 0x##v3, 0x##v4, 0x##v5, 0x##v6, 0x##v7, \ + 0x##v8, 0x##v9, 0x##v10, 0x##v11, 0x##v12, 0x##v13, 0x##v14, 0x##v15 }} + +#define SD_ID128_MAKE(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15) \ + ((const sd_id128_t) SD_ID128_ARRAY(v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14, v15)) + +/* Note that SD_ID128_FORMAT_VAL will evaluate the passed argument 16 + * times. It is hence not a good idea to call this macro with an + * expensive function as parameter or an expression with side + * effects */ + +#define SD_ID128_FORMAT_STR "%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x%02x" +#define SD_ID128_FORMAT_VAL(x) (x).bytes[0], (x).bytes[1], (x).bytes[2], (x).bytes[3], (x).bytes[4], (x).bytes[5], (x).bytes[6], (x).bytes[7], (x).bytes[8], (x).bytes[9], (x).bytes[10], (x).bytes[11], (x).bytes[12], (x).bytes[13], (x).bytes[14], (x).bytes[15] + +/* Like SD_ID128_FORMAT_STR, but formats as UUID, not in plain format (Strictly Big Endian byte order, + * i.e. treats everything as RFC4122 Variant 1 UUIDs, even if variant says otherwise, but matching other + * Linux userspace behaviour.) */ +#define SD_ID128_UUID_FORMAT_STR "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x" + +#define SD_ID128_CONST_STR(x) \ + ((const char[SD_ID128_STRING_MAX]) { \ + ((x).bytes[0] >> 4) >= 10 ? 'a' + ((x).bytes[0] >> 4) - 10 : '0' + ((x).bytes[0] >> 4), \ + ((x).bytes[0] & 15) >= 10 ? 'a' + ((x).bytes[0] & 15) - 10 : '0' + ((x).bytes[0] & 15), \ + ((x).bytes[1] >> 4) >= 10 ? 'a' + ((x).bytes[1] >> 4) - 10 : '0' + ((x).bytes[1] >> 4), \ + ((x).bytes[1] & 15) >= 10 ? 'a' + ((x).bytes[1] & 15) - 10 : '0' + ((x).bytes[1] & 15), \ + ((x).bytes[2] >> 4) >= 10 ? 'a' + ((x).bytes[2] >> 4) - 10 : '0' + ((x).bytes[2] >> 4), \ + ((x).bytes[2] & 15) >= 10 ? 'a' + ((x).bytes[2] & 15) - 10 : '0' + ((x).bytes[2] & 15), \ + ((x).bytes[3] >> 4) >= 10 ? 'a' + ((x).bytes[3] >> 4) - 10 : '0' + ((x).bytes[3] >> 4), \ + ((x).bytes[3] & 15) >= 10 ? 'a' + ((x).bytes[3] & 15) - 10 : '0' + ((x).bytes[3] & 15), \ + ((x).bytes[4] >> 4) >= 10 ? 'a' + ((x).bytes[4] >> 4) - 10 : '0' + ((x).bytes[4] >> 4), \ + ((x).bytes[4] & 15) >= 10 ? 'a' + ((x).bytes[4] & 15) - 10 : '0' + ((x).bytes[4] & 15), \ + ((x).bytes[5] >> 4) >= 10 ? 'a' + ((x).bytes[5] >> 4) - 10 : '0' + ((x).bytes[5] >> 4), \ + ((x).bytes[5] & 15) >= 10 ? 'a' + ((x).bytes[5] & 15) - 10 : '0' + ((x).bytes[5] & 15), \ + ((x).bytes[6] >> 4) >= 10 ? 'a' + ((x).bytes[6] >> 4) - 10 : '0' + ((x).bytes[6] >> 4), \ + ((x).bytes[6] & 15) >= 10 ? 'a' + ((x).bytes[6] & 15) - 10 : '0' + ((x).bytes[6] & 15), \ + ((x).bytes[7] >> 4) >= 10 ? 'a' + ((x).bytes[7] >> 4) - 10 : '0' + ((x).bytes[7] >> 4), \ + ((x).bytes[7] & 15) >= 10 ? 'a' + ((x).bytes[7] & 15) - 10 : '0' + ((x).bytes[7] & 15), \ + ((x).bytes[8] >> 4) >= 10 ? 'a' + ((x).bytes[8] >> 4) - 10 : '0' + ((x).bytes[8] >> 4), \ + ((x).bytes[8] & 15) >= 10 ? 'a' + ((x).bytes[8] & 15) - 10 : '0' + ((x).bytes[8] & 15), \ + ((x).bytes[9] >> 4) >= 10 ? 'a' + ((x).bytes[9] >> 4) - 10 : '0' + ((x).bytes[9] >> 4), \ + ((x).bytes[9] & 15) >= 10 ? 'a' + ((x).bytes[9] & 15) - 10 : '0' + ((x).bytes[9] & 15), \ + ((x).bytes[10] >> 4) >= 10 ? 'a' + ((x).bytes[10] >> 4) - 10 : '0' + ((x).bytes[10] >> 4), \ + ((x).bytes[10] & 15) >= 10 ? 'a' + ((x).bytes[10] & 15) - 10 : '0' + ((x).bytes[10] & 15), \ + ((x).bytes[11] >> 4) >= 10 ? 'a' + ((x).bytes[11] >> 4) - 10 : '0' + ((x).bytes[11] >> 4), \ + ((x).bytes[11] & 15) >= 10 ? 'a' + ((x).bytes[11] & 15) - 10 : '0' + ((x).bytes[11] & 15), \ + ((x).bytes[12] >> 4) >= 10 ? 'a' + ((x).bytes[12] >> 4) - 10 : '0' + ((x).bytes[12] >> 4), \ + ((x).bytes[12] & 15) >= 10 ? 'a' + ((x).bytes[12] & 15) - 10 : '0' + ((x).bytes[12] & 15), \ + ((x).bytes[13] >> 4) >= 10 ? 'a' + ((x).bytes[13] >> 4) - 10 : '0' + ((x).bytes[13] >> 4), \ + ((x).bytes[13] & 15) >= 10 ? 'a' + ((x).bytes[13] & 15) - 10 : '0' + ((x).bytes[13] & 15), \ + ((x).bytes[14] >> 4) >= 10 ? 'a' + ((x).bytes[14] >> 4) - 10 : '0' + ((x).bytes[14] >> 4), \ + ((x).bytes[14] & 15) >= 10 ? 'a' + ((x).bytes[14] & 15) - 10 : '0' + ((x).bytes[14] & 15), \ + ((x).bytes[15] >> 4) >= 10 ? 'a' + ((x).bytes[15] >> 4) - 10 : '0' + ((x).bytes[15] >> 4), \ + ((x).bytes[15] & 15) >= 10 ? 'a' + ((x).bytes[15] & 15) - 10 : '0' + ((x).bytes[15] & 15), \ + 0 }) + +#define SD_ID128_MAKE_STR(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \ + #a #b #c #d #e #f #g #h #i #j #k #l #m #n #o #p + +#define SD_ID128_MAKE_UUID_STR(a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p) \ + #a #b #c #d "-" #e #f "-" #g #h "-" #i #j "-" #k #l #m #n #o #p + +_sd_pure_ static __inline__ int sd_id128_equal(sd_id128_t a, sd_id128_t b) { + return a.qwords[0] == b.qwords[0] && a.qwords[1] == b.qwords[1]; +} + +int sd_id128_string_equal(const char *s, sd_id128_t id); + +_sd_pure_ static __inline__ int sd_id128_is_null(sd_id128_t a) { + return a.qwords[0] == 0 && a.qwords[1] == 0; +} + +_sd_pure_ static __inline__ int sd_id128_is_allf(sd_id128_t a) { + return a.qwords[0] == UINT64_C(0xFFFFFFFFFFFFFFFF) && a.qwords[1] == UINT64_C(0xFFFFFFFFFFFFFFFF); +} + +#define SD_ID128_NULL ((const sd_id128_t) { .qwords = { 0, 0 }}) +#define SD_ID128_ALLF ((const sd_id128_t) { .qwords = { UINT64_C(0xFFFFFFFFFFFFFFFF), UINT64_C(0xFFFFFFFFFFFFFFFF) }}) + +_sd_pure_ static __inline__ int sd_id128_in_setv(sd_id128_t a, va_list ap) { + for (;;) { + sd_id128_t b = va_arg(ap, sd_id128_t); + + if (sd_id128_is_null(b)) + return 0; + + if (sd_id128_equal(a, b)) + return 1; + } +} + +_sd_pure_ static __inline__ int sd_id128_in_set_sentinel(sd_id128_t a, ...) { + va_list ap; + int r; + + va_start(ap, a); + r = sd_id128_in_setv(a, ap); + va_end(ap); + + return r; +} + +#define sd_id128_in_set(a, ...) \ + sd_id128_in_set_sentinel(a, ##__VA_ARGS__, SD_ID128_NULL) + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-journal.h b/thirdparty/systemd/include/systemd/sd-journal.h new file mode 100644 index 000000000..7434051ce --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-journal.h @@ -0,0 +1,182 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdjournalhfoo +#define foosdjournalhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <stdarg.h> +#include <sys/types.h> +#include <sys/uio.h> +#include <syslog.h> + +#include "sd-id128.h" + +#include "_sd-common.h" + +/* Journal APIs. See sd-journal(3) for more information. */ + +_SD_BEGIN_DECLARATIONS; + +/* Write to daemon */ +int sd_journal_print(int priority, const char *format, ...) _sd_printf_(2, 3); +int sd_journal_printv(int priority, const char *format, va_list ap) _sd_printf_(2, 0); +int sd_journal_send(const char *format, ...) _sd_printf_(1, 0) _sd_sentinel_; +int sd_journal_sendv(const struct iovec *iov, int n); +int sd_journal_perror(const char *message); + +/* Used by the macros below. You probably don't want to call this directly. */ +int sd_journal_print_with_location(int priority, const char *file, const char *line, const char *func, const char *format, ...) _sd_printf_(5, 6); +int sd_journal_printv_with_location(int priority, const char *file, const char *line, const char *func, const char *format, va_list ap) _sd_printf_(5, 0); +int sd_journal_send_with_location(const char *file, const char *line, const char *func, const char *format, ...) _sd_printf_(4, 0) _sd_sentinel_; +int sd_journal_sendv_with_location(const char *file, const char *line, const char *func, const struct iovec *iov, int n); +int sd_journal_perror_with_location(const char *file, const char *line, const char *func, const char *message); + +/* implicitly add code location to messages sent, if this is enabled */ +#ifndef SD_JOURNAL_SUPPRESS_LOCATION + +#define sd_journal_print(priority, ...) sd_journal_print_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _SD_STRINGIFY(__LINE__), __func__, __VA_ARGS__) +#define sd_journal_printv(priority, format, ap) sd_journal_printv_with_location(priority, "CODE_FILE=" __FILE__, "CODE_LINE=" _SD_STRINGIFY(__LINE__), __func__, format, ap) +#define sd_journal_send(...) sd_journal_send_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _SD_STRINGIFY(__LINE__), __func__, __VA_ARGS__) +#define sd_journal_sendv(iovec, n) sd_journal_sendv_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _SD_STRINGIFY(__LINE__), __func__, iovec, n) +#define sd_journal_perror(message) sd_journal_perror_with_location("CODE_FILE=" __FILE__, "CODE_LINE=" _SD_STRINGIFY(__LINE__), __func__, message) + +#endif + +int sd_journal_stream_fd(const char *identifier, int priority, int level_prefix); +int sd_journal_stream_fd_with_namespace(const char *name_space, const char *identifier, int priority, int level_prefix); + +/* Browse journal stream */ + +typedef struct sd_journal sd_journal; + +/* Open flags */ +enum { + SD_JOURNAL_LOCAL_ONLY = 1 << 0, + SD_JOURNAL_RUNTIME_ONLY = 1 << 1, + SD_JOURNAL_SYSTEM = 1 << 2, + SD_JOURNAL_CURRENT_USER = 1 << 3, + SD_JOURNAL_OS_ROOT = 1 << 4, + SD_JOURNAL_ALL_NAMESPACES = 1 << 5, /* Show all namespaces, not just the default or specified one */ + SD_JOURNAL_INCLUDE_DEFAULT_NAMESPACE = 1 << 6, /* Show default namespace in addition to specified one */ + SD_JOURNAL_TAKE_DIRECTORY_FD = 1 << 7, /* sd_journal_open_directory_fd() will take ownership of the provided file descriptor. */ + SD_JOURNAL_ASSUME_IMMUTABLE = 1 << 8, /* Assume the opened journal files are immutable. Journal entries added later may be ignored. */ + + SD_JOURNAL_SYSTEM_ONLY _sd_deprecated_ = SD_JOURNAL_SYSTEM /* old name */ +}; + +/* Wakeup event types */ +enum { + SD_JOURNAL_NOP, + SD_JOURNAL_APPEND, + SD_JOURNAL_INVALIDATE +}; + +int sd_journal_open(sd_journal **ret, int flags); +int sd_journal_open_namespace(sd_journal **ret, const char *name_space, int flags); +int sd_journal_open_directory(sd_journal **ret, const char *path, int flags); +int sd_journal_open_directory_fd(sd_journal **ret, int fd, int flags); +int sd_journal_open_files(sd_journal **ret, const char **paths, int flags); +int sd_journal_open_files_fd(sd_journal **ret, int fds[], unsigned n_fds, int flags); +int sd_journal_open_container(sd_journal **ret, const char *machine, int flags) _sd_deprecated_; +void sd_journal_close(sd_journal *j); + +int sd_journal_previous(sd_journal *j); +int sd_journal_next(sd_journal *j); +int sd_journal_step_one(sd_journal *j, int advanced); + +int sd_journal_previous_skip(sd_journal *j, uint64_t skip); +int sd_journal_next_skip(sd_journal *j, uint64_t skip); + +int sd_journal_get_realtime_usec(sd_journal *j, uint64_t *ret); +int sd_journal_get_monotonic_usec(sd_journal *j, uint64_t *ret, sd_id128_t *ret_boot_id); +int sd_journal_get_seqnum(sd_journal *j, uint64_t *ret_seqnum, sd_id128_t *ret_seqnum_id); + +int sd_journal_set_data_threshold(sd_journal *j, size_t sz); +int sd_journal_get_data_threshold(sd_journal *j, size_t *sz); + +int sd_journal_get_data(sd_journal *j, const char *field, const void **data, size_t *l); +int sd_journal_enumerate_data(sd_journal *j, const void **data, size_t *l); +int sd_journal_enumerate_available_data(sd_journal *j, const void **data, size_t *l); +void sd_journal_restart_data(sd_journal *j); + +int sd_journal_add_match(sd_journal *j, const void *data, size_t size); +int sd_journal_add_disjunction(sd_journal *j); +int sd_journal_add_conjunction(sd_journal *j); +void sd_journal_flush_matches(sd_journal *j); + +int sd_journal_seek_head(sd_journal *j); +int sd_journal_seek_tail(sd_journal *j); +int sd_journal_seek_monotonic_usec(sd_journal *j, sd_id128_t boot_id, uint64_t usec); +int sd_journal_seek_realtime_usec(sd_journal *j, uint64_t usec); +int sd_journal_seek_cursor(sd_journal *j, const char *cursor); + +int sd_journal_get_cursor(sd_journal *j, char **cursor); +int sd_journal_test_cursor(sd_journal *j, const char *cursor); + +int sd_journal_get_cutoff_realtime_usec(sd_journal *j, uint64_t *from, uint64_t *to); +int sd_journal_get_cutoff_monotonic_usec(sd_journal *j, const sd_id128_t boot_id, uint64_t *from, uint64_t *to); + +int sd_journal_get_usage(sd_journal *j, uint64_t *bytes); + +int sd_journal_query_unique(sd_journal *j, const char *field); +int sd_journal_enumerate_unique(sd_journal *j, const void **data, size_t *l); +int sd_journal_enumerate_available_unique(sd_journal *j, const void **data, size_t *l); +void sd_journal_restart_unique(sd_journal *j); + +int sd_journal_enumerate_fields(sd_journal *j, const char **field); +void sd_journal_restart_fields(sd_journal *j); + +int sd_journal_get_fd(sd_journal *j); +int sd_journal_get_events(sd_journal *j); +int sd_journal_get_timeout(sd_journal *j, uint64_t *timeout_usec); +int sd_journal_process(sd_journal *j); +int sd_journal_wait(sd_journal *j, uint64_t timeout_usec); +int sd_journal_reliable_fd(sd_journal *j); + +int sd_journal_get_catalog(sd_journal *j, char **text); +int sd_journal_get_catalog_for_message_id(sd_id128_t id, char **text); + +int sd_journal_has_runtime_files(sd_journal *j); +int sd_journal_has_persistent_files(sd_journal *j); + +/* The inverse condition avoids ambiguity of dangling 'else' after the macro */ +#define SD_JOURNAL_FOREACH(j) \ + if (sd_journal_seek_head(j) < 0) { } \ + else while (sd_journal_next(j) > 0) + +/* The inverse condition avoids ambiguity of dangling 'else' after the macro */ +#define SD_JOURNAL_FOREACH_BACKWARDS(j) \ + if (sd_journal_seek_tail(j) < 0) { } \ + else while (sd_journal_previous(j) > 0) + +/* Iterate through all available data fields of the current journal entry */ +#define SD_JOURNAL_FOREACH_DATA(j, data, l) \ + for (sd_journal_restart_data(j); sd_journal_enumerate_available_data((j), &(data), &(l)) > 0; ) + +/* Iterate through all available values of a specific field */ +#define SD_JOURNAL_FOREACH_UNIQUE(j, data, l) \ + for (sd_journal_restart_unique(j); sd_journal_enumerate_available_unique((j), &(data), &(l)) > 0; ) + +/* Iterate through all known field names */ +#define SD_JOURNAL_FOREACH_FIELD(j, field) \ + for (sd_journal_restart_fields(j); sd_journal_enumerate_fields((j), &(field)) > 0; ) + +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_journal, sd_journal_close); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-login.h b/thirdparty/systemd/include/systemd/sd-login.h new file mode 100644 index 000000000..c84f2c06b --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-login.h @@ -0,0 +1,270 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdloginhfoo +#define foosdloginhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> +#include <sys/types.h> + +#include "_sd-common.h" + +/* + * A few points: + * + * Instead of returning an empty string array or empty uid array, we + * may return NULL. + * + * Free the data the library returns with libc free(). String arrays + * are NULL terminated, and you need to free the array itself, in + * addition to the strings contained. + * + * We return error codes as negative errno, kernel-style. On success, we + * return 0 or positive. + * + * These functions access data in /proc, /sys/fs/cgroup, and /run. All + * of these are virtual file systems; therefore, accesses are + * relatively cheap. + * + * See sd-login(3) for more information. + */ + +_SD_BEGIN_DECLARATIONS; + +/* Get session from PID. Note that 'shared' processes of a user are + * not attached to a session, but only attached to a user. This will + * return an error for system processes and 'shared' processes of a + * user. */ +int sd_pid_get_session(pid_t pid, char **session); + +/* Get UID of the owner of the session of the PID (or in case the + * process is a 'shared' user process, the UID of that user is + * returned). This will not return the UID of the process, but rather + * the UID of the owner of the cgroup that the process is in. This will + * return an error for system processes. */ +int sd_pid_get_owner_uid(pid_t pid, uid_t *uid); + +/* Get systemd non-slice unit (i.e. service) name from PID, for system + * services. This will return an error for non-service processes. */ +int sd_pid_get_unit(pid_t pid, char **unit); + +/* Get systemd non-slice unit (i.e. service) name from PID, for user + * services. This will return an error for non-user-service + * processes. */ +int sd_pid_get_user_unit(pid_t pid, char **unit); + +/* Get slice name from PID. */ +int sd_pid_get_slice(pid_t pid, char **slice); + +/* Get user slice name from PID. */ +int sd_pid_get_user_slice(pid_t pid, char **slice); + +/* Get machine name from PID, for processes assigned to a VM or + * container. This will return an error for non-machine processes. */ +int sd_pid_get_machine_name(pid_t pid, char **machine); + +/* Get the control group from a PID, relative to the root of the + * hierarchy. */ +int sd_pid_get_cgroup(pid_t pid, char **cgroup); + +/* Equivalent to the corresponding sd_pid_get* functions, but take a + * PIDFD instead of a PID, to ensure there can be no possible PID + * recycle issues before/after the calls. */ +int sd_pidfd_get_session(int pidfd, char **session); +int sd_pidfd_get_owner_uid(int pidfd, uid_t *uid); +int sd_pidfd_get_unit(int pidfd, char **unit); +int sd_pidfd_get_user_unit(int pidfd, char **unit); +int sd_pidfd_get_slice(int pidfd, char **slice); +int sd_pidfd_get_user_slice(int pidfd, char **slice); +int sd_pidfd_get_machine_name(int pidfd, char **machine); +int sd_pidfd_get_cgroup(int pidfd, char **cgroup); + +/* Similar to sd_pid_get_session(), but retrieves data about the peer + * of a connected AF_UNIX socket */ +int sd_peer_get_session(int fd, char **session); + +/* Similar to sd_pid_get_owner_uid(), but retrieves data about the peer of + * a connected AF_UNIX socket */ +int sd_peer_get_owner_uid(int fd, uid_t *uid); + +/* Similar to sd_pid_get_unit(), but retrieves data about the peer of + * a connected AF_UNIX socket */ +int sd_peer_get_unit(int fd, char **unit); + +/* Similar to sd_pid_get_user_unit(), but retrieves data about the peer of + * a connected AF_UNIX socket */ +int sd_peer_get_user_unit(int fd, char **unit); + +/* Similar to sd_pid_get_slice(), but retrieves data about the peer of + * a connected AF_UNIX socket */ +int sd_peer_get_slice(int fd, char **slice); + +/* Similar to sd_pid_get_user_slice(), but retrieves data about the peer of + * a connected AF_UNIX socket */ +int sd_peer_get_user_slice(int fd, char **slice); + +/* Similar to sd_pid_get_machine_name(), but retrieves data about the + * peer of a connected AF_UNIX socket */ +int sd_peer_get_machine_name(int fd, char **machine); + +/* Similar to sd_pid_get_cgroup(), but retrieves data about the peer + * of a connected AF_UNIX socket. */ +int sd_peer_get_cgroup(int fd, char **cgroup); + +/* Get state from UID. Possible states: offline, lingering, online, active, closing */ +int sd_uid_get_state(uid_t uid, char **state); + +/* Return primary session of user, if there is any */ +int sd_uid_get_display(uid_t uid, char **session); + +/* Determine the login time of user */ +int sd_uid_get_login_time(uid_t uid, uint64_t *usec); + +/* Return 1 if UID has session on seat. If require_active is true, this will + * look for active sessions only. */ +int sd_uid_is_on_seat(uid_t uid, int require_active, const char *seat); + +/* Return sessions of user. If require_active is true, this will look for + * active sessions only. Returns the number of sessions. + * If sessions is NULL, this will just return the number of sessions. */ +int sd_uid_get_sessions(uid_t uid, int require_active, char ***sessions); + +/* Return seats of user is on. If require_active is true, this will look for + * active seats only. Returns the number of seats. + * If seats is NULL, this will just return the number of seats. */ +int sd_uid_get_seats(uid_t uid, int require_active, char ***seats); + +/* Return 1 if the session is active. */ +int sd_session_is_active(const char *session); + +/* Return 1 if the session is remote. */ +int sd_session_is_remote(const char *session); + +/* Get state from session. Possible states: online, active, closing. + * This function is a more generic version of sd_session_is_active(). */ +int sd_session_get_state(const char *session, char **state); + +/* Determine user ID of session */ +int sd_session_get_uid(const char *session, uid_t *uid); + +/* Determine username of session */ +int sd_session_get_username(const char *session, char **username); + +/* Determine seat of session */ +int sd_session_get_seat(const char *session, char **seat); + +/* Determine the start time of session */ +int sd_session_get_start_time(const char *session, uint64_t *usec); + +/* Determine the (PAM) service name this session was registered by. */ +int sd_session_get_service(const char *session, char **service); + +/* Determine the type of this session, i.e. one of "tty", "x11", "wayland", "mir" or "unspecified". */ +int sd_session_get_type(const char *session, char **type); + +/* Determine the class of this session, i.e. one of "user", "greeter" or "lock-screen". */ +int sd_session_get_class(const char *session, char **clazz); + +/* Determine the desktop brand of this session, i.e. something like "GNOME", "KDE" or "systemd-console". */ +int sd_session_get_desktop(const char *session, char **desktop); + +/* Determine the X11 display of this session. */ +int sd_session_get_display(const char *session, char **display); + +/* Determine the leader process of this session. */ +int sd_session_get_leader(const char *session, pid_t *leader); + +/* Determine the remote host of this session. */ +int sd_session_get_remote_host(const char *session, char **remote_host); + +/* Determine the remote user of this session (if provided by PAM). */ +int sd_session_get_remote_user(const char *session, char **remote_user); + +/* Determine the TTY of this session. */ +int sd_session_get_tty(const char *session, char **display); + +/* Determine the VT number of this session. */ +int sd_session_get_vt(const char *session, unsigned *vtnr); + +/* Return active session and user of seat */ +int sd_seat_get_active(const char *seat, char **session, uid_t *uid); + +/* Return sessions and users on seat. Returns number of sessions. + * If sessions is NULL, this returns only the number of sessions. */ +int sd_seat_get_sessions( + const char *seat, + char ***ret_sessions, + uid_t **ret_uids, + unsigned *ret_n_uids); + +/* Return whether the seat is multi-session capable */ +int sd_seat_can_multi_session(const char *seat) _sd_deprecated_; + +/* Return whether the seat is TTY capable, i.e. suitable for showing console UIs */ +int sd_seat_can_tty(const char *seat); + +/* Return whether the seat is graphics capable, i.e. suitable for showing graphical UIs */ +int sd_seat_can_graphical(const char *seat); + +/* Return the class of machine */ +int sd_machine_get_class(const char *machine, char **clazz); + +/* Return the list if host-side network interface indices of a machine */ +int sd_machine_get_ifindices(const char *machine, int **ret_ifindices); + +/* Get all seats, store in *seats. Returns the number of seats. If + * seats is NULL, this only returns the number of seats. */ +int sd_get_seats(char ***seats); + +/* Get all sessions, store in *sessions. Returns the number of + * sessions. If sessions is NULL, this only returns the number of sessions. */ +int sd_get_sessions(char ***sessions); + +/* Get all logged in users, store in *users. Returns the number of + * users. If users is NULL, this only returns the number of users. */ +int sd_get_uids(uid_t **users); + +/* Get all running virtual machines/containers */ +int sd_get_machine_names(char ***machines); + +/* Monitor object */ +typedef struct sd_login_monitor sd_login_monitor; + +/* Create a new monitor. Category must be NULL, "seat", "session", + * "uid", or "machine" to get monitor events for the specific category + * (or all). */ +int sd_login_monitor_new(const char *category, sd_login_monitor** ret); + +/* Destroys the passed monitor. Returns NULL. */ +sd_login_monitor* sd_login_monitor_unref(sd_login_monitor *m); + +/* Flushes the monitor */ +int sd_login_monitor_flush(sd_login_monitor *m); + +/* Get FD from monitor */ +int sd_login_monitor_get_fd(sd_login_monitor *m); + +/* Get poll() mask to monitor */ +int sd_login_monitor_get_events(sd_login_monitor *m); + +/* Get timeout for poll(), as usec value relative to CLOCK_MONOTONIC's epoch */ +int sd_login_monitor_get_timeout(sd_login_monitor *m, uint64_t *timeout_usec); + +_SD_DEFINE_POINTER_CLEANUP_FUNC(sd_login_monitor, sd_login_monitor_unref); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-messages.h b/thirdparty/systemd/include/systemd/sd-messages.h new file mode 100644 index 000000000..16e9986be --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-messages.h @@ -0,0 +1,280 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdmessageshfoo +#define foosdmessageshfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include "sd-id128.h" + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +/* Hey! If you add a new message here, you *must* also update the message catalog with an appropriate explanation */ + +/* And if you add a new ID here, make sure to generate a random one with "systemd-id128 new". Do not use any + * other IDs, and do not count them up manually. */ + +#define SD_MESSAGE_JOURNAL_START SD_ID128_MAKE(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) +#define SD_MESSAGE_JOURNAL_START_STR SD_ID128_MAKE_STR(f7,73,79,a8,49,0b,40,8b,be,5f,69,40,50,5a,77,7b) +#define SD_MESSAGE_JOURNAL_STOP SD_ID128_MAKE(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) +#define SD_MESSAGE_JOURNAL_STOP_STR SD_ID128_MAKE_STR(d9,3f,b3,c9,c2,4d,45,1a,97,ce,a6,15,ce,59,c0,0b) +#define SD_MESSAGE_JOURNAL_DROPPED SD_ID128_MAKE(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) +#define SD_MESSAGE_JOURNAL_DROPPED_STR SD_ID128_MAKE_STR(a5,96,d6,fe,7b,fa,49,94,82,8e,72,30,9e,95,d6,1e) +#define SD_MESSAGE_JOURNAL_MISSED SD_ID128_MAKE(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06) +#define SD_MESSAGE_JOURNAL_MISSED_STR SD_ID128_MAKE_STR(e9,bf,28,e6,e8,34,48,1b,b6,f4,8f,54,8a,d1,36,06) +#define SD_MESSAGE_JOURNAL_USAGE SD_ID128_MAKE(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6) +#define SD_MESSAGE_JOURNAL_USAGE_STR SD_ID128_MAKE_STR(ec,38,7f,57,7b,84,4b,8f,a9,48,f3,3c,ad,9a,75,e6) + +#define SD_MESSAGE_COREDUMP SD_ID128_MAKE(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) +#define SD_MESSAGE_COREDUMP_STR SD_ID128_MAKE_STR(fc,2e,22,bc,6e,e6,47,b6,b9,07,29,ab,34,a2,50,b1) +#define SD_MESSAGE_TRUNCATED_CORE SD_ID128_MAKE(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37) +#define SD_MESSAGE_TRUNCATED_CORE_STR SD_ID128_MAKE_STR(5a,ad,d8,e9,54,dc,4b,1a,8c,95,4d,63,fd,9e,11,37) +#define SD_MESSAGE_BACKTRACE SD_ID128_MAKE(1f,4e,0a,44,a8,86,49,93,9a,ae,a3,4f,c6,da,8c,95) +#define SD_MESSAGE_BACKTRACE_STR SD_ID128_MAKE_STR(1f,4e,0a,44,a8,86,49,93,9a,ae,a3,4f,c6,da,8c,95) + +#define SD_MESSAGE_SESSION_START SD_ID128_MAKE(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66) +#define SD_MESSAGE_SESSION_START_STR SD_ID128_MAKE_STR(8d,45,62,0c,1a,43,48,db,b1,74,10,da,57,c6,0c,66) +#define SD_MESSAGE_SESSION_STOP SD_ID128_MAKE(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a) +#define SD_MESSAGE_SESSION_STOP_STR SD_ID128_MAKE_STR(33,54,93,94,24,b4,45,6d,98,02,ca,83,33,ed,42,4a) +#define SD_MESSAGE_SEAT_START SD_ID128_MAKE(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b) +#define SD_MESSAGE_SEAT_START_STR SD_ID128_MAKE_STR(fc,be,fc,5d,a2,3d,42,80,93,f9,7c,82,a9,29,0f,7b) +#define SD_MESSAGE_SEAT_STOP SD_ID128_MAKE(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5) +#define SD_MESSAGE_SEAT_STOP_STR SD_ID128_MAKE_STR(e7,85,2b,fe,46,78,4e,d0,ac,cd,e0,4b,c8,64,c2,d5) +#define SD_MESSAGE_MACHINE_START SD_ID128_MAKE(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2) +#define SD_MESSAGE_MACHINE_START_STR SD_ID128_MAKE_STR(24,d8,d4,45,25,73,40,24,96,06,83,81,a6,31,2d,f2) +#define SD_MESSAGE_MACHINE_STOP SD_ID128_MAKE(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58) +#define SD_MESSAGE_MACHINE_STOP_STR SD_ID128_MAKE_STR(58,43,2b,d3,ba,ce,47,7c,b5,14,b5,63,81,b8,a7,58) + +#define SD_MESSAGE_TIME_CHANGE SD_ID128_MAKE(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27) +#define SD_MESSAGE_TIME_CHANGE_STR SD_ID128_MAKE_STR(c7,a7,87,07,9b,35,4e,aa,a9,e7,7b,37,18,93,cd,27) +#define SD_MESSAGE_TIMEZONE_CHANGE SD_ID128_MAKE(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90) +#define SD_MESSAGE_TIMEZONE_CHANGE_STR SD_ID128_MAKE_STR(45,f8,2f,4a,ef,7a,4b,bf,94,2c,e8,61,d1,f2,09,90) + +#define SD_MESSAGE_TAINTED SD_ID128_MAKE(50,87,6a,9d,b0,0f,4c,40,bd,e1,a2,ad,38,1c,3a,1b) +#define SD_MESSAGE_TAINTED_STR SD_ID128_MAKE_STR(50,87,6a,9d,b0,0f,4c,40,bd,e1,a2,ad,38,1c,3a,1b) +#define SD_MESSAGE_STARTUP_FINISHED SD_ID128_MAKE(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff) +#define SD_MESSAGE_STARTUP_FINISHED_STR SD_ID128_MAKE_STR(b0,7a,24,9c,d0,24,41,4a,82,dd,00,cd,18,13,78,ff) +#define SD_MESSAGE_USER_STARTUP_FINISHED SD_ID128_MAKE(ee,d0,0a,68,ff,d8,4e,31,88,21,05,fd,97,3a,bd,d1) +#define SD_MESSAGE_USER_STARTUP_FINISHED_STR SD_ID128_MAKE_STR(ee,d0,0a,68,ff,d8,4e,31,88,21,05,fd,97,3a,bd,d1) + +#define SD_MESSAGE_SLEEP_START SD_ID128_MAKE(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28) +#define SD_MESSAGE_SLEEP_START_STR SD_ID128_MAKE_STR(6b,bd,95,ee,97,79,41,e4,97,c4,8b,e2,7c,25,41,28) +#define SD_MESSAGE_SLEEP_STOP SD_ID128_MAKE(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14) +#define SD_MESSAGE_SLEEP_STOP_STR SD_ID128_MAKE_STR(88,11,e6,df,2a,8e,40,f5,8a,94,ce,a2,6f,8e,bf,14) + +#define SD_MESSAGE_SHUTDOWN SD_ID128_MAKE(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40) +#define SD_MESSAGE_SHUTDOWN_STR SD_ID128_MAKE_STR(98,26,88,66,d1,d5,4a,49,9c,4e,98,92,1d,93,bc,40) + +#define SD_MESSAGE_FACTORY_RESET SD_ID128_MAKE(c1,4a,af,76,ec,28,4a,5f,a1,f1,05,f8,8d,fb,06,1c) +#define SD_MESSAGE_FACTORY_RESET_STR SD_ID128_MAKE_STR(c1,4a,af,76,ec,28,4a,5f,a1,f1,05,f8,8d,fb,06,1c) + +#define SD_MESSAGE_CRASH_EXIT SD_ID128_MAKE(d9,ec,5e,95,e4,b6,46,aa,ae,a2,fd,05,21,4e,db,da) +#define SD_MESSAGE_CRASH_EXIT_STR SD_ID128_MAKE_STR(d9,ec,5e,95,e4,b6,46,aa,ae,a2,fd,05,21,4e,db,da) +#define SD_MESSAGE_CRASH_FAILED SD_ID128_MAKE(3e,d0,16,3e,86,8a,44,17,ab,8b,9e,21,04,07,a9,6c) +#define SD_MESSAGE_CRASH_FAILED_STR SD_ID128_MAKE_STR(3e,d0,16,3e,86,8a,44,17,ab,8b,9e,21,04,07,a9,6c) +#define SD_MESSAGE_CRASH_FREEZE SD_ID128_MAKE(64,5c,73,55,37,63,4a,e0,a3,2b,15,a7,c6,cb,a7,d4) +#define SD_MESSAGE_CRASH_FREEZE_STR SD_ID128_MAKE_STR(64,5c,73,55,37,63,4a,e0,a3,2b,15,a7,c6,cb,a7,d4) + +#define SD_MESSAGE_CRASH_NO_COREDUMP SD_ID128_MAKE(5a,dd,b3,a0,6a,73,4d,33,96,b7,94,bf,98,fb,2d,01) +#define SD_MESSAGE_CRASH_NO_COREDUMP_STR SD_ID128_MAKE_STR(5a,dd,b3,a0,6a,73,4d,33,96,b7,94,bf,98,fb,2d,01) +#define SD_MESSAGE_CRASH_NO_FORK SD_ID128_MAKE(5c,9e,98,de,4a,b9,4c,6a,9d,04,d0,ad,79,3b,d9,03) +#define SD_MESSAGE_CRASH_NO_FORK_STR SD_ID128_MAKE_STR(5c,9e,98,de,4a,b9,4c,6a,9d,04,d0,ad,79,3b,d9,03) +#define SD_MESSAGE_CRASH_UNKNOWN_SIGNAL SD_ID128_MAKE(5e,6f,1f,5e,4d,b6,4a,0e,ae,e3,36,82,49,d2,0b,94) +#define SD_MESSAGE_CRASH_UNKNOWN_SIGNAL_STR SD_ID128_MAKE_STR(5e,6f,1f,5e,4d,b6,4a,0e,ae,e3,36,82,49,d2,0b,94) +#define SD_MESSAGE_CRASH_SYSTEMD_SIGNAL SD_ID128_MAKE(83,f8,4b,35,ee,26,4f,74,a3,89,6a,97,17,af,34,cb) +#define SD_MESSAGE_CRASH_SYSTEMD_SIGNAL_STR SD_ID128_MAKE_STR(83,f8,4b,35,ee,26,4f,74,a3,89,6a,97,17,af,34,cb) +#define SD_MESSAGE_CRASH_PROCESS_SIGNAL SD_ID128_MAKE(3a,73,a9,8b,af,5b,4b,19,99,29,e3,22,6c,0b,e7,83) +#define SD_MESSAGE_CRASH_PROCESS_SIGNAL_STR SD_ID128_MAKE_STR(3a,73,a9,8b,af,5b,4b,19,99,29,e3,22,6c,0b,e7,83) +#define SD_MESSAGE_CRASH_WAITPID_FAILED SD_ID128_MAKE(2e,d1,8d,4f,78,ca,47,f0,a9,bc,25,27,1c,26,ad,b4) +#define SD_MESSAGE_CRASH_WAITPID_FAILED_STR SD_ID128_MAKE_STR(2e,d1,8d,4f,78,ca,47,f0,a9,bc,25,27,1c,26,ad,b4) +#define SD_MESSAGE_CRASH_COREDUMP_FAILED SD_ID128_MAKE(56,b1,cd,96,f2,42,46,c5,b6,07,66,6f,da,95,23,56) +#define SD_MESSAGE_CRASH_COREDUMP_FAILED_STR SD_ID128_MAKE_STR(56,b1,cd,96,f2,42,46,c5,b6,07,66,6f,da,95,23,56) +#define SD_MESSAGE_CRASH_COREDUMP_PID SD_ID128_MAKE(4a,c7,56,6d,4d,75,48,f4,98,1f,62,9a,28,f0,f8,29) +#define SD_MESSAGE_CRASH_COREDUMP_PID_STR SD_ID128_MAKE_STR(4a,c7,56,6d,4d,75,48,f4,98,1f,62,9a,28,f0,f8,29) +#define SD_MESSAGE_CRASH_SHELL_FORK_FAILED SD_ID128_MAKE(38,e8,b1,e0,39,ad,46,92,91,b1,8b,44,c5,53,a5,b7) +#define SD_MESSAGE_CRASH_SHELL_FORK_FAILED_STR SD_ID128_MAKE_STR(38,e8,b1,e0,39,ad,46,92,91,b1,8b,44,c5,53,a5,b7) +#define SD_MESSAGE_CRASH_EXECLE_FAILED SD_ID128_MAKE(87,27,29,b4,7d,be,47,3e,b7,68,cc,ec,d4,77,be,da) +#define SD_MESSAGE_CRASH_EXECLE_FAILED_STR SD_ID128_MAKE_STR(87,27,29,b4,7d,be,47,3e,b7,68,cc,ec,d4,77,be,da) + +#define SD_MESSAGE_SELINUX_FAILED SD_ID128_MAKE(65,8a,67,ad,c1,c9,40,b3,b3,31,6e,7e,86,28,83,4a) +#define SD_MESSAGE_SELINUX_FAILED_STR SD_ID128_MAKE_STR(65,8a,67,ad,c1,c9,40,b3,b3,31,6e,7e,86,28,83,4a) + +#define SD_MESSAGE_BATTERY_LOW_WARNING SD_ID128_MAKE(e6,f4,56,bd,92,00,4d,95,80,16,0b,22,07,55,51,86) +#define SD_MESSAGE_BATTERY_LOW_WARNING_STR SD_ID128_MAKE_STR(e6,f4,56,bd,92,00,4d,95,80,16,0b,22,07,55,51,86) +#define SD_MESSAGE_BATTERY_LOW_POWEROFF SD_ID128_MAKE(26,74,37,d3,3f,dd,41,09,9a,d7,62,21,cc,24,a3,35) +#define SD_MESSAGE_BATTERY_LOW_POWEROFF_STR SD_ID128_MAKE_STR(26,74,37,d3,3f,dd,41,09,9a,d7,62,21,cc,24,a3,35) + +#define SD_MESSAGE_CORE_MAINLOOP_FAILED SD_ID128_MAKE(79,e0,5b,67,bc,45,45,d1,92,2f,e4,71,07,ee,60,c5) +#define SD_MESSAGE_CORE_MAINLOOP_FAILED_STR SD_ID128_MAKE_STR(79,e0,5b,67,bc,45,45,d1,92,2f,e4,71,07,ee,60,c5) +#define SD_MESSAGE_CORE_NO_XDGDIR_PATH SD_ID128_MAKE(db,b1,36,b1,0e,f4,45,7b,a4,7a,79,5d,62,f1,08,c9) +#define SD_MESSAGE_CORE_NO_XDGDIR_PATH_STR SD_ID128_MAKE_STR(db,b1,36,b1,0e,f4,45,7b,a4,7a,79,5d,62,f1,08,c9) +#define SD_MESSAGE_CORE_CAPABILITY_BOUNDING_USER SD_ID128_MAKE(ed,15,8c,2d,f8,88,4f,a5,84,ee,ad,2d,90,2c,10,32) +#define SD_MESSAGE_CORE_CAPABILITY_BOUNDING_USER_STR SD_ID128_MAKE_STR(ed,15,8c,2d,f8,88,4f,a5,84,ee,ad,2d,90,2c,10,32) +#define SD_MESSAGE_CORE_CAPABILITY_BOUNDING SD_ID128_MAKE(42,69,5b,50,0d,f0,48,29,8b,ee,37,15,9c,aa,9f,2e) +#define SD_MESSAGE_CORE_CAPABILITY_BOUNDING_STR SD_ID128_MAKE_STR(42,69,5b,50,0d,f0,48,29,8b,ee,37,15,9c,aa,9f,2e) +#define SD_MESSAGE_CORE_DISABLE_PRIVILEGES SD_ID128_MAKE(bf,c2,43,07,24,ab,44,49,97,35,b4,f9,4c,ca,92,95) +#define SD_MESSAGE_CORE_DISABLE_PRIVILEGES_STR SD_ID128_MAKE_STR(bf,c2,43,07,24,ab,44,49,97,35,b4,f9,4c,ca,92,95) +#define SD_MESSAGE_CORE_START_TARGET_FAILED SD_ID128_MAKE(59,28,8a,f5,23,be,43,a2,8d,49,4e,41,e2,6e,45,10) +#define SD_MESSAGE_CORE_START_TARGET_FAILED_STR SD_ID128_MAKE_STR(59,28,8a,f5,23,be,43,a2,8d,49,4e,41,e2,6e,45,10) +#define SD_MESSAGE_CORE_ISOLATE_TARGET_FAILED SD_ID128_MAKE(68,9b,4f,cc,97,b4,48,6e,a5,da,92,db,69,c9,e3,14) +#define SD_MESSAGE_CORE_ISOLATE_TARGET_FAILED_STR SD_ID128_MAKE_STR(68,9b,4f,cc,97,b4,48,6e,a5,da,92,db,69,c9,e3,14) +#define SD_MESSAGE_CORE_FD_SET_FAILED SD_ID128_MAKE(5e,d8,36,f1,76,6f,4a,8a,9f,c5,da,45,aa,e2,3b,29) +#define SD_MESSAGE_CORE_FD_SET_FAILED_STR SD_ID128_MAKE_STR(5e,d8,36,f1,76,6f,4a,8a,9f,c5,da,45,aa,e2,3b,29) +#define SD_MESSAGE_CORE_PID1_ENVIRONMENT SD_ID128_MAKE(6a,40,fb,fb,d2,ba,4b,8d,b0,2f,b4,0c,9c,d0,90,d7) +#define SD_MESSAGE_CORE_PID1_ENVIRONMENT_STR SD_ID128_MAKE_STR(6a,40,fb,fb,d2,ba,4b,8d,b0,2f,b4,0c,9c,d0,90,d7) +#define SD_MESSAGE_CORE_MANAGER_ALLOCATE SD_ID128_MAKE(0e,54,47,09,84,ac,41,96,89,74,3d,95,7a,11,9e,2e) +#define SD_MESSAGE_CORE_MANAGER_ALLOCATE_STR SD_ID128_MAKE_STR(0e,54,47,09,84,ac,41,96,89,74,3d,95,7a,11,9e,2e) + +#define SD_MESSAGE_SMACK_FAILED_WRITE SD_ID128_MAKE(d6,7f,a9,f8,47,aa,4b,04,8a,2a,e3,35,35,33,1a,db) +#define SD_MESSAGE_SMACK_FAILED_WRITE_STR SD_ID128_MAKE_STR(d6,7f,a9,f8,47,aa,4b,04,8a,2a,e3,35,35,33,1a,db) + +#define SD_MESSAGE_SHUTDOWN_ERROR SD_ID128_MAKE(af,55,a6,f7,5b,54,44,31,b7,26,49,f3,6f,f6,d6,2c) +#define SD_MESSAGE_SHUTDOWN_ERROR_STR SD_ID128_MAKE_STR(af,55,a6,f7,5b,54,44,31,b7,26,49,f3,6f,f6,d6,2c) + +#define SD_MESSAGE_VALGRIND_HELPER_FORK SD_ID128_MAKE(d1,8e,03,39,ef,b2,4a,06,8d,9c,10,60,22,10,48,c2) +#define SD_MESSAGE_VALGRIND_HELPER_FORK_STR SD_ID128_MAKE_STR(d1,8e,03,39,ef,b2,4a,06,8d,9c,10,60,22,10,48,c2) + +/* The messages below are actually about jobs, not really about units, the macros are misleadingly named. + * Moreover SD_MESSAGE_UNIT_FAILED is not actually about a failing unit but about a failed start job. A job + * either finishes with SD_MESSAGE_UNIT_STARTED or with SD_MESSAGE_UNIT_FAILED hence. */ +#define SD_MESSAGE_UNIT_STARTING SD_ID128_MAKE(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5) +#define SD_MESSAGE_UNIT_STARTING_STR SD_ID128_MAKE_STR(7d,49,58,e8,42,da,4a,75,8f,6c,1c,dc,7b,36,dc,c5) +#define SD_MESSAGE_UNIT_STARTED SD_ID128_MAKE(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf) +#define SD_MESSAGE_UNIT_STARTED_STR SD_ID128_MAKE_STR(39,f5,34,79,d3,a0,45,ac,8e,11,78,62,48,23,1f,bf) +#define SD_MESSAGE_UNIT_FAILED SD_ID128_MAKE(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d) +#define SD_MESSAGE_UNIT_FAILED_STR SD_ID128_MAKE_STR(be,02,cf,68,55,d2,42,8b,a4,0d,f7,e9,d0,22,f0,3d) +#define SD_MESSAGE_UNIT_STOPPING SD_ID128_MAKE(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f) +#define SD_MESSAGE_UNIT_STOPPING_STR SD_ID128_MAKE_STR(de,5b,42,6a,63,be,47,a7,b6,ac,3e,aa,c8,2e,2f,6f) +#define SD_MESSAGE_UNIT_STOPPED SD_ID128_MAKE(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86) +#define SD_MESSAGE_UNIT_STOPPED_STR SD_ID128_MAKE_STR(9d,1a,aa,27,d6,01,40,bd,96,36,54,38,aa,d2,02,86) +#define SD_MESSAGE_UNIT_RELOADING SD_ID128_MAKE(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25) +#define SD_MESSAGE_UNIT_RELOADING_STR SD_ID128_MAKE_STR(d3,4d,03,7f,ff,18,47,e6,ae,66,9a,37,0e,69,47,25) +#define SD_MESSAGE_UNIT_RELOADED SD_ID128_MAKE(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54) +#define SD_MESSAGE_UNIT_RELOADED_STR SD_ID128_MAKE_STR(7b,05,eb,c6,68,38,42,22,ba,a8,88,11,79,cf,da,54) + +#define SD_MESSAGE_UNIT_RESTART_SCHEDULED SD_ID128_MAKE(5e,b0,34,94,b6,58,48,70,a5,36,b3,37,29,08,09,b3) +#define SD_MESSAGE_UNIT_RESTART_SCHEDULED_STR SD_ID128_MAKE_STR(5e,b0,34,94,b6,58,48,70,a5,36,b3,37,29,08,09,b3) + +#define SD_MESSAGE_UNIT_RESOURCES SD_ID128_MAKE(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0) +#define SD_MESSAGE_UNIT_RESOURCES_STR SD_ID128_MAKE_STR(ae,8f,7b,86,6b,03,47,b9,af,31,fe,1c,80,b1,27,c0) + +#define SD_MESSAGE_UNIT_SUCCESS SD_ID128_MAKE(7a,d2,d1,89,f7,e9,4e,70,a3,8c,78,13,54,91,24,48) +#define SD_MESSAGE_UNIT_SUCCESS_STR SD_ID128_MAKE_STR(7a,d2,d1,89,f7,e9,4e,70,a3,8c,78,13,54,91,24,48) +#define SD_MESSAGE_UNIT_SKIPPED SD_ID128_MAKE(0e,42,84,a0,ca,ca,4b,fc,81,c0,bb,67,86,97,26,73) +#define SD_MESSAGE_UNIT_SKIPPED_STR SD_ID128_MAKE_STR(0e,42,84,a0,ca,ca,4b,fc,81,c0,bb,67,86,97,26,73) +#define SD_MESSAGE_UNIT_FAILURE_RESULT SD_ID128_MAKE(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) +#define SD_MESSAGE_UNIT_FAILURE_RESULT_STR SD_ID128_MAKE_STR(d9,b3,73,ed,55,a6,4f,eb,82,42,e0,2d,be,79,a4,9c) + +#define SD_MESSAGE_SPAWN_FAILED SD_ID128_MAKE(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) +#define SD_MESSAGE_SPAWN_FAILED_STR SD_ID128_MAKE_STR(64,12,57,65,1c,1b,4e,c9,a8,62,4d,7a,40,a9,e1,e7) + +#define SD_MESSAGE_UNIT_PROCESS_EXIT SD_ID128_MAKE(98,e3,22,20,3f,7a,4e,d2,90,d0,9f,e0,3c,09,fe,15) +#define SD_MESSAGE_UNIT_PROCESS_EXIT_STR SD_ID128_MAKE_STR(98,e3,22,20,3f,7a,4e,d2,90,d0,9f,e0,3c,09,fe,15) + +#define SD_MESSAGE_FORWARD_SYSLOG_MISSED SD_ID128_MAKE(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e) +#define SD_MESSAGE_FORWARD_SYSLOG_MISSED_STR SD_ID128_MAKE_STR(00,27,22,9c,a0,64,41,81,a7,6c,4e,92,45,8a,fa,2e) + +#define SD_MESSAGE_OVERMOUNTING SD_ID128_MAKE(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7) +#define SD_MESSAGE_OVERMOUNTING_STR SD_ID128_MAKE_STR(1d,ee,03,69,c7,fc,47,36,b7,09,9b,38,ec,b4,6e,e7) + +#define SD_MESSAGE_UNIT_OOMD_KILL SD_ID128_MAKE(d9,89,61,1b,15,e4,4c,9d,bf,31,e3,c8,12,56,e4,ed) +#define SD_MESSAGE_UNIT_OOMD_KILL_STR SD_ID128_MAKE_STR(d9,89,61,1b,15,e4,4c,9d,bf,31,e3,c8,12,56,e4,ed) + +#define SD_MESSAGE_UNIT_OUT_OF_MEMORY SD_ID128_MAKE(fe,6f,aa,94,e7,77,46,63,a0,da,52,71,78,91,d8,ef) +#define SD_MESSAGE_UNIT_OUT_OF_MEMORY_STR SD_ID128_MAKE_STR(fe,6f,aa,94,e7,77,46,63,a0,da,52,71,78,91,d8,ef) + +#define SD_MESSAGE_LID_OPENED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f) +#define SD_MESSAGE_LID_OPENED_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,6f) +#define SD_MESSAGE_LID_CLOSED SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70) +#define SD_MESSAGE_LID_CLOSED_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,70) +#define SD_MESSAGE_SYSTEM_DOCKED SD_ID128_MAKE(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff) +#define SD_MESSAGE_SYSTEM_DOCKED_STR SD_ID128_MAKE_STR(f5,f4,16,b8,62,07,4b,28,92,7a,48,c3,ba,7d,51,ff) +#define SD_MESSAGE_SYSTEM_UNDOCKED SD_ID128_MAKE(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53) +#define SD_MESSAGE_SYSTEM_UNDOCKED_STR SD_ID128_MAKE_STR(51,e1,71,bd,58,52,48,56,81,10,14,4c,51,7c,ca,53) +#define SD_MESSAGE_POWER_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) +#define SD_MESSAGE_POWER_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,71) +#define SD_MESSAGE_POWER_KEY_LONG_PRESS SD_ID128_MAKE(3e,01,17,10,1e,b2,43,c1,b9,a5,0d,b3,49,4a,b1,0b) +#define SD_MESSAGE_POWER_KEY_LONG_PRESS_STR SD_ID128_MAKE_STR(3e,01,17,10,1e,b2,43,c1,b9,a5,0d,b3,49,4a,b1,0b) +#define SD_MESSAGE_REBOOT_KEY SD_ID128_MAKE(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0) +#define SD_MESSAGE_REBOOT_KEY_STR SD_ID128_MAKE_STR(9f,a9,d2,c0,12,13,4e,c3,85,45,1f,fe,31,6f,97,d0) +#define SD_MESSAGE_REBOOT_KEY_LONG_PRESS SD_ID128_MAKE(f1,c5,9a,58,c9,d9,43,66,89,65,c3,37,ca,ec,59,75) +#define SD_MESSAGE_REBOOT_KEY_LONG_PRESS_STR SD_ID128_MAKE_STR(f1,c5,9a,58,c9,d9,43,66,89,65,c3,37,ca,ec,59,75) +#define SD_MESSAGE_SUSPEND_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) +#define SD_MESSAGE_SUSPEND_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,72) +#define SD_MESSAGE_SUSPEND_KEY_LONG_PRESS SD_ID128_MAKE(bf,da,f6,d3,12,ab,40,07,bc,1f,e4,0a,15,df,78,e8) +#define SD_MESSAGE_SUSPEND_KEY_LONG_PRESS_STR SD_ID128_MAKE_STR(bf,da,f6,d3,12,ab,40,07,bc,1f,e4,0a,15,df,78,e8) +#define SD_MESSAGE_HIBERNATE_KEY SD_ID128_MAKE(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) +#define SD_MESSAGE_HIBERNATE_KEY_STR SD_ID128_MAKE_STR(b7,2e,a4,a2,88,15,45,a0,b5,0e,20,0e,55,b9,b0,73) +#define SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS SD_ID128_MAKE(16,78,36,df,6f,7f,42,8e,98,14,72,27,b2,dc,89,45) +#define SD_MESSAGE_HIBERNATE_KEY_LONG_PRESS_STR SD_ID128_MAKE_STR(16,78,36,df,6f,7f,42,8e,98,14,72,27,b2,dc,89,45) + +#define SD_MESSAGE_INVALID_CONFIGURATION SD_ID128_MAKE(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01) +#define SD_MESSAGE_INVALID_CONFIGURATION_STR SD_ID128_MAKE_STR(c7,72,d2,4e,9a,88,4c,be,b9,ea,12,62,5c,30,6c,01) + +#define SD_MESSAGE_DNSSEC_FAILURE SD_ID128_MAKE(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d) +#define SD_MESSAGE_DNSSEC_FAILURE_STR SD_ID128_MAKE_STR(16,75,d7,f1,72,17,40,98,b1,10,8b,f8,c7,dc,8f,5d) +#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED SD_ID128_MAKE(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65) +#define SD_MESSAGE_DNSSEC_TRUST_ANCHOR_REVOKED_STR SD_ID128_MAKE_STR(4d,44,08,cf,d0,d1,44,85,91,84,d1,e6,5d,7c,8a,65) +#define SD_MESSAGE_DNSSEC_DOWNGRADE SD_ID128_MAKE(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57) +#define SD_MESSAGE_DNSSEC_DOWNGRADE_STR SD_ID128_MAKE_STR(36,db,2d,fa,5a,90,45,e1,bd,4a,f5,f9,3e,1c,f0,57) + +#define SD_MESSAGE_UNSAFE_USER_NAME SD_ID128_MAKE(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f) +#define SD_MESSAGE_UNSAFE_USER_NAME_STR SD_ID128_MAKE_STR(b6,1f,da,c6,12,e9,4b,91,82,28,5b,99,88,43,06,1f) + +#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE SD_ID128_MAKE(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93) +#define SD_MESSAGE_MOUNT_POINT_PATH_NOT_SUITABLE_STR SD_ID128_MAKE_STR(1b,3b,b9,40,37,f0,4b,bf,81,02,8e,13,5a,12,d2,93) +#define SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE SD_ID128_MAKE(01,01,90,13,8f,49,4e,29,a0,ef,66,69,74,95,31,aa) +#define SD_MESSAGE_DEVICE_PATH_NOT_SUITABLE_STR SD_ID128_MAKE_STR(01,01,90,13,8f,49,4e,29,a0,ef,66,69,74,95,31,aa) + +#define SD_MESSAGE_NOBODY_USER_UNSUITABLE SD_ID128_MAKE(b4,80,32,5f,9c,39,4a,7b,80,2c,23,1e,51,a2,75,2c) +#define SD_MESSAGE_NOBODY_USER_UNSUITABLE_STR SD_ID128_MAKE_STR(b4,80,32,5f,9c,39,4a,7b,80,2c,23,1e,51,a2,75,2c) + +#define SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED SD_ID128_MAKE(1c,04,54,c1,bd,22,41,e0,ac,6f,ef,b4,bc,63,14,33) +#define SD_MESSAGE_SYSTEMD_UDEV_SETTLE_DEPRECATED_STR SD_ID128_MAKE_STR(1c,04,54,c1,bd,22,41,e0,ac,6f,ef,b4,bc,63,14,33) + +#define SD_MESSAGE_TIME_SYNC SD_ID128_MAKE(7c,8a,41,f3,7b,76,49,41,a0,e1,78,0b,1b,e2,f0,37) +#define SD_MESSAGE_TIME_SYNC_STR SD_ID128_MAKE_STR(7c,8a,41,f3,7b,76,49,41,a0,e1,78,0b,1b,e2,f0,37) + +#define SD_MESSAGE_TIME_BUMP SD_ID128_MAKE(7d,b7,3c,8a,f0,d9,4e,eb,82,2a,e0,43,23,fe,6a,b6) +#define SD_MESSAGE_TIME_BUMP_STR SD_ID128_MAKE_STR(7d,b7,3c,8a,f0,d9,4e,eb,82,2a,e0,43,23,fe,6a,b6) + +#define SD_MESSAGE_SHUTDOWN_SCHEDULED SD_ID128_MAKE(9e,70,66,27,9d,c8,40,3d,a7,9c,e4,b1,a6,90,64,b2) +#define SD_MESSAGE_SHUTDOWN_SCHEDULED_STR SD_ID128_MAKE_STR(9e,70,66,27,9d,c8,40,3d,a7,9c,e4,b1,a6,90,64,b2) + +#define SD_MESSAGE_SHUTDOWN_CANCELED SD_ID128_MAKE(24,9f,6f,b9,e6,e2,42,8c,96,f3,f0,87,56,81,ff,a3) +#define SD_MESSAGE_SHUTDOWN_CANCELED_STR SD_ID128_MAKE_STR(24,9f,6f,b9,e6,e2,42,8c,96,f3,f0,87,56,81,ff,a3) + +#define SD_MESSAGE_TPM_PCR_EXTEND SD_ID128_MAKE(3f,7d,5e,f3,e5,4f,43,02,b4,f0,b1,43,bb,27,0c,ab) +#define SD_MESSAGE_TPM_PCR_EXTEND_STR SD_ID128_MAKE_STR(3f,7d,5e,f3,e5,4f,43,02,b4,f0,b1,43,bb,27,0c,ab) + +#define SD_MESSAGE_MEMORY_TRIM SD_ID128_MAKE(f9,b0,be,46,5a,d5,40,d0,85,0a,d3,21,72,d5,7c,21) +#define SD_MESSAGE_MEMORY_TRIM_STR SD_ID128_MAKE_STR(f9,b0,be,46,5a,d5,40,d0,85,0a,d3,21,72,d5,7c,21) + +#define SD_MESSAGE_SYSV_GENERATOR_DEPRECATED SD_ID128_MAKE(a8,fa,8d,ac,db,1d,44,3e,95,03,b8,be,36,7a,6a,db) +#define SD_MESSAGE_SYSV_GENERATOR_DEPRECATED_STR SD_ID128_MAKE_STR(a8,fa,8d,ac,db,1d,44,3e,95,03,b8,be,36,7a,6a,db) + +#define SD_MESSAGE_PORTABLE_ATTACHED SD_ID128_MAKE(18,7c,62,eb,1e,7f,46,3b,b5,30,39,4f,52,cb,09,0f) +#define SD_MESSAGE_PORTABLE_ATTACHED_STR SD_ID128_MAKE_STR(18,7c,62,eb,1e,7f,46,3b,b5,30,39,4f,52,cb,09,0f) +#define SD_MESSAGE_PORTABLE_DETACHED SD_ID128_MAKE(76,c5,c7,54,d6,28,49,0d,8e,cb,a4,c9,d0,42,11,2b) +#define SD_MESSAGE_PORTABLE_DETACHED_STR SD_ID128_MAKE_STR(76,c5,c7,54,d6,28,49,0d,8e,cb,a4,c9,d0,42,11,2b) + +#define SD_MESSAGE_SRK_ENROLLMENT_NEEDS_AUTHORIZATION SD_ID128_MAKE(ad,70,89,f9,28,ac,4f,7e,a0,0c,07,45,7d,47,ba,8a) +#define SD_MESSAGE_SRK_ENROLLMENT_NEEDS_AUTHORIZATION_STR SD_ID128_MAKE_STR(ad,70,89,f9,28,ac,4f,7e,a0,0c,07,45,7d,47,ba,8a) + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/include/systemd/sd-path.h b/thirdparty/systemd/include/systemd/sd-path.h new file mode 100644 index 000000000..fcd90aa96 --- /dev/null +++ b/thirdparty/systemd/include/systemd/sd-path.h @@ -0,0 +1,131 @@ +/* SPDX-License-Identifier: LGPL-2.1-or-later */ +#ifndef foosdpathhfoo +#define foosdpathhfoo + +/*** + systemd is free software; you can redistribute it and/or modify it + under the terms of the GNU Lesser General Public License as published by + the Free Software Foundation; either version 2.1 of the License, or + (at your option) any later version. + + systemd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public License + along with systemd; If not, see <https://www.gnu.org/licenses/>. +***/ + +#include <inttypes.h> + +#include "_sd-common.h" + +_SD_BEGIN_DECLARATIONS; + +enum { + /* Temporary files */ + SD_PATH_TEMPORARY, + SD_PATH_TEMPORARY_LARGE, + + /* Vendor supplied data */ + SD_PATH_SYSTEM_BINARIES, + SD_PATH_SYSTEM_INCLUDE, + SD_PATH_SYSTEM_LIBRARY_PRIVATE, + SD_PATH_SYSTEM_LIBRARY_ARCH, + SD_PATH_SYSTEM_SHARED, + SD_PATH_SYSTEM_CONFIGURATION_FACTORY, + SD_PATH_SYSTEM_STATE_FACTORY, + + /* System configuration, runtime, state, ... */ + SD_PATH_SYSTEM_CONFIGURATION, + SD_PATH_SYSTEM_RUNTIME, + SD_PATH_SYSTEM_RUNTIME_LOGS, + SD_PATH_SYSTEM_STATE_PRIVATE, + SD_PATH_SYSTEM_STATE_LOGS, + SD_PATH_SYSTEM_STATE_CACHE, + SD_PATH_SYSTEM_STATE_SPOOL, + + /* Vendor supplied data */ + SD_PATH_USER_BINARIES, + SD_PATH_USER_LIBRARY_PRIVATE, + SD_PATH_USER_LIBRARY_ARCH, + SD_PATH_USER_SHARED, + + /* User configuration, state, runtime ... */ + SD_PATH_USER_CONFIGURATION, + SD_PATH_USER_RUNTIME, + SD_PATH_USER_STATE_CACHE, + /* → SD_PATH_USER_STATE_PRIVATE is added at the bottom */ + + /* User resources */ + SD_PATH_USER, /* $HOME itself */ + SD_PATH_USER_DOCUMENTS, + SD_PATH_USER_MUSIC, + SD_PATH_USER_PICTURES, + SD_PATH_USER_VIDEOS, + SD_PATH_USER_DOWNLOAD, + SD_PATH_USER_PUBLIC, + SD_PATH_USER_TEMPLATES, + SD_PATH_USER_DESKTOP, + + /* Search paths */ + SD_PATH_SEARCH_BINARIES, + SD_PATH_SEARCH_BINARIES_DEFAULT, + SD_PATH_SEARCH_LIBRARY_PRIVATE, + SD_PATH_SEARCH_LIBRARY_ARCH, + SD_PATH_SEARCH_SHARED, + SD_PATH_SEARCH_CONFIGURATION_FACTORY, + SD_PATH_SEARCH_STATE_FACTORY, + SD_PATH_SEARCH_CONFIGURATION, + + /* Various systemd paths, generally mirroring systemd.pc — Except we drop the "dir" suffix (and + * replaces "path" by "search"), since this API is about dirs/paths anyway, and contains "path" + * already in the prefix */ + SD_PATH_SYSTEMD_UTIL, + + SD_PATH_SYSTEMD_SYSTEM_UNIT, + SD_PATH_SYSTEMD_SYSTEM_PRESET, + SD_PATH_SYSTEMD_SYSTEM_CONF, + SD_PATH_SYSTEMD_USER_UNIT, + SD_PATH_SYSTEMD_USER_PRESET, + SD_PATH_SYSTEMD_USER_CONF, + + SD_PATH_SYSTEMD_SEARCH_SYSTEM_UNIT, + SD_PATH_SYSTEMD_SEARCH_USER_UNIT, + + SD_PATH_SYSTEMD_SYSTEM_GENERATOR, + SD_PATH_SYSTEMD_USER_GENERATOR, + SD_PATH_SYSTEMD_SEARCH_SYSTEM_GENERATOR, + SD_PATH_SYSTEMD_SEARCH_USER_GENERATOR, + + SD_PATH_SYSTEMD_SLEEP, + SD_PATH_SYSTEMD_SHUTDOWN, + + SD_PATH_TMPFILES, + SD_PATH_SYSUSERS, + SD_PATH_SYSCTL, + SD_PATH_BINFMT, + SD_PATH_MODULES_LOAD, + SD_PATH_CATALOG, + + /* systemd-networkd search paths */ + SD_PATH_SYSTEMD_SEARCH_NETWORK, + + /* systemd environment generators */ + SD_PATH_SYSTEMD_SYSTEM_ENVIRONMENT_GENERATOR, + SD_PATH_SYSTEMD_USER_ENVIRONMENT_GENERATOR, + SD_PATH_SYSTEMD_SEARCH_SYSTEM_ENVIRONMENT_GENERATOR, + SD_PATH_SYSTEMD_SEARCH_USER_ENVIRONMENT_GENERATOR, + + SD_PATH_USER_STATE_PRIVATE, + + _SD_PATH_MAX +}; + +int sd_path_lookup(uint64_t type, const char *suffix, char **path); +int sd_path_lookup_strv(uint64_t type, const char *suffix, char ***paths); + +_SD_END_DECLARATIONS; + +#endif diff --git a/thirdparty/systemd/lib/libblkid.a b/thirdparty/systemd/lib/libblkid.a Binary files differnew file mode 100644 index 000000000..d0bcf9191 --- /dev/null +++ b/thirdparty/systemd/lib/libblkid.a diff --git a/thirdparty/systemd/lib/libcap.a b/thirdparty/systemd/lib/libcap.a Binary files differnew file mode 100644 index 000000000..f82526191 --- /dev/null +++ b/thirdparty/systemd/lib/libcap.a diff --git a/thirdparty/systemd/lib/libcrypt.a b/thirdparty/systemd/lib/libcrypt.a Binary files differnew file mode 100644 index 000000000..42ab1a2be --- /dev/null +++ b/thirdparty/systemd/lib/libcrypt.a diff --git a/thirdparty/systemd/lib/liblz4.a b/thirdparty/systemd/lib/liblz4.a Binary files differnew file mode 100644 index 000000000..4354b76f0 --- /dev/null +++ b/thirdparty/systemd/lib/liblz4.a diff --git a/thirdparty/systemd/lib/liblzma.a b/thirdparty/systemd/lib/liblzma.a Binary files differnew file mode 100644 index 000000000..25c9cc2fd --- /dev/null +++ b/thirdparty/systemd/lib/liblzma.a diff --git a/thirdparty/systemd/lib/libmount.a b/thirdparty/systemd/lib/libmount.a Binary files differnew file mode 100644 index 000000000..8b2f8237a --- /dev/null +++ b/thirdparty/systemd/lib/libmount.a diff --git a/thirdparty/systemd/lib/libpsx.a b/thirdparty/systemd/lib/libpsx.a Binary files differnew file mode 100644 index 000000000..e40f6b852 --- /dev/null +++ b/thirdparty/systemd/lib/libpsx.a diff --git a/thirdparty/systemd/lib/libsystemd.a b/thirdparty/systemd/lib/libsystemd.a Binary files differnew file mode 100644 index 000000000..059667f0b --- /dev/null +++ b/thirdparty/systemd/lib/libsystemd.a diff --git a/thirdparty/systemd/lib/libzstd.a b/thirdparty/systemd/lib/libzstd.a Binary files differnew file mode 100644 index 000000000..8bbce4b3b --- /dev/null +++ b/thirdparty/systemd/lib/libzstd.a |