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}