From 119de2e91a1a884d4c63a7551fc70e147ba017bf Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 11 Sep 2024 16:06:14 +0800 Subject: [PATCH 01/30] Packaging: update debian stuff [ci skip] --- debian/changelog | 6 ++++++ debian/files | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/debian/changelog b/debian/changelog index bb2ff4cd8b..647ba54c12 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fastfetch (2.24.0) jammy; urgency=medium + + * Update to 2.24.0 + + -- Carter Li Wed, 11 Sep 2024 13:50:02 +0800 + fastfetch (2.23.0) jammy; urgency=medium * Update to 2.23.0 diff --git a/debian/files b/debian/files index 5c6a37a05f..1e5930ffc0 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fastfetch_2.23.0_source.buildinfo universe/utils optional +fastfetch_2.24.0_source.buildinfo universe/utils optional From 0c4edf7d0edcbf8fee88f57866906ac72995d4ce Mon Sep 17 00:00:00 2001 From: R0CKSTAR Date: Thu, 12 Sep 2024 19:30:02 +0800 Subject: [PATCH 02/30] feat: Moore Threads GPU add support to query number of cores (#1259) Signed-off-by: Xiaodong Ye --- src/detection/gpu/gpu_mthreads.c | 5 +++++ src/detection/gpu/mtml.h | 2 ++ 2 files changed, 7 insertions(+) diff --git a/src/detection/gpu/gpu_mthreads.c b/src/detection/gpu/gpu_mthreads.c index 0104518fc9..ac0ffa07b5 100644 --- a/src/detection/gpu/gpu_mthreads.c +++ b/src/detection/gpu/gpu_mthreads.c @@ -5,6 +5,7 @@ struct FFMtmlData { + FF_LIBRARY_SYMBOL(mtmlDeviceCountGpuCores) FF_LIBRARY_SYMBOL(mtmlDeviceGetBrand) FF_LIBRARY_SYMBOL(mtmlDeviceGetIndex) FF_LIBRARY_SYMBOL(mtmlDeviceGetName) @@ -43,6 +44,7 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive mtmlData.inited = true; FF_LIBRARY_LOAD(libmtml, "dlopen mtml failed", soName, 1); FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libmtml, mtmlLibraryInit) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceCountGpuCores) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetBrand) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetIndex) FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libmtml, mtmlData, mtmlDeviceGetName) @@ -158,6 +160,9 @@ const char *ffDetectMthreadsGpuInfo(const FFGpuDriverCondition *cond, FFGpuDrive } } + if (result.coreCount) + mtmlData.ffmtmlDeviceCountGpuCores(device, result.coreCount); + if (result.frequency) { MtmlGpu *gpu = NULL; diff --git a/src/detection/gpu/mtml.h b/src/detection/gpu/mtml.h index be5a6cee5f..a97cfeb37c 100644 --- a/src/detection/gpu/mtml.h +++ b/src/detection/gpu/mtml.h @@ -56,6 +56,8 @@ typedef struct int rsvd[6]; //!< Reserved for future extension. } MtmlPciInfo; +// Retrieves the number of cores of a device. +MtmlReturn MTML_API mtmlDeviceCountGpuCores(const MtmlDevice* device, unsigned int* numCores); // Retrieves the brand of a device. MtmlReturn MTML_API mtmlDeviceGetBrand(const MtmlDevice *dev, MtmlBrandType *type); // Retrieves the index associated with the specified device. From ce90689ba36f13cdd0fde413f1230f349166b245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 12 Sep 2024 20:55:28 +0800 Subject: [PATCH 03/30] CPU (FreeBSD): fix invalid CPU temperature Ref: #1260 --- src/detection/temps/temps_bsd.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detection/temps/temps_bsd.c b/src/detection/temps/temps_bsd.c index 2355ac8bfe..d3160775fd 100644 --- a/src/detection/temps/temps_bsd.c +++ b/src/detection/temps/temps_bsd.c @@ -7,8 +7,8 @@ const char* ffDetectCpuTemp(double* current) if (temp == -999999) return "ffSysctlGetInt(\"dev.cpu.0.temperature\") failed"; - // In tenth of degrees Celsius - *current = (double) temp / 10; + // In tenth of degrees Kelvin + *current = (double) temp / 10 - 273.15; return NULL; } From 7bbaca2fab6af4208baa8008286c7b2101522ab2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 12 Sep 2024 20:57:59 +0800 Subject: [PATCH 04/30] CPU (FreeBSD): remove `showPeCoreCount` support It doesn't work. Ref #1260 --- src/detection/cpu/cpu_bsd.c | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index c7b3cec44e..dec08e602a 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -53,16 +53,6 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) // 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; - - if (options->showPeCoreCount) - { - uint32_t ifreq = 0; - while (cpu->coreTypes[ifreq].freq != fmax && cpu->coreTypes[ifreq].freq > 0) - ++ifreq; - if (cpu->coreTypes[ifreq].freq == 0) - cpu->coreTypes[ifreq].freq = fmax; - cpu->coreTypes[ifreq].count++; - } } else break; From 03c901b26073938fdef93f8c788fc7732033ac55 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 12 Sep 2024 15:39:22 +0800 Subject: [PATCH 05/30] Packages (Linux): cache result based on mtime --- src/detection/packages/packages.c | 44 +++++++++++++++++++++++ src/detection/packages/packages.h | 2 ++ src/detection/packages/packages_linux.c | 48 +++++++++++++++++++------ 3 files changed, 84 insertions(+), 10 deletions(-) diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index b3549a16aa..8af7046383 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -1,7 +1,13 @@ #include "packages.h" +#include "common/io/io.h" +#include #include +#ifdef __APPLE__ +#define st_mtim st_mtimespec +#endif + void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options); const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options) @@ -16,3 +22,41 @@ const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* option return NULL; } + +bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result) +{ + struct stat st; + if (stat(filePath, &st) < 0) // file doesn't exist or isn't accessable + { + *result = 0; + return true; + } + + uint64_t mtime_current = (uint64_t) st.st_mtim.tv_sec * 1000 + (uint64_t) st.st_mtim.tv_nsec / 1000000; + + ffStrbufSet(cacheDir, &instance.state.platform.cacheDir); + ffStrbufEnsureEndsWithC(cacheDir, '/'); + ffStrbufAppendF(cacheDir, "fastfetch/packages/%s.txt", packageId); + + if (ffReadFileBuffer(cacheDir->chars, cacheContent)) + { + uint64_t mtime_cached; + uint32_t num_cached; + if (sscanf(cacheContent->chars, "%" SCNu64 " %" SCNu32, &mtime_cached, &num_cached) == 2 && + mtime_cached == mtime_current && num_cached > 0) + { + *result = num_cached; + return true; + } + } + + ffStrbufSetF(cacheContent, "%" PRIu64 " ", mtime_current); + + return false; +} + +bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements) +{ + ffStrbufAppendF(cacheContent, "%" PRIu32, num_elements); + return ffWriteFileBuffer(cacheDir->chars, cacheContent); +} diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index feffb0ceaa..43e9a78b48 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -42,3 +42,5 @@ typedef struct FFPackagesResult } FFPackagesResult; const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options); +bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result); +bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements); diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index e1bd54cdf0..f3ca054f28 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -56,21 +56,49 @@ static uint32_t getNumStringsImpl(const char* filename, const char* needle) return count; } -static uint32_t getNumStrings(FFstrbuf* baseDir, const char* filename, const char* needle) +static uint32_t getNumStrings(FFstrbuf* baseDir, const char* filename, const char* needle, const char* packageId) { uint32_t baseDirLength = baseDir->length; ffStrbufAppendS(baseDir, filename); - uint32_t num_elements = getNumStringsImpl(baseDir->chars, needle); + + FF_STRBUF_AUTO_DESTROY cacheDir = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreate(); + + uint32_t num_elements; + if (ffPackagesReadCache(&cacheDir, &cacheContent, baseDir->chars, packageId, &num_elements)) + { + ffStrbufSubstrBefore(baseDir, baseDirLength); + return num_elements; + } + + num_elements = getNumStringsImpl(baseDir->chars, needle); ffStrbufSubstrBefore(baseDir, baseDirLength); + + ffPackagesWriteCache(&cacheDir, &cacheContent, num_elements); + return num_elements; } -static uint32_t getSQLite3Int(FFstrbuf* baseDir, const char* dbPath, const char* query) +static uint32_t getSQLite3Int(FFstrbuf* baseDir, const char* dbPath, const char* query, const char* packageId) { uint32_t baseDirLength = baseDir->length; ffStrbufAppendS(baseDir, dbPath); - uint32_t num_elements = (uint32_t) ffSettingsGetSQLite3Int(baseDir->chars, query); + + FF_STRBUF_AUTO_DESTROY cacheDir = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreate(); + + uint32_t num_elements; + if (ffPackagesReadCache(&cacheDir, &cacheContent, baseDir->chars, packageId, &num_elements)) + { + ffStrbufSubstrBefore(baseDir, baseDirLength); + return num_elements; + } + + num_elements = (uint32_t) ffSettingsGetSQLite3Int(baseDir->chars, query); ffStrbufSubstrBefore(baseDir, baseDirLength); + + ffPackagesWriteCache(&cacheDir, &cacheContent, num_elements); + return num_elements; } @@ -441,9 +469,9 @@ static uint32_t getGuixPackages(FFstrbuf* baseDir, const char* dirname) static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options) { - if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q"); - if (!(options->disabled & FF_PACKAGES_FLAG_DPKG_BIT)) packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: install ok installed"); - if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n"); + if (!(options->disabled & FF_PACKAGES_FLAG_APK_BIT)) packageCounts->apk += getNumStrings(baseDir, "/lib/apk/db/installed", "C:Q", "apk"); + if (!(options->disabled & FF_PACKAGES_FLAG_DPKG_BIT)) packageCounts->dpkg += getNumStrings(baseDir, "/var/lib/dpkg/status", "Status: install ok installed", "dpkg"); + if (!(options->disabled & FF_PACKAGES_FLAG_LPKG_BIT)) packageCounts->lpkg += getNumStrings(baseDir, "/opt/Loc-OS-LPKG/installed-lpkg/Listinstalled-lpkg.list", "\n", "lpkg"); if (!(options->disabled & FF_PACKAGES_FLAG_EMERGE_BIT)) packageCounts->emerge += countFilesRecursive(baseDir, "/var/db/pkg", "SIZE"); if (!(options->disabled & FF_PACKAGES_FLAG_EOPKG_BIT)) packageCounts->eopkg += getNumElements(baseDir, "/var/lib/eopkg/package", DT_DIR); if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) packageCounts->flatpakSystem += getNumElements(baseDir, "/var/lib/flatpak/app", DT_DIR); @@ -455,7 +483,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, if (!(options->disabled & FF_PACKAGES_FLAG_PACMAN_BIT)) packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR); if (!(options->disabled & FF_PACKAGES_FLAG_LPKGBUILD_BIT)) packageCounts->lpkgbuild += getNumElements(baseDir, "/opt/Loc-OS-LPKG/lpkgbuild/remove", DT_REG); if (!(options->disabled & FF_PACKAGES_FLAG_PKGTOOL_BIT)) packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG); - if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages"); + if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages", "rpm"); if (!(options->disabled & FF_PACKAGES_FLAG_SNAP_BIT)) packageCounts->snap += getSnap(baseDir); if (!(options->disabled & FF_PACKAGES_FLAG_XBPS_BIT)) packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps"); if (!(options->disabled & FF_PACKAGES_FLAG_BREW_BIT)) @@ -464,9 +492,9 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, packageCounts->brew += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Cellar", DT_DIR); } if (!(options->disabled & FF_PACKAGES_FLAG_PALUDIS_BIT)) packageCounts->paludis += countFilesRecursive(baseDir, "/var/db/paludis/repositories", "environment.bz2"); - if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:"); // openwrt + if (!(options->disabled & FF_PACKAGES_FLAG_OPKG_BIT)) packageCounts->opkg += getNumStrings(baseDir, "/usr/lib/opkg/status", "Package:", "opkg"); // openwrt if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->am = getAM(baseDir); - if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:"); + if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:", "sorcery"); if (!(options->disabled & FF_PACKAGES_FLAG_GUIX_BIT)) { packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile"); From af450ae78891679c26859e253a87965aca4c9e41 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 13 Sep 2024 10:02:50 +0800 Subject: [PATCH 06/30] Packages (FreeBSD): cache result --- src/detection/packages/packages_bsd.c | 20 +++++++++++++++++++- 1 file changed, 19 insertions(+), 1 deletion(-) diff --git a/src/detection/packages/packages_bsd.c b/src/detection/packages/packages_bsd.c index 5948d678b9..8212229270 100644 --- a/src/detection/packages/packages_bsd.c +++ b/src/detection/packages/packages_bsd.c @@ -2,8 +2,26 @@ #include "common/settings.h" +static uint32_t getSQLite3Int(const char* dbPath, const char* query, const char* packageId) +{ + FF_STRBUF_AUTO_DESTROY cacheDir = ffStrbufCreate(); + FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreate(); + + uint32_t num_elements; + if (ffPackagesReadCache(&cacheDir, &cacheContent, dbPath, packageId, &num_elements)) + return num_elements; + + num_elements = (uint32_t) ffSettingsGetSQLite3Int(dbPath, query); + + ffPackagesWriteCache(&cacheDir, &cacheContent, num_elements); + + return num_elements; +} + void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options) { if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT)) - result->pkg = (uint32_t) ffSettingsGetSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages"); + { + result->pkg = getSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages", "pkg"); + } } From b1eceb6be24ea7c44133970c02a8fe43a08c7368 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Sep 2024 15:47:52 +0800 Subject: [PATCH 07/30] CMake: simplify --- CMakeLists.txt | 18 ++++-------------- 1 file changed, 4 insertions(+), 14 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 7efcfde89d..75d5ed6341 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -885,8 +885,8 @@ add_library(libfastfetch OBJECT ) if(yyjson_FOUND) - target_compile_definitions(libfastfetch PRIVATE FF_USE_SYSTEM_YYJSON) - target_link_libraries(libfastfetch PRIVATE yyjson::yyjson) + target_compile_definitions(libfastfetch PUBLIC FF_USE_SYSTEM_YYJSON) + target_link_libraries(libfastfetch PUBLIC yyjson::yyjson) # `target_link_libraries(yyjson::yyjson)` sets rpath implicitly else() # Used for dlopen finding dylibs installed by homebrew @@ -928,11 +928,11 @@ elseif(SunOS) endif() if(HAVE_STATX) - target_compile_definitions(libfastfetch PRIVATE FF_HAVE_STATX) + target_compile_definitions(libfastfetch PUBLIC FF_HAVE_STATX) endif() if(HAVE_WCWIDTH) - target_compile_definitions(libfastfetch PRIVATE FF_HAVE_WCWIDTH) + target_compile_definitions(libfastfetch PUBLIC FF_HAVE_WCWIDTH) endif() if(NOT "${CUSTOM_PCI_IDS_PATH}" STREQUAL "") @@ -1294,13 +1294,6 @@ set(CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "") set_target_properties(fastfetch PROPERTIES LINKER_LANGUAGE C) set_target_properties(flashfetch PROPERTIES LINKER_LANGUAGE C) -if(yyjson_FOUND) - target_compile_definitions(fastfetch PRIVATE FF_USE_SYSTEM_YYJSON) - target_link_libraries(fastfetch PRIVATE yyjson::yyjson) - target_compile_definitions(flashfetch PRIVATE FF_USE_SYSTEM_YYJSON) - target_link_libraries(flashfetch PRIVATE yyjson::yyjson) -endif() - if(WIN32) target_sources(fastfetch PRIVATE src/util/windows/version.rc @@ -1347,9 +1340,6 @@ if (BUILD_TESTS) target_link_libraries(fastfetch-test-format PRIVATE libfastfetch ) - if(yyjson_FOUND) - target_compile_definitions(fastfetch-test-format PRIVATE FF_USE_SYSTEM_YYJSON) - endif() enable_testing() add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf) From 3d1a6b67c5336f7fb83060468def023a6dae3fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Sep 2024 15:45:53 +0800 Subject: [PATCH 08/30] Packages: add cmake options to disable certain package managers at compile time --- CMakeLists.txt | 25 +++++++++++++++++++++++++ src/modules/packages/packages.c | 12 ++++++------ 2 files changed, 31 insertions(+), 6 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 75d5ed6341..547d4f06e4 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -88,6 +88,15 @@ 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 PALUDIS PKG PKGTOOL RPM SCOOP SNAP 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) + else() + option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" OFF) + endif() +endforeach() + if (LINUX) set(CUSTOM_PCI_IDS_PATH "" CACHE STRING "Custom path to file pci.ids, defaults to `/usr/share/hwdata/pci.ids`") set(CUSTOM_AMDGPU_IDS_PATH "" CACHE STRING "Custom path to file amdgpu.ids, defaults to `/usr/share/libdrm/amdgpu.ids`") @@ -1264,6 +1273,22 @@ if(NOT WIN32) endif() endif() +set(PACKAGES_DISABLE_LIST "") +foreach(package_manager ${PACKAGE_MANAGERS}) + if(PACKAGES_DISABLE_${package_manager}) + list(APPEND PACKAGES_DISABLE_LIST "${package_manager}") + endif() +endforeach() +if("${PACKAGES_DISABLE_LIST}" STREQUAL "") + set(PACKAGES_DISABLE_LIST "FF_PACKAGES_FLAG_NONE") +else() + message(STATUS "Disabled package managers: ${PACKAGES_DISABLE_LIST}") + list(TRANSFORM PACKAGES_DISABLE_LIST PREPEND "FF_PACKAGES_FLAG_") + list(TRANSFORM PACKAGES_DISABLE_LIST APPEND "_BIT") + list(JOIN PACKAGES_DISABLE_LIST " | " PACKAGES_DISABLE_LIST) +endif() +target_compile_definitions(libfastfetch PRIVATE FF_PACKAGES_DISABLE_LIST=${PACKAGES_DISABLE_LIST}) + ###################### # Executable targets # ###################### diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index 3d056c12d4..3e2b09fc7e 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -336,6 +336,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "disabled"); #define FF_TEST_PACKAGE_NAME(name) else if ((options->disabled & FF_PACKAGES_FLAG_ ## name ## _BIT) != (defaultOptions.disabled & FF_PACKAGES_FLAG_ ## name ## _BIT)) { yyjson_mut_arr_add_str(doc, arr, #name); } if (false); + FF_TEST_PACKAGE_NAME(AM) FF_TEST_PACKAGE_NAME(APK) FF_TEST_PACKAGE_NAME(BREW) FF_TEST_PACKAGE_NAME(CHOCO) @@ -343,24 +344,23 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do FF_TEST_PACKAGE_NAME(EMERGE) FF_TEST_PACKAGE_NAME(EOPKG) FF_TEST_PACKAGE_NAME(FLATPAK) + FF_TEST_PACKAGE_NAME(GUIX) + FF_TEST_PACKAGE_NAME(LINGLONG) FF_TEST_PACKAGE_NAME(LPKG) FF_TEST_PACKAGE_NAME(LPKGBUILD) + FF_TEST_PACKAGE_NAME(MACPORTS) FF_TEST_PACKAGE_NAME(NIX) FF_TEST_PACKAGE_NAME(OPKG) FF_TEST_PACKAGE_NAME(PACMAN) FF_TEST_PACKAGE_NAME(PALUDIS) FF_TEST_PACKAGE_NAME(PKG) FF_TEST_PACKAGE_NAME(PKGTOOL) - FF_TEST_PACKAGE_NAME(MACPORTS) FF_TEST_PACKAGE_NAME(RPM) FF_TEST_PACKAGE_NAME(SCOOP) FF_TEST_PACKAGE_NAME(SNAP) + FF_TEST_PACKAGE_NAME(SORCERY) FF_TEST_PACKAGE_NAME(WINGET) FF_TEST_PACKAGE_NAME(XBPS) - FF_TEST_PACKAGE_NAME(AM) - FF_TEST_PACKAGE_NAME(SORCERY) - FF_TEST_PACKAGE_NAME(GUIX) - FF_TEST_PACKAGE_NAME(LINGLONG) #undef FF_TEST_PACKAGE_NAME } } @@ -473,7 +473,7 @@ void ffInitPackagesOptions(FFPackagesOptions* options) ); ffOptionInitModuleArg(&options->moduleArgs, "󰏖"); - options->disabled = FF_PACKAGES_FLAG_WINGET_BIT; + options->disabled = FF_PACKAGES_DISABLE_LIST; } void ffDestroyPackagesOptions(FFPackagesOptions* options) From 9faa38296ab157d9fd099c9bef9daa9f4d9a82f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Sep 2024 16:36:21 +0800 Subject: [PATCH 09/30] Packages: don't cache values if we fail to acquire modify time --- src/detection/packages/packages.c | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 8af7046383..9a634e6285 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -32,6 +32,9 @@ bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* return true; } + if (__builtin_expect(st.st_mtim.tv_sec <= 0, false)) + return false; + uint64_t mtime_current = (uint64_t) st.st_mtim.tv_sec * 1000 + (uint64_t) st.st_mtim.tv_nsec / 1000000; ffStrbufSet(cacheDir, &instance.state.platform.cacheDir); @@ -57,6 +60,9 @@ bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements) { + if (__builtin_expect(cacheContent->length == 0, false)) + return false; + ffStrbufAppendF(cacheContent, "%" PRIu32, num_elements); return ffWriteFileBuffer(cacheDir->chars, cacheContent); } From ed2dd8f2ec459670f345c46d4d113fdff79b32e0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Sep 2024 20:47:02 +0800 Subject: [PATCH 10/30] CPU (FreeBSD): remove using of freq_levels Doesn't work at all Fix #1260 --- src/detection/cpu/cpu_bsd.c | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index dec08e602a..edb1583bd2 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -41,23 +41,6 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) ffCPUDetectSpeedByCpuid(cpu); - 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->frequencyBase = (uint32_t) ffSysctlGetInt("hw.clockrate", 0); cpu->temperature = FF_CPU_TEMP_UNSET; From cd11a9dff4ddb8bf9d00569e528aba10b184ca20 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Sep 2024 21:31:25 +0800 Subject: [PATCH 11/30] Packages (Windows): fix compiling --- src/detection/packages/packages.c | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 9a634e6285..9390a2bf88 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -25,6 +25,7 @@ const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* option bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result) { + #ifndef _WIN32 struct stat st; if (stat(filePath, &st) < 0) // file doesn't exist or isn't accessable { @@ -35,7 +36,25 @@ bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* if (__builtin_expect(st.st_mtim.tv_sec <= 0, false)) return false; - uint64_t mtime_current = (uint64_t) st.st_mtim.tv_sec * 1000 + (uint64_t) st.st_mtim.tv_nsec / 1000000; + uint64_t mtime_current = (uint64_t) st.st_mtim.tv_sec * 1000ull + (uint64_t) st.st_mtim.tv_nsec / 1000000ull; + #else + FF_AUTO_CLOSE_FD HANDLE handle = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (handle == INVALID_HANDLE_VALUE) // file doesn't exist or isn't accessable + { + *result = 0; + return true; + } + + uint64_t mtime_current; + if (!GetFileTime(handle, NULL, NULL, (FILETIME*) &mtime_current)) + return false; + + mtime_current = (mtime_current - 116444736000000000ull) / 10000ull; + + if (__builtin_expect(mtime_current == 0, false)) + return false; + #endif ffStrbufSet(cacheDir, &instance.state.platform.cacheDir); ffStrbufEnsureEndsWithC(cacheDir, '/'); From a1f0570a96f46b74bcbc08d545f66142d1d047f0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 13 Sep 2024 22:26:47 +0800 Subject: [PATCH 12/30] Chore: fix typos --- src/detection/disk/disk_windows.c | 4 ++-- src/detection/packages/packages.c | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/detection/disk/disk_windows.c b/src/detection/disk/disk_windows.c index 581b662321..9c0e06760b 100644 --- a/src/detection/disk/disk_windows.c +++ b/src/detection/disk/disk_windows.c @@ -6,7 +6,7 @@ #include #include -static unsigned __stdcall testRemoteVolumeAccessable(void* mountpoint) +static unsigned __stdcall testRemoteVolumeAccessible(void* mountpoint) { FF_AUTO_CLOSE_FD HANDLE handle = CreateFileW( (wchar_t*) mountpoint, @@ -84,7 +84,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) #ifdef FF_HAVE_THREADS if (driveType == DRIVE_REMOTE) { - FFThreadType thread = ffThreadCreate(testRemoteVolumeAccessable, mountpoint); + FFThreadType thread = ffThreadCreate(testRemoteVolumeAccessible, mountpoint); if (!ffThreadJoin(thread, 500)) continue; } diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c index 9390a2bf88..1a12bc328b 100644 --- a/src/detection/packages/packages.c +++ b/src/detection/packages/packages.c @@ -27,7 +27,7 @@ bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* { #ifndef _WIN32 struct stat st; - if (stat(filePath, &st) < 0) // file doesn't exist or isn't accessable + if (stat(filePath, &st) < 0) // file doesn't exist or isn't accessible { *result = 0; return true; @@ -40,7 +40,7 @@ bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* #else FF_AUTO_CLOSE_FD HANDLE handle = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); - if (handle == INVALID_HANDLE_VALUE) // file doesn't exist or isn't accessable + if (handle == INVALID_HANDLE_VALUE) // file doesn't exist or isn't accessible { *result = 0; return true; From 74fcd8b1c31421f481d310308e50b8dad0ccbc57 Mon Sep 17 00:00:00 2001 From: Nyx <144965845+nnyyxxxx@users.noreply.github.com> Date: Fri, 13 Sep 2024 10:34:06 -0400 Subject: [PATCH 13/30] Doc: Change grammar (#1263) Co-authored-by: nnyyxxxx --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 362773418f..e82de5b393 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/ ### Linux -Some distros packaged an outdated fastfetch version. Older version receive no support, so please try always to use the latest version. +Some distros package an outdated fastfetch version. Older versions receive no support, so please try always to use the latest version. * Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (for Ubuntu 22.04 or newer) * Debian: `apt install fastfetch` (for Debian 13 or newer) @@ -90,7 +90,7 @@ See Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building Fastfetch uses the JSONC (or JSON with comments) for configuration. [See Wiki for detail](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in [`presets`](presets), including the ones used for the screenshots above. You can load them using `-c `. Those files can serve as examples of the configuration syntax. -Logos can be heavily customized too; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information. +Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information. ## Packaging @@ -112,7 +112,7 @@ Logos can be heavily customized too; see the [logo documentation](https://github 2. Fastfetch is faster. As the name suggests. 3. Fastfetch has a greater number of features, though by default fastfetch only has a few modules enabled; use `fastfetch -c all` to find what you want. 4. Fastfetch is more configurable. You can find more information in the Wiki: . -5. Fastfetch is more polished. For example, neofetch prints `555MiB` in `Memory` module and `23G` in `Disk` module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively. +5. Fastfetch is more polished. For example, neofetch prints `555 MiB` in the Memory module and `23 G` in the Disk module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively. 6. Fastfetch is more accurate. For example, [neofetch never actually supports the Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395). ### Q: Fastfetch shows my local IP address. It leaks my privacy! From 553b0fe8cc7f0b2986b481683fbcdcfada01f81b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 14 Sep 2024 09:00:27 +0800 Subject: [PATCH 14/30] OS (Linux): fix parrot logo detection --- src/detection/os/os_linux.c | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index af6b37ba45..862d958191 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -172,6 +172,13 @@ static bool detectDebianDerived(FFOSResult* result) ffStrbufSetS(&result->idLike, "debian"); return true; } + else if (ffStrbufEqualS(&result->name, "Parrot Security")) + { + // https://github.com/ParrotSec/base-files/blob/c06f6d42ddf8d79564882306576576eddab7d907/etc/os-release + ffStrbufSetS(&result->id, "parrot"); + ffStrbufSetS(&result->idLike, "debian"); + return true; + } else if (ffPathExists("/usr/bin/pveversion", FF_PATHTYPE_FILE)) { ffStrbufSetS(&result->id, "pve"); From 3381062ab9e32bb062732cf6aecf4c1f99b73b4d Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 14 Sep 2024 21:53:43 +0800 Subject: [PATCH 15/30] CPU (FreeBSD): fix cpu temperature detection --- src/detection/cpu/cpu_bsd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index edb1583bd2..4b073f9d51 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -46,7 +46,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) if (options->temp) { - if (!ffDetectCpuTemp(&cpu->temperature)) + if (ffDetectCpuTemp(&cpu->temperature) != NULL) ffDetectThermalTemp(&cpu->temperature); } From c58f4c24c4561e1bac7532604c25ba0c1742d80e Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 14 Sep 2024 09:51:19 +0800 Subject: [PATCH 16/30] LocalIP: add new option `--show-localip-{speed,mtu}` --- src/detection/localip/localip_linux.c | 791 ++++++++++++------------ src/detection/localip/localip_windows.c | 6 +- src/modules/localip/localip.c | 68 +- src/modules/localip/option.h | 2 + 4 files changed, 475 insertions(+), 392 deletions(-) diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index bdd91ac09d..9dfea2537b 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -172,403 +172,416 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) if (ifAddrStruct) freeifaddrs(ifAddrStruct); - FF_AUTO_CLOSE_FD int sockfd = socket(AF_INET, SOCK_DGRAM, 0); - if (sockfd > 0) + if ((options->showType & FF_LOCALIP_TYPE_MTU_BIT) || (options->showType & FF_LOCALIP_TYPE_SPEED_BIT) + #ifdef __sun + || (options->showType & FF_LOCALIP_TYPE_MAC_BIT) + #endif + ) { - FF_LIST_FOR_EACH(FFLocalIpResult, iface, *results) + FF_AUTO_CLOSE_FD int sockfd = socket(AF_INET, SOCK_DGRAM, 0); + if (sockfd > 0) { - struct ifreq ifr; - strncpy(ifr.ifr_name, iface->name.chars, IFNAMSIZ - 1); + FF_LIST_FOR_EACH(FFLocalIpResult, iface, *results) + { + struct ifreq ifr; + strncpy(ifr.ifr_name, iface->name.chars, IFNAMSIZ - 1); - if (ioctl(sockfd, SIOCGIFMTU, &ifr) == 0) - iface->mtu = (int32_t) ifr.ifr_mtu; + if (options->showType & FF_LOCALIP_TYPE_MTU_BIT) + { + if (ioctl(sockfd, SIOCGIFMTU, &ifr) == 0) + iface->mtu = (int32_t) ifr.ifr_mtu; + } - #ifdef __linux__ - struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET }; - ifr.ifr_data = (void*) &edata; - if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0) - iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android - #elif __FreeBSD__ || __APPLE__ - struct ifmediareq ifmr = {}; - strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1); - if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0) - { - switch (IFM_SUBTYPE(ifmr.ifm_active)) + if (options->showType & FF_LOCALIP_TYPE_SPEED_BIT) { - #ifdef IFM_HPNA_1 - case IFM_HPNA_1: - #endif - iface->speed = 1; break; - #ifdef IFM_1000_CX - case IFM_1000_CX: - #endif - #ifdef IFM_1000_CX_SGMII - case IFM_1000_CX_SGMII: - #endif - #ifdef IFM_1000_KX - case IFM_1000_KX: - #endif - #ifdef IFM_1000_LX - case IFM_1000_LX: - #endif - #ifdef IFM_1000_SGMII - case IFM_1000_SGMII: - #endif - #ifdef IFM_1000_SX - case IFM_1000_SX: - #endif - #ifdef IFM_1000_T - case IFM_1000_T: - #endif - iface->speed = 1000; break; - #ifdef IFM_100G_AUI2 - case IFM_100G_AUI2: - #endif - #ifdef IFM_100G_AUI2_AC - case IFM_100G_AUI2_AC: - #endif - #ifdef IFM_100G_AUI4 - case IFM_100G_AUI4: - #endif - #ifdef IFM_100G_AUI4_AC - case IFM_100G_AUI4_AC: - #endif - #ifdef IFM_100G_CAUI2 - case IFM_100G_CAUI2: - #endif - #ifdef IFM_100G_CAUI2_AC - case IFM_100G_CAUI2_AC: - #endif - #ifdef IFM_100G_CAUI4 - case IFM_100G_CAUI4: - #endif - #ifdef IFM_100G_CAUI4_AC - case IFM_100G_CAUI4_AC: - #endif - #ifdef IFM_100G_CP2 - case IFM_100G_CP2: - #endif - #ifdef IFM_100G_CR4 - case IFM_100G_CR4: - #endif - #ifdef IFM_100G_CR_PAM4 - case IFM_100G_CR_PAM4: - #endif - #ifdef IFM_100G_DR - case IFM_100G_DR: - #endif - #ifdef IFM_100G_KR2_PAM4 - case IFM_100G_KR2_PAM4: - #endif - #ifdef IFM_100G_KR4 - case IFM_100G_KR4: - #endif - #ifdef IFM_100G_KR_PAM4 - case IFM_100G_KR_PAM4: - #endif - #ifdef IFM_100G_LR4 - case IFM_100G_LR4: - #endif - #ifdef IFM_100G_SR2 - case IFM_100G_SR2: - #endif - #ifdef IFM_100G_SR4 - case IFM_100G_SR4: - #endif - iface->speed = 100000; break; - #ifdef IFM_100_FX - case IFM_100_FX: - #endif - #ifdef IFM_100_SGMII - case IFM_100_SGMII: - #endif - #ifdef IFM_100_T - case IFM_100_T: - #endif - #ifdef IFM_100_T2 - case IFM_100_T2: - #endif - #ifdef IFM_100_T4 - case IFM_100_T4: - #endif - #ifdef IFM_100_TX - case IFM_100_TX: - #endif - #ifdef IFM_100_VG - case IFM_100_VG: - #endif - iface->speed = 100; break; - #ifdef IFM_10G_AOC - case IFM_10G_AOC: - #endif - #ifdef IFM_10G_CR1 - case IFM_10G_CR1: - #endif - #ifdef IFM_10G_CX4 - case IFM_10G_CX4: - #endif - #ifdef IFM_10G_ER - case IFM_10G_ER: - #endif - #ifdef IFM_10G_KR - case IFM_10G_KR: - #endif - #ifdef IFM_10G_KX4 - case IFM_10G_KX4: - #endif - #ifdef IFM_10G_LR - case IFM_10G_LR: - #endif - #ifdef IFM_10G_LRM - case IFM_10G_LRM: - #endif - #ifdef IFM_10G_SFI - case IFM_10G_SFI: - #endif - #ifdef IFM_10G_SR - case IFM_10G_SR: - #endif - #ifdef IFM_10G_T - case IFM_10G_T: - #endif - #ifdef IFM_10G_TWINAX - case IFM_10G_TWINAX: - #endif - #ifdef IFM_10G_TWINAX_LONG - case IFM_10G_TWINAX_LONG: - #endif - iface->speed = 10000; break; - #ifdef IFM_10_2 - case IFM_10_2: - #endif - #ifdef IFM_10_5 - case IFM_10_5: - #endif - #ifdef IFM_10_FL - case IFM_10_FL: - #endif - #ifdef IFM_10_STP - case IFM_10_STP: - #endif - #ifdef IFM_10_T - case IFM_10_T: - #endif - iface->speed = 10; break; - #ifdef IFM_200G_AUI4 - case IFM_200G_AUI4: - #endif - #ifdef IFM_200G_AUI4_AC - case IFM_200G_AUI4_AC: - #endif - #ifdef IFM_200G_AUI8 - case IFM_200G_AUI8: - #endif - #ifdef IFM_200G_AUI8_AC - case IFM_200G_AUI8_AC: - #endif - #ifdef IFM_200G_CR4_PAM4 - case IFM_200G_CR4_PAM4: - #endif - #ifdef IFM_200G_DR4 - case IFM_200G_DR4: - #endif - #ifdef IFM_200G_FR4 - case IFM_200G_FR4: - #endif - #ifdef IFM_200G_KR4_PAM4 - case IFM_200G_KR4_PAM4: - #endif - #ifdef IFM_200G_LR4 - case IFM_200G_LR4: - #endif - #ifdef IFM_200G_SR4 - case IFM_200G_SR4: - #endif - iface->speed = 200000; break; - #ifdef IFM_20G_KR2 - case IFM_20G_KR2: - #endif - iface->speed = 20000; break; - #ifdef IFM_2500_KX - case IFM_2500_KX: - #endif - #ifdef IFM_2500_SX - case IFM_2500_SX: - #endif - #ifdef IFM_2500_T - case IFM_2500_T: - #endif - #ifdef IFM_2500_X - case IFM_2500_X: - #endif - iface->speed = 2500; break; - #ifdef IFM_25G_ACC - case IFM_25G_ACC: - #endif - #ifdef IFM_25G_AOC - case IFM_25G_AOC: - #endif - #ifdef IFM_25G_AUI - case IFM_25G_AUI: - #endif - #ifdef IFM_25G_CR - case IFM_25G_CR: - #endif - #ifdef IFM_25G_CR1 - case IFM_25G_CR1: - #endif - #ifdef IFM_25G_CR_S - case IFM_25G_CR_S: - #endif - #ifdef IFM_25G_KR - case IFM_25G_KR: - #endif - #ifdef IFM_25G_KR1 - case IFM_25G_KR1: - #endif - #ifdef IFM_25G_KR_S - case IFM_25G_KR_S: - #endif - #ifdef IFM_25G_LR - case IFM_25G_LR: - #endif - #ifdef IFM_25G_PCIE - case IFM_25G_PCIE: - #endif - #ifdef IFM_25G_SR - case IFM_25G_SR: - #endif - #ifdef IFM_25G_T - case IFM_25G_T: - #endif - iface->speed = 25000; break; - #ifdef IFM_400G_AUI8 - case IFM_400G_AUI8: - #endif - #ifdef IFM_400G_AUI8_AC - case IFM_400G_AUI8_AC: - #endif - #ifdef IFM_400G_DR4 - case IFM_400G_DR4: - #endif - #ifdef IFM_400G_FR8 - case IFM_400G_FR8: - #endif - #ifdef IFM_400G_LR8 - case IFM_400G_LR8: - #endif - iface->speed = 400000; break; - #ifdef IFM_40G_CR4 - case IFM_40G_CR4: - #endif - #ifdef IFM_40G_ER4 - case IFM_40G_ER4: - #endif - #ifdef IFM_40G_KR4 - case IFM_40G_KR4: - #endif - #ifdef IFM_40G_LR4 - case IFM_40G_LR4: - #endif - #ifdef IFM_40G_SR4 - case IFM_40G_SR4: - #endif - #ifdef IFM_40G_XLAUI - case IFM_40G_XLAUI: - #endif - #ifdef IFM_40G_XLAUI_AC - case IFM_40G_XLAUI_AC: - #endif - #ifdef IFM_40G_XLPPI - case IFM_40G_XLPPI: - #endif - #ifdef IFM_40G_LM4 - case IFM_40G_LM4: - #endif - iface->speed = 40000; break; - #ifdef IFM_5000_KR - case IFM_5000_KR: - #endif - #ifdef IFM_5000_KR1 - case IFM_5000_KR1: - #endif - #ifdef IFM_5000_KR_S - case IFM_5000_KR_S: - #endif - #ifdef IFM_5000_T - case IFM_5000_T: - #endif - iface->speed = 5000; break; - #ifdef IFM_50G_AUI1 - case IFM_50G_AUI1: - #endif - #ifdef IFM_50G_AUI1_AC - case IFM_50G_AUI1_AC: - #endif - #ifdef IFM_50G_AUI2 - case IFM_50G_AUI2: - #endif - #ifdef IFM_50G_AUI2_AC - case IFM_50G_AUI2_AC: - #endif - #ifdef IFM_50G_CP - case IFM_50G_CP: - #endif - #ifdef IFM_50G_CR2 - case IFM_50G_CR2: - #endif - #ifdef IFM_50G_FR - case IFM_50G_FR: - #endif - #ifdef IFM_50G_KR2 - case IFM_50G_KR2: - #endif - #ifdef IFM_50G_KR_PAM4 - case IFM_50G_KR_PAM4: - #endif - #ifdef IFM_50G_LAUI2 - case IFM_50G_LAUI2: - #endif - #ifdef IFM_50G_LAUI2_AC - case IFM_50G_LAUI2_AC: - #endif - #ifdef IFM_50G_LR - case IFM_50G_LR: - #endif - #ifdef IFM_50G_LR2 - case IFM_50G_LR2: - #endif - #ifdef IFM_50G_PCIE - case IFM_50G_PCIE: - #endif - #ifdef IFM_50G_SR - case IFM_50G_SR: - #endif - #ifdef IFM_50G_SR2 - case IFM_50G_SR2: - #endif - #ifdef IFM_50G_KR4 - case IFM_50G_KR4: - #endif - iface->speed = 50000; break; - #ifdef IFM_56G_R4 - case IFM_56G_R4: - #endif - iface->speed = 56000; break; - default: - iface->speed = -1; + #ifdef __linux__ + struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET }; + ifr.ifr_data = (void*) &edata; + if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0) + iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android + #elif __FreeBSD__ || __APPLE__ + struct ifmediareq ifmr = {}; + strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1); + if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0) + { + switch (IFM_SUBTYPE(ifmr.ifm_active)) + { + #ifdef IFM_HPNA_1 + case IFM_HPNA_1: + #endif + iface->speed = 1; break; + #ifdef IFM_1000_CX + case IFM_1000_CX: + #endif + #ifdef IFM_1000_CX_SGMII + case IFM_1000_CX_SGMII: + #endif + #ifdef IFM_1000_KX + case IFM_1000_KX: + #endif + #ifdef IFM_1000_LX + case IFM_1000_LX: + #endif + #ifdef IFM_1000_SGMII + case IFM_1000_SGMII: + #endif + #ifdef IFM_1000_SX + case IFM_1000_SX: + #endif + #ifdef IFM_1000_T + case IFM_1000_T: + #endif + iface->speed = 1000; break; + #ifdef IFM_100G_AUI2 + case IFM_100G_AUI2: + #endif + #ifdef IFM_100G_AUI2_AC + case IFM_100G_AUI2_AC: + #endif + #ifdef IFM_100G_AUI4 + case IFM_100G_AUI4: + #endif + #ifdef IFM_100G_AUI4_AC + case IFM_100G_AUI4_AC: + #endif + #ifdef IFM_100G_CAUI2 + case IFM_100G_CAUI2: + #endif + #ifdef IFM_100G_CAUI2_AC + case IFM_100G_CAUI2_AC: + #endif + #ifdef IFM_100G_CAUI4 + case IFM_100G_CAUI4: + #endif + #ifdef IFM_100G_CAUI4_AC + case IFM_100G_CAUI4_AC: + #endif + #ifdef IFM_100G_CP2 + case IFM_100G_CP2: + #endif + #ifdef IFM_100G_CR4 + case IFM_100G_CR4: + #endif + #ifdef IFM_100G_CR_PAM4 + case IFM_100G_CR_PAM4: + #endif + #ifdef IFM_100G_DR + case IFM_100G_DR: + #endif + #ifdef IFM_100G_KR2_PAM4 + case IFM_100G_KR2_PAM4: + #endif + #ifdef IFM_100G_KR4 + case IFM_100G_KR4: + #endif + #ifdef IFM_100G_KR_PAM4 + case IFM_100G_KR_PAM4: + #endif + #ifdef IFM_100G_LR4 + case IFM_100G_LR4: + #endif + #ifdef IFM_100G_SR2 + case IFM_100G_SR2: + #endif + #ifdef IFM_100G_SR4 + case IFM_100G_SR4: + #endif + iface->speed = 100000; break; + #ifdef IFM_100_FX + case IFM_100_FX: + #endif + #ifdef IFM_100_SGMII + case IFM_100_SGMII: + #endif + #ifdef IFM_100_T + case IFM_100_T: + #endif + #ifdef IFM_100_T2 + case IFM_100_T2: + #endif + #ifdef IFM_100_T4 + case IFM_100_T4: + #endif + #ifdef IFM_100_TX + case IFM_100_TX: + #endif + #ifdef IFM_100_VG + case IFM_100_VG: + #endif + iface->speed = 100; break; + #ifdef IFM_10G_AOC + case IFM_10G_AOC: + #endif + #ifdef IFM_10G_CR1 + case IFM_10G_CR1: + #endif + #ifdef IFM_10G_CX4 + case IFM_10G_CX4: + #endif + #ifdef IFM_10G_ER + case IFM_10G_ER: + #endif + #ifdef IFM_10G_KR + case IFM_10G_KR: + #endif + #ifdef IFM_10G_KX4 + case IFM_10G_KX4: + #endif + #ifdef IFM_10G_LR + case IFM_10G_LR: + #endif + #ifdef IFM_10G_LRM + case IFM_10G_LRM: + #endif + #ifdef IFM_10G_SFI + case IFM_10G_SFI: + #endif + #ifdef IFM_10G_SR + case IFM_10G_SR: + #endif + #ifdef IFM_10G_T + case IFM_10G_T: + #endif + #ifdef IFM_10G_TWINAX + case IFM_10G_TWINAX: + #endif + #ifdef IFM_10G_TWINAX_LONG + case IFM_10G_TWINAX_LONG: + #endif + iface->speed = 10000; break; + #ifdef IFM_10_2 + case IFM_10_2: + #endif + #ifdef IFM_10_5 + case IFM_10_5: + #endif + #ifdef IFM_10_FL + case IFM_10_FL: + #endif + #ifdef IFM_10_STP + case IFM_10_STP: + #endif + #ifdef IFM_10_T + case IFM_10_T: + #endif + iface->speed = 10; break; + #ifdef IFM_200G_AUI4 + case IFM_200G_AUI4: + #endif + #ifdef IFM_200G_AUI4_AC + case IFM_200G_AUI4_AC: + #endif + #ifdef IFM_200G_AUI8 + case IFM_200G_AUI8: + #endif + #ifdef IFM_200G_AUI8_AC + case IFM_200G_AUI8_AC: + #endif + #ifdef IFM_200G_CR4_PAM4 + case IFM_200G_CR4_PAM4: + #endif + #ifdef IFM_200G_DR4 + case IFM_200G_DR4: + #endif + #ifdef IFM_200G_FR4 + case IFM_200G_FR4: + #endif + #ifdef IFM_200G_KR4_PAM4 + case IFM_200G_KR4_PAM4: + #endif + #ifdef IFM_200G_LR4 + case IFM_200G_LR4: + #endif + #ifdef IFM_200G_SR4 + case IFM_200G_SR4: + #endif + iface->speed = 200000; break; + #ifdef IFM_20G_KR2 + case IFM_20G_KR2: + #endif + iface->speed = 20000; break; + #ifdef IFM_2500_KX + case IFM_2500_KX: + #endif + #ifdef IFM_2500_SX + case IFM_2500_SX: + #endif + #ifdef IFM_2500_T + case IFM_2500_T: + #endif + #ifdef IFM_2500_X + case IFM_2500_X: + #endif + iface->speed = 2500; break; + #ifdef IFM_25G_ACC + case IFM_25G_ACC: + #endif + #ifdef IFM_25G_AOC + case IFM_25G_AOC: + #endif + #ifdef IFM_25G_AUI + case IFM_25G_AUI: + #endif + #ifdef IFM_25G_CR + case IFM_25G_CR: + #endif + #ifdef IFM_25G_CR1 + case IFM_25G_CR1: + #endif + #ifdef IFM_25G_CR_S + case IFM_25G_CR_S: + #endif + #ifdef IFM_25G_KR + case IFM_25G_KR: + #endif + #ifdef IFM_25G_KR1 + case IFM_25G_KR1: + #endif + #ifdef IFM_25G_KR_S + case IFM_25G_KR_S: + #endif + #ifdef IFM_25G_LR + case IFM_25G_LR: + #endif + #ifdef IFM_25G_PCIE + case IFM_25G_PCIE: + #endif + #ifdef IFM_25G_SR + case IFM_25G_SR: + #endif + #ifdef IFM_25G_T + case IFM_25G_T: + #endif + iface->speed = 25000; break; + #ifdef IFM_400G_AUI8 + case IFM_400G_AUI8: + #endif + #ifdef IFM_400G_AUI8_AC + case IFM_400G_AUI8_AC: + #endif + #ifdef IFM_400G_DR4 + case IFM_400G_DR4: + #endif + #ifdef IFM_400G_FR8 + case IFM_400G_FR8: + #endif + #ifdef IFM_400G_LR8 + case IFM_400G_LR8: + #endif + iface->speed = 400000; break; + #ifdef IFM_40G_CR4 + case IFM_40G_CR4: + #endif + #ifdef IFM_40G_ER4 + case IFM_40G_ER4: + #endif + #ifdef IFM_40G_KR4 + case IFM_40G_KR4: + #endif + #ifdef IFM_40G_LR4 + case IFM_40G_LR4: + #endif + #ifdef IFM_40G_SR4 + case IFM_40G_SR4: + #endif + #ifdef IFM_40G_XLAUI + case IFM_40G_XLAUI: + #endif + #ifdef IFM_40G_XLAUI_AC + case IFM_40G_XLAUI_AC: + #endif + #ifdef IFM_40G_XLPPI + case IFM_40G_XLPPI: + #endif + #ifdef IFM_40G_LM4 + case IFM_40G_LM4: + #endif + iface->speed = 40000; break; + #ifdef IFM_5000_KR + case IFM_5000_KR: + #endif + #ifdef IFM_5000_KR1 + case IFM_5000_KR1: + #endif + #ifdef IFM_5000_KR_S + case IFM_5000_KR_S: + #endif + #ifdef IFM_5000_T + case IFM_5000_T: + #endif + iface->speed = 5000; break; + #ifdef IFM_50G_AUI1 + case IFM_50G_AUI1: + #endif + #ifdef IFM_50G_AUI1_AC + case IFM_50G_AUI1_AC: + #endif + #ifdef IFM_50G_AUI2 + case IFM_50G_AUI2: + #endif + #ifdef IFM_50G_AUI2_AC + case IFM_50G_AUI2_AC: + #endif + #ifdef IFM_50G_CP + case IFM_50G_CP: + #endif + #ifdef IFM_50G_CR2 + case IFM_50G_CR2: + #endif + #ifdef IFM_50G_FR + case IFM_50G_FR: + #endif + #ifdef IFM_50G_KR2 + case IFM_50G_KR2: + #endif + #ifdef IFM_50G_KR_PAM4 + case IFM_50G_KR_PAM4: + #endif + #ifdef IFM_50G_LAUI2 + case IFM_50G_LAUI2: + #endif + #ifdef IFM_50G_LAUI2_AC + case IFM_50G_LAUI2_AC: + #endif + #ifdef IFM_50G_LR + case IFM_50G_LR: + #endif + #ifdef IFM_50G_LR2 + case IFM_50G_LR2: + #endif + #ifdef IFM_50G_PCIE + case IFM_50G_PCIE: + #endif + #ifdef IFM_50G_SR + case IFM_50G_SR: + #endif + #ifdef IFM_50G_SR2 + case IFM_50G_SR2: + #endif + #ifdef IFM_50G_KR4 + case IFM_50G_KR4: + #endif + iface->speed = 50000; break; + #ifdef IFM_56G_R4 + case IFM_56G_R4: + #endif + iface->speed = 56000; break; + default: + iface->speed = -1; + } + } + #endif } - } - #endif - #ifdef __sun - if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0) - { - const uint8_t* ptr = (uint8_t*) ifr.ifr_addr.sa_data; // NOT ifr_enaddr - ffStrbufSetF(&iface->mac, "%02x:%02x:%02x:%02x:%02x:%02x", - ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); + #ifdef __sun + if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0) + { + const uint8_t* ptr = (uint8_t*) ifr.ifr_addr.sa_data; // NOT ifr_enaddr + ffStrbufSetF(&iface->mac, "%02x:%02x:%02x:%02x:%02x:%02x", + ptr[0], ptr[1], ptr[2], ptr[3], ptr[4], ptr[5]); + } + #endif } - #endif } } diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index c378100f95..a24d38591b 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -153,8 +153,10 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) if (!newIp) { FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1); - result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000); - result->mtu = (int32_t) adapter->Mtu; + if (options->showType & FF_LOCALIP_TYPE_SPEED_BIT) + result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000); + if (options->showType & FF_LOCALIP_TYPE_MTU_BIT) + result->mtu = (int32_t) adapter->Mtu; } } diff --git a/src/modules/localip/localip.c b/src/modules/localip/localip.c index da9440610d..0ca38374f7 100644 --- a/src/modules/localip/localip.c +++ b/src/modules/localip/localip.c @@ -54,6 +54,28 @@ static void printIp(FFLocalIpResult* ip, bool markDefaultRoute) printf(" (%s)", ip->mac.chars); else ffStrbufWriteTo(&ip->mac, stdout); + flag = true; + } + if (ip->mtu > 0 || ip->speed > 0) + { + if (flag) + fputs(" [", stdout); + if (ip->speed > 0) + { + if (ip->speed >= 1000000) + printf("%g Tbps", ip->speed / 1000000.0); + else if (ip->speed >= 1000) + printf("Speed %g Gbps", ip->speed / 1000.0); + else + printf("Speed %u Mbps", (unsigned) ip->speed); + + if (ip->mtu > 0) + fputs(" / ", stdout); + } + if (ip->mtu > 0) + printf("MTU %u", (unsigned) ip->mtu); + putchar(']'); + flag = true; } if (markDefaultRoute && flag && ip->defaultRoute) fputs(" *", stdout); @@ -114,7 +136,9 @@ void ffPrintLocalIp(FFLocalIpOptions* options) FF_STRBUF_AUTO_DESTROY speedStr = ffStrbufCreate(); if (ip->speed > 0) { - if (ip->speed >= 1000) + if (ip->speed >= 1000000) + ffStrbufSetF(&speedStr, "%g Tbps", ip->speed / 1000000.0); + else if (ip->speed >= 1000) ffStrbufSetF(&speedStr, "%g Gbps", ip->speed / 1000.0); else ffStrbufSetF(&speedStr, "%u Mbps", (unsigned) ip->speed); @@ -194,6 +218,24 @@ bool ffParseLocalIpCommandOptions(FFLocalIpOptions* options, const char* key, co return true; } + if (ffStrEqualsIgnCase(subKey, "show-mtu")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_MTU_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_MTU_BIT; + return true; + } + + if (ffStrEqualsIgnCase(subKey, "show-speed")) + { + if (ffOptionParseBoolean(value)) + options->showType |= FF_LOCALIP_TYPE_SPEED_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_SPEED_BIT; + return true; + } + if(ffStrEqualsIgnCase(subKey, "compact")) { if (ffOptionParseBoolean(value)) @@ -288,6 +330,24 @@ void ffParseLocalIpJsonObject(FFLocalIpOptions* options, yyjson_val* module) continue; } + if (ffStrEqualsIgnCase(key, "showMtu")) + { + if (yyjson_get_bool(val)) + options->showType |= FF_LOCALIP_TYPE_MTU_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_MTU_BIT; + continue; + } + + if (ffStrEqualsIgnCase(key, "showSpeed")) + { + if (yyjson_get_bool(val)) + options->showType |= FF_LOCALIP_TYPE_SPEED_BIT; + else + options->showType &= ~FF_LOCALIP_TYPE_SPEED_BIT; + continue; + } + if (ffStrEqualsIgnCase(key, "compact")) { if (yyjson_get_bool(val)) @@ -349,6 +409,12 @@ void ffGenerateLocalIpJsonConfig(FFLocalIpOptions* options, yyjson_mut_doc* doc, if (options->showType & FF_LOCALIP_TYPE_PREFIX_LEN_BIT) yyjson_mut_obj_add_bool(doc, module, "showPrefixLen", true); + if (options->showType & FF_LOCALIP_TYPE_MTU_BIT) + yyjson_mut_obj_add_bool(doc, module, "showMtu", true); + + if (options->showType & FF_LOCALIP_TYPE_SPEED_BIT) + yyjson_mut_obj_add_bool(doc, module, "showSpeed", true); + if (options->showType & FF_LOCALIP_TYPE_COMPACT_BIT) yyjson_mut_obj_add_bool(doc, module, "compact", true); diff --git a/src/modules/localip/option.h b/src/modules/localip/option.h index 55b9192cd3..1a01611528 100644 --- a/src/modules/localip/option.h +++ b/src/modules/localip/option.h @@ -12,6 +12,8 @@ typedef enum FFLocalIpType FF_LOCALIP_TYPE_IPV6_BIT = 1 << 2, FF_LOCALIP_TYPE_MAC_BIT = 1 << 3, FF_LOCALIP_TYPE_PREFIX_LEN_BIT = 1 << 4, + FF_LOCALIP_TYPE_MTU_BIT = 1 << 5, + FF_LOCALIP_TYPE_SPEED_BIT = 1 << 6, FF_LOCALIP_TYPE_COMPACT_BIT = 1 << 10, FF_LOCALIP_TYPE_DEFAULT_ROUTE_ONLY_BIT = 1 << 11, From c24328e26e9a0ce289bb37f164f89039edebfa50 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 14 Sep 2024 16:18:35 +0800 Subject: [PATCH 17/30] Btrfs: add new module --- CMakeLists.txt | 7 + src/common/modules.c | 1 + src/detection/btrfs/btrfs.h | 28 +++ src/detection/btrfs/btrfs_linux.c | 166 +++++++++++++++++ src/detection/btrfs/btrfs_nosupport.c | 6 + src/modules/btrfs/btrfs.c | 254 ++++++++++++++++++++++++++ src/modules/btrfs/btrfs.h | 9 + src/modules/btrfs/option.h | 14 ++ src/modules/modules.h | 1 + src/modules/options.h | 1 + src/modules/zpool/zpool.c | 8 +- src/options/modules.c | 2 + src/options/modules.h | 1 + 13 files changed, 494 insertions(+), 4 deletions(-) create mode 100644 src/detection/btrfs/btrfs.h create mode 100644 src/detection/btrfs/btrfs_linux.c create mode 100644 src/detection/btrfs/btrfs_nosupport.c create mode 100644 src/modules/btrfs/btrfs.c create mode 100644 src/modules/btrfs/btrfs.h create mode 100644 src/modules/btrfs/option.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 547d4f06e4..4dcfc48689 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -342,6 +342,7 @@ set(LIBFASTFETCH_SRC src/modules/bootmgr/bootmgr.c src/modules/brightness/brightness.c src/modules/break/break.c + src/modules/btrfs/btrfs.c src/modules/camera/camera.c src/modules/chassis/chassis.c src/modules/colors/colors.c @@ -428,6 +429,7 @@ if(LINUX) src/detection/board/board_linux.c src/detection/bootmgr/bootmgr_linux.c src/detection/brightness/brightness_linux.c + src/detection/btrfs/btrfs_linux.c src/detection/chassis/chassis_linux.c src/detection/cpu/cpu_linux.c src/detection/cpucache/cpucache_linux.c @@ -508,6 +510,7 @@ elseif(ANDROID) src/detection/board/board_android.c src/detection/bootmgr/bootmgr_nosupport.c src/detection/brightness/brightness_nosupport.c + src/detection/btrfs/btrfs_nosupport.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_linux.c src/detection/cpucache/cpucache_linux.c @@ -573,6 +576,7 @@ elseif(FreeBSD) src/detection/board/board_bsd.c src/detection/bootmgr/bootmgr_bsd.c src/detection/brightness/brightness_bsd.c + src/detection/btrfs/btrfs_nosupport.c src/detection/chassis/chassis_bsd.c src/detection/cpu/cpu_bsd.c src/detection/cpucache/cpucache_shared.c @@ -652,6 +656,7 @@ elseif(APPLE) src/detection/board/board_apple.c src/detection/bootmgr/bootmgr_apple.c src/detection/brightness/brightness_apple.c + src/detection/btrfs/btrfs_nosupport.c src/detection/chassis/chassis_nosupport.c src/detection/cpu/cpu_apple.c src/detection/cpucache/cpucache_apple.c @@ -718,6 +723,7 @@ elseif(WIN32) src/detection/board/board_windows.c src/detection/bootmgr/bootmgr_windows.c src/detection/brightness/brightness_windows.cpp + src/detection/btrfs/btrfs_nosupport.c src/detection/chassis/chassis_windows.c src/detection/cpu/cpu_windows.c src/detection/cpucache/cpucache_windows.c @@ -785,6 +791,7 @@ elseif(SunOS) src/detection/board/board_windows.c src/detection/bootmgr/bootmgr_nosupport.c src/detection/brightness/brightness_nosupport.c + src/detection/btrfs/btrfs_nosupport.c src/detection/chassis/chassis_windows.c src/detection/cpu/cpu_sunos.c src/detection/cpucache/cpucache_shared.c diff --git a/src/common/modules.c b/src/common/modules.c index 28f270165e..232c555f04 100644 --- a/src/common/modules.c +++ b/src/common/modules.c @@ -13,6 +13,7 @@ static FFModuleBaseInfo* B[] = { (void*) &instance.config.modules.bootmgr, (void*) &instance.config.modules.break_, (void*) &instance.config.modules.brightness, + (void*) &instance.config.modules.btrfs, NULL, }; diff --git a/src/detection/btrfs/btrfs.h b/src/detection/btrfs/btrfs.h new file mode 100644 index 0000000000..a82157d091 --- /dev/null +++ b/src/detection/btrfs/btrfs.h @@ -0,0 +1,28 @@ +#pragma once + +#include "fastfetch.h" + +typedef struct FFBtrfsDiskUsage +{ + uint64_t total; + uint64_t used; + const char* type; + bool dup; +} FFBtrfsDiskUsage; + +typedef struct FFBtrfsResult +{ + FFstrbuf name; + FFstrbuf uuid; + FFstrbuf devices; + FFstrbuf features; + uint32_t generation; + uint32_t nodeSize; + uint32_t sectorSize; + uint64_t totalSize; + uint64_t globalReservationUsed; + uint64_t globalReservationTotal; + FFBtrfsDiskUsage allocation[3]; +} FFBtrfsResult; + +const char* ffDetectBtrfs(FFlist* result /* list of FFBtrfsResult */); diff --git a/src/detection/btrfs/btrfs_linux.c b/src/detection/btrfs/btrfs_linux.c new file mode 100644 index 0000000000..993300bac4 --- /dev/null +++ b/src/detection/btrfs/btrfs_linux.c @@ -0,0 +1,166 @@ +#include "btrfs.h" + +#include "common/io/io.h" + +enum { uuidLen = (uint32_t) __builtin_strlen("00000000-0000-0000-0000-000000000000") }; + +static const char* enumerateDevices(FFBtrfsResult* item, FFstrbuf* path, FFstrbuf* buffer) +{ + ffStrbufAppendS(path, "devices/"); + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path->chars); + if(dirp == NULL) + return "opendir(\"/sys/fs/btrfs/UUID/devices\") == NULL"; + const uint32_t devicesPathLen = path->length; + + struct dirent* entry; + while ((entry = readdir(dirp)) != NULL) + { + if (entry->d_name[0] == '.') + continue; + + if (item->devices.length) + ffStrbufAppendC(&item->devices, ','); + ffStrbufAppendS(&item->devices, entry->d_name); + ffStrbufAppendS(path, entry->d_name); + ffStrbufAppendS(path, "/size"); + + if (ffReadFileBuffer(path->chars, buffer)) + item->totalSize += ffStrbufToUInt(buffer, 0) * 512; + + ffStrbufSubstrBefore(path, devicesPathLen); + } + + return NULL; +} + +static const char* enumerateFeatures(FFBtrfsResult* item, FFstrbuf* path) +{ + ffStrbufAppendS(path, "features/"); + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path->chars); + if(dirp == NULL) + return "opendir(\"/sys/fs/btrfs/UUID/features\") == NULL"; + const uint32_t featuresPathLen = path->length; + + struct dirent* entry; + while ((entry = readdir(dirp)) != NULL) + { + if (entry->d_name[0] == '.') + continue; + if (item->features.length) + ffStrbufAppendC(&item->features, ','); + ffStrbufAppendS(&item->features, entry->d_name); + + ffStrbufSubstrBefore(path, featuresPathLen); + } + + return NULL; +} + +static const char* detectAllocation(FFBtrfsResult* item, FFstrbuf* path, FFstrbuf* buffer) +{ + ffStrbufAppendS(path, "allocation/"); + const uint32_t AllocationPathLen = path->length; + + ffStrbufAppendS(path, "global_rsv_size"); + if (ffReadFileBuffer(path->chars, buffer)) + item->globalReservationTotal = ffStrbufToUInt(buffer, 0); + else + return "ffReadFileBuffer(\"/sys/fs/btrfs/UUID/allocation/global_rsv_size\") == NULL"; + ffStrbufSubstrBefore(path, AllocationPathLen); + + ffStrbufAppendS(path, "global_rsv_reserved"); + if (ffReadFileBuffer(path->chars, buffer)) + item->globalReservationUsed = ffStrbufToUInt(buffer, 0); + ffStrbufSubstrBefore(path, AllocationPathLen); + item->globalReservationUsed = item->globalReservationTotal - item->globalReservationUsed; + + #define FF_BTRFS_DETECT_TYPE(index, _type) \ + ffStrbufAppendS(path, #_type "/total_bytes"); \ + if (ffReadFileBuffer(path->chars, buffer)) \ + item->allocation[index].total = ffStrbufToUInt(buffer, 0); \ + ffStrbufSubstrBefore(path, AllocationPathLen); \ + \ + ffStrbufAppendS(path, #_type "/bytes_used"); \ + if (ffReadFileBuffer(path->chars, buffer)) \ + item->allocation[index].used = ffStrbufToUInt(buffer, 0); \ + ffStrbufSubstrBefore(path, AllocationPathLen); \ + \ + ffStrbufAppendS(path, #_type "/dup"); \ + item->allocation[index].dup = ffPathExists(path->chars, FF_PATHTYPE_DIRECTORY); \ + ffStrbufSubstrBefore(path, AllocationPathLen); \ + \ + item->allocation[index].type = #_type; + + FF_BTRFS_DETECT_TYPE(0, data); + FF_BTRFS_DETECT_TYPE(1, metadata); + FF_BTRFS_DETECT_TYPE(2, system); + + #undef FF_BTRFS_DETECT_TYPE + + return NULL; +} + +const char* ffDetectBtrfs(FFlist* result) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateS("/sys/fs/btrfs/"); + const uint32_t basePathLen = path.length; + + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(path.chars); + if(dirp == NULL) + return "opendir(\"/sys/fs/btrfs\") == NULL"; + + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + + struct dirent* entry; + while ((entry = readdir(dirp)) != NULL) + { + if (entry->d_name[0] == '.') + continue; + if (strlen(entry->d_name) != uuidLen) + continue; + + FFBtrfsResult* item = ffListAdd(result); + (*item) = (FFBtrfsResult){}; + ffStrbufInitNS(&item->uuid, uuidLen, entry->d_name); + ffStrbufInit(&item->name); + ffStrbufInit(&item->devices); + ffStrbufInit(&item->features); + + ffStrbufAppendNS(&path, uuidLen, entry->d_name); + ffStrbufAppendC(&path, '/'); + const uint32_t itemPathLen = path.length; + + ffStrbufAppendS(&path, "label"); + if (ffAppendFileBuffer(path.chars, &item->name)) + ffStrbufTrimRightSpace(&item->name); + ffStrbufSubstrBefore(&path, itemPathLen); + + enumerateDevices(item, &path, &buffer); + ffStrbufSubstrBefore(&path, itemPathLen); + + enumerateFeatures(item, &path); + ffStrbufSubstrBefore(&path, itemPathLen); + + ffStrbufAppendS(&path, "generation"); + if (ffReadFileBuffer(path.chars, &buffer)) + item->generation = (uint32_t) ffStrbufToUInt(&buffer, 0); + ffStrbufSubstrBefore(&path, itemPathLen); + + ffStrbufAppendS(&path, "nodesize"); + if (ffReadFileBuffer(path.chars, &buffer)) + item->nodeSize = (uint32_t) ffStrbufToUInt(&buffer, 0); + ffStrbufSubstrBefore(&path, itemPathLen); + + ffStrbufAppendS(&path, "sectorsize"); + if (ffReadFileBuffer(path.chars, &buffer)) + item->sectorSize = (uint32_t) ffStrbufToUInt(&buffer, 0); + ffStrbufSubstrBefore(&path, itemPathLen); + + detectAllocation(item, &path, &buffer); + + // finally + ffStrbufSubstrBefore(&path, basePathLen); + } + + return NULL; +} diff --git a/src/detection/btrfs/btrfs_nosupport.c b/src/detection/btrfs/btrfs_nosupport.c new file mode 100644 index 0000000000..23c70a1ef9 --- /dev/null +++ b/src/detection/btrfs/btrfs_nosupport.c @@ -0,0 +1,6 @@ +#include "btrfs.h" + +const char* ffDetectBtrfs(FF_MAYBE_UNUSED FFlist* result) +{ + return "Not supported on this platform"; +} diff --git a/src/modules/btrfs/btrfs.c b/src/modules/btrfs/btrfs.c new file mode 100644 index 0000000000..77e7ba1ad0 --- /dev/null +++ b/src/modules/btrfs/btrfs.c @@ -0,0 +1,254 @@ +#include "common/printing.h" +#include "common/jsonconfig.h" +#include "common/percent.h" +#include "detection/btrfs/btrfs.h" +#include "modules/btrfs/btrfs.h" +#include "util/stringUtils.h" + +#define FF_BTRFS_NUM_FORMAT_ARGS 13 + +static void printBtrfs(FFBtrfsOptions* options, FFBtrfsResult* result, uint8_t index) +{ + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + if (options->moduleArgs.key.length == 0) + { + if (result->name.length > 0) + ffStrbufSetF(&buffer, "%s (%s)", FF_BTRFS_MODULE_NAME, result->name.chars); + else + ffStrbufSetS(&buffer, FF_BTRFS_MODULE_NAME); + } + else + { + ffStrbufClear(&buffer); + FF_PARSE_FORMAT_STRING_CHECKED(&buffer, &options->moduleArgs.key, 3, ((FFformatarg[]){ + FF_FORMAT_ARG(index, "index"), + FF_FORMAT_ARG(result->name, "name"), + FF_FORMAT_ARG(options->moduleArgs.keyIcon, "icon"), + })); + } + + uint64_t used = 0, allocated = 0, total = result->totalSize; + for (int i = 0; i < 3; ++i) + { + uint64_t times = result->allocation[i].dup ? 2 : 1; + used += result->allocation[i].used * times; + allocated += result->allocation[i].total * times; + } + + FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); + ffParseSize(used, &usedPretty); + FF_STRBUF_AUTO_DESTROY allocatedPretty = ffStrbufCreate(); + ffParseSize(allocated, &allocatedPretty); + FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); + ffParseSize(total, &totalPretty); + + double usedPercentage = total > 0 ? (double) used / (double) total * 100.0 : 0; + double allocatedPercentage = total > 0 ? (double) allocated / (double) total * 100.0 : 0; + + if(options->moduleArgs.outputFormat.length == 0) + { + ffPrintLogoAndKey(buffer.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); + + ffStrbufClear(&buffer); + ffStrbufSetF(&buffer, "%s / %s (", usedPretty.chars, totalPretty.chars); + ffPercentAppendNum(&buffer, usedPercentage, options->percent, false, &options->moduleArgs); + ffStrbufAppendS(&buffer, ", "); + ffPercentAppendNum(&buffer, allocatedPercentage, options->percent, false, &options->moduleArgs); + ffStrbufAppendF(&buffer, " allocated)"); + ffStrbufPutTo(&buffer, stdout); + } + else + { + FF_STRBUF_AUTO_DESTROY usedPercentageNum = ffStrbufCreate(); + ffPercentAppendNum(&usedPercentageNum, usedPercentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY usedPercentageBar = ffStrbufCreate(); + ffPercentAppendBar(&usedPercentageBar, usedPercentage, options->percent, &options->moduleArgs); + + FF_STRBUF_AUTO_DESTROY allocatedPercentageNum = ffStrbufCreate(); + ffPercentAppendNum(&allocatedPercentageNum, allocatedPercentage, options->percent, false, &options->moduleArgs); + FF_STRBUF_AUTO_DESTROY allocatedPercentageBar = ffStrbufCreate(); + ffPercentAppendBar(&allocatedPercentageBar, allocatedPercentage, options->percent, &options->moduleArgs); + + FF_STRBUF_AUTO_DESTROY nodeSizePretty = ffStrbufCreate(); + ffParseSize(result->nodeSize, &nodeSizePretty); + FF_STRBUF_AUTO_DESTROY sectorSizePretty = ffStrbufCreate(); + ffParseSize(result->sectorSize, §orSizePretty); + + FF_PRINT_FORMAT_CHECKED(buffer.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BTRFS_NUM_FORMAT_ARGS, ((FFformatarg[]) { + FF_FORMAT_ARG(result->name, "name"), + FF_FORMAT_ARG(result->uuid, "uuid"), + FF_FORMAT_ARG(result->devices, "devices"), + FF_FORMAT_ARG(result->features, "features"), + FF_FORMAT_ARG(usedPretty, "used"), + FF_FORMAT_ARG(allocatedPretty, "allocated"), + FF_FORMAT_ARG(totalPretty, "total"), + FF_FORMAT_ARG(usedPercentageNum, "used-percentage"), + FF_FORMAT_ARG(allocatedPercentageNum, "allocated-percentage"), + FF_FORMAT_ARG(usedPercentageBar, "used-percentage-bar"), + FF_FORMAT_ARG(allocatedPercentageBar, "allocated-percentage-bar"), + FF_FORMAT_ARG(nodeSizePretty, "node-size"), + FF_FORMAT_ARG(sectorSizePretty, "sector-size"), + })); + } +} + +void ffPrintBtrfs(FFBtrfsOptions* options) +{ + FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFBtrfsResult)); + + const char* error = ffDetectBtrfs(&results); + + if (error) + { + ffPrintError(FF_BTRFS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error); + return; + } + if(results.length == 0) + { + ffPrintError(FF_BTRFS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", "No btrfs drive found"); + return; + } + + for(uint32_t i = 0; i < results.length; i++) + { + FFBtrfsResult* result = FF_LIST_GET(FFBtrfsResult, results, i); + uint8_t index = results.length == 1 ? 0 : (uint8_t) (i + 1); + printBtrfs(options, result, index); + } + + FF_LIST_FOR_EACH(FFBtrfsResult, result, results) + { + ffStrbufDestroy(&result->name); + ffStrbufDestroy(&result->uuid); + ffStrbufDestroy(&result->devices); + ffStrbufDestroy(&result->features); + } +} + +bool ffParseBtrfsCommandOptions(FFBtrfsOptions* options, const char* key, const char* value) +{ + const char* subKey = ffOptionTestPrefix(key, FF_BTRFS_MODULE_NAME); + if (!subKey) return false; + if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs)) + return true; + + if (ffPercentParseCommandOptions(key, subKey, value, &options->percent)) + return true; + + return false; +} + +void ffParseBtrfsJsonObject(FFBtrfsOptions* options, yyjson_val* module) +{ + yyjson_val *key_, *val; + size_t idx, max; + yyjson_obj_foreach(module, idx, max, key_, val) + { + const char* key = yyjson_get_str(key_); + if(ffStrEqualsIgnCase(key, "type")) + continue; + + if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs)) + continue; + + if (ffPercentParseJsonObject(key, val, &options->percent)) + continue; + + ffPrintError(FF_BTRFS_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key); + } +} + +void ffGenerateBtrfsJsonConfig(FFBtrfsOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) +{ + __attribute__((__cleanup__(ffDestroyBtrfsOptions))) FFBtrfsOptions defaultOptions; + ffInitBtrfsOptions(&defaultOptions); + + ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs); + + ffPercentGenerateJsonConfig(doc, module, defaultOptions.percent, options->percent); +} + +void ffGenerateBtrfsJsonResult(FF_MAYBE_UNUSED FFBtrfsOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) +{ + FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFBtrfsResult)); + + const char* error = ffDetectBtrfs(&results); + if (error) + { + yyjson_mut_obj_add_str(doc, module, "error", error); + return; + } + + yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result"); + + FF_LIST_FOR_EACH(FFBtrfsResult, btrfs, results) + { + yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr); + yyjson_mut_obj_add_strbuf(doc, obj, "name", &btrfs->name); + yyjson_mut_obj_add_strbuf(doc, obj, "uuid", &btrfs->uuid); + yyjson_mut_obj_add_strbuf(doc, obj, "devices", &btrfs->devices); + yyjson_mut_obj_add_strbuf(doc, obj, "features", &btrfs->features); + yyjson_mut_obj_add_uint(doc, obj, "generation", btrfs->generation); + yyjson_mut_obj_add_uint(doc, obj, "nodeSize", btrfs->nodeSize); + yyjson_mut_obj_add_uint(doc, obj, "sectorSize", btrfs->sectorSize); + yyjson_mut_obj_add_uint(doc, obj, "totalSize", btrfs->totalSize); + yyjson_mut_val* allocation = yyjson_mut_obj_add_arr(doc, obj, "allocation"); + for (int i = 0; i < 3; ++i) + { + yyjson_mut_val* item = yyjson_mut_arr_add_obj(doc, allocation); + yyjson_mut_obj_add_str(doc, item, "type", btrfs->allocation[i].type); + yyjson_mut_obj_add_bool(doc, item, "dup", btrfs->allocation[i].dup); + yyjson_mut_obj_add_uint(doc, item, "used", btrfs->allocation[i].used); + yyjson_mut_obj_add_uint(doc, item, "total", btrfs->allocation[i].total); + } + } + + FF_LIST_FOR_EACH(FFBtrfsResult, btrfs, results) + { + ffStrbufDestroy(&btrfs->name); + ffStrbufDestroy(&btrfs->uuid); + ffStrbufDestroy(&btrfs->devices); + ffStrbufDestroy(&btrfs->features); + } +} + +void ffPrintBtrfsHelpFormat(void) +{ + FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_BTRFS_MODULE_NAME, "{5} / {7} ({8}, {9} allocated)", FF_BTRFS_NUM_FORMAT_ARGS, ((const char* []) { + "Name / Label - name", + "UUID - uuid", + "Associated devices - devices", + "Enabled features - features", + "Size used - used", + "Size allocated - allocated", + "Size total - total", + "Used percentage num - used-percentage", + "Allocated percentage num - allocated-percentage", + "Used percentage bar - used-percentage-bar", + "Allocated percentage bar - allocated-percentage-bar", + "Node size - node-size", + "Sector size - sector-size", + })); +} + +void ffInitBtrfsOptions(FFBtrfsOptions* options) +{ + ffOptionInitModuleBaseInfo( + &options->moduleInfo, + FF_BTRFS_MODULE_NAME, + "Print BTRFS volumes", + ffParseBtrfsCommandOptions, + ffParseBtrfsJsonObject, + ffPrintBtrfs, + ffGenerateBtrfsJsonResult, + ffPrintBtrfsHelpFormat, + ffGenerateBtrfsJsonConfig + ); + ffOptionInitModuleArg(&options->moduleArgs, "󱑛"); + options->percent = (FFColorRangeConfig) { 50, 80 }; +} + +void ffDestroyBtrfsOptions(FFBtrfsOptions* options) +{ + ffOptionDestroyModuleArg(&options->moduleArgs); +} diff --git a/src/modules/btrfs/btrfs.h b/src/modules/btrfs/btrfs.h new file mode 100644 index 0000000000..25df250847 --- /dev/null +++ b/src/modules/btrfs/btrfs.h @@ -0,0 +1,9 @@ +#pragma once + +#include "fastfetch.h" + +#define FF_BTRFS_MODULE_NAME "Btrfs" + +void ffPrintBtrfs(FFBtrfsOptions* options); +void ffInitBtrfsOptions(FFBtrfsOptions* options); +void ffDestroyBtrfsOptions(FFBtrfsOptions* options); diff --git a/src/modules/btrfs/option.h b/src/modules/btrfs/option.h new file mode 100644 index 0000000000..504b15768a --- /dev/null +++ b/src/modules/btrfs/option.h @@ -0,0 +1,14 @@ +#pragma once + +// This file will be included in "fastfetch.h", do NOT put unnecessary things here + +#include "common/option.h" +#include "common/percent.h" + +typedef struct FFBtrfsOptions +{ + FFModuleBaseInfo moduleInfo; + FFModuleArgs moduleArgs; + + FFColorRangeConfig percent; +} FFBtrfsOptions; diff --git a/src/modules/modules.h b/src/modules/modules.h index d6e6f5c14c..84d9e6fcb2 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -10,6 +10,7 @@ #include "modules/board/board.h" #include "modules/bootmgr/bootmgr.h" #include "modules/break/break.h" +#include "modules/btrfs/btrfs.h" #include "modules/camera/camera.h" #include "modules/chassis/chassis.h" #include "modules/cpu/cpu.h" diff --git a/src/modules/options.h b/src/modules/options.h index 74ad4c0b49..2677d2515f 100644 --- a/src/modules/options.h +++ b/src/modules/options.h @@ -10,6 +10,7 @@ #include "modules/bootmgr/option.h" #include "modules/break/option.h" #include "modules/brightness/option.h" +#include "modules/btrfs/option.h" #include "modules/camera/option.h" #include "modules/chassis/option.h" #include "modules/cpu/option.h" diff --git a/src/modules/zpool/zpool.c b/src/modules/zpool/zpool.c index 66a59f2913..7288a03dd1 100644 --- a/src/modules/zpool/zpool.c +++ b/src/modules/zpool/zpool.c @@ -66,7 +66,7 @@ static void printZpool(FFZpoolOptions* options, FFZpoolResult* result, uint8_t i FF_FORMAT_ARG(usedPretty, "size-used"), FF_FORMAT_ARG(totalPretty, "size-total"), FF_FORMAT_ARG(bytesPercentageNum, "size-percentage"), - FF_FORMAT_ARG(fragPercentage, "frag-percentage"), + FF_FORMAT_ARG(fragPercentageNum, "frag-percentage"), FF_FORMAT_ARG(bytesPercentageBar, "size-percentage-bar"), FF_FORMAT_ARG(fragPercentageBar, "frag-percentage-bar"), })); @@ -171,10 +171,10 @@ void ffGenerateZpoolJsonResult(FF_MAYBE_UNUSED FFZpoolOptions* options, yyjson_m yyjson_mut_obj_add_uint(doc, obj, "fragmentation", zpool->fragmentation); } - FF_LIST_FOR_EACH(FFZpoolResult, battery, results) + FF_LIST_FOR_EACH(FFZpoolResult, zpool, results) { - ffStrbufDestroy(&battery->name); - ffStrbufDestroy(&battery->state); + ffStrbufDestroy(&zpool->name); + ffStrbufDestroy(&zpool->state); } } diff --git a/src/options/modules.c b/src/options/modules.c index 22c6fcf5b1..10b6fc627a 100644 --- a/src/options/modules.c +++ b/src/options/modules.c @@ -11,6 +11,7 @@ void ffOptionsInitModules(FFOptionsModules* options) ffInitBootmgrOptions(&options->bootmgr); ffInitBreakOptions(&options->break_); ffInitBrightnessOptions(&options->brightness); + ffInitBtrfsOptions(&options->btrfs); ffInitCameraOptions(&options->camera); ffInitCPUOptions(&options->cpu); ffInitCPUUsageOptions(&options->cpuUsage); @@ -84,6 +85,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options) ffDestroyBootmgrOptions(&options->bootmgr); ffDestroyBreakOptions(&options->break_); ffDestroyBrightnessOptions(&options->brightness); + ffDestroyBtrfsOptions(&options->btrfs); ffDestroyCameraOptions(&options->camera); ffDestroyCPUOptions(&options->cpu); ffDestroyCPUCacheOptions(&options->cpuCache); diff --git a/src/options/modules.h b/src/options/modules.h index 27ec92dc4d..7f210be69b 100644 --- a/src/options/modules.h +++ b/src/options/modules.h @@ -12,6 +12,7 @@ typedef struct FFOptionsModules FFBootmgrOptions bootmgr; FFBreakOptions break_; FFBrightnessOptions brightness; + FFBtrfsOptions btrfs; FFCPUOptions cpu; FFCPUCacheOptions cpuCache; FFCPUUsageOptions cpuUsage; From 1b9345267fdb905002aedc2bd17381a3e4580660 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 15 Sep 2024 10:42:00 +0800 Subject: [PATCH 18/30] Presets: update all / ci --- presets/all.jsonc | 10 ++- presets/ci.jsonc | 200 ++++++++++++++++++++++++---------------------- 2 files changed, 111 insertions(+), 99 deletions(-) diff --git a/presets/all.jsonc b/presets/all.jsonc index efcec55dd5..b1c28c31d9 100644 --- a/presets/all.jsonc +++ b/presets/all.jsonc @@ -54,8 +54,12 @@ "physicalmemory", "swap", "disk", + "btrfs", "zpool", - "battery", + { + "type": "battery", + "temp": true + }, "poweradapter", "player", "media", @@ -66,7 +70,9 @@ { "type": "localip", "showIpv6": true, - "showMac": true + "showMac": true, + "showSpeed": true, + "showMtu": true }, "dns", "wifi", diff --git a/presets/ci.jsonc b/presets/ci.jsonc index 565e28b6ea..2bb446bfdb 100644 --- a/presets/ci.jsonc +++ b/presets/ci.jsonc @@ -1,100 +1,106 @@ { - "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", - "display": { - "stat": true, - "pipe": true, - "showErrors": true, - "noBuffer": true - }, - "logo": null, - "modules": [ - "title", - "separator", - "os", - "host", - "bios", - "bootmgr", - "board", - "chassis", - "kernel", - "initsystem", - "uptime", - "loadavg", - "processes", - "packages", - "shell", - "editor", - "display", - "brightness", - "monitor", - "lm", - "de", - "wm", - "wmtheme", - "theme", - "icons", - "font", - "cursor", - "wallpaper", - "terminal", - "terminalfont", - "terminalsize", - "terminaltheme", - { - "type": "cpu", - "showPeCoreCount": true, - "temp": true + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "display": { + "stat": true, + "pipe": true, + "showErrors": true, + "noBuffer": true }, - "cpucache", - "cpuusage", - { - "type": "gpu", - "driverSpecific": true, - "temp": true - }, - "memory", - "physicalmemory", - "swap", - "disk", - "zpool", - "battery", - "poweradapter", - "player", - "media", - { - "type": "publicip", - "timeout": 1000 - }, - { - "type": "localip", - "showIpv6": true, - "showMac": true - }, - "dns", - "wifi", - "datetime", - "locale", - "vulkan", - "opengl", - "opencl", - "users", - "bluetooth", - "bluetoothradio", - "sound", - "camera", - "gamepad", - { - "type": "weather", - "timeout": 1000 - }, - "netio", - "diskio", - { - "type": "physicaldisk", - "temp": true - }, - "version", - "break", - "colors" - ] + "logo": null, + "modules": [ + "title", + "separator", + "os", + "host", + "bios", + "bootmgr", + "board", + "chassis", + "kernel", + "initsystem", + "uptime", + "loadavg", + "processes", + "packages", + "shell", + "editor", + "display", + "brightness", + "monitor", + "lm", + "de", + "wm", + "wmtheme", + "theme", + "icons", + "font", + "cursor", + "wallpaper", + "terminal", + "terminalfont", + "terminalsize", + "terminaltheme", + { + "type": "cpu", + "showPeCoreCount": true, + "temp": true + }, + "cpucache", + "cpuusage", + { + "type": "gpu", + "driverSpecific": true, + "temp": true + }, + "memory", + "physicalmemory", + "swap", + "disk", + "btrfs", + "zpool", + { + "type": "battery", + "temp": true + }, + "poweradapter", + "player", + "media", + { + "type": "publicip", + "timeout": 1000 + }, + { + "type": "localip", + "showIpv6": true, + "showMac": true, + "showSpeed": true, + "showMtu": true + }, + "dns", + "wifi", + "datetime", + "locale", + "vulkan", + "opengl", + "opencl", + "users", + "bluetooth", + "bluetoothradio", + "sound", + "camera", + "gamepad", + { + "type": "weather", + "timeout": 1000 + }, + "netio", + "diskio", + { + "type": "physicaldisk", + "temp": true + }, + "version", + "break", + "colors" + ] } From acdd1fc69c4d916ae374373882c4ee7836899a74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 15 Sep 2024 10:42:22 +0800 Subject: [PATCH 19/30] JsonSchema: add btrfs --- doc/json_schema.json | 79 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index db9e587b53..e985921a77 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -655,6 +655,7 @@ "bootmgr", "break", "brightness", + "btrfs", "camera", "chassis", "cpu", @@ -887,10 +888,6 @@ { "const": "wmtheme", "description": "Print current theme of window manager" - }, - { - "const": "zpool", - "description": "Print ZFS storage pools" } ] }, @@ -1059,6 +1056,38 @@ } } }, + { + "title": "BTRFS", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "btrfs", + "description": "Print Btrfs volumes" + }, + "percent": { + "$ref": "#/$defs/percent" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "keyIcon": { + "$ref": "#/$defs/keyIcon" + }, + "keyWidth": { + "$ref": "#/$defs/keyWidth" + }, + "outputColor": { + "$ref": "#/$defs/outputColor" + }, + "format": { + "$ref": "#/$defs/format" + } + } + }, { "title": "Chassis", "type": "object", @@ -1634,6 +1663,16 @@ "type": "boolean", "default": false }, + "showSpeed": { + "description": "Show ethernet rx speed", + "type": "boolean", + "default": false + }, + "showMtu": { + "description": "Show MTU", + "type": "boolean", + "default": false + }, "showMac": { "description": "Show MAC addresses", "type": "boolean", @@ -2261,6 +2300,38 @@ "$ref": "#/$defs/format" } } + }, + { + "title": "Zpool", + "type": "object", + "additionalProperties": false, + "properties": { + "type": { + "const": "zpool", + "description": "Print ZFS storage pools" + }, + "percent": { + "$ref": "#/$defs/percent" + }, + "key": { + "$ref": "#/$defs/key" + }, + "keyColor": { + "$ref": "#/$defs/keyColor" + }, + "keyIcon": { + "$ref": "#/$defs/keyIcon" + }, + "keyWidth": { + "$ref": "#/$defs/keyWidth" + }, + "outputColor": { + "$ref": "#/$defs/outputColor" + }, + "format": { + "$ref": "#/$defs/format" + } + } } ] } From 0eecdd16ead710ce362bf2a8d1c75d0d91de713b Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 15 Sep 2024 13:17:53 +0800 Subject: [PATCH 20/30] LocalIP (FreeBSD): don't use Wifi speed as Ethernet speed --- src/detection/localip/localip_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 9dfea2537b..9dd8aaeacd 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -202,7 +202,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) #elif __FreeBSD__ || __APPLE__ struct ifmediareq ifmr = {}; strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1); - if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0) + if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0 && (IFM_TYPE(ifmr.ifm_active) & IFM_ETHER)) { switch (IFM_SUBTYPE(ifmr.ifm_active)) { From c64720c6da7b7233ac5b0bdaff5e67c25db06a5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 16 Sep 2024 11:12:30 +0800 Subject: [PATCH 21/30] Camera (Linux): fix compiling with old linux headers Fix #1265 --- src/detection/camera/camera_linux.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/detection/camera/camera_linux.c b/src/detection/camera/camera_linux.c index d7e2988e43..e7f5c925f6 100644 --- a/src/detection/camera/camera_linux.c +++ b/src/detection/camera/camera_linux.c @@ -43,10 +43,10 @@ const char* ffDetectCamera(FFlist* result) case V4L2_COLORSPACE_JPEG: ffStrbufInitStatic(&camera->colorspace, "JPEG"); break; case V4L2_COLORSPACE_REC709: case V4L2_COLORSPACE_SRGB: ffStrbufInitStatic(&camera->colorspace, "sRGB"); break; - case V4L2_COLORSPACE_OPRGB: ffStrbufInitStatic(&camera->colorspace, "Adobe RGB"); break; - case V4L2_COLORSPACE_BT2020: ffStrbufInitStatic(&camera->colorspace, "BT.2020"); break; - case V4L2_COLORSPACE_RAW: ffStrbufInitStatic(&camera->colorspace, "RAW"); break; - case V4L2_COLORSPACE_DCI_P3: ffStrbufInitStatic(&camera->colorspace, "DCI-P3"); break; + case 9 /* V4L2_COLORSPACE_OPRGB */: ffStrbufInitStatic(&camera->colorspace, "Adobe RGB"); break; + case 10 /* V4L2_COLORSPACE_BT2020 */: ffStrbufInitStatic(&camera->colorspace, "BT.2020"); break; + case 11 /* V4L2_COLORSPACE_RAW */: ffStrbufInitStatic(&camera->colorspace, "RAW"); break; + case 12 /* V4L2_COLORSPACE_DCI_P3 */: ffStrbufInitStatic(&camera->colorspace, "DCI-P3"); break; default: ffStrbufInit(&camera->colorspace); break; } camera->width = fmt.fmt.pix.width; From 756865855b111d835f1ee1002f88ecf7b83eb5b7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 18 Sep 2024 16:08:42 +0800 Subject: [PATCH 22/30] Wifi (macOS): improve support for macOS Sequoia Fix #1194 --- src/detection/wifi/wifi_apple.m | 104 +++++++++++++++++++++++++++++++- 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/src/detection/wifi/wifi_apple.m b/src/detection/wifi/wifi_apple.m index 55085fda18..9145aef9ef 100644 --- a/src/detection/wifi/wifi_apple.m +++ b/src/detection/wifi/wifi_apple.m @@ -1,5 +1,6 @@ #include "wifi.h" #include "common/processing.h" +#include "util/stringUtils.h" #import @@ -20,7 +21,7 @@ @interface CWInterface() return CFBridgingRelease(result); } -const char* ffDetectWifi(FFlist* result) +static const char* detectWifiByCoreWlan(FFlist* result) { NSArray* interfaces = CWWiFiClient.sharedWiFiClient.interfaces; if(!interfaces) @@ -211,3 +212,104 @@ @interface CWInterface() } return NULL; } + +static const char* detectWifiBySystemProfiler(FFlist* result) +{ + // Warning: costs about 2s on my machine + + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + if (ffProcessAppendStdOut(&buffer, (char* const[]) { + "system_profiler", + "SPAirPortDataType", + "-xml", + "-detailLevel", + "basic", + NULL + }) != NULL) + return "Starting `system_profiler SPAirPortDataType -xml -detailLevel basic` failed"; + + NSArray* arr = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytes:buffer.chars length:buffer.length] + options:NSPropertyListImmutable + format:nil + error:nil]; + if (!arr || !arr.count) + return "system_profiler SPAirPortDataType returned an empty array"; + + for (NSDictionary* data in arr[0][@"_items"]) + { + for (NSDictionary* inf in data[@"spairport_airport_interfaces"]) + { + if (![inf[@"spairport_wireless_card_type"] isEqualToString:@"spairport_wireless_card_type_wifi (0x14E4, 0x4387)"]) continue; + + FFWifiResult* item = (FFWifiResult*)ffListAdd(result); + ffStrbufInitS(&item->inf.description, [inf[@"_name"] UTF8String]); + 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; + + NSString* status = inf[@"spairport_status_information"]; // spairport_status_connected spairport_status_disassociated spairport_status_off + + ffStrbufSetStatic(&item->inf.status, [status isEqualToString:@"spairport_status_off"] ? "Power Off" : "Power On"); + + NSDictionary* station = inf[@"spairport_current_network_information"]; + if (!station) continue; + + ffStrbufSetS(&item->conn.status, status.UTF8String + strlen("spairport_status_")); + item->conn.status.chars[0] = (char) toupper(item->conn.status.chars[0]); + + ffStrbufSetS(&item->conn.ssid, [station[@"_name"] UTF8String]); + + ffStrbufSetS(&item->conn.protocol, [station[@"spairport_network_phymode"] UTF8String]); + if (ffStrbufStartsWithS(&item->conn.protocol, "802.11")) + { + const char* subProtocol = item->conn.protocol.chars + strlen("802.11"); + if (ffStrEquals(subProtocol, "be")) + ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)"); + else if (ffStrEquals(subProtocol, "ax")) + ffStrbufSetStatic(&item->conn.protocol, "802.11ax (Wi-Fi 6)"); + else if (ffStrEquals(subProtocol, "ac")) + ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)"); + else if (ffStrEquals(subProtocol, "n")) + ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)"); + } + + ffStrbufSetS(&item->conn.security, [station[@"spairport_security_mode"] UTF8String]); + ffStrbufSubstrAfterFirstS(&item->conn.security, "_mode_"); + if (ffStrbufEqualS(&item->conn.security, "none")) + ffStrbufSetStatic(&item->conn.security, "Insecure"); + else + { + ffStrbufReplaceAllC(&item->conn.security, '_', ' '); + if (ffStrbufStartsWithS(&item->conn.security, "wpa")) + { + item->conn.security.chars[0] = 'W'; + item->conn.security.chars[1] = 'P'; + item->conn.security.chars[2] = 'A'; + char* sub = strchr(item->conn.security.chars, ' '); + if (sub && sub[1]) + sub[1] = (char) toupper(sub[1]); + } + } + + double rssiValue = strtod([station[@"spairport_signal_noise"] UTF8String], nil); + item->conn.signalQuality = (double) (rssiValue >= -50 ? 100 : rssiValue <= -100 ? 0 : (rssiValue + 100) * 2); + item->conn.txRate = (double) [station[@"spairport_network_rate"] longValue]; + } + } + + return NULL; +} + +const char* ffDetectWifi(FFlist* result) +{ + if (@available(macOS 15.0, *)) + return detectWifiBySystemProfiler(result); + else + return detectWifiByCoreWlan(result); +} From 6acc33cd16e6ad6222d5145f894c6bd1bab3593e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 18 Sep 2024 16:09:38 +0800 Subject: [PATCH 23/30] Processing: increase the default value of `processingTimeout` For 756865855b111d835f1ee1002f88ecf7b83eb5b7 --- doc/json_schema.json | 2 +- src/data/help.json | 2 +- src/options/general.c | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index e985921a77..0ebda7d2cf 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -337,7 +337,7 @@ "processingTimeout": { "type": "integer", "description": "Set the timeout (ms) when waiting for child processes, `-1` for no timeout", - "default": 1000 + "default": 5000 }, "preRun": { "type": "string", diff --git a/src/data/help.json b/src/data/help.json index f6c1ffc2fa..486c6c61f0 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -128,7 +128,7 @@ "desc": "Set the timeout (ms) when waiting for child processes", "arg": { "type": "num", - "default": 1000 + "default": 5000 } }, { diff --git a/src/options/general.c b/src/options/general.c index c1eabf9cda..abb8d10546 100644 --- a/src/options/general.c +++ b/src/options/general.c @@ -111,7 +111,7 @@ bool ffOptionsParseGeneralCommandLine(FFOptionsGeneral* options, const char* key void ffOptionsInitGeneral(FFOptionsGeneral* options) { - options->processingTimeout = 1000; + options->processingTimeout = 5000; options->multithreading = true; options->detectVersion = true; From 6c8b4b25d2caa4db88600e83e04d670453fa10db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 18 Sep 2024 16:43:57 +0800 Subject: [PATCH 24/30] Doc: update changelog --- CHANGELOG.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 647b07c0db..3cf1d379d0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,26 @@ +# 2.25.0 + +Features: +* Moore Threads GPU add support to query number of cores (#1259, GPU) +* Cache result based on mtime (Packages) +* Add cmake options to disable certain package managers at compile time + * Package managers are encouraged to disable some package managers by passing `-DPACKAGES_DISABLE_` when running `cmake`. For example, when building for Arch Linux, `-DPACKAGES_DISABLE_APK=ON -DPACKAGES_DISABLE_DPKG=ON -DPACKAGES_DISABLE_RPM=ON ...` should be specified. + * See all available options by [running `cmake -L | grep PACKAGES_DISABLE_`](https://github.com/fastfetch-cli/fastfetch/blob/dev/CMakeLists.txt#L91) + * This option does NOT remove the detection code. It just disables the detection at runtime. One can still use `--packages-disabled ""` to enable all package managers. +* Add new option `--show-localip-{speed,mtu}` (LocalIP) +* Add new module `Btrfs`, which prints all mounted Btrfs volumes, like `Zpool` module (#1262, Linux) +* Improve Wifi module support for macOS Sequoia (Wifi, macOS) + * Currently it uses `system_profiler` which costs about 2 seconds on my MBP. I suggest disabling it for now until a better solution is found. + +Bugfixes: +* Fix invalid CPU temperature detection on FreeBSD (#1260, CPU, FreeBSD) +* Remove `showPeCoreCount` support on FreeBSD (#1260, CPU, FreeBSD) +* Don't use Wifi speed as Ethernet speed (LocalIP, FreeBSD) +* Fix compiling with old linux headers (Camera, Linux) + +Logo: +* fix parrot logo detection + # 2.24.0 Changes: From 5a9a2ca0fd79838c67782795cdf39069f381184a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 18 Sep 2024 23:39:13 +0800 Subject: [PATCH 25/30] Networking (Windows): fix calling IPv6 server --- src/common/networking_windows.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c index 83b3fd8645..b1add200ce 100644 --- a/src/common/networking_windows.c +++ b/src/common/networking_windows.c @@ -63,19 +63,21 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho return "socket() failed"; } - { - //ConnectEx requires the socket to be initially bound - if(bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) { + //ConnectEx requires the socket to be initially bound + if((state->ipv6 + ? bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in6) { + .sin6_family = AF_INET6, + .sin6_addr = in6addr_any, + }, sizeof(struct sockaddr_in6)) + : bind(state->sockfd, (SOCKADDR *) &(struct sockaddr_in) { .sin_family = AF_INET, .sin_addr.s_addr = INADDR_ANY, - .sin_port = 0, - }, sizeof(struct sockaddr_in)) != 0) - { - closesocket(state->sockfd); - freeaddrinfo(addr); - state->sockfd = INVALID_SOCKET; - return "bind() failed"; - } + }, sizeof(struct sockaddr_in))) != 0) + { + closesocket(state->sockfd); + freeaddrinfo(addr); + state->sockfd = INVALID_SOCKET; + return "bind() failed"; } FF_STRBUF_AUTO_DESTROY command = ffStrbufCreateA(64); @@ -93,7 +95,6 @@ const char* ffNetworkingSendHttpRequest(FFNetworkingState* state, const char* ho if(!result && WSAGetLastError() != WSA_IO_PENDING) { closesocket(state->sockfd); - freeaddrinfo(addr); state->sockfd = INVALID_SOCKET; return "ConnectEx() failed"; } From 0025c78ccee4b2788194073c0f3b7d6d993a73c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 18 Sep 2024 23:50:17 +0800 Subject: [PATCH 26/30] Networking: report empty server response --- src/common/networking_linux.c | 1 + src/common/networking_windows.c | 1 + 2 files changed, 2 insertions(+) diff --git a/src/common/networking_linux.c b/src/common/networking_linux.c index 8bdd16bbd8..0bc39d6126 100644 --- a/src/common/networking_linux.c +++ b/src/common/networking_linux.c @@ -132,5 +132,6 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf } while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL); close(state->sockfd); + if (buffer->length == 0) return "Empty server response received"; return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response"; } diff --git a/src/common/networking_windows.c b/src/common/networking_windows.c index b1add200ce..305f558642 100644 --- a/src/common/networking_windows.c +++ b/src/common/networking_windows.c @@ -141,5 +141,6 @@ const char* ffNetworkingRecvHttpResponse(FFNetworkingState* state, FFstrbuf* buf } while (ffStrbufGetFree(buffer) > 0 && strstr(buffer->chars + recvStart, "\r\n\r\n") == NULL); closesocket(state->sockfd); + if (buffer->length == 0) return "Empty server response received"; return ffStrbufStartsWithS(buffer, "HTTP/1.1 200 OK\r\n") ? NULL : "Invalid response"; } From 43d6f81b012ef03a12c4e6d598be3fc5c9c78d7a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 19 Sep 2024 09:32:10 +0800 Subject: [PATCH 27/30] Wifi (macOS): improve security type detection --- src/detection/wifi/wifi_apple.m | 207 ++++++++++++++------------------ 1 file changed, 93 insertions(+), 114 deletions(-) diff --git a/src/detection/wifi/wifi_apple.m b/src/detection/wifi/wifi_apple.m index 9145aef9ef..242ac941e4 100644 --- a/src/detection/wifi/wifi_apple.m +++ b/src/detection/wifi/wifi_apple.m @@ -13,21 +13,61 @@ @interface CWInterface() @property (readonly) struct Apple80211* device; @end -static NSDictionary* getWifiInfoByApple80211(CWInterface* inf) +inline static NSDictionary* getWifiInfoByApple80211(CWInterface* inf) { - if (!Apple80211GetInfoCopy) return NULL; + if (!inf.device || !Apple80211GetInfoCopy) return NULL; CFDictionaryRef result = NULL; if (Apple80211GetInfoCopy(inf.device, &result) < 0) return NULL; return CFBridgingRelease(result); } -static const char* detectWifiByCoreWlan(FFlist* result) +static NSDictionary* getWifiInfoBySystemProfiler(NSString* ifName) +{ + // Warning: costs about 2s on my machine + static NSArray* spData; + static bool inited; + if (!inited) + { + inited = true; + FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); + if (ffProcessAppendStdOut(&buffer, (char* const[]) { + "system_profiler", + "SPAirPortDataType", + "-xml", + "-detailLevel", + "basic", + NULL + }) != NULL) + return nil; + + spData = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytes:buffer.chars length:buffer.length] + options:NSPropertyListImmutable + format:nil + error:nil]; + } + + if (spData) + { + for (NSDictionary* data in spData[0][@"_items"]) + { + for (NSDictionary* inf in data[@"spairport_airport_interfaces"]) + { + if ([ifName isEqualToString:inf[@"_name"]]) + return inf[@"spairport_current_network_information"]; + } + } + } + + return NULL; +} + +const char* ffDetectWifi(FFlist* result) { NSArray* interfaces = CWWiFiClient.sharedWiFiClient.interfaces; - if(!interfaces) + if (!interfaces) return "CWWiFiClient.sharedWiFiClient.interfaces is nil"; - for(CWInterface* inf in interfaces) + for (CWInterface* inf in interfaces) { FFWifiResult* item = (FFWifiResult*)ffListAdd(result); ffStrbufInit(&item->inf.description); @@ -47,22 +87,25 @@ @interface CWInterface() continue; ffStrbufSetStatic(&item->conn.status, inf.interfaceMode != kCWInterfaceModeNone ? "Active" : "Inactive"); - if(!inf.serviceActive) + if(inf.interfaceMode == kCWInterfaceModeNone) continue; - NSDictionary* apple = NULL; + NSDictionary* apple = nil; // For getWifiInfoByApple80211 + NSDictionary* sp = nil; // For getWifiInfoBySystemProfiler if (inf.ssid) // https://developer.apple.com/forums/thread/732431 ffStrbufAppendS(&item->conn.ssid, inf.ssid.UTF8String); else if (apple || (apple = getWifiInfoByApple80211(inf))) - ffStrbufAppendS(&item->conn.ssid, [[apple valueForKey:@"SSID_STR"] UTF8String]); + ffStrbufAppendS(&item->conn.ssid, [apple[@"SSID_STR"] UTF8String]); + else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName))) + ffStrbufAppendS(&item->conn.ssid, [sp[@"_name"] UTF8String]); else ffStrbufSetStatic(&item->conn.ssid, ""); // https://developer.apple.com/forums/thread/732431 if (inf.bssid) ffStrbufAppendS(&item->conn.bssid, inf.bssid.UTF8String); else if (apple || (apple = getWifiInfoByApple80211(inf))) - ffStrbufAppendS(&item->conn.bssid, [[apple valueForKey:@"BSSID"] UTF8String]); + ffStrbufAppendS(&item->conn.bssid, [apple[@"BSSID"] UTF8String]); switch(inf.activePHYMode) { @@ -91,7 +134,24 @@ @interface CWInterface() ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)"); break; default: - ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode); + if (inf.activePHYMode < 64) + ffStrbufAppendF(&item->conn.protocol, "Unknown (%ld)", inf.activePHYMode); + else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName))) + { + ffStrbufSetS(&item->conn.protocol, [sp[@"spairport_network_phymode"] UTF8String]); + if (ffStrbufStartsWithS(&item->conn.protocol, "802.11")) + { + const char* subProtocol = item->conn.protocol.chars + strlen("802.11"); + if (ffStrEquals(subProtocol, "be")) + ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)"); + else if (ffStrEquals(subProtocol, "ax")) + ffStrbufSetStatic(&item->conn.protocol, "802.11ax (Wi-Fi 6)"); + else if (ffStrEquals(subProtocol, "ac")) + ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)"); + else if (ffStrEquals(subProtocol, "n")) + ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)"); + } + } break; } item->conn.signalQuality = (double) (inf.rssiValue >= -50 ? 100 : inf.rssiValue <= -100 ? 0 : (inf.rssiValue + 100) * 2); @@ -151,17 +211,17 @@ @interface CWInterface() // Sonoma... if (apple || (apple = getWifiInfoByApple80211(inf))) { - NSDictionary* authType = [apple valueForKey:@"AUTH_TYPE"]; + NSDictionary* authType = apple[@"AUTH_TYPE"]; if (authType) { // AUTH_LOWER seems useless. `airport` verifies if its value is between 1 and 3, and prints `unknown` if not - NSNumber* authUpper = [authType valueForKey:@"AUTH_UPPER"]; + NSNumber* authUpper = authType[@"AUTH_UPPER"]; if (!authUpper) ffStrbufSetStatic(&item->conn.security, "Insecure"); else { - int authUpperValue = [authUpper intValue]; + int authUpperValue = authUpper.intValue; switch (authUpperValue) { case 1: @@ -204,6 +264,26 @@ @interface CWInterface() } } } + else if (sp || (sp = getWifiInfoBySystemProfiler(inf.interfaceName))) + { + ffStrbufSetS(&item->conn.security, [sp[@"spairport_security_mode"] UTF8String]); + ffStrbufSubstrAfterFirstS(&item->conn.security, "_mode_"); + if (ffStrbufEqualS(&item->conn.security, "none")) + ffStrbufSetStatic(&item->conn.security, "Insecure"); + else + { + ffStrbufReplaceAllC(&item->conn.security, '_', ' '); + if (ffStrbufStartsWithS(&item->conn.security, "wpa")) + { + item->conn.security.chars[0] = 'W'; + item->conn.security.chars[1] = 'P'; + item->conn.security.chars[2] = 'A'; + char* sub = strchr(item->conn.security.chars, ' '); + if (sub && sub[1]) + sub[1] = (char) toupper(sub[1]); + } + } + } break; default: ffStrbufAppendF(&item->conn.security, "Unknown (%ld)", inf.security); @@ -212,104 +292,3 @@ @interface CWInterface() } return NULL; } - -static const char* detectWifiBySystemProfiler(FFlist* result) -{ - // Warning: costs about 2s on my machine - - FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate(); - if (ffProcessAppendStdOut(&buffer, (char* const[]) { - "system_profiler", - "SPAirPortDataType", - "-xml", - "-detailLevel", - "basic", - NULL - }) != NULL) - return "Starting `system_profiler SPAirPortDataType -xml -detailLevel basic` failed"; - - NSArray* arr = [NSPropertyListSerialization propertyListWithData:[NSData dataWithBytes:buffer.chars length:buffer.length] - options:NSPropertyListImmutable - format:nil - error:nil]; - if (!arr || !arr.count) - return "system_profiler SPAirPortDataType returned an empty array"; - - for (NSDictionary* data in arr[0][@"_items"]) - { - for (NSDictionary* inf in data[@"spairport_airport_interfaces"]) - { - if (![inf[@"spairport_wireless_card_type"] isEqualToString:@"spairport_wireless_card_type_wifi (0x14E4, 0x4387)"]) continue; - - FFWifiResult* item = (FFWifiResult*)ffListAdd(result); - ffStrbufInitS(&item->inf.description, [inf[@"_name"] UTF8String]); - 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; - - NSString* status = inf[@"spairport_status_information"]; // spairport_status_connected spairport_status_disassociated spairport_status_off - - ffStrbufSetStatic(&item->inf.status, [status isEqualToString:@"spairport_status_off"] ? "Power Off" : "Power On"); - - NSDictionary* station = inf[@"spairport_current_network_information"]; - if (!station) continue; - - ffStrbufSetS(&item->conn.status, status.UTF8String + strlen("spairport_status_")); - item->conn.status.chars[0] = (char) toupper(item->conn.status.chars[0]); - - ffStrbufSetS(&item->conn.ssid, [station[@"_name"] UTF8String]); - - ffStrbufSetS(&item->conn.protocol, [station[@"spairport_network_phymode"] UTF8String]); - if (ffStrbufStartsWithS(&item->conn.protocol, "802.11")) - { - const char* subProtocol = item->conn.protocol.chars + strlen("802.11"); - if (ffStrEquals(subProtocol, "be")) - ffStrbufSetStatic(&item->conn.protocol, "802.11be (Wi-Fi 7)"); - else if (ffStrEquals(subProtocol, "ax")) - ffStrbufSetStatic(&item->conn.protocol, "802.11ax (Wi-Fi 6)"); - else if (ffStrEquals(subProtocol, "ac")) - ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)"); - else if (ffStrEquals(subProtocol, "n")) - ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)"); - } - - ffStrbufSetS(&item->conn.security, [station[@"spairport_security_mode"] UTF8String]); - ffStrbufSubstrAfterFirstS(&item->conn.security, "_mode_"); - if (ffStrbufEqualS(&item->conn.security, "none")) - ffStrbufSetStatic(&item->conn.security, "Insecure"); - else - { - ffStrbufReplaceAllC(&item->conn.security, '_', ' '); - if (ffStrbufStartsWithS(&item->conn.security, "wpa")) - { - item->conn.security.chars[0] = 'W'; - item->conn.security.chars[1] = 'P'; - item->conn.security.chars[2] = 'A'; - char* sub = strchr(item->conn.security.chars, ' '); - if (sub && sub[1]) - sub[1] = (char) toupper(sub[1]); - } - } - - double rssiValue = strtod([station[@"spairport_signal_noise"] UTF8String], nil); - item->conn.signalQuality = (double) (rssiValue >= -50 ? 100 : rssiValue <= -100 ? 0 : (rssiValue + 100) * 2); - item->conn.txRate = (double) [station[@"spairport_network_rate"] longValue]; - } - } - - return NULL; -} - -const char* ffDetectWifi(FFlist* result) -{ - if (@available(macOS 15.0, *)) - return detectWifiBySystemProfiler(result); - else - return detectWifiByCoreWlan(result); -} From 174359dc3e3353b54ae2ec5038404fe561f5f2c3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 19 Sep 2024 09:40:41 +0800 Subject: [PATCH 28/30] Presets: add new example --- presets/examples/24.jsonc | 152 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 152 insertions(+) create mode 100644 presets/examples/24.jsonc diff --git a/presets/examples/24.jsonc b/presets/examples/24.jsonc new file mode 100644 index 0000000000..66145db6ff --- /dev/null +++ b/presets/examples/24.jsonc @@ -0,0 +1,152 @@ +// By jan-rex +// Modified from: https://github.com/fastfetch-cli/fastfetch/discussions/1269 +{ + "$schema": "https://github.com/fastfetch-cli/fastfetch/raw/dev/doc/json_schema.json", + "logo": { + "padding": { + "top": 2 + } + }, + "display": { + "separator": "", + "constants": [ + // CONSTANT {$1} - COLOR BACKGROUND FOR KEY + "\u001b[48;2;43;43;69m", + // CONSTANT {$2} - COLOR BACKGROUND FOR OUTPUT + "\u001b[48;2;56;59;78m", + // CONSTANT {$3} - VERTICAL BARS AT START AND 75th CHARACTERS FORWARD AND BACKWARD + "\u001b[90m│ │\u001b[60D\u001b[39m", + ] + }, + "modules": [ + // CUSTOM - Top UI bar + { + "type": "custom", + "key": "{#90}{$1}╭─────────────╮", + "format": "{#90}{$2}╭────────────────────────────────────────────────────────────╮", + }, + { + "type": "title", + "key": "{#90}{$1}│ {#92}User {#90}│", + "format": "{$2}{$3}{user-name} {#2}[{home-dir}]" + }, + { + "type": "users", + "key": "{#90}{$1}│ {#92}Users {#90}│", + "myselfOnly": false, + "format": "{$2}{$3}{1}@{host-name}{/host-name}localhost{/}{?client-ip} {#2}[IP:{client-ip}]{?} {#2}[Login time: {login-time}]", + }, + { + "type": "datetime", + "key": "{#90}{$1}│ {#92}Datetime {#90}│", + "format": "{$2}{$3}{year}-{month-pretty}-{day-in-month} {hour-pretty}:{minute-pretty}:{second-pretty} {#2}{weekday} {#2}[W{week}] {#2}[UTC{offset-from-utc}]" + }, + { + "type": "title", + "key": "{#90}{$1}│ {#93}Host: {#90}│", + "format": "{$2}{$3}{#1}{#36}{host-name}" + }, + { + "type": "host", + "key": "{#90}{$1}│ {#93}Machine {#90}│", + "format": "{$2}{$3}{name} {#2}{version}" + }, + { + "type": "os", + "key": "{#90}{$1}│ {#93}OS {#90}│", + "format": "{$2}{$3}{pretty-name} {codename} {#2}[v{version}] {#2}[{arch}]" + }, + { + "type": "kernel", + "key": "{#90}{$1}│ {#93}Kernel {#90}│", + "format": "{$2}{$3}{sysname} {#2}[v{release}]" + }, + { + "type": "uptime", + "key": "{#90}{$1}│ {#93}Uptime {#90}│", + "format": "{$2}{$3}{?days}{days} Days + {?}{hours}:{minutes}:{seconds}" + }, + { + "type": "cpu", + "key": "{#90}{$1}│ {#91}CPU {#90}│", + "showPeCoreCount": true, + "temp": true, + "format": "{$2}{$3}{name} {#2}[C:{core-types}] {#2}[{freq-max}]" + }, + { + "type": "gpu", + "key": "{#90}{$1}│ {#91}GPU {#90}│", + "detectionMethod": "auto", + "driverSpecific": true, + "format": "{$2}{$3}{name} {#2}[C:{core-count}] {#2}[{type}]" + }, + { + "type": "memory", + "key": "{#90}{$1}│ {#91}Memory {#90}│", + "format": "{$2}{$3}{used} / {total} ({percentage}{$2})" + }, + { + "type": "disk", + "key": "{#90}{$1}│ {#91}Disk {#90}│", + "format": "{$2}{$3}{size-used} / {size-used} ({size-percentage}{$2})" + }, + { + "type": "poweradapter", + "key": "{#90}{$1}│ {#91}Power {#90}│", + "format": "{$2}{$3}{name}" + }, + { + "type": "terminal", + "key": "{#90}{$1}│ {#95}Terminal {#90}│", + "format": "{$2}{$3}{pretty-name} {#2}[{version}] [PID:{pid}]" + }, + { + "type": "terminalfont", + "key": "{#90}{$1}│ {#95}Font {#90}│", + "format": "{$2}{$3}{name} {#2}[{size}]" + }, + { + "type": "shell", + "key": "{#90}{$1}│ {#95}Shell {#90}│", + "format": "{$2}{$3}{pretty-name} {#2}[v{version}] [PID:{pid}]" + }, + { + // localip IPv4 + "type": "localip", + "key": "{#90}{$1}│ {#94}Local IPv4 {#90}│", + "showPrefixLen": true, + "showIpv4": true, + "showIpv6": false, + "showMtu": true, + "format": "{$2}{$3}{ifname}: {ipv4} {#2}[MTU:{mtu}]" + }, + { + // localip IPv6 + "type": "localip", + "key": "{#90}{$1}│ {#94}Local IPv6 {#90}│", + "showPrefixLen": true, + "showIpv4": false, + "showIpv6": true, + "showMtu": true, + "format": "{$2}{$3}{ifname}: {ipv6} {#2}[MTU:{mtu}]" + }, + { + "type": "publicip", + "key": "{#90}{$1}│ {#94}Public IPv4 {#90}│", + "ipv6": false, + "format": "{$2}{$3}{ip} {#2}[{location}]" + }, + { + "type": "publicip", + "key": "{#90}{$1}│ {#94}Public IPv6 {#90}│", + "ipv6": true, + "format": "{$2}{$3}{ip} {#2}[{location}]" + }, + // CUSTOM - Button UI bar + { + "type": "custom", + "key": "{#90}{$1}╰─────────────╯", + "format": "{#90}{$2}╰────────────────────────────────────────────────────────────╯", + } + ] + } From c49c857db2e35db11be12aafab12e8fc46cda13d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 19 Sep 2024 09:43:27 +0800 Subject: [PATCH 29/30] Logo (Builtin): update TorizonCore To Torizon OS Close: #1270 --- src/logo/builtin.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 0280693163..52f1a91664 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -4288,9 +4288,9 @@ static const FFlogo T[] = { FF_COLOR_FG_GREEN, }, }, - // TorizonCore + // Torizon OS { - .names = {"TorizonCore"}, + .names = {"Torizon OS", "TorizonCore"}, .lines = FASTFETCH_DATATEXT_LOGO_TORIZONCORE, .colors = { FF_COLOR_FG_LIGHT_WHITE, From f80423607df662447f1d4b5bd97fd8dd7da9baa1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 19 Sep 2024 09:48:22 +0800 Subject: [PATCH 30/30] Release: v2.25.0 --- CHANGELOG.md | 6 ++++-- CMakeLists.txt | 2 +- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3cf1d379d0..6ab26cd0ef 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,7 +2,7 @@ Features: * Moore Threads GPU add support to query number of cores (#1259, GPU) -* Cache result based on mtime (Packages) +* Cache detection result based on last modification time (Packages) * Add cmake options to disable certain package managers at compile time * Package managers are encouraged to disable some package managers by passing `-DPACKAGES_DISABLE_` when running `cmake`. For example, when building for Arch Linux, `-DPACKAGES_DISABLE_APK=ON -DPACKAGES_DISABLE_DPKG=ON -DPACKAGES_DISABLE_RPM=ON ...` should be specified. * See all available options by [running `cmake -L | grep PACKAGES_DISABLE_`](https://github.com/fastfetch-cli/fastfetch/blob/dev/CMakeLists.txt#L91) @@ -17,9 +17,11 @@ Bugfixes: * Remove `showPeCoreCount` support on FreeBSD (#1260, CPU, FreeBSD) * Don't use Wifi speed as Ethernet speed (LocalIP, FreeBSD) * Fix compiling with old linux headers (Camera, Linux) +* Fix detecting public ipv6 address (PublicIP, Windows) Logo: -* fix parrot logo detection +* Fix parrot logo detection +* Rename TorizonCore to Torizon OS # 2.24.0 diff --git a/CMakeLists.txt b/CMakeLists.txt index 4dcfc48689..47b2792412 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.24.0 + VERSION 2.25.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"