From d7e5e81a6db5d9fb3f49b70d28e398a39c825bfb Mon Sep 17 00:00:00 2001 From: pupbrained Date: Mon, 12 May 2025 22:55:38 -0400 Subject: [PATCH] oops --- src/OS/Haiku.cpp | 153 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 153 insertions(+) create mode 100644 src/OS/Haiku.cpp diff --git a/src/OS/Haiku.cpp b/src/OS/Haiku.cpp new file mode 100644 index 0000000..9d5d58f --- /dev/null +++ b/src/OS/Haiku.cpp @@ -0,0 +1,153 @@ +#ifdef __HAIKU__ + +// clang-format off +#include // For BAppFileInfo and version_info +#include // B_OK, strerror, status_t +#include // For BFile +#include // get_system_info, system_info +#include // PATH_MAX +#include // std::strlen +#include // BPackageKit::BPackageInfoSet +#include // BPackageKit::BPackageInfo +#include // BPackageKit::BPackageRoster +#include // ucred, getsockopt, SOL_SOCKET, SO_PEERCRED +#include // statvfs +#include // std::move + +#include "Services/PackageCounting.hpp" +#include "Util/Definitions.hpp" +#include "Util/Error.hpp" +#include "Util/Env.hpp" +#include "Util/Loggin.hpp" +#include "Util/Types.hpp" + +#include "OperatingSystem.hpp" +// clang-format on + +using namespace util::types; +using util::error::DracError, util::error::DracErrorCode; +using util::helpers::GetEnv; + +namespace os { + fn GetOSVersion() -> Result { + BFile file; + status_t status = file.SetTo("/boot/system/lib/libbe.so", B_READ_ONLY); + + if (status != B_OK) + return Err(DracError(DracErrorCode::InternalError, "Error opening /boot/system/lib/libbe.so")); + + BAppFileInfo appInfo; + status = appInfo.SetTo(&file); + + if (status != B_OK) + return Err(DracError(DracErrorCode::InternalError, "Error initializing BAppFileInfo")); + + version_info versionInfo; + status = appInfo.GetVersionInfo(&versionInfo, B_APP_VERSION_KIND); + + if (status != B_OK) + return Err(DracError(DracErrorCode::InternalError, "Error reading version info attribute")); + + String versionShortString = versionInfo.short_info; + + if (versionShortString.empty()) + return Err(DracError(DracErrorCode::InternalError, "Version info short_info is empty")); + + return std::format("Haiku {}", versionShortString); + } + + fn GetMemInfo() -> Result { + system_info sysinfo; + const status_t status = get_system_info(&sysinfo); + + if (status != B_OK) + return Err(DracError(DracErrorCode::InternalError, std::format("get_system_info failed: {}", strerror(status)))); + + return static_cast(sysinfo.max_pages) * B_PAGE_SIZE; + } + + fn GetNowPlaying() -> Result { + return Err(DracError(DracErrorCode::NotSupported, "Now playing is not supported on Haiku")); + } + + fn GetWindowManager() -> Result { + return "app_server"; + } + + fn GetDesktopEnvironment() -> Result { + return "Haiku Desktop Environment"; + } + + fn GetShell() -> Result { + if (const Result shellPath = GetEnv("SHELL")) { + // clang-format off + constexpr Array, 5> shellMap {{ + { "bash", "Bash" }, + { "zsh", "Zsh" }, + { "fish", "Fish" }, + { "nu", "Nushell" }, + { "sh", "SH" }, // sh last because other shells contain "sh" + }}; + // clang-format on + + for (const auto& [exe, name] : shellMap) + if (shellPath->contains(exe)) + return String(name); + + return *shellPath; // fallback to the raw shell path + } + + return Err(DracError(DracErrorCode::NotFound, "Could not find SHELL environment variable")); + } + + fn GetHost() -> Result { + Array hostnameBuffer {}; + + if (gethostname(hostnameBuffer.data(), hostnameBuffer.size()) != 0) + return Err(DracError( + DracErrorCode::ApiUnavailable, std::format("gethostname() failed: {} (errno {})", strerror(errno), errno) + )); + + hostnameBuffer.at(HOST_NAME_MAX) = '\0'; + + return String(hostnameBuffer.data(), hostnameBuffer.size()); + } + + fn GetKernelVersion() -> Result { + system_info sysinfo; + const status_t status = get_system_info(&sysinfo); + + if (status != B_OK) + return Err(DracError(DracErrorCode::InternalError, std::format("get_system_info failed: {}", strerror(status)))); + + return std::to_string(sysinfo.kernel_version); + } + + fn GetDiskUsage() -> Result { + struct statvfs stat; + + if (statvfs("/boot", &stat) == -1) + return Err(DracError::withErrno(std::format("Failed to get filesystem stats for '/boot' (statvfs call failed)"))); + + return DiskSpace { + .used_bytes = (stat.f_blocks * stat.f_frsize) - (stat.f_bfree * stat.f_frsize), + .total_bytes = stat.f_blocks * stat.f_frsize, + }; + } +} // namespace os + +namespace package { + fn GetHaikuCount() -> Result { + BPackageKit::BPackageRoster roster; + BPackageKit::BPackageInfoSet packageList; + + const status_t status = roster.GetActivePackages(BPackageKit::B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, packageList); + + if (status != B_OK) + return Err(DracError(DracErrorCode::ApiUnavailable, "Failed to get active package list")); + + return static_cast(packageList.CountInfos()); + } +} // namespace package + +#endif // __HAIKU__