AuroraRuntime/Source/SWInfo/AuSWInfo.Linux.cpp

212 lines
5.5 KiB
C++

/***
Copyright (C) 2022 J Reece Wilson (a/k/a "Reece"). All rights reserved.
File: AuSWInfo.Linux.cpp
Date: 2022-4-6
Author: Reece
***/
#include <Source/RuntimeInternal.hpp>
#include "AuSWInfo.hpp"
#include "AuSWInfo.Linux.hpp"
namespace Aurora::SWInfo
{
static AuString gKernelString;
static AuString gUserlandBrand;
static AuString gUserlandDesktopEnv;
static AuString gBuildString;
static void SetProcVersion()
{
AuIOFS::ReadString("/proc/version", gBuildString);
if (gBuildString.size() && gBuildString[gBuildString.size() - 1] == '\n')
{
gBuildString.pop_back();
}
}
static void SetVersion(OSInformation &osInfo)
{
char *endPtr;
auto versionItr = gBuildString.find("ersion ");
if (versionItr == AuString::npos) return;
if (versionItr > 2)
{
gKernelString = gBuildString.substr(0, versionItr - 2);
}
auto ptr = gBuildString.c_str() + (7 + AuUInt(versionItr));
osInfo.uKernelMajor = strtoll(ptr, &endPtr, 10);
if (errno == ERANGE) return;
if (*endPtr != '.') return;
endPtr++;
osInfo.uKernelMinor = strtoll(endPtr, &endPtr, 10);
if (errno == ERANGE) return;
if (*endPtr != '.') return;
endPtr++;
osInfo.uKernelPatch = strtoll(endPtr, &endPtr, 10);
}
static bool ProcessVersionLine(OSInformation &osInfo, const AuROString &line);
static void ParseOSRel(OSInformation &osInfo)
{
AuString osRel;
if (!AuIOFS::ReadString("/etc/os-release", osRel))
{
if (!AuIOFS::ReadString("/usr/lib/os-release", osRel))
{
return;
}
}
AuReplaceAll(osRel, "\"", "");
AuList<AuROString> versionNumbers;
Parse::SplitNewlines(osRel, [&](const AuROString &line)
{
if (AuStartsWith(line, "NAME="))
{
gUserlandBrand = AuString(line.substr(5));
}
else if (AuStartsWith(line, "VERSION="))
{
versionNumbers.push_back(line.substr(8));
}
else if (AuStartsWith(line, "VERSION_ID="))
{
versionNumbers.push_back(line.substr(11));
}
else if (AuStartsWith(line, "BUILD_ID="))
{
versionNumbers.push_back(line.substr(9));
}
});
std::sort(versionNumbers.begin(), versionNumbers.end(), [](const AuROString &str, const AuROString &strb)
{
return str.length() >= strb.length();
});
for (auto &line : versionNumbers)
{
if (line.size() > 2 && line[0] == '"' && line[line.size() - 1] == '"')
{
line = line.substr(1, line.size() - 2);
}
if (ProcessVersionLine(osInfo, line))
{
break;
}
}
// generic server/*erver (Server/server) distros
osInfo.bIsServer |= osRel.find("erver") != AuString::npos;
}
static bool ProcessVersionLineParts(OSInformation &osInfo, const AuROString &line)
{
auto firstPeriod = line.find(".");
if (firstPeriod == AuString::npos)
{
return false;
}
auto ptr = line.data();
char *endPtr = (char *)line.data() + line.size();
osInfo.uUserlandMajor = strtoll(ptr, &endPtr, 10);
if (errno == ERANGE) return false;
if (*endPtr != '.') return true;
endPtr++;
osInfo.uUserlandMinor = strtoll(endPtr, &endPtr, 10);
if (errno == ERANGE) return false;
if (*endPtr != '.') return true;
endPtr++;
osInfo.uUserlandPatch = strtoll(endPtr, &endPtr, 10);
return true;
}
static bool ProcessVersionLine(OSInformation &osInfo, const AuROString &line)
{
auto parts = AuSplitString(line, " ");
for (const auto &line : parts)
{
if (ProcessVersionLineParts(osInfo, line))
{
return true;
}
}
return false;
}
static void SetDesktopWindowManager()
{
const char *name;
name = ::getenv("XDG_CURRENT_DESKTOP");
if (!name)
{
name = ::getenv("XDG_SESSION_DESKTOP");
}
if (!name)
{
name = ::getenv("DESKTOP_SESSION");
}
if (name)
{
gUserlandDesktopEnv = name;
}
}
static void CheckForSupportLicenseHints(OSInformation &osInfo)
{
AuString a;
osInfo.bIsEnterprise = false;
if (AuFS::ReadString("/etc/system-release-cpe", a))
{
// redhat
osInfo.bIsEnterprise |= a.find("nterprise") != AuString::npos; // cpe:?????:enterprise_linux:??????
// aws
osInfo.bIsServer |= a.find("ami") != AuString::npos; // al202?-ami-202?.?.????.0-kernel-?.?-x86_64
}
else
{
// centos and similar
osInfo.bIsServer |= AuFS::FileExists("/etc/redhat-release");
}
}
void InitLinuxInfo(OSInformation &osInfo)
{
osInfo = AuMove(OSInformation(&gKernelString, &gUserlandBrand, &gUserlandDesktopEnv, &gBuildString, AuBuild::kCurrentPlatform));
SetProcVersion();
SetVersion(osInfo);
ParseOSRel(osInfo);
CheckForSupportLicenseHints(osInfo);
SetDesktopWindowManager();
}
}