From e13eb05073297aa6f1dc244ab3414e98170a43e1 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 5 Apr 2025 12:08:35 +0800 Subject: [PATCH 01/35] CPU (Linux): detect physical core count on non-x86 platforms --- src/detection/cpu/cpu_linux.c | 92 ++++++++++++++++++++++++++++++++--- 1 file changed, 85 insertions(+), 7 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 04b0f00b48..8a84422298 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -9,6 +9,7 @@ #include #include #include +#include #define FF_CPUINFO_PATH "/proc/cpuinfo" @@ -432,11 +433,11 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo) { p += strlen("\nphysical id\t:"); char* pend; - unsigned long id = strtoul(p, &pend, 10); + unsigned long long id = strtoul(p, &pend, 10); if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist? - high |= 1 << (id - 64); + high |= 1ULL << (id - 64); else - low |= 1 << id; + low |= 1ULL << id; p = pend; } @@ -458,9 +459,7 @@ FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFC cpu->coresOnline = (uint16_t) get_nprocs(); cpu->packages = getPackageCount(&cpuinfo); cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, 0); // physical cores in single package - if (cpu->coresPhysical == 0) - cpu->coresPhysical = cpu->coresLogical; - else if (cpu->packages > 1) + if (cpu->coresPhysical > 0 && cpu->packages > 1) cpu->coresPhysical *= cpu->packages; // Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252 @@ -473,6 +472,82 @@ FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFC #else +static const char* detectPhysicalCores(FFCPUResult* cpu) +{ + int dfd = open("/sys/devices/system/cpu/", O_RDONLY | O_DIRECTORY); + if (dfd < 0) return "open(\"/sys/devices/system/cpu/\") failed"; + + FF_AUTO_CLOSE_DIR DIR* dir = fdopendir(dfd); + if (!dir) return "fdopendir(dfd) failed"; + + uint64_t pkgLow = 0, pkgHigh = 0; + + struct dirent* entry; + FF_LIST_AUTO_DESTROY cpuList = ffListCreate(sizeof(uint32_t)); + while ((entry = readdir(dir)) != NULL) + { + if (entry->d_type != DT_DIR || !ffStrStartsWith(entry->d_name, "cpu") || !ffCharIsDigit(entry->d_name[strlen("cpu")])) + continue; + + FF_AUTO_CLOSE_FD int cpuxfd = openat(dirfd(dir), entry->d_name, O_RDONLY | O_DIRECTORY); + if (cpuxfd < 0) + continue; + + char buf[128]; + + // Check if the directory contains a file named "topology/physical_package_id" + // that lists the physical package id of the CPU. + + ssize_t len = ffReadFileDataRelative(cpuxfd, "topology/physical_package_id", sizeof(buf) - 1, buf); + if (len > 0) + { + buf[len] = '\0'; + unsigned long long id = strtoul(buf, NULL, 10); + if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist? + pkgHigh |= 1ULL << (id - 64); + else + pkgLow |= 1ULL << id; + } + + // Check if the directory contains a file named "topology/core_cpus_list" + // that lists the physical cores in the package. + + len = ffReadFileDataRelative(cpuxfd, "topology/core_cpus_list", sizeof(buf) - 1, buf); + if (len > 0) + { + buf[len] = '\0'; // low-high or low + + for (const char* p = buf; *p;) + { + char* pend; + uint32_t coreId = (uint32_t) strtoul(p, &pend, 10); + if (pend == p) break; + + bool found = false; + FF_LIST_FOR_EACH(uint32_t, id, cpuList) + { + if (*id == coreId) + { + // This core is already counted + found = true; + break; + } + } + if (!found) + *(uint32_t*) ffListAdd(&cpuList) = coreId; + + p = strchr(pend, ','); + if (!p) break; + ++p; + } + } + } + + cpu->coresPhysical = (uint16_t) cpuList.length; + cpu->packages = (uint16_t) (__builtin_popcountll(pkgLow) + __builtin_popcountll(pkgHigh)); + return NULL; +} + FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa) { // Always use the last part of the ISA string. Ref: #590 #1204 @@ -601,7 +676,7 @@ FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const c FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu) { - cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf(); + cpu->coresLogical = (uint16_t) get_nprocs_conf(); cpu->coresOnline = (uint16_t) get_nprocs(); #if __ANDROID__ @@ -663,6 +738,9 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, #endif } + if (cpu->coresPhysical == 0) + detectPhysicalCores(cpu); + return NULL; } #endif From 59868c66a0f2dd0ca8d09bf6d10d5315bc99b5f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 5 Apr 2025 13:45:26 +0800 Subject: [PATCH 02/35] CPU (FreeBSD): don't assume one SMT group has only two threads Fix #1670 --- src/detection/cpu/cpu_bsd.c | 68 +++++++++++++++++++++++++------------ 1 file changed, 47 insertions(+), 21 deletions(-) diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index bf1f293940..5c74ebf54b 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -1,5 +1,6 @@ #include "cpu.h" #include "common/sysctl.h" +#include "util/stringUtils.h" #include #if __has_include() @@ -34,35 +35,60 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) if (ffSysctlGetString("hw.model", &cpu->name) != NULL) return "sysctlbyname(hw.model) failed"; - cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); - cpu->coresLogical = cpu->coresPhysical; + cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1); + cpu->coresPhysical = 0; cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0) { // - // - // 0, 1, 2, 3 - // - // - // 0, 1 - // THREAD groupSMT group - // - // - // 2, 3 - // THREAD groupSMT group - // - // - // + // + // 0, 1, 2, 3 + // + // + // 0, 1 + // THREAD groupSMT group + // + // + // 2, 3 + // THREAD groupSMT group + // + // + // // - uint32_t i = 0; - while (true) + char* line = NULL; + size_t len = 0; + bool inLvl2 = false, threadGroup = false; + uint32_t cpuCount = 0; + while (ffStrbufGetline(&line, &len, &buffer)) { - i = ffStrbufNextIndexS(&buffer, i, "THREAD group"); // Find physical core with hyper-threading enabled - if (i >= buffer.length) break; - cpu->coresPhysical--; - i += (uint32_t) strlen("THREAD group"); + if (!inLvl2) + { + if (ffStrStartsWith(line, " packages++; + } + else + { + if (ffStrEquals(line, " ")) + { + cpu->coresPhysical += threadGroup ? 1 : cpuCount; + inLvl2 = false; + } + else if (cpuCount == 0 && ffStrStartsWith(line, " 0 && ffStrStartsWith(line, " ")) + { + if (ffStrContains(line, "THREAD group")) + threadGroup = true; + } + } } } From 3def466ee0c8a3d815a31bcb0192a8a65a75395f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 5 Apr 2025 13:54:20 +0800 Subject: [PATCH 03/35] Revert "CPU (FreeBSD): remove using of freq_levels" This reverts commit ed2dd8f2ec459670f345c46d4d113fdff79b32e0. --- src/detection/cpu/cpu_bsd.c | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 5c74ebf54b..6db4dc1abb 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -105,6 +105,24 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) uint32_t clockrate = (uint32_t) ffSysctlGetInt("hw.clockrate", 0); if (clockrate > cpu->frequencyBase) cpu->frequencyBase = clockrate; + + for (uint16_t i = 0; i < cpu->coresLogical; ++i) + { + ffStrbufClear(&buffer); + char key[32]; + snprintf(key, sizeof(key), "dev.cpu.%u.freq_levels", i); + if (ffSysctlGetString(key, &buffer) == NULL) + { + if (buffer.length == 0) continue; + + // MHz/Watts pairs like: 2501/32000 2187/27125 2000/24000 + uint32_t fmax = (uint32_t) strtoul(buffer.chars, NULL, 10); + if (cpu->frequencyMax < fmax) cpu->frequencyMax = fmax; + } + else + break; + } + cpu->temperature = FF_CPU_TEMP_UNSET; if (options->temp) From a57bbbadf4aeec24292b3105dce3e30470095a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 5 Apr 2025 20:55:05 +0800 Subject: [PATCH 04/35] PhysicalDisk (Linux): don't detect disk type for virtual disks Fix #1669 --- src/detection/physicaldisk/physicaldisk_linux.c | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c index b4c88e0e20..24817995e6 100644 --- a/src/detection/physicaldisk/physicaldisk_linux.c +++ b/src/detection/physicaldisk/physicaldisk_linux.c @@ -78,6 +78,7 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption ffStrbufInitMove(&device->name, &name); ffStrbufInitF(&device->devPath, "/dev/%s", devName); + bool isVirtual = false; { ffStrbufInit(&device->interconnect); if (ffStrStartsWith(devName, "nvme")) @@ -97,6 +98,8 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption ffStrbufSetStatic(&device->interconnect, "SCSI"); else if (strstr(pathSysDeviceReal, "/nvme") != NULL) ffStrbufSetStatic(&device->interconnect, "NVMe"); + else if (strstr(pathSysDeviceReal, "/virtio") != NULL) + ffStrbufSetStatic(&device->interconnect, "Virtual"); else { if (ffAppendFileBufferRelative(devfd, "transport", &device->interconnect)) @@ -106,6 +109,7 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption } } + if (!isVirtual) { char isRotationalChar = '1'; if (ffReadFileDataRelative(dfd, "queue/rotational", 1, &isRotationalChar) > 0) From 536ad9594eac792a3a2b54a3472318e1f787c1fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 5 Apr 2025 21:08:06 +0800 Subject: [PATCH 05/35] PhysicalDisk (Linux): add more disk types --- src/detection/physicaldisk/physicaldisk_linux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c index 24817995e6..1a5ea20c2c 100644 --- a/src/detection/physicaldisk/physicaldisk_linux.c +++ b/src/detection/physicaldisk/physicaldisk_linux.c @@ -83,6 +83,13 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption ffStrbufInit(&device->interconnect); if (ffStrStartsWith(devName, "nvme")) ffStrbufSetStatic(&device->interconnect, "NVMe"); + else if (ffStrStartsWith(devName, "mmcblk")) + ffStrbufSetStatic(&device->interconnect, "MMC"); + else if (ffStrStartsWith(devName, "md")) + { + ffStrbufSetStatic(&device->interconnect, "RAID"); + isVirtual = true; + } else { char pathSysDeviceLink[64]; From 8d5d8b4c908b9c8861288bc0ed1d450e38302e0f Mon Sep 17 00:00:00 2001 From: Rabindra Dhakal Date: Sat, 5 Apr 2025 21:39:27 +0545 Subject: [PATCH 06/35] Packages (Linux): add soar packages count (#1531) * add soar packages count * use || instead of concat for better compatibility with older SQLite versions * convert package flags to 64-bit --- CMakeLists.txt | 2 +- doc/json_schema.json | 2 +- src/detection/packages/packages.h | 1 + src/detection/packages/packages_linux.c | 3 ++ src/modules/packages/option.h | 67 +++++++++++++------------ src/modules/packages/packages.c | 7 +++ 6 files changed, 47 insertions(+), 35 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 4cc6895d41..1948e96d15 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -102,7 +102,7 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS) message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}") endif() -set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS) +set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SOAR SORCERY WINGET XBPS) foreach(package_manager ${PACKAGE_MANAGERS}) if(package_manager STREQUAL "WINGET") option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON) diff --git a/doc/json_schema.json b/doc/json_schema.json index 8b14fed50b..b6ad80b0a4 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -279,7 +279,7 @@ "type": "string" }, "packagesFormat": { - "description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop}: Number of scoop packages\n 21. {choco}: Number of choco packages\n 22. {pkgtool}: Number of pkgtool packages\n 23. {paludis}: Number of paludis packages\n 24. {winget}: Number of winget packages\n 25. {opkg}: Number of opkg packages\n 26. {am-system}: Number of am-system packages\n 27. {sorcery}: Number of sorcery packages\n 28. {lpkg}: Number of lpkg packages\n 29. {lpkgbuild}: Number of lpkgbuild packages\n 30. {guix-system}: Number of guix-system packages\n 31. {guix-user}: Number of guix-user packages\n 32. {guix-home}: Number of guix-home packages\n 33. {linglong}: Number of linglong packages\n 34. {pacstall}: Number of pacstall packages\n 35. {mport}: Number of mport packages\n 36. {qi}: Number of qi packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {nix-all}: Total number of all nix packages\n 43. {flatpak-all}: Total number of all flatpak app packages\n 44. {brew-all}: Total number of all brew packages\n 45. {guix-all}: Total number of all guix packages\n 46. {hpkg-all}: Total number of all hpkg packages", + "description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop}: Number of scoop packages\n 21. {choco}: Number of choco packages\n 22. {pkgtool}: Number of pkgtool packages\n 23. {paludis}: Number of paludis packages\n 24. {winget}: Number of winget packages\n 25. {opkg}: Number of opkg packages\n 26. {am-system}: Number of am-system packages\n 27. {sorcery}: Number of sorcery packages\n 28. {lpkg}: Number of lpkg packages\n 29. {lpkgbuild}: Number of lpkgbuild packages\n 30. {guix-system}: Number of guix-system packages\n 31. {guix-user}: Number of guix-user packages\n 32. {guix-home}: Number of guix-home packages\n 33. {linglong}: Number of linglong packages\n 34. {pacstall}: Number of pacstall packages\n 35. {mport}: Number of mport packages\n 36. {qi}: Number of qi packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {nix-all}: Total number of all nix packages\n 44. {flatpak-all}: Total number of all flatpak app packages\n 45. {brew-all}: Total number of all brew packages\n 46. {guix-all}: Total number of all guix packages\n 47. {hpkg-all}: Total number of all hpkg packages", "type": "string" }, "physicaldiskFormat": { diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index eb8afc44a3..ad7dd93414 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -40,6 +40,7 @@ typedef struct FFPackagesResult uint32_t rpm; uint32_t scoop; uint32_t snap; + uint32_t soar; uint32_t sorcery; uint32_t winget; uint32_t xbps; diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 43ed96e6c7..fa5c0aee62 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -682,4 +682,7 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) result->amUser = getAMUser(); + + if (!(options->disabled & FF_PACKAGES_FLAG_SOAR_BIT)) + result->soar += getSQLite3Int(&baseDir, ".local/share/soar/db/soar.db", "SELECT COUNT(DISTINCT pkg_id || pkg_name) FROM packages WHERE is_installed = true", "soar"); } diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h index ec12db341c..37a93c151e 100644 --- a/src/modules/packages/option.h +++ b/src/modules/packages/option.h @@ -7,40 +7,41 @@ typedef enum __attribute__((__packed__)) FFPackagesFlags { FF_PACKAGES_FLAG_NONE = 0, - FF_PACKAGES_FLAG_APK_BIT = 1 << 0, - FF_PACKAGES_FLAG_BREW_BIT = 1 << 1, - FF_PACKAGES_FLAG_CHOCO_BIT = 1 << 2, - FF_PACKAGES_FLAG_DPKG_BIT = 1 << 3, - FF_PACKAGES_FLAG_EMERGE_BIT = 1 << 4, - FF_PACKAGES_FLAG_EOPKG_BIT = 1 << 5, - FF_PACKAGES_FLAG_FLATPAK_BIT = 1 << 6, - FF_PACKAGES_FLAG_NIX_BIT = 1 << 7, - FF_PACKAGES_FLAG_OPKG_BIT = 1 << 8, - FF_PACKAGES_FLAG_PACMAN_BIT = 1 << 9, - FF_PACKAGES_FLAG_PALUDIS_BIT = 1 << 10, - FF_PACKAGES_FLAG_PKG_BIT = 1 << 11, - FF_PACKAGES_FLAG_PKGTOOL_BIT = 1 << 12, - FF_PACKAGES_FLAG_MACPORTS_BIT = 1 << 13, - FF_PACKAGES_FLAG_RPM_BIT = 1 << 14, - FF_PACKAGES_FLAG_SCOOP_BIT = 1 << 15, - FF_PACKAGES_FLAG_SNAP_BIT = 1 << 16, - FF_PACKAGES_FLAG_WINGET_BIT = 1 << 17, - FF_PACKAGES_FLAG_XBPS_BIT = 1 << 18, - FF_PACKAGES_FLAG_AM_BIT = 1 << 19, - FF_PACKAGES_FLAG_SORCERY_BIT = 1 << 20, - FF_PACKAGES_FLAG_LPKG_BIT = 1 << 21, - FF_PACKAGES_FLAG_LPKGBUILD_BIT = 1 << 22, - FF_PACKAGES_FLAG_GUIX_BIT = 1 << 23, - FF_PACKAGES_FLAG_LINGLONG_BIT = 1 << 24, - FF_PACKAGES_FLAG_PACSTALL_BIT = 1 << 25, - FF_PACKAGES_FLAG_MPORT_BIT = 1 << 26, - FF_PACKAGES_FLAG_QI_BIT = 1 << 27, - FF_PACKAGES_FLAG_PKGSRC_BIT = 1 << 28, - FF_PACKAGES_FLAG_HPKG_BIT = 1 << 29, - FF_PACKAGES_FLAG_PISI_BIT = 1 << 30, - FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT32_MAX, + FF_PACKAGES_FLAG_APK_BIT = 1ULL << 0, + FF_PACKAGES_FLAG_BREW_BIT = 1ULL << 1, + FF_PACKAGES_FLAG_CHOCO_BIT = 1ULL << 2, + FF_PACKAGES_FLAG_DPKG_BIT = 1ULL << 3, + FF_PACKAGES_FLAG_EMERGE_BIT = 1ULL << 4, + FF_PACKAGES_FLAG_EOPKG_BIT = 1ULL << 5, + FF_PACKAGES_FLAG_FLATPAK_BIT = 1ULL << 6, + FF_PACKAGES_FLAG_NIX_BIT = 1ULL << 7, + FF_PACKAGES_FLAG_OPKG_BIT = 1ULL << 8, + FF_PACKAGES_FLAG_PACMAN_BIT = 1ULL << 9, + FF_PACKAGES_FLAG_PALUDIS_BIT = 1ULL << 10, + FF_PACKAGES_FLAG_PKG_BIT = 1ULL << 11, + FF_PACKAGES_FLAG_PKGTOOL_BIT = 1ULL << 12, + FF_PACKAGES_FLAG_MACPORTS_BIT = 1ULL << 13, + FF_PACKAGES_FLAG_RPM_BIT = 1ULL << 14, + FF_PACKAGES_FLAG_SCOOP_BIT = 1ULL << 15, + FF_PACKAGES_FLAG_SNAP_BIT = 1ULL << 16, + FF_PACKAGES_FLAG_WINGET_BIT = 1ULL << 17, + FF_PACKAGES_FLAG_XBPS_BIT = 1ULL << 18, + FF_PACKAGES_FLAG_AM_BIT = 1ULL << 19, + FF_PACKAGES_FLAG_SORCERY_BIT = 1ULL << 20, + FF_PACKAGES_FLAG_LPKG_BIT = 1ULL << 21, + FF_PACKAGES_FLAG_LPKGBUILD_BIT = 1ULL << 22, + FF_PACKAGES_FLAG_GUIX_BIT = 1ULL << 23, + FF_PACKAGES_FLAG_LINGLONG_BIT = 1ULL << 24, + FF_PACKAGES_FLAG_PACSTALL_BIT = 1ULL << 25, + FF_PACKAGES_FLAG_MPORT_BIT = 1ULL << 26, + FF_PACKAGES_FLAG_QI_BIT = 1ULL << 27, + FF_PACKAGES_FLAG_PKGSRC_BIT = 1ULL << 28, + FF_PACKAGES_FLAG_HPKG_BIT = 1ULL << 29, + FF_PACKAGES_FLAG_PISI_BIT = 1ULL << 30, + FF_PACKAGES_FLAG_SOAR_BIT = 1ULL << 31, + FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT64_MAX, } FFPackagesFlags; -static_assert(sizeof(FFPackagesFlags) == sizeof(uint32_t), ""); +static_assert(sizeof(FFPackagesFlags) == sizeof(uint64_t), ""); typedef struct FFPackagesOptions { diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index 8766cbda3b..8754cfa7f5 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -78,6 +78,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE(mport) FF_PRINT_PACKAGE(qi) FF_PRINT_PACKAGE(pisi) + FF_PRINT_PACKAGE(soar) putchar('\n'); } @@ -130,6 +131,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.hpkgSystem, "hpkg-system"), FF_FORMAT_ARG(counts.hpkgUser, "hpkg-user"), FF_FORMAT_ARG(counts.pisi, "pisi"), + FF_FORMAT_ARG(counts.soar, "soar"), FF_FORMAT_ARG(nixAll, "nix-all"), FF_FORMAT_ARG(flatpakAll, "flatpak-all"), FF_FORMAT_ARG(brewAll, "brew-all"), @@ -222,6 +224,7 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, case 'S': if (false); FF_TEST_PACKAGE_NAME(SCOOP) FF_TEST_PACKAGE_NAME(SNAP) + FF_TEST_PACKAGE_NAME(SOAR) FF_TEST_PACKAGE_NAME(SORCERY) break; case 'W': if (false); @@ -341,6 +344,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) case 'S': if (false); FF_TEST_PACKAGE_NAME(SCOOP) FF_TEST_PACKAGE_NAME(SNAP) + FF_TEST_PACKAGE_NAME(SOAR) FF_TEST_PACKAGE_NAME(SORCERY) break; case 'W': if (false); @@ -400,6 +404,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do FF_TEST_PACKAGE_NAME(RPM) FF_TEST_PACKAGE_NAME(SCOOP) FF_TEST_PACKAGE_NAME(SNAP) + FF_TEST_PACKAGE_NAME(SOAR) FF_TEST_PACKAGE_NAME(SORCERY) FF_TEST_PACKAGE_NAME(WINGET) FF_TEST_PACKAGE_NAME(XBPS) @@ -459,6 +464,7 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy FF_APPEND_PACKAGE_COUNT(rpm) FF_APPEND_PACKAGE_COUNT(scoop) FF_APPEND_PACKAGE_COUNT(snap) + FF_APPEND_PACKAGE_COUNT(soar) FF_APPEND_PACKAGE_COUNT(sorcery) FF_APPEND_PACKAGE_COUNT(winget) FF_APPEND_PACKAGE_COUNT(xbps) @@ -515,6 +521,7 @@ static FFModuleBaseInfo ffModuleInfo = { {"Number of hpkg-system packages", "hpkg-system"}, {"Number of hpkg-user packages", "hpkg-user"}, {"Number of pisi packages", "pisi"}, + {"Number of soar packages", "soar"}, {"Total number of all nix packages", "nix-all"}, {"Total number of all flatpak app packages", "flatpak-all"}, {"Total number of all brew packages", "brew-all"}, From 8509f9705476d6e29d171a7729c44301ffc87b26 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 6 Apr 2025 17:21:32 +0800 Subject: [PATCH 07/35] WM (Linux): remove `v` from Hyprland version --- src/detection/wm/wm_linux.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/wm/wm_linux.c b/src/detection/wm/wm_linux.c index 42c205dce1..60ff5a3b83 100644 --- a/src/detection/wm/wm_linux.c +++ b/src/detection/wm/wm_linux.c @@ -38,6 +38,7 @@ static const char* getHyprland(FFstrbuf* result) { ffStrbufSubstrAfterFirstC(result, '"'); ffStrbufSubstrBeforeFirstC(result, '"'); + ffStrbufTrimLeft(result, 'v'); FF_DEBUG("Extracted version from version.h: %s", result->chars); return NULL; } From 85d7390fa8866716a1d71ef10b57c6e2965ad9ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 7 Apr 2025 16:38:13 +0800 Subject: [PATCH 08/35] Util (Windows): use native win32 functions --- src/util/path.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/src/util/path.c b/src/util/path.c index e61de11631..eecfb7e9c8 100644 --- a/src/util/path.c +++ b/src/util/path.c @@ -3,6 +3,7 @@ #include "common/io/io.h" #include "util/stringUtils.h" +#if !_WIN32 const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) { char* path = getenv("PATH"); @@ -47,6 +48,22 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) ffStrbufClear(result); return "Executable not found"; } +#else +#include + +const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) +{ + char buffer[MAX_PATH + 1]; + DWORD length = SearchPathA(NULL, name, ".exe", sizeof(buffer), buffer, NULL); + if (length == 0) + { + ffStrbufClear(result); + return "Executable not found"; + } + ffStrbufSetS(result, buffer); + return NULL; +} +#endif bool ffIsAbsolutePath(const char* path) { From 354062118f11977623811f9acbf266f09f16a995 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 7 Apr 2025 10:07:19 +0800 Subject: [PATCH 09/35] Chore: update comment --- src/logo/builtin.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index b60a94b803..3edc705b99 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2365,7 +2365,7 @@ static const FFlogo K[] = { }, // KDE Neon { - .names = {"KDE Neon"}, // Distro ID is `neon`; Distro name is `KDE Neon` + .names = {"KDE Neon"}, // Distro ID is "neon"; Distro name is "KDE Neon" .lines = FASTFETCH_DATATEXT_LOGO_KDENEON, .colors = { FF_COLOR_FG_GREEN, From 3c3188eb055fea681198e3021947f7773d1d39b0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 7 Apr 2025 16:43:36 +0800 Subject: [PATCH 10/35] IO (Windows): support `~` expanding --- src/common/io/io_windows.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index 25f82cdc1c..fa3057e76c 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -147,6 +147,14 @@ ssize_t ffReadFileDataRelative(HANDLE dfd, const char* fileName, size_t dataSize bool ffPathExpandEnv(const char* in, FFstrbuf* out) { + if (in[0] == '~') { + if ((in[1] == '/' || in[1] == '\\' || in[1] == '\0') && !ffStrContainsC(in, '%')) { + ffStrbufSet(out, &instance.state.platform.homeDir); + ffStrbufAppendS(out, in + 1); + return true; + } + } + DWORD length = ExpandEnvironmentStringsA(in, NULL, 0); if (length <= 1) return false; From 523a9590b8c9da36cd30177f6a993368d4ef96fd Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 8 Apr 2025 09:11:08 +0800 Subject: [PATCH 11/35] Fastfetch: fix loading presets in `{exePath}/presets` Regression of v2.40.0 --- src/fastfetch.c | 15 ++++++++++++--- src/util/platform/FFPlatform_unix.c | 8 -------- src/util/platform/FFPlatform_windows.c | 8 -------- 3 files changed, 12 insertions(+), 19 deletions(-) diff --git a/src/fastfetch.c b/src/fastfetch.c index 19ff6a9821..ccd4b37bf1 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -483,13 +483,22 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val if (instance.state.platform.exePath.length) { - ffStrbufSet(&absolutePath, &instance.state.platform.exePath); - ffStrbufSubstrBeforeLastC(&absolutePath, '/'); - ffStrbufAppendS(&absolutePath, "/"); + uint32_t lastSlash = ffStrbufLastIndexC(&instance.state.platform.exePath, '/') + 1; + assert(lastSlash < instance.state.platform.exePath.length); + + // Try {exePath}/ + ffStrbufSetNS(&absolutePath, lastSlash, instance.state.platform.exePath.chars); ffStrbufAppendS(&absolutePath, value); if (needExtension) ffStrbufAppendS(&absolutePath, ".jsonc"); + if (parseJsoncFile(absolutePath.chars, strictJson)) return; + // Try {exePath}/presets/ + ffStrbufSubstrBefore(&absolutePath, lastSlash); + ffStrbufAppendS(&absolutePath, "presets/"); + ffStrbufAppendS(&absolutePath, value); + if (needExtension) + ffStrbufAppendS(&absolutePath, ".jsonc"); if (parseJsoncFile(absolutePath.chars, strictJson)) return; } diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index a6d5321d66..fbf59d85fe 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -172,14 +172,6 @@ static void getDataDirs(FFPlatform* platform) #endif ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/local/share/"); ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/share/"); - - if (platform->exePath.length > 0) - { - // Add ${currentExePath} - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&platform->exePath); - ffStrbufSubstrBeforeLastC(&path, '/'); - ffPlatformPathAddAbsolute(&platform->dataDirs, path.chars); - } } static void getUserName(FFPlatform* platform, const struct passwd* pwd) diff --git a/src/util/platform/FFPlatform_windows.c b/src/util/platform/FFPlatform_windows.c index d95c9443f0..71feae3f30 100644 --- a/src/util/platform/FFPlatform_windows.c +++ b/src/util/platform/FFPlatform_windows.c @@ -129,14 +129,6 @@ static void getDataDirs(FFPlatform* platform) platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_RoamingAppData); platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_LocalAppData); ffPlatformPathAddHome(&platform->dataDirs, platform, ""); - - if (platform->exePath.length > 0) - { - // Add ${currentExePath} - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&platform->exePath); - ffStrbufSubstrBeforeLastC(&path, '/'); - ffPlatformPathAddAbsolute(&platform->dataDirs, path.chars); - } } static void getUserName(FFPlatform* platform) From 3c291f1af91e1f2e2c4d81ae5288fecf8516c27f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 9 Apr 2025 14:58:36 +0800 Subject: [PATCH 12/35] Platform: retrieve full user name --- CMakeLists.txt | 1 + src/modules/title/title.c | 3 +++ src/util/platform/FFPlatform.c | 1 + src/util/platform/FFPlatform.h | 1 + src/util/platform/FFPlatform_unix.c | 2 ++ src/util/platform/FFPlatform_windows.c | 10 +++++++++- 6 files changed, 17 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 089a7c16b7..765bdc5524 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1589,6 +1589,7 @@ elseif(WIN32) PRIVATE "cfgmgr32" PRIVATE "winbrand" PRIVATE "propsys" + PRIVATE "secur32" ) elseif(FreeBSD) target_link_libraries(libfastfetch diff --git a/src/modules/title/title.c b/src/modules/title/title.c index 31b5e79c42..fdd74271e3 100644 --- a/src/modules/title/title.c +++ b/src/modules/title/title.c @@ -63,6 +63,7 @@ void ffPrintTitle(FFTitleOptions* options) FF_FORMAT_ARG(userNameColored, "user-name-colored"), FF_FORMAT_ARG(atColored, "at-symbol-colored"), FF_FORMAT_ARG(hostNameColored, "host-name-colored"), + FF_FORMAT_ARG(instance.state.platform.fullUserName, "full-user-name"), })); } } @@ -170,6 +171,7 @@ void ffGenerateTitleJsonResult(FF_MAYBE_UNUSED FFTitleOptions* options, yyjson_m { yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result"); yyjson_mut_obj_add_strbuf(doc, obj, "userName", &instance.state.platform.userName); + yyjson_mut_obj_add_strbuf(doc, obj, "fullUserName", &instance.state.platform.fullUserName); yyjson_mut_obj_add_strbuf(doc, obj, "hostName", &instance.state.platform.hostName); yyjson_mut_obj_add_strbuf(doc, obj, "homeDir", &instance.state.platform.homeDir); yyjson_mut_obj_add_strbuf(doc, obj, "exePath", &instance.state.platform.exePath); @@ -193,6 +195,7 @@ static FFModuleBaseInfo ffModuleInfo = { {"User name (colored)", "user-name-colored"}, {"@ symbol (colored)", "at-symbol-colored"}, {"Host name (colored)", "host-name-colored"}, + {"Full user name", "full-user-name"}, })) }; diff --git a/src/util/platform/FFPlatform.c b/src/util/platform/FFPlatform.c index cb044f7503..25e03650af 100644 --- a/src/util/platform/FFPlatform.c +++ b/src/util/platform/FFPlatform.c @@ -12,6 +12,7 @@ void ffPlatformInit(FFPlatform* platform) ffStrbufInit(&platform->exePath); ffStrbufInit(&platform->userName); + ffStrbufInit(&platform->fullUserName); ffStrbufInit(&platform->hostName); ffStrbufInit(&platform->userShell); diff --git a/src/util/platform/FFPlatform.h b/src/util/platform/FFPlatform.h index 5dd6c0efa6..79b7499125 100644 --- a/src/util/platform/FFPlatform.h +++ b/src/util/platform/FFPlatform.h @@ -22,6 +22,7 @@ typedef struct FFPlatform FFstrbuf exePath; // The real path of current exe FFstrbuf userName; + FFstrbuf fullUserName; FFstrbuf hostName; FFstrbuf userShell; diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index fbf59d85fe..eb9ee450e8 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -181,6 +181,8 @@ static void getUserName(FFPlatform* platform, const struct passwd* pwd) user = pwd->pw_name; ffStrbufAppendS(&platform->userName, user); + + if (pwd) ffStrbufAppendS(&platform->fullUserName, pwd->pw_gecos); } static void getHostName(FFPlatform* platform, const struct utsname* uts) diff --git a/src/util/platform/FFPlatform_windows.c b/src/util/platform/FFPlatform_windows.c index 71feae3f30..b78aa8cc71 100644 --- a/src/util/platform/FFPlatform_windows.c +++ b/src/util/platform/FFPlatform_windows.c @@ -9,6 +9,9 @@ #include #include +#define SECURITY_WIN32 1 // For secext.h +#include + static void getExePath(FFPlatform* platform) { wchar_t exePathW[MAX_PATH]; @@ -138,11 +141,16 @@ static void getUserName(FFPlatform* platform) ffStrbufSetS(&platform->userName, userName); else { - wchar_t buffer[128]; + wchar_t buffer[256]; DWORD len = ARRAY_SIZE(buffer); if(GetUserNameW(buffer, &len)) ffStrbufSetWS(&platform->userName, buffer); } + + wchar_t buffer[256]; + DWORD len = ARRAY_SIZE(buffer); + if (GetUserNameExW(NameDisplay, buffer, &len)) + ffStrbufSetWS(&platform->fullUserName, buffer); } static void getHostName(FFPlatform* platform) From 090529ffef57fb6afd443d457e8752b84378891c Mon Sep 17 00:00:00 2001 From: Anduin Xue Date: Thu, 10 Apr 2025 15:13:26 +0000 Subject: [PATCH 13/35] Logo (Builtin): Add support for anduinos (#1684) * Add anduinos * fix logo. * Update anduinos.txt --- src/logo/ascii/anduinos.txt | 19 +++++++++++++++++++ src/logo/builtin.c | 11 +++++++++++ 2 files changed, 30 insertions(+) create mode 100644 src/logo/ascii/anduinos.txt diff --git a/src/logo/ascii/anduinos.txt b/src/logo/ascii/anduinos.txt new file mode 100644 index 0000000000..d57e6f9bd6 --- /dev/null +++ b/src/logo/ascii/anduinos.txt @@ -0,0 +1,19 @@ + $1+++++++++++ + +++++++++++++++++++++ + +++++++++++++++++++++++++++++++ +=+++++++++++++++++++++++++++++++++++++++= ++++++++++++++++++++++++++++++++++++++++++++++ +=++++++++++++++++++++++++++++++++++++++++++++ + ==+++++++++++++++++++++++++++++++++== + +++++++++++++++++++++++++++ +$2**** $1++=+++++++++++=++ $2**** +********** $1+++++++ $2********** +************** ************** + **************** **************** + *********************** +****** ************* ****** +*********** *** *********** +*************** *************** + *************** *************** + ********************* + *********** diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 3edc705b99..3731c6fffb 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -197,6 +197,17 @@ static const FFlogo A[] = { .colorKeys = FF_COLOR_FG_GREEN, .colorTitle = FF_COLOR_FG_GREEN, }, + //AnduinOS + { + .names = {"anduinos"}, + .lines = FASTFETCH_DATATEXT_LOGO_ANDUINOS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_BLUE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_WHITE, + }, // Antergos { .names = {"Antergos"}, From 73bc71e922b09b5bd0fa0d2949e1812dfe4de005 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 12 Apr 2025 10:47:57 +0800 Subject: [PATCH 14/35] CPU (Windows): use PDH to detect thermal temp No Administrator privileges needed --- CMakeLists.txt | 2 +- src/detection/cpu/cpu_windows.c | 44 ++++++++++++++++++++++++++++--- src/detection/cpu/cpu_windows.cpp | 34 ------------------------ 3 files changed, 42 insertions(+), 38 deletions(-) delete mode 100644 src/detection/cpu/cpu_windows.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 765bdc5524..481fd855d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -977,7 +977,6 @@ elseif(WIN32) src/detection/btrfs/btrfs_nosupport.c src/detection/chassis/chassis_windows.c src/detection/cpu/cpu_windows.c - src/detection/cpu/cpu_windows.cpp src/detection/cpucache/cpucache_windows.c src/detection/cpuusage/cpuusage_windows.c src/detection/cursor/cursor_windows.c @@ -1590,6 +1589,7 @@ elseif(WIN32) PRIVATE "winbrand" PRIVATE "propsys" PRIVATE "secur32" + PRIVATE "pdh" ) elseif(FreeBSD) target_link_libraries(libfastfetch diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index 32c31768d9..2f6a703b4d 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -4,6 +4,46 @@ #include "util/mallocHelper.h" #include "util/smbiosHelper.h" +#include + +static void ffPdhOpenCloseQuery(HQUERY* query) +{ + assert(query); + if (*query) + { + PdhCloseQuery(*query); + *query = NULL; + } +} + +static const char* detectThermalTemp(double* result) +{ + // typeperf.exe -sc 1 "\Thermal Zone Information(*)\Temperature" + + __attribute__((__cleanup__(ffPdhOpenCloseQuery))) HQUERY query = NULL; + + if (PdhOpenQuery(NULL, 0, &query) != ERROR_SUCCESS) + return "Failed to open PDH query"; + + HCOUNTER counter = NULL; + if (PdhAddEnglishCounter(query, + L"\\Thermal Zone Information(*)\\Temperature", + 0, + &counter) != ERROR_SUCCESS) + return "Failed to add TZI temperature counter"; + + if (PdhCollectQueryData(query) != ERROR_SUCCESS) + return "Failed to collect query data"; + + PDH_FMT_COUNTERVALUE value; + if (PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, NULL, &value) != ERROR_SUCCESS) + return "Failed to format counter value"; + + *result = value.doubleValue - 273; + + return NULL; +} + // 7.5 typedef struct FFSmbiosProcessorInfo { @@ -165,8 +205,6 @@ static const char* detectCoreTypes(FFCPUResult* cpu) return NULL; } -const char* detectThermalTemp(double* current, double* critical); - const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) { detectNCores(cpu); @@ -182,7 +220,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) detectMaxSpeedBySmbios(cpu); if(options->temp) - detectThermalTemp(&cpu->temperature, NULL); + detectThermalTemp(&cpu->temperature); return NULL; } diff --git a/src/detection/cpu/cpu_windows.cpp b/src/detection/cpu/cpu_windows.cpp deleted file mode 100644 index 85b3ee0849..0000000000 --- a/src/detection/cpu/cpu_windows.cpp +++ /dev/null @@ -1,34 +0,0 @@ -#include "util/windows/wmi.hpp" - -extern "C" -const char* detectThermalTemp(double* current, double* critical) -{ - // Requires Administrator privileges - // https://wutils.com/wmi/root/wmi/msacpi_thermalzonetemperature/#properties - FFWmiQuery query(L"SELECT CurrentTemperature, CriticalTripPoint FROM MSAcpi_ThermalZoneTemperature WHERE Active = TRUE", nullptr, FFWmiNamespace::WMI); - if(!query) - return "Query WMI service failed"; - - if(FFWmiRecord record = query.next()) - { - if (current) - { - if(auto vtCurrent = record.get(L"CurrentTemperature")) - *current = vtCurrent.get() / 10 - 273.15; // In tenth of degrees Kelvin - else - *current = 0.0/0.0; - } - - if (critical) - { - if(auto vtCritical = record.get(L"CriticalTripPoint")) - *critical = vtCritical.get() / 10 - 273.15; // In tenth of degrees Kelvin - else - *critical = 0.0/0.0; - } - - return NULL; - } - - return "No WMI result returned"; -} From 6e77b592cbda8593e8f592e2aebdc6a9e915ba2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 12 Apr 2025 10:48:26 +0800 Subject: [PATCH 15/35] WM (FreeBSD): enable Hyprland version detection --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 481fd855d6..c3a484b69b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -705,7 +705,7 @@ elseif(FreeBSD) src/detection/uptime/uptime_bsd.c src/detection/users/users_linux.c src/detection/wallpaper/wallpaper_linux.c - src/detection/wm/wm_nosupport.c + src/detection/wm/wm_linux.c src/detection/de/de_linux.c src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_linux.c From 114088b845895d66611c844fc7b9928030acb8e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 12 Apr 2025 20:33:18 +0800 Subject: [PATCH 16/35] Doc: add comments about displaying image logo on Windows [ci skip] Fix #1686 --- README.md | 50 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/README.md b/README.md index 7e9643cb45..683679640b 100644 --- a/README.md +++ b/README.md @@ -230,6 +230,56 @@ Set the key to a white space. } ``` +### Q: How can I display images on Windows? + +As of April 2025: + +#### mintty and Wezterm + +mintty (used by Bash on Windows and MSYS2) and Wezterm (nightly build only) support the iTerm image protocol on Windows. + +In `config.jsonc`: +```json +{ + "logo": { + "type": "iterm", + "source": "C:/path/to/image.png", + "width": + } +} +``` + +#### Windows Terminal + +Windows Terminal supports the sixel image protocol only. + +* If you installed fastfetch through MSYS2: + 1. Install imagemagick: `pacman -S mingw-w64--x86_64-imagemagick` + 2. In `config.jsonc`: +```jsonc +{ + "logo": { + "type": "sixel", // DO NOT USE "auto" + "source": "C:/path/to/image.png", // Do NOT use `~` as fastfetch is a native Windows program and doesn't apply cygwin path conversion + "width": , // Optional + "height": // Optional + } +} +``` +* If you installed fastfetch via scoop or downloaded the binary directly from the GitHub Releases page: + 1. Convert your image manually to sixel format using [any online image conversion service](https://www.google.com/search?q=convert+image+to+sixel) + 2. In `config.jsonc`: +```jsonc +{ + "logo": { + "type": "raw", // DO NOT USE "auto" + "source": "C:/path/to/image.sixel", + "width": , // Required + "height": // Required + } +} +``` + ### Q: I want feature A / B / C. Will fastfetch support it? Fastfetch is a system information tool. We only accept hardware or system-level software feature requests. For most personal uses, I recommend using the `Command` module to implement custom functionality, which can be used to grab output from a custom shell script: From 58908f69bae0a46cc4dd3fd432500ff759e20e8a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 13 Apr 2025 00:30:19 +0800 Subject: [PATCH 17/35] Wifi (OpenBSD): add support Completely untested. --- CMakeLists.txt | 2 +- src/detection/wifi/wifi_nbsd.c | 119 +++++++++++++++++++++++++++++++++ 2 files changed, 120 insertions(+), 1 deletion(-) create mode 100644 src/detection/wifi/wifi_nbsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index c3a484b69b..986d14187f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -879,7 +879,7 @@ elseif(OpenBSD) src/detection/uptime/uptime_bsd.c src/detection/users/users_obsd.c src/detection/wallpaper/wallpaper_linux.c - src/detection/wifi/wifi_nosupport.c + src/detection/wifi/wifi_nbsd.c src/detection/wm/wm_nosupport.c src/detection/de/de_linux.c src/detection/wmtheme/wmtheme_linux.c diff --git a/src/detection/wifi/wifi_nbsd.c b/src/detection/wifi/wifi_nbsd.c new file mode 100644 index 0000000000..e7b992d1f8 --- /dev/null +++ b/src/detection/wifi/wifi_nbsd.c @@ -0,0 +1,119 @@ +#include "wifi.h" +#include "common/io/io.h" +#include "util/stringUtils.h" + +#include +#include +#include +#include +#include +#include + +const char* ffDetectWifi(FFlist* result) +{ + struct if_nameindex* infs = if_nameindex(); + if(!infs) { + return "if_nameindex() failed"; + } + + FF_AUTO_CLOSE_FD int sock = socket(AF_INET, SOCK_DGRAM, 0); + if(sock < 0) { + return "socket() failed"; + } + + for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i) + { + if (!ffStrStartsWith(i->if_name, "iwm")) { + continue; + } + + FFWifiResult* item = (FFWifiResult*) ffListAdd(result); + ffStrbufInitS(&item->inf.description, i->if_name); + ffStrbufInit(&item->inf.status); + ffStrbufInit(&item->conn.status); + ffStrbufInit(&item->conn.ssid); + ffStrbufInit(&item->conn.bssid); + ffStrbufInit(&item->conn.protocol); + ffStrbufInit(&item->conn.security); + item->conn.signalQuality = 0.0/0.0; + item->conn.rxRate = 0.0/0.0; + item->conn.txRate = 0.0/0.0; + item->conn.channel = 0; + item->conn.frequency = 0; + + struct ieee80211_nodereq nr = {}; + strlcpy(nr.nr_ifname, i->if_name, sizeof(nr.nr_ifname)); + + // 首先检查接口状态 + struct ifreq ifr = {}; + strlcpy(ifr.ifr_name, i->if_name, sizeof(ifr.ifr_name)); + if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { + ffStrbufSetStatic(&item->inf.status, "Unknown"); + } else { + ffStrbufSetStatic(&item->inf.status, ifr.ifr_flags & IFF_UP ? "Up" : "Down"); + } + + // 尝试获取当前连接的节点信息 + if (ioctl(sock, SIOCG80211NODE, &nr) < 0) { + ffStrbufSetStatic(&item->conn.status, "Not associated"); + continue; + } + + // 获取SSID + if (nr.nr_nwid_len > 0) { + ffStrbufSetStatic(&item->conn.status, "Associated"); + ffStrbufAppendNS(&item->conn.ssid, nr.nr_nwid_len, (char*)nr.nr_nwid); + } else { + ffStrbufSetStatic(&item->conn.status, "Not associated"); + continue; + } + + // 获取BSSID + ffStrbufSetF(&item->conn.bssid, "%02X:%02X:%02X:%02X:%02X:%02X", + nr.nr_bssid[0], nr.nr_bssid[1], nr.nr_bssid[2], + nr.nr_bssid[3], nr.nr_bssid[4], nr.nr_bssid[5]); + + // 获取信道和频率 + item->conn.channel = nr.nr_channel; + + // 获取信号强度 + if (nr.nr_max_rssi) { + item->conn.signalQuality = ((float)nr.nr_rssi / nr.nr_max_rssi) * 100.0; + } + + // 确定协议类型 + if (nr.nr_flags & IEEE80211_NODEREQ_HT) { + ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)"); + } else if (nr.nr_flags & IEEE80211_NODEREQ_VHT) { + ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)"); + } else if (nr.nr_chan_flags & IEEE80211_CHANINFO_5GHZ) { + ffStrbufSetStatic(&item->conn.protocol, "802.11a"); + } else if (nr.nr_chan_flags & IEEE80211_CHANINFO_2GHZ) { + ffStrbufSetStatic(&item->conn.protocol, "802.11g"); + } + + // 获取安全设置 + struct ieee80211_wpaparams wpa = {}; + strlcpy(wpa.i_name, i->if_name, sizeof(wpa.i_name)); + + if (ioctl(sock, SIOCG80211WPAPARMS, &wpa) >= 0 && wpa.i_enabled) { + if (wpa.i_protos & IEEE80211_WPA_PROTO_WPA2) + ffStrbufSetStatic(&item->conn.security, "WPA2"); + else if (wpa.i_protos & IEEE80211_WPA_PROTO_WPA1) + ffStrbufSetStatic(&item->conn.security, "WPA"); + } else { + struct ieee80211_nwkey nwkey = {}; + strlcpy(nwkey.i_name, i->if_name, sizeof(nwkey.i_name)); + + if (ioctl(sock, SIOCG80211NWKEY, &nwkey) >= 0) { + if (nwkey.i_wepon) + ffStrbufSetStatic(&item->conn.security, "WEP"); + else + ffStrbufSetStatic(&item->conn.security, "Open"); + } + } + } + + if_freenameindex(infs); + return NULL; +} From ba01b1e4ceb4986cbd51b4604a5a45f008934ae1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 14 Apr 2025 09:27:01 +0800 Subject: [PATCH 18/35] CPU (Linux): add new ARM part numbers --- src/detection/cpu/cpu_arm.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/detection/cpu/cpu_arm.h b/src/detection/cpu/cpu_arm.h index 1a6be11521..39b482bd42 100644 --- a/src/detection/cpu/cpu_arm.h +++ b/src/detection/cpu/cpu_arm.h @@ -106,9 +106,14 @@ static const char* armPartId2name(uint32_t partId) case 0xd80: return "Cortex-A520"; case 0xd81: return "Cortex-A720"; case 0xd82: return "Cortex-X4"; + case 0xd83: return "Neoverse-V3AE"; case 0xd84: return "Neoverse-V3"; case 0xd85: return "Cortex-X925"; case 0xd87: return "Cortex-A725"; + case 0xd88: return "Cortex-A520AE"; + case 0xd89: return "Cortex-A720AE"; + case 0xd8e: return "Neoverse-N3"; + case 0xd8f: return "Cortex-A320"; default: return NULL; } } @@ -314,6 +319,7 @@ static const char* fujitsuPartId2name(uint32_t partId) switch (partId) { case 0x001: return "A64FX"; + case 0x003: return "MONAKA" default: return NULL; } } From 79d0197dcf823f732fdb2caac6f0bdb34538dfbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 14 Apr 2025 10:04:11 +0800 Subject: [PATCH 19/35] Wifi (FreeBSD): remove unused sys headers --- src/detection/wifi/wifi_bsd.c | 4 ---- 1 file changed, 4 deletions(-) diff --git a/src/detection/wifi/wifi_bsd.c b/src/detection/wifi/wifi_bsd.c index ca42a7ed80..d6ce117571 100644 --- a/src/detection/wifi/wifi_bsd.c +++ b/src/detection/wifi/wifi_bsd.c @@ -2,15 +2,11 @@ #include "common/io/io.h" #include "util/stringUtils.h" -#include -#include -#include #include #include #include #include #include -#include const char* ffDetectWifi(FFlist* result) { From 9cda7e20fb97e7c576659577fa848cce508c199f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 14 Apr 2025 10:28:01 +0800 Subject: [PATCH 20/35] Chore: simplify `fastfetch.h` --- src/common/init.c | 1 + src/common/init.h | 7 +++++++ src/common/printing.c | 1 + src/fastfetch.c | 2 ++ src/fastfetch.h | 24 ------------------------ src/flashfetch.c | 1 + src/logo/logo.h | 6 ++++++ src/modules/break/break.c | 1 + src/modules/colors/colors.c | 3 ++- src/modules/separator/separator.c | 1 + 10 files changed, 22 insertions(+), 25 deletions(-) create mode 100644 src/common/init.h diff --git a/src/common/init.c b/src/common/init.c index 1db2aa01d7..561e856cfd 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -1,4 +1,5 @@ #include "fastfetch.h" +#include "common/init.h" #include "common/parsing.h" #include "common/thread.h" #include "detection/displayserver/displayserver.h" diff --git a/src/common/init.h b/src/common/init.h new file mode 100644 index 0000000000..c2ea4c06cb --- /dev/null +++ b/src/common/init.h @@ -0,0 +1,7 @@ +#pragma once + +void ffInitInstance(void); +void ffStart(void); +void ffFinish(void); +void ffDestroyInstance(void); +void ffListFeatures(void); diff --git a/src/common/printing.c b/src/common/printing.c index ac8fd30550..38369d373e 100644 --- a/src/common/printing.c +++ b/src/common/printing.c @@ -1,5 +1,6 @@ #include "fastfetch.h" #include "common/printing.h" +#include "logo/logo.h" #include "util/textModifier.h" void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType) diff --git a/src/fastfetch.c b/src/fastfetch.c index ccd4b37bf1..9a278619c6 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1,9 +1,11 @@ #include "fastfetch.h" #include "common/commandoption.h" +#include "common/init.h" #include "common/io/io.h" #include "common/jsonconfig.h" #include "common/printing.h" #include "detection/version/version.h" +#include "logo/logo.h" #include "util/stringUtils.h" #include "util/mallocHelper.h" #include "fastfetch_datatext.h" diff --git a/src/fastfetch.h b/src/fastfetch.h index a95ab7501b..1c99a8c2a1 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -63,27 +63,3 @@ typedef struct FFinstance } FFinstance; extern FFinstance instance; // Defined in `common/init.c` extern FFModuleBaseInfo** ffModuleInfos[]; - -////////////////////// -// Init functions // -////////////////////// - -//common/init.c -void ffInitInstance(); -void ffStart(); -void ffFinish(); -void ffDestroyInstance(); - -void ffListFeatures(); - -//////////////////// -// Logo functions // -//////////////////// - -void ffLogoPrint(); -void ffLogoPrintRemaining(); -void ffLogoPrintLine(); - -void ffLogoBuiltinPrint(); -void ffLogoBuiltinList(); -void ffLogoBuiltinListAutocompletion(); diff --git a/src/flashfetch.c b/src/flashfetch.c index 6aeb31bfe7..371a0ca98b 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -1,5 +1,6 @@ #include "fastfetch.h" +#include "common/init.h" #include "modules/modules.h" int main(void) diff --git a/src/logo/logo.h b/src/logo/logo.h index 92a1683a66..d4f332dad6 100644 --- a/src/logo/logo.h +++ b/src/logo/logo.h @@ -21,7 +21,13 @@ typedef struct FFlogo } FFlogo; //logo.c +void ffLogoPrint(void); void ffLogoPrintChars(const char* data, bool doColorReplacement); +void ffLogoPrintLine(void); +void ffLogoPrintRemaining(void); +void ffLogoBuiltinPrint(void); +void ffLogoBuiltinList(void); +void ffLogoBuiltinListAutocompletion(void); //builtin.c extern const FFlogo* ffLogoBuiltins[]; diff --git a/src/modules/break/break.c b/src/modules/break/break.c index 89228e4f4a..6e3379ee05 100644 --- a/src/modules/break/break.c +++ b/src/modules/break/break.c @@ -1,4 +1,5 @@ #include "common/printing.h" +#include "logo/logo.h" #include "modules/break/break.h" void ffPrintBreak(FF_MAYBE_UNUSED FFBreakOptions* options) diff --git a/src/modules/colors/colors.c b/src/modules/colors/colors.c index 038bb5cc17..63c69b9994 100644 --- a/src/modules/colors/colors.c +++ b/src/modules/colors/colors.c @@ -1,7 +1,8 @@ #include "common/printing.h" #include "common/jsonconfig.h" -#include "util/textModifier.h" +#include "logo/logo.h" #include "modules/colors/colors.h" +#include "util/textModifier.h" #include "util/stringUtils.h" static inline uint8_t min(uint8_t a, uint8_t b) diff --git a/src/modules/separator/separator.c b/src/modules/separator/separator.c index 29dd5db417..4a61184780 100644 --- a/src/modules/separator/separator.c +++ b/src/modules/separator/separator.c @@ -1,5 +1,6 @@ #include "common/printing.h" #include "common/jsonconfig.h" +#include "logo/logo.h" #include "modules/separator/separator.h" #include "util/stringUtils.h" #include "util/mallocHelper.h" From 4eefab8ccfb59b03dfd05bb6bee5bf70c6ba20c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 14 Apr 2025 10:54:35 +0800 Subject: [PATCH 21/35] CPU (Linux): fix build --- src/detection/cpu/cpu_arm.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_arm.h b/src/detection/cpu/cpu_arm.h index 39b482bd42..cc23d4576e 100644 --- a/src/detection/cpu/cpu_arm.h +++ b/src/detection/cpu/cpu_arm.h @@ -319,7 +319,7 @@ static const char* fujitsuPartId2name(uint32_t partId) switch (partId) { case 0x001: return "A64FX"; - case 0x003: return "MONAKA" + case 0x003: return "MONAKA"; default: return NULL; } } From c60bc8ee5b14f3c15cdd8c3b0dfe0db2c11d0e72 Mon Sep 17 00:00:00 2001 From: naix Date: Mon, 14 Apr 2025 05:50:45 +0000 Subject: [PATCH 22/35] Logo (Builtin): Add 2 more Alpine logos (#1687) * Logo (Builtin): Add 2 more Alpine logos * Remove unnecessary $1 in ASCII logo file * Add type field to Alpine2 logo configuration --------- Co-authored-by: naix Co-authored-by: Carter Li --- src/logo/ascii/alpine2.txt | 16 ++++++++++++++++ src/logo/ascii/alpine3_small.txt | 6 ++++++ src/logo/builtin.c | 23 +++++++++++++++++++++++ 3 files changed, 45 insertions(+) create mode 100644 src/logo/ascii/alpine2.txt create mode 100644 src/logo/ascii/alpine3_small.txt diff --git a/src/logo/ascii/alpine2.txt b/src/logo/ascii/alpine2.txt new file mode 100644 index 0000000000..4d79ae3e28 --- /dev/null +++ b/src/logo/ascii/alpine2.txt @@ -0,0 +1,16 @@ + .:::::::::::::::::::::. + .:::::::::::::::::::::::. + .:::::::::::::::::::::::::. + .:::::::::::::::::::::::::::. + .:::::::::$2,db,$1::::::::::::::::. + .::::::::$2,d%%%%b,$1::$2,db,$1:::::::::. + .:::::::$2,%%%%P'%%%b,d%%%b,$1::::::::. +.::::::$2,%%%%P,$1:::$2`%%%b'^q%%b,$1:::::::. +'::::$2,%%%%P,d|$1:::::$2`%%%b:'^%%b,$1:::::' + '::$2`%%%'$1:$2'q$|$1:::::::$2'q%%b'`q%%b'$1::' + ':::::::::::::::::::::::::::::::' + ':::::::::::::::::::::::::::::' + ':::::::::::::::::::::::::::' + ':::::::::::::::::::::::::' + ':::::::::::::::::::::::' + ':::::::::::::::::::::' diff --git a/src/logo/ascii/alpine3_small.txt b/src/logo/ascii/alpine3_small.txt new file mode 100644 index 0000000000..38a4476ee3 --- /dev/null +++ b/src/logo/ascii/alpine3_small.txt @@ -0,0 +1,6 @@ + ,db, + ,d%%%%b, ,db, + ,%%%%P'%%%b,d%%%b, + ,%%%%P, `%%%b'^q%%b, + ,%%%%P,d| `%%%b '^%%b, +`%%%' 'q$| 'q%%b'`q%%b diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 3731c6fffb..dce7a19cfe 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -89,6 +89,18 @@ static const FFlogo A[] = { .colorKeys = FF_COLOR_FG_MAGENTA, .colorTitle = FF_COLOR_FG_BLUE, }, + // Alpine2 + { + .names = {"Alpine2"}, + .lines = FASTFETCH_DATATEXT_LOGO_ALPINE2, + .type = FF_LOGO_LINE_TYPE_ALTER_BIT, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, // AlpineSmall { .names = {"Alpine_small"}, @@ -113,6 +125,17 @@ static const FFlogo A[] = { .colorKeys = FF_COLOR_FG_MAGENTA, .colorTitle = FF_COLOR_FG_BLUE, }, + // Alpine3Small + { + .names = {"alpine3_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_ALPINE3_SMALL, + .colors = { + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, // Alter { .names = {"Alter"}, From bcc64921153a0630176245db03d02e3ca48ca72b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Mon, 14 Apr 2025 16:30:02 +0800 Subject: [PATCH 23/35] NetIO (Linux): use `openat` --- src/detection/netio/netio_linux.c | 51 +++++++++++-------------------- 1 file changed, 18 insertions(+), 33 deletions(-) diff --git a/src/detection/netio/netio_linux.c b/src/detection/netio/netio_linux.c index 2f0ee9dcfc..2a28c10eb4 100644 --- a/src/detection/netio/netio_linux.c +++ b/src/detection/netio/netio_linux.c @@ -4,60 +4,46 @@ #include "common/netif/netif.h" #include "util/stringUtils.h" +#include #include -static void getData(FFstrbuf* buffer, const char* ifName, bool isDefaultRoute, FFstrbuf* path, FFlist* result) +static void getData(FFstrbuf* buffer, const char* ifName, bool isDefaultRoute, int basefd, FFlist* result) { - ffStrbufSetF(path, "/sys/class/net/%s/operstate", ifName); - if(!ffReadFileBuffer(path->chars, buffer) || !ffStrbufEqualS(buffer, "up\n")) + FF_AUTO_CLOSE_FD int dfd = openat(basefd, ifName, O_RDONLY | O_DIRECTORY); + if (dfd < 0) + return; + + char operstate; + if(!ffReadFileDataRelative(dfd, "operstate", 1, &operstate) || operstate != 'u' /* up or unknown */) return; FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result); ffStrbufInitS(&counters->name, ifName); counters->defaultRoute = isDefaultRoute; - ffStrbufSetF(path, "/sys/class/net/%s/statistics/", ifName); - uint32_t statLen = path->length; - - ffStrbufAppendS(path, "rx_bytes"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/rx_bytes", buffer)) counters->rxBytes = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "tx_bytes"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/tx_bytes", buffer)) counters->txBytes = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "rx_packets"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/rx_packets", buffer)) counters->rxPackets = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "tx_packets"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/tx_packets", buffer)) counters->txPackets = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "rx_errors"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/rx_errors", buffer)) counters->rxErrors = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "tx_errors"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/tx_errors", buffer)) counters->txErrors = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "rx_dropped"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/rx_dropped", buffer)) counters->rxDrops = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); - ffStrbufAppendS(path, "tx_dropped"); - if (ffReadFileBuffer(path->chars, buffer)) + if (ffReadFileBufferRelative(dfd, "statistics/tx_dropped", buffer)) counters->txDrops = ffStrbufToUInt(buffer, 0); - ffStrbufSubstrBefore(path, statLen); } const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) @@ -65,7 +51,6 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/net"); if (!dirp) return "opendir(\"/sys/class/net\") == NULL"; - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(64); FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); const char* defaultRouteIfName = ffNetifGetDefaultRouteIfName(); @@ -75,7 +60,7 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) if (options->namePrefix.length && strncmp(defaultRouteIfName, options->namePrefix.chars, options->namePrefix.length) != 0) return NULL; - getData(&buffer, defaultRouteIfName, true, &path, result); + getData(&buffer, defaultRouteIfName, true, dirfd(dirp), result); } else { @@ -89,7 +74,7 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options) if (options->namePrefix.length && strncmp(ifName, options->namePrefix.chars, options->namePrefix.length) != 0) continue; - getData(&buffer, ifName, ffStrEquals(ifName, defaultRouteIfName), &path, result); + getData(&buffer, ifName, ffStrEquals(ifName, defaultRouteIfName), dirfd(dirp), result); } } From 33205326683fd89ec63204f83549839e2374c286 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 14 Apr 2025 15:32:31 +0800 Subject: [PATCH 24/35] GPU (Linux): add temp detection for Intel GPU Untested --- src/detection/gpu/gpu_linux.c | 40 ++++++++++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 3 deletions(-) diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index f2073a69b5..a64ce0de64 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -228,7 +228,7 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu, } } -static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const char* drmKey) +static void pciDetectIntelSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const char* drmKey) { // Works for Intel GPUs // https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/ @@ -238,12 +238,46 @@ static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* if (!drmKey) return; - if (ffStrbufEqualS(&gpu->driver, "xe")) + const uint32_t pciDirLen = pciDir->length; + + bool isXE = ffStrbufEqualS(&gpu->driver, "xe"); + if (isXE) ffStrbufAppendS(pciDir, "/tile0/gt0/freq0/max_freq"); else ffStrbufAppendF(pciDir, "/drm/%s/gt_max_freq_mhz", drmKey); if (ffReadFileBuffer(pciDir->chars, buffer)) gpu->frequency = (uint32_t) ffStrbufToUInt(buffer, 0); + ffStrbufSubstrBefore(pciDir, pciDirLen); + + if (options->temp) + { + ffStrbufAppendS(pciDir, "/hwmon/"); + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars); + if (dirp) + { + struct dirent* entry; + while ((entry = readdir(dirp)) != NULL) + { + if (entry->d_name[0] == '.') continue; + + ffStrbufSubstrBefore(pciDir, pciDirLen + strlen("/hwmon/")); + ffStrbufAppendS(pciDir, entry->d_name); + // https://github.com/Syllo/nvtop/blob/73291884d926445e499d6b9b71cb7a9bdbc7c393/src/extract_gpuinfo_intel.c#L279-L281 + ffStrbufAppendS(pciDir, isXE ? "/temp2_input" : "/temp1_input"); + + if (ffReadFileBuffer(pciDir->chars, buffer)) + { + uint64_t value = ffStrbufToUInt(buffer, 0); + if (value > 0) + { + gpu->temperature = (double) value / 1000; + break; + } + } + } + } + ffStrbufSubstrBefore(pciDir, pciDirLen); + } } static inline int popcountBytes(uint8_t* bytes, uint32_t length) @@ -500,7 +534,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf } else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL) { - pciDetectIntelSpecific(gpu, deviceDir, buffer, drmKey); + pciDetectIntelSpecific(options, gpu, deviceDir, buffer, drmKey); ffStrbufSubstrBefore(deviceDir, drmDirPathLength); if (options->driverSpecific && drmKey) drmDetectIntelSpecific(gpu, drmKey, buffer); From 0d20164d4099f8cfc6301a173f6c32448234c59a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Apr 2025 10:59:10 +0800 Subject: [PATCH 25/35] CI (Windows): add WoA --- .github/workflows/ci.yml | 63 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index c98ddf258d..b39305abe9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -654,6 +654,68 @@ jobs: name: fastfetch-windows-amd64 path: ./fastfetch-windows-amd64.* + windows-aarch64: + name: Windows-aarch64 + runs-on: windows-11-arm + permissions: + security-events: write + contents: read + defaults: + run: + shell: msys2 {0} + steps: + - name: checkout repository + uses: actions/checkout@v4 + + - name: setup-msys2 + uses: msys2/setup-msys2@v2 + with: + msystem: CLANGARM64 + update: true + install: git mingw-w64-clang-aarch64-7zip mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-vulkan-loader mingw-w64-clang-aarch64-vulkan-headers mingw-w64-clang-aarch64-opencl-icd mingw-w64-clang-aarch64-opencl-headers mingw-w64-clang-aarch64-cppwinrt mingw-w64-clang-aarch64-imagemagick + + - name: print msys version + run: uname -a + + - name: configure project + run: env PKG_CONFIG_PATH=/clangarm64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On . + + - name: build project + run: cmake --build . --verbose -j4 + + - name: copy necessary dlls + run: cp /clangarm64/bin/{OpenCL,vulkan-1}.dll . + + - name: list features + run: ./fastfetch --list-features + + - name: run fastfetch + run: time ./fastfetch -c presets/ci.jsonc --stat false + + - name: run fastfetch --format json + run: time ./fastfetch -c presets/ci.jsonc --format json + + - name: run flashfetch + run: time ./flashfetch + + - name: print dependencies + run: ldd fastfetch + + - name: run tests + run: ctest --output-on-failure + + - name: create zip archive + run: 7z a -tzip -mx9 -bd -y fastfetch-windows-aarch64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets + + - name: create 7z archive + run: 7z a -t7z -mx9 -bd -y fastfetch-windows-aarch64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets + + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: fastfetch-windows-aarch64 + path: ./fastfetch-windows-aarch64.* + release: if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch' name: Release @@ -673,6 +735,7 @@ jobs: - netbsd-amd64 - sunos-amd64 - windows-amd64 + - windows-aarch64 permissions: contents: write steps: From a51dd641c17736031a08b99525d755b1168f8165 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Apr 2025 16:39:16 +0800 Subject: [PATCH 26/35] Processing (Windows): use `GetOverlappedResultEx` on WoA --- src/common/processing_windows.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 60b3ec2711..8b5500a1b2 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -130,7 +130,11 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use switch (GetLastError()) { case ERROR_IO_PENDING: - if (!timeout || WaitForSingleObject(hChildPipeRead, (DWORD) timeout) != WAIT_OBJECT_0) + #if __aarch64__ + if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, timeout < 0 ? INFINITE : (DWORD) timeout, FALSE)) + #else + // To support Windows 7 + if (timeout >= 0 && WaitForSingleObject(hChildPipeRead, (DWORD) timeout) != WAIT_OBJECT_0) { CancelIo(hChildPipeRead); TerminateProcess(hProcess, 1); @@ -138,13 +142,18 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use } if (!GetOverlappedResult(hChildPipeRead, &overlapped, &nRead, FALSE)) + #endif { if (GetLastError() == ERROR_BROKEN_PIPE) return NULL; CancelIo(hChildPipeRead); TerminateProcess(hProcess, 1); - return "GetOverlappedResult(hChildPipeRead) failed"; + return "GetOverlappedResult" + #if __arch64__ + "Ex" + #endif + "(hChildPipeRead) failed"; } break; From 6da8181bbebd24cd170125095e6d5dc6a7221068 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Apr 2025 16:39:34 +0800 Subject: [PATCH 27/35] CMake: use mincore on WoA --- CMakeLists.txt | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 986d14187f..76624fd984 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1591,6 +1591,12 @@ elseif(WIN32) PRIVATE "secur32" PRIVATE "pdh" ) + if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64") + # WoA only works on Windows 10 or higher + target_link_libraries(libfastfetch + PRIVATE "mincore" + ) + endif() elseif(FreeBSD) target_link_libraries(libfastfetch PRIVATE "m" From b812f3ccde4f231385cbecf6046e77fa281813b4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Apr 2025 16:41:19 +0800 Subject: [PATCH 28/35] Uptime (Windows): use `QueryUnbiasedInterruptTime` As suggested by MSDN --- src/detection/uptime/uptime_windows.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/detection/uptime/uptime_windows.c b/src/detection/uptime/uptime_windows.c index 6978a1163d..775b428e94 100644 --- a/src/detection/uptime/uptime_windows.c +++ b/src/detection/uptime/uptime_windows.c @@ -1,11 +1,13 @@ #include "uptime.h" #include "common/time.h" -#include +#include const char* ffDetectUptime(FFUptimeResult* result) { - result->uptime = GetTickCount64(); + // According to MSDN, this function only fails if it's called with NULL + QueryUnbiasedInterruptTime(&result->uptime); + result->uptime /= 10000; // Convert from 100-nanosecond intervals to milliseconds result->bootTime = ffTimeGetNow() - result->uptime; return NULL; } From 2e7e68ef23ebec146f1775b3554a742acfb05cf1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Apr 2025 19:04:19 +0800 Subject: [PATCH 29/35] Doc: add installation instructions for pkgsrc [ci skip] Fix #1689 --- README.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/README.md b/README.md index 683679640b..079ffaa7b9 100644 --- a/README.md +++ b/README.md @@ -71,6 +71,10 @@ You may also download the program directly from [the GitHub releases page](https * `pkg install fastfetch` +### NetBSD + +* `pkgin in fastfetch` + ### Android (Termux) * `pkg install fastfetch` From f8a5d5561aa374b8f5f6848f07fee1bfed98d0e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 15 Apr 2025 19:05:31 +0800 Subject: [PATCH 30/35] Bluetooth (NetBSD): add base implementation Ref: #1690 --- CMakeLists.txt | 3 ++- src/detection/bluetooth/bluetooth_bsd.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 76624fd984..dc0d571dca 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -734,7 +734,7 @@ elseif(NetBSD) src/common/sysctl.c src/detection/battery/battery_nbsd.c src/detection/bios/bios_nbsd.c - src/detection/bluetooth/bluetooth_nosupport.c + src/detection/bluetooth/bluetooth_bsd.c src/detection/bluetoothradio/bluetoothradio_nosupport.c src/detection/board/board_nbsd.c src/detection/bootmgr/bootmgr_bsd.c @@ -1620,6 +1620,7 @@ elseif(OpenBSD) ) elseif(NetBSD) target_link_libraries(libfastfetch + PRIVATE "bluetooth" PRIVATE "m" PRIVATE "prop" ) diff --git a/src/detection/bluetooth/bluetooth_bsd.c b/src/detection/bluetooth/bluetooth_bsd.c index a9a752b0d7..7425c614f0 100644 --- a/src/detection/bluetooth/bluetooth_bsd.c +++ b/src/detection/bluetooth/bluetooth_bsd.c @@ -6,7 +6,13 @@ static int enumDev(FF_MAYBE_UNUSED int sockfd, struct bt_devinfo const* dev, FFlist* devices) { FFBluetoothResult* device = ffListAdd(devices); - ffStrbufInitS(&device->name, bt_devremote_name_gen(dev->devname, &dev->bdaddr)); + ffStrbufInitS(&device->name, + #if __FreeBSD__ + bt_devremote_name_gen(dev->devname, &dev->bdaddr) + #else + dev->devname + #endif + ); ffStrbufInitS(&device->address, bt_ntoa(&dev->bdaddr, NULL)); ffStrbufUpperCase(&device->address); ffStrbufInit(&device->type); From 2d497038eba74432ea975647f03ce8761a91a881 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Apr 2025 09:19:38 +0800 Subject: [PATCH 31/35] Release: v2.41.0 --- CHANGELOG.md | 26 ++++++++++++++++++++++++++ CMakeLists.txt | 2 +- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b8070ffa12..5193f11e56 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +# 2.41.0 + +Bugfixes: +* Don't detect disk type for virtual disks (PhysicalDisk, Linux, #1669) + +Features: +* Support physical core count detection on non-x86 platforms (CPU, Linux / FreeBSD) +* Support CPU frequency detection on PPC64 (CPU, FreeBSD) +* Support soar packages count detection (Packages, Linux) +* Support `~` path expanding on Windows (Logo, Windows) +* Support retrieving full user name (Title) + * Exposed with `--title-format '{full-user-name}'` +* Improve CPU (thermal zone) temperature detection on Windows (CPU, Windows) + * Administrator privileges are no longer needed +* Support base Wifi info detection on OpenBSD (Wifi, OpenBSD) + * To be tested +* Support GPU temperature detection for Intel dGPU on Linux (GPU, Linux) + * To be tested +* Add new ARM CPU part numbers (CPU, Linux) +* Add base implementation of Bluetooth device detection (Bluetooth, NetBSD, #1690) +* Some small improvements + +Logo: +* Add anduinos +* Add 2 more Alpine logos + # 2.40.4 Bugfixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index dc0d571dca..615c01531f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.40.4 + VERSION 2.41.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" From 61d83af9ea4c6d794d14ba31524309f1d5570885 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Apr 2025 10:20:59 +0800 Subject: [PATCH 32/35] CI (Linux): bump GH runner for linux-amd64 Ref: https://github.com/actions/runner-images/issues/11101 --- .github/workflows/ci.yml | 6 +++--- CHANGELOG.md | 4 ++++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index b39305abe9..4e1b1821aa 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -60,7 +60,7 @@ jobs: linux-amd64: name: Linux-amd64 - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 permissions: security-events: write contents: read @@ -80,12 +80,12 @@ jobs: run: cat /proc/cpuinfo - name: install required packages - run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev + run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev directx-headers-dev - name: install linuxbrew packages run: | /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" - /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa ddcutil --ignore-dependencies + /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies - name: Initialize CodeQL uses: github/codeql-action/init@v3 diff --git a/CHANGELOG.md b/CHANGELOG.md index 5193f11e56..89d824cf51 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # 2.41.0 +Changes: +* Due to [the deprecation](https://github.com/actions/runner-images/issues/11101), Linux x86_64 binaries are now built with Ubuntu 22.04 (Glibc 2.35, Debian 12) + * You can always build fastfetch yourself on your own. Please don't report bugs related to this change. + Bugfixes: * Don't detect disk type for virtual disks (PhysicalDisk, Linux, #1669) From b08eea76b101aee11d6787966d237fc2999e6c9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Apr 2025 10:45:25 +0800 Subject: [PATCH 33/35] CI (Linux): enable chafa on Linux aarch64 --- .github/workflows/ci.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4e1b1821aa..6480487a1e 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -151,8 +151,13 @@ jobs: - name: install required packages run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev libchafa-dev libddcutil-dev rpm + - name: install linuxbrew packages + run: | + /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)" + /home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies + - name: configure project - run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr . + run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr . - name: build project run: cmake --build . --target package --verbose -j4 From 75290154b0b7d8869f386d9cfb9fed08776f41a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Apr 2025 11:08:55 +0800 Subject: [PATCH 34/35] Chore: remove Chinese comments [ci skip] --- src/detection/wifi/wifi_nbsd.c | 8 -------- 1 file changed, 8 deletions(-) diff --git a/src/detection/wifi/wifi_nbsd.c b/src/detection/wifi/wifi_nbsd.c index e7b992d1f8..969df87806 100644 --- a/src/detection/wifi/wifi_nbsd.c +++ b/src/detection/wifi/wifi_nbsd.c @@ -44,7 +44,6 @@ const char* ffDetectWifi(FFlist* result) struct ieee80211_nodereq nr = {}; strlcpy(nr.nr_ifname, i->if_name, sizeof(nr.nr_ifname)); - // 首先检查接口状态 struct ifreq ifr = {}; strlcpy(ifr.ifr_name, i->if_name, sizeof(ifr.ifr_name)); if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) { @@ -53,13 +52,11 @@ const char* ffDetectWifi(FFlist* result) ffStrbufSetStatic(&item->inf.status, ifr.ifr_flags & IFF_UP ? "Up" : "Down"); } - // 尝试获取当前连接的节点信息 if (ioctl(sock, SIOCG80211NODE, &nr) < 0) { ffStrbufSetStatic(&item->conn.status, "Not associated"); continue; } - // 获取SSID if (nr.nr_nwid_len > 0) { ffStrbufSetStatic(&item->conn.status, "Associated"); ffStrbufAppendNS(&item->conn.ssid, nr.nr_nwid_len, (char*)nr.nr_nwid); @@ -68,20 +65,16 @@ const char* ffDetectWifi(FFlist* result) continue; } - // 获取BSSID ffStrbufSetF(&item->conn.bssid, "%02X:%02X:%02X:%02X:%02X:%02X", nr.nr_bssid[0], nr.nr_bssid[1], nr.nr_bssid[2], nr.nr_bssid[3], nr.nr_bssid[4], nr.nr_bssid[5]); - // 获取信道和频率 item->conn.channel = nr.nr_channel; - // 获取信号强度 if (nr.nr_max_rssi) { item->conn.signalQuality = ((float)nr.nr_rssi / nr.nr_max_rssi) * 100.0; } - // 确定协议类型 if (nr.nr_flags & IEEE80211_NODEREQ_HT) { ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)"); } else if (nr.nr_flags & IEEE80211_NODEREQ_VHT) { @@ -92,7 +85,6 @@ const char* ffDetectWifi(FFlist* result) ffStrbufSetStatic(&item->conn.protocol, "802.11g"); } - // 获取安全设置 struct ieee80211_wpaparams wpa = {}; strlcpy(wpa.i_name, i->if_name, sizeof(wpa.i_name)); From 894c66d793650f41212a003b65ffa3852ffa6b23 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 16 Apr 2025 11:12:36 +0800 Subject: [PATCH 35/35] Processing (Windows): fix macro name `__aarch64__` Found by AI --- src/common/processing_windows.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/common/processing_windows.c b/src/common/processing_windows.c index 8b5500a1b2..3ec86583ee 100644 --- a/src/common/processing_windows.c +++ b/src/common/processing_windows.c @@ -150,7 +150,7 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use CancelIo(hChildPipeRead); TerminateProcess(hProcess, 1); return "GetOverlappedResult" - #if __arch64__ + #if __aarch64__ "Ex" #endif "(hChildPipeRead) failed";