Files
fastfetch/src/detection/os/os_linux.c
T

429 lines
18 KiB
C
Raw Normal View History

2022-09-04 13:33:18 +02:00
#include "os.h"
2026-01-06 09:48:38 +08:00
#include "common/properties.h"
#include "common/parsing.h"
#include "common/io.h"
#include "common/processing.h"
2026-05-28 15:58:08 +08:00
#include "common/strutil.h"
2022-01-14 13:21:49 +01:00
2022-04-26 19:21:19 +02:00
#include <string.h>
2022-06-18 14:25:31 +02:00
#include <stdlib.h>
2022-01-14 13:21:49 +01:00
2026-03-29 09:28:49 +08:00
static bool parseLsbRelease(const char* fileName, FFOSResult* result) {
return ffParsePropFileValues(fileName, 4, (FFpropquery[]) {
2026-03-30 10:27:23 +08:00
{ "DISTRIB_ID =", &result->id },
{ "DISTRIB_DESCRIPTION =", &result->prettyName },
{ "DISTRIB_RELEASE =", &result->version },
{ "DISTRIB_CODENAME =", &result->codename },
2026-03-29 09:28:49 +08:00
});
}
2026-03-29 09:28:49 +08:00
static bool parseOsRelease(const char* fileName, FFOSResult* result) {
2024-05-19 11:12:06 +08:00
return ffParsePropFileValues(fileName, 11, (FFpropquery[]) {
2026-03-30 10:27:23 +08:00
{ "PRETTY_NAME =", &result->prettyName },
{ "NAME =", &result->name },
{ "ID =", &result->id },
{ "ID_LIKE =", &result->idLike },
{ "VARIANT =", &result->variant },
{ "VARIANT_ID =", &result->variantID },
{ "VERSION =", &result->version },
{ "VERSION_ID =", &result->versionID },
{ "VERSION_CODENAME =", &result->codename },
{ "CODENAME =", &result->codename },
{ "BUILD_ID =", &result->buildID },
2026-03-29 09:28:49 +08:00
});
2022-01-18 18:56:37 +01:00
}
// Common logic for detecting Armbian image version
2026-04-09 16:20:59 +08:00
FF_A_UNUSED static bool detectArmbianVersion(FFOSResult* result) {
// Possible values `PRETTY_NAME` starts with on Armbian:
// - `Armbian` for official releases
// - `Armbian_community` for community releases
// - `Armbian_Security` for images with kali repo added
// - `Armbian-unofficial` for an unofficial image built from source, e.g. during development and testing
2026-03-29 09:28:49 +08:00
if (ffStrbufStartsWithS(&result->prettyName, "Armbian")) {
ffStrbufSetStatic(&result->name, "Armbian");
2026-03-29 09:28:49 +08:00
} else {
return false;
2026-03-29 09:28:49 +08:00
}
ffStrbufSet(&result->idLike, &result->id);
ffStrbufSetS(&result->id, "armbian");
ffStrbufClear(&result->versionID);
uint32_t versionStart = ffStrbufFirstIndexC(&result->prettyName, ' ') + 1;
uint32_t versionEnd = ffStrbufNextIndexC(&result->prettyName, versionStart, ' ');
ffStrbufSetNS(&result->versionID, versionEnd - versionStart, result->prettyName.chars + versionStart);
return true;
}
2025-09-30 09:02:26 +08:00
// Returns false if PrettyName should be updated by caller
2026-04-09 16:20:59 +08:00
FF_A_UNUSED static bool getUbuntuFlavour(FFOSResult* result) {
2026-03-29 09:28:49 +08:00
if (detectArmbianVersion(result)) {
2025-09-30 09:02:26 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->prettyName, "Linux Lite ")) {
ffStrbufSetStatic(&result->name, "Linux Lite");
ffStrbufSetStatic(&result->id, "linuxlite");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2024-12-11 16:35:19 +08:00
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Linux Lite "));
2025-09-30 09:02:26 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->prettyName, "Rhino Linux ")) {
ffStrbufSetStatic(&result->name, "Rhino Linux");
ffStrbufSetStatic(&result->id, "rhinolinux");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-01-07 16:30:22 +03:00
ffStrbufSetS(&result->versionID, result->prettyName.chars + strlen("Rhino Linux "));
2025-09-30 09:02:26 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->prettyName, "VanillaOS ")) {
ffStrbufSetStatic(&result->id, "vanilla");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return true;
2025-02-21 10:32:34 +08:00
}
2024-12-11 16:35:19 +08:00
2026-03-29 09:28:49 +08:00
if (ffPathExists("/usr/bin/lliurex-version", FF_PATHTYPE_FILE)) {
2025-08-11 03:45:53 +02:00
ffStrbufSetStatic(&result->name, "LliureX");
ffStrbufSetStatic(&result->id, "lliurex");
ffStrbufClear(&result->version);
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
2026-03-29 09:28:49 +08:00
"/usr/bin/lliurex-version",
2026-07-10 18:08:04 +08:00
nullptr,
}) == nullptr) { // 8.2.2
2025-08-11 03:45:53 +02:00
ffStrbufTrimRightSpace(&result->version);
2026-03-29 09:28:49 +08:00
}
2025-08-11 03:45:53 +02:00
ffStrbufSetF(&result->prettyName, "LliureX %s", result->version.chars);
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return true;
2025-08-11 16:38:39 +08:00
}
2025-08-11 03:45:53 +02:00
2026-05-02 22:18:08 +08:00
// xdgConfigDirs contains plasma only
if (ffPathExists("/var/lib/dpkg/info/ubuntustudio-desktop.list", FF_PATHTYPE_FILE)) {
ffStrbufSetStatic(&result->name, "Ubuntu Studio");
ffStrbufSetStatic(&result->id, "ubuntu-studio");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return false;
}
2026-05-02 22:18:08 +08:00
const char* xdgConfigDirs = getenv("XDG_CONFIG_DIRS");
if (!ffStrSet(xdgConfigDirs)) {
return false;
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "kde") || ffStrContains(xdgConfigDirs, "plasma") || ffStrContains(xdgConfigDirs, "kubuntu")) {
ffStrbufSetStatic(&result->name, "Kubuntu");
ffStrbufSetStatic(&result->id, "kubuntu");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "xfce") || ffStrContains(xdgConfigDirs, "xubuntu")) {
ffStrbufSetStatic(&result->name, "Xubuntu");
ffStrbufSetStatic(&result->id, "xubuntu");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "lxqt") || ffStrContains(xdgConfigDirs, "lubuntu")) {
ffStrbufSetStatic(&result->name, "Lubuntu");
ffStrbufSetStatic(&result->id, "lubuntu");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "budgie")) {
ffStrbufSetStatic(&result->name, "Ubuntu Budgie");
ffStrbufSetStatic(&result->id, "ubuntu-budgie");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "cinnamon")) {
ffStrbufSetStatic(&result->name, "Ubuntu Cinnamon");
ffStrbufSetStatic(&result->id, "ubuntu-cinnamon");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2023-08-04 14:35:39 +08:00
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "mate")) {
ffStrbufSetStatic(&result->name, "Ubuntu MATE");
ffStrbufSetStatic(&result->id, "ubuntu-mate");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2026-05-02 21:59:22 +08:00
if (ffStrContains(xdgConfigDirs, "ukui")) {
ffStrbufSetStatic(&result->name, "Ubuntu Kylin");
ffStrbufSetStatic(&result->id, "ubuntu-kylin");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2023-08-04 14:35:39 +08:00
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "sway")) {
ffStrbufSetStatic(&result->name, "Ubuntu Sway");
ffStrbufSetStatic(&result->id, "ubuntu-sway");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2023-08-04 14:35:39 +08:00
}
2026-03-29 09:28:49 +08:00
if (ffStrContains(xdgConfigDirs, "touch")) {
ffStrbufSetStatic(&result->name, "Ubuntu Touch");
ffStrbufSetStatic(&result->id, "ubuntu-touch");
ffStrbufSetStatic(&result->idLike, "ubuntu");
2025-09-30 09:02:26 +08:00
return false;
2026-05-02 22:06:18 +08:00
}
if (ffStrContains(xdgConfigDirs, "unity")) {
ffStrbufSetStatic(&result->name, "Ubuntu Unity");
ffStrbufSetStatic(&result->id, "ubuntu-unity");
ffStrbufSetStatic(&result->idLike, "ubuntu");
return false;
2023-08-04 14:35:39 +08:00
}
2025-09-30 09:02:26 +08:00
return false;
2022-04-26 19:21:19 +02:00
}
2026-04-09 16:20:59 +08:00
FF_A_UNUSED static void getDebianVersion(FFOSResult* result) {
2023-09-24 21:49:39 +08:00
FF_STRBUF_AUTO_DESTROY debianVersion = ffStrbufCreate();
ffAppendFileBuffer("/etc/debian_version", &debianVersion);
2023-12-23 04:55:14 +09:00
ffStrbufTrimRightSpace(&debianVersion);
2026-03-29 09:28:49 +08:00
if (!debianVersion.length) {
return;
}
2025-09-30 09:02:03 +08:00
ffStrbufDestroy(&result->versionID);
ffStrbufInitMove(&result->versionID, &debianVersion);
ffStrbufSetF(&result->prettyName, "%s %s (%s)", result->name.chars, result->versionID.chars, result->codename.chars);
2023-09-24 21:49:39 +08:00
}
2026-04-09 16:20:59 +08:00
FF_A_UNUSED static bool detectDebianDerived(FFOSResult* result) {
2026-03-29 09:28:49 +08:00
if (detectArmbianVersion(result)) {
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->name, "Loc-OS")) {
ffStrbufSetStatic(&result->id, "locos");
ffStrbufSetStatic(&result->idLike, "debian");
2024-09-14 09:00:27 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufEqualS(&result->name, "Parrot Security")) {
2024-09-14 09:00:27 +08:00
// https://github.com/ParrotSec/base-files/blob/c06f6d42ddf8d79564882306576576eddab7d907/etc/os-release
ffStrbufSetS(&result->id, "parrot");
ffStrbufSetS(&result->idLike, "debian");
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->name, "Lilidog GNU/Linux")) {
2024-11-04 09:19:53 +08:00
// https://github.com/fastfetch-cli/fastfetch/issues/1373
ffStrbufSetStatic(&result->id, "lilidog");
ffStrbufSetStatic(&result->idLike, "debian");
2024-11-04 09:19:53 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else if (access("/usr/bin/pveversion", X_OK) == 0) {
ffStrbufSetStatic(&result->id, "proxmox");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "Proxmox VE");
2024-05-06 16:46:27 +08:00
ffStrbufClear(&result->versionID);
if (ffProcessAppendStdOut(&result->versionID, (char* const[]) {
2026-03-29 09:28:49 +08:00
"/usr/bin/dpkg-query",
"--showformat=${version}",
"--show",
"pve-manager",
2026-07-10 18:08:04 +08:00
nullptr,
}) == nullptr) { // 8.2.2
ffStrbufTrimRightSpace(&result->versionID);
ffStrbufSetStatic(&result->prettyName, "Proxmox VE ");
ffStrbufAppend(&result->prettyName, &result->versionID);
} else {
ffStrbufSetStatic(&result->prettyName, "Proxmox VE");
}
return true;
} else if (access("/usr/sbin/proxmox-backup-manager", X_OK) == 0) {
ffStrbufSetStatic(&result->id, "proxmox");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "Proxmox Backup Server");
ffStrbufClear(&result->versionID);
if (ffProcessAppendStdOut(&result->versionID, (char* const[]) {
"/usr/bin/dpkg-query",
"--showformat=${version}",
"--show",
"proxmox-backup-server",
2026-07-10 18:08:04 +08:00
nullptr,
}) == nullptr) {
ffStrbufTrimRightSpace(&result->versionID);
ffStrbufSetStatic(&result->prettyName, "Proxmox Backup Server ");
ffStrbufAppend(&result->prettyName, &result->versionID);
} else {
ffStrbufSetStatic(&result->prettyName, "Proxmox Backup Server");
2026-03-29 09:28:49 +08:00
}
return true;
2026-03-29 09:28:49 +08:00
} else if (ffPathExists("/etc/rpi-issue", FF_PATHTYPE_FILE)) {
2025-06-23 22:10:50 +08:00
// Raspberry Pi OS
ffStrbufSetStatic(&result->id, "raspbian");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "Raspberry Pi OS");
getDebianVersion(result);
2025-06-23 22:10:50 +08:00
return true;
2026-03-29 09:28:49 +08:00
} else if (ffPathExists("/boot/dietpi/.version", FF_PATHTYPE_FILE)) {
2025-06-23 22:10:50 +08:00
// DietPi
ffStrbufSetStatic(&result->id, "dietpi");
ffStrbufSetStatic(&result->name, "DietPi");
ffStrbufSetStatic(&result->prettyName, "DietPi");
ffStrbufSetStatic(&result->idLike, "debian");
FF_STRBUF_AUTO_DESTROY core = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY sub = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY rc = ffStrbufCreate();
if (ffParsePropFileValues("/boot/dietpi/.version", 3, (FFpropquery[]) {
2026-03-30 10:27:23 +08:00
{ "G_DIETPI_VERSION_CORE=", &core },
{ "G_DIETPI_VERSION_SUB=", &sub },
{ "G_DIETPI_VERSION_RC=", &rc },
2026-03-29 09:28:49 +08:00
})) {
ffStrbufAppendF(&result->prettyName, " %s.%s.%s", core.chars, sub.chars, rc.chars);
}
return true;
2026-03-29 09:28:49 +08:00
} else if (ffStrbufEndsWithS(&instance.state.platform.sysinfo.release, "+truenas")) {
// TrueNAS Scale
ffStrbufSetStatic(&result->id, "truenas-scale");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "TrueNAS Scale");
ffStrbufSetStatic(&result->prettyName, "TrueNAS Scale");
return true;
2026-03-29 09:28:49 +08:00
} else if (ffPathExists("/usr/bin/emmabuntus_config.sh", FF_PATHTYPE_FILE)) {
// Emmabuntüs
ffStrbufSetStatic(&result->id, "emmabuntus");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "Emmabuntüs");
getDebianVersion(result);
return true;
2026-03-29 09:28:49 +08:00
} else {
// Hack for MX Linux. See #847
FF_STRBUF_AUTO_DESTROY lsbRelease = ffStrbufCreate();
2026-03-29 09:28:49 +08:00
if (ffAppendFileBuffer("/etc/lsb-release", &lsbRelease) && ffStrbufContainS(&lsbRelease, "DISTRIB_ID=MX")) {
ffStrbufSetStatic(&result->id, "mx");
ffStrbufSetStatic(&result->idLike, "debian");
ffStrbufSetStatic(&result->name, "MX");
ffStrbufClear(&result->version);
ffParsePropLines(lsbRelease.chars, "DISTRIB_RELEASE=", &result->version);
ffStrbufSet(&result->versionID, &result->version);
ffStrbufClear(&result->codename);
ffParsePropLines(lsbRelease.chars, "DISTRIB_CODENAME=", &result->codename);
ffStrbufClear(&result->prettyName);
ffParsePropLines(lsbRelease.chars, "DISTRIB_DESCRIPTION=", &result->prettyName);
return true;
}
}
return false;
2024-05-06 16:46:27 +08:00
}
2026-04-09 16:20:59 +08:00
FF_A_UNUSED static bool detectFedoraVariant(FFOSResult* result) {
2026-03-29 09:28:49 +08:00
if (ffStrbufEqualS(&result->variantID, "coreos") || ffStrbufEqualS(&result->variantID, "kinoite") || ffStrbufEqualS(&result->variantID, "sericea") || ffStrbufEqualS(&result->variantID, "silverblue")) {
2025-07-04 10:10:29 +08:00
ffStrbufAppendC(&result->id, '-');
ffStrbufAppend(&result->id, &result->variantID);
ffStrbufSetStatic(&result->idLike, "fedora");
return true;
}
return false;
}
2026-05-06 18:15:57 +08:00
FF_A_UNUSED static bool detectBedrock(FFOSResult* os) {
const char* bedrockRestrict = getenv("BEDROCK_RESTRICT");
2026-03-29 09:28:49 +08:00
if (bedrockRestrict && bedrockRestrict[0] == '1') {
return false;
}
return parseOsRelease(FASTFETCH_TARGET_DIR_ROOT "/bedrock/strata/bedrock/etc/os-release", os);
}
2026-05-06 18:15:57 +08:00
FF_A_UNUSED static void detectDeepinEnhancement(FFOSResult* result) {
if (ffStrbufContainC(&result->prettyName, '(')) {
return;
}
FF_STRBUF_AUTO_DESTROY minor = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY edition = ffStrbufCreate();
if (!ffParsePropFileValues(
FASTFETCH_TARGET_DIR_ETC "/os-version",
2,
(FFpropquery[]) {
{ "MinorVersion=", &minor },
{ "EditionName=", &edition },
}) ||
minor.length == 0) {
return;
}
ffStrbufSet(&result->versionID, &minor);
if (edition.length > 0) {
ffStrbufSetF(&result->prettyName, "%s %s (%s)", result->name.chars, minor.chars, edition.chars);
} else {
ffStrbufSetF(&result->prettyName, "%s %s", result->name.chars, minor.chars);
}
}
FF_A_UNUSED static void detectAstraVersion(FFOSResult* result) {
// `PRETTY_NAME` is just `Astra Linux`; the version is in `VERSION_ID`, e.g. `2.12_x86-64`
2026-07-03 15:37:38 +08:00
if (result->version.length == 0) { // Should be empty. Just in case
ffStrbufAppendSUntilC(&result->version, result->versionID.chars, '_');
}
if (result->version.length > 0) {
ffStrbufAppendC(&result->prettyName, ' ');
ffStrbufAppend(&result->prettyName, &result->version);
}
}
2026-03-29 09:28:49 +08:00
static void detectOS(FFOSResult* os) {
#ifdef FF_CUSTOM_OS_RELEASE_PATH
parseOsRelease(FF_STR(FF_CUSTOM_OS_RELEASE_PATH), os);
#ifdef FF_CUSTOM_LSB_RELEASE_PATH
2026-03-29 09:28:49 +08:00
parseLsbRelease(FF_STR(FF_CUSTOM_LSB_RELEASE_PATH), os);
#endif
return;
2026-03-29 09:28:49 +08:00
#endif
2026-05-06 18:15:57 +08:00
#ifdef __linux__
2026-03-29 09:28:49 +08:00
if (detectBedrock(os)) {
return;
2026-03-29 09:28:49 +08:00
}
2026-05-06 18:15:57 +08:00
#endif
2022-04-26 19:21:19 +02:00
// Refer: https://gist.github.com/natefoo/814c5bf936922dad97ff
parseOsRelease(FASTFETCH_TARGET_DIR_ETC "/os-release", os);
2026-03-29 09:28:49 +08:00
if (os->id.length == 0 || os->version.length == 0 || os->prettyName.length == 0 || os->codename.length == 0) {
parseLsbRelease(FASTFETCH_TARGET_DIR_ETC "/lsb-release", os);
2026-03-29 09:28:49 +08:00
}
if (os->id.length == 0 || os->name.length == 0 || os->prettyName.length == 0) {
parseOsRelease(FASTFETCH_TARGET_DIR_USR "/lib/os-release", os);
2026-03-29 09:28:49 +08:00
}
if (os->id.length == 0 && os->name.length == 0 && os->prettyName.length == 0) {
// HarmonyOS has no os-release file
2026-03-29 09:28:49 +08:00
if (ffStrbufEqualS(&instance.state.platform.sysinfo.name, "HarmonyOS")) {
ffStrbufSetS(&os->id, "harmonyos");
ffStrbufSetS(&os->idLike, "harmonyos");
ffStrbufSetS(&os->name, "HarmonyOS");
ffStrbufSetS(&os->prettyName, "HarmonyOS");
}
}
2022-09-04 13:33:18 +02:00
}
2022-01-14 13:21:49 +01:00
2026-03-29 09:28:49 +08:00
void ffDetectOSImpl(FFOSResult* os) {
detectOS(os);
2022-09-04 13:33:18 +02:00
2026-03-29 09:28:49 +08:00
#if __linux__ || __GNU__
if (ffStrbufEqualS(&os->id, "ubuntu")) {
if (!getUbuntuFlavour(os)) {
if (!ffStrbufEndsWithS(&os->prettyName, " (development branch)")) {
ffStrbufSetF(&os->prettyName, "%s %s", os->name.chars, os->version.chars); // os->version contains code name
2026-03-29 09:28:49 +08:00
}
}
2026-03-29 09:28:49 +08:00
} else if (ffStrbufEqualS(&os->id, "debian")) {
if (!detectDebianDerived(os)) {
getDebianVersion(os);
2026-03-29 09:28:49 +08:00
}
} else if (ffStrbufEqualS(&os->id, "fedora")) {
2025-07-04 10:10:29 +08:00
detectFedoraVariant(os);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufEqualS(&os->id, "linuxmint")) {
if (ffStrbufEqualS(&os->name, "LMDE")) {
2024-11-25 14:18:33 +08:00
ffStrbufSetS(&os->id, "lmde");
ffStrbufSetS(&os->idLike, "linuxmint");
}
} else if (ffStrbufEqualS(&os->id, "deepin")) {
detectDeepinEnhancement(os);
} else if (ffStrbufEqualS(&os->id, "astra")) {
detectAstraVersion(os);
2024-11-25 14:18:33 +08:00
}
2026-03-29 09:28:49 +08:00
#endif
2022-01-14 13:21:49 +01:00
}