master ohmu/fastfetch-openbsd / src / detection / host / host_linux.c
ohmu  ·  2026-10-15
  1#include "host.h"
  2#include "common/io.h"
  3#include "common/processing.h"
  4#include "common/smbios.h"
  5
  6#include <stdlib.h>
  7
  8static bool getHostProductName(FFstrbuf* name) {
  9    if (ffReadFileBuffer("/sys/firmware/devicetree/base/model", name) ||
 10        ffReadFileBuffer("/sys/firmware/devicetree/base/banner-name", name)) {
 11        ffStrbufTrimRight(name, '\0');
 12        return true;
 13    }
 14
 15    if (ffReadFileBuffer("/tmp/sysinfo/model", name)) {
 16        ffStrbufTrimRightSpace(name);
 17        ffStrbufTrimRight(name, '\0');
 18        if (ffIsSmbiosValueSet(name)) {
 19            return true;
 20        }
 21    }
 22
 23    return false;
 24}
 25
 26static bool getHostSerialNumber(FFstrbuf* serial) {
 27    if (ffReadFileBuffer("/sys/firmware/devicetree/base/smbios/smbios/system/serial", serial) ||
 28        ffReadFileBuffer("/sys/firmware/devicetree/base/serial-number", serial)) {
 29        ffStrbufTrimRight(serial, '\0');
 30        return true;
 31    }
 32    return false;
 33}
 34
 35static bool getHostProductFamily(FFstrbuf* family) {
 36    if (ffReadFileBuffer("/sys/firmware/devicetree/base/smbios/smbios/system/family", family) ||
 37        ffReadFileBuffer("/sys/firmware/devicetree/base/smbios/smbios/system/product", family)) {
 38        ffStrbufTrimRight(family, '\0');
 39        return true;
 40    }
 41    return false;
 42}
 43
 44static bool getHostVendor(FFstrbuf* vendor) {
 45    if (ffReadFileBuffer("/sys/firmware/devicetree/base/smbios/smbios/system/manufacturer", vendor)) {
 46        ffStrbufTrimRight(vendor, '\0');
 47        return true;
 48    }
 49    return false;
 50}
 51
 52const char* ffDetectHost(FFHostResult* host) {
 53    // This is a hack for Asahi Linux, whose product_family is empty
 54    bool productName = ffGetSmbiosValue("/sys/devices/virtual/dmi/id/product_name", "/sys/class/dmi/id/product_name", &host->name);
 55    bool productFamily = ffGetSmbiosValue("/sys/devices/virtual/dmi/id/product_family", "/sys/class/dmi/id/product_family", &host->family);
 56    if (productName || productFamily) {
 57        ffGetSmbiosValue("/sys/devices/virtual/dmi/id/product_version", "/sys/class/dmi/id/product_version", &host->version);
 58        ffGetSmbiosValue("/sys/devices/virtual/dmi/id/product_sku", "/sys/class/dmi/id/product_sku", &host->sku);
 59        ffGetSmbiosValue("/sys/devices/virtual/dmi/id/product_serial", "/sys/class/dmi/id/product_serial", &host->serial);
 60        ffGetSmbiosValue("/sys/devices/virtual/dmi/id/sys_vendor", "/sys/class/dmi/id/sys_vendor", &host->vendor);
 61
 62#if __x86_64__
 63        ffHostDetectMac(host);
 64#endif
 65
 66        // KVM/Qemu virtual machine
 67        if (ffStrbufStartsWithS(&host->name, "Standard PC")) {
 68            ffStrbufPrependS(&host->name, "KVM/QEMU ");
 69        }
 70#if __aarch64__
 71        else if (host->family.length == 0 && ffStrbufEqualS(&host->vendor, "Apple Inc.") && ffStrbufStartsWithS(&host->name, "Mac")) {
 72            // Hack for Asahi Linux
 73            ffStrbufDestroy(&host->family);
 74            ffStrbufInitMove(&host->family, &host->name);
 75            getHostProductName(&host->name);
 76            getHostSerialNumber(&host->serial);
 77        }
 78#endif
 79    } else {
 80        getHostProductFamily(&host->family);
 81        getHostProductName(&host->name);
 82        getHostSerialNumber(&host->serial);
 83        getHostVendor(&host->vendor);
 84    }
 85
 86    if (host->family.length == 0 && host->name.length == 0) {
 87        const char* wslDistroName = getenv("WSL_DISTRO_NAME");
 88        // On WSL, the real host can't be detected. Instead use WSL as host.
 89        if (wslDistroName != nullptr || getenv("WSL_DISTRO") != nullptr || getenv("WSL_INTEROP") != nullptr) {
 90            ffStrbufSetStatic(&host->name, "Windows Subsystem for Linux");
 91            if (wslDistroName) {
 92                ffStrbufAppendF(&host->name, " - %s", wslDistroName);
 93            }
 94            ffStrbufSetStatic(&host->family, "WSL");
 95            ffStrbufSetStatic(&host->vendor, "Microsoft Corporation");
 96
 97            if (instance.config.general.detectVersion) {
 98                ffProcessAppendStdOut(&host->version, (char* const[]) {
 99                                                          "wslinfo",
100                                                          "--wsl-version",
101                                                          "-n",
102                                                          nullptr,
103                                                      }); // supported in 2.2.3 and later
104            }
105        } else if (ffStrbufStartsWithS(&instance.state.platform.sysinfo.version, "FreeBSD ")) {
106            ffStrbufSetStatic(&host->name, "Linux Binary Compatibility on FreeBSD");
107            ffStrbufSetStatic(&host->family, "FreeBSD");
108            ffStrbufSetStatic(&host->vendor, "FreeBSD Foundation");
109            if (instance.config.general.detectVersion) {
110                ffStrbufSetS(&host->version, instance.state.platform.sysinfo.version.chars + strlen("FreeBSD "));
111                ffStrbufSubstrBeforeFirstC(&host->version, ' ');
112            }
113        }
114    }
115
116    return nullptr;
117}