From e0d733f030d2eb84a85d9c8235431e5534247750 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 15 Aug 2024 19:01:23 +0800 Subject: [PATCH 01/41] DisplayServer (macOS): fix building on ancient macOS version Fix #1190 --- src/detection/displayserver/displayserver_apple.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/detection/displayserver/displayserver_apple.c b/src/detection/displayserver/displayserver_apple.c index d05eb8b1e..ab2abe5e2 100644 --- a/src/detection/displayserver/displayserver_apple.c +++ b/src/detection/displayserver/displayserver_apple.c @@ -89,10 +89,12 @@ static void detectDisplays(FFDisplayServerResult* ds) display->bitDepth = (uint8_t) bitDepth; } + #ifdef MAC_OS_X_VERSION_10_15 if (CoreDisplay_Display_IsHDRModeEnabled) { display->hdrEnabled = CoreDisplay_Display_IsHDRModeEnabled(screen); } + #endif } CGDisplayModeRelease(mode); } From c8e4de983195d9246515dd586b76c9db052b3ae4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 15 Aug 2024 19:40:39 +0800 Subject: [PATCH 02/41] CPU (Linux): silence complier warnings --- src/detection/cpu/cpu_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 5b948150c..60ab31ac2 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -137,7 +137,7 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId) } #endif -static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch, FFstrbuf* cpuImplementer) +static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch, FF_MAYBE_UNUSED FFstrbuf* cpuImplementer) { FF_AUTO_FREE char* line = NULL; size_t len = 0; From bbb873c27bf616421b8e36390002955b239881f4 Mon Sep 17 00:00:00 2001 From: AlbydS <119180144+AlbydST@users.noreply.github.com> Date: Thu, 15 Aug 2024 15:07:45 +0000 Subject: [PATCH 03/41] Doc: Improve installation instructions in the README (#1182) * Improve installation instructions in the README * Revert some stuff * Update README.md --------- Co-authored-by: Carter Li --- README.md | 21 ++++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index cd25100d8..0ed074eb3 100644 --- a/README.md +++ b/README.md @@ -30,17 +30,23 @@ There are [screenshots on different platforms](https://github.com/fastfetch-cli/ Some distros packaged an outdated fastfetch version. Older version 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: `sudo apt install fastfetch` (for Debian 13 or newer) +* Debian: `apt install fastfetch` (for Debian 13 or newer) * Debian / Ubuntu: Download `fastfetch-linux-.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer). -* Arch Linux: `sudo pacman -S fastfetch` -* Fedora: `sudo dnf install fastfetch` -* Gentoo: `sudo emerge --ask app-misc/fastfetch` +* Arch Linux: `pacman -S fastfetch` +* Fedora: `dnf install fastfetch` +* Gentoo: `emerge --ask app-misc/fastfetch` * Alpine: `apk add --upgrade fastfetch` * NixOS: `nix-shell -p fastfetch` -* openSUSE: `sudo zypper install fastfetch` -* ALT Linux: `sudo apt-get install fastfetch` +* openSUSE: `zypper install fastfetch` +* ALT Linux: `apt-get install fastfetch` +* Exherbo: `cave resolve --execute app-misc/fastfetch` +* GNU Guix: `guix install fastfetch` +* Solus: `eopkg install fastfetch` +* Slackware: `sbopkg -i fastfetch` +* Void Linux: `xbps-install fastfetch` +* Venom Linux: `scratch install fastfetch` -Replace sudo with doas depending on what you use. +You may need `sudo`, `doas` or `sup` to run these commands. [See also if fastfetch has been packaged for your favorite Linux distro](#Packaging). @@ -54,6 +60,7 @@ If fastfetch is not packaged for your distro or an outdated version is packaged, ### Windows * [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch` +* [Chocolatey](https://community.chocolatey.org/packages/fastfetch): `choco install fastfetch` * [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch` * [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64---fastfetch` From 9d27106964a336c2cb4454f0381b7a1352bce68c Mon Sep 17 00:00:00 2001 From: Carter Li Date: Fri, 16 Aug 2024 10:13:59 +0800 Subject: [PATCH 04/41] 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 9274e6956..fd559ffe9 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fastfetch (2.21.3) jammy; urgency=medium + + * Update to 2.21.3 + + -- Carter Li Thu, 15 Aug 2024 16:14:52 +0800 + fastfetch (2.21.2) jammy; urgency=medium * Update to 2.21.2 diff --git a/debian/files b/debian/files index b4af41394..a2ab3b200 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fastfetch_2.21.2_source.buildinfo universe/utils optional +fastfetch_2.21.3_source.buildinfo universe/utils optional From b46d9d8b8ed8f10a50c852e07b73ae02c8f02cac Mon Sep 17 00:00:00 2001 From: Lingmo <115727099+lingmo-dream@users.noreply.github.com> Date: Fri, 16 Aug 2024 14:15:30 +0800 Subject: [PATCH 05/41] Logo (Builtin): Add Lingmo OS Logo (#1192) * Update builtin.c * Create lingmo.txt * Update lingmo.txt * Update builtin.c --------- Co-authored-by: Carter Li --- src/logo/ascii/lingmo.txt | 20 ++++++++++++++++++++ src/logo/builtin.c | 11 +++++++++++ 2 files changed, 31 insertions(+) create mode 100644 src/logo/ascii/lingmo.txt diff --git a/src/logo/ascii/lingmo.txt b/src/logo/ascii/lingmo.txt new file mode 100644 index 000000000..23651b458 --- /dev/null +++ b/src/logo/ascii/lingmo.txt @@ -0,0 +1,20 @@ + ..',;;;;;;,,.. + ..,;;;;;;;;;;;;;;;;,.. + .';;;;;;;;;;;;;;;;;;;;;;;;,. + .;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;' + .;;;;;;;;;$2clodddol:$1;;;;;;;;;;;;;;;;. + ';;;;;;;$2ckXWWWNNWWWN0d:$1;;;;;;;;;;;;;;' + ';;;;;;$2cOWWKxl:$1;;;:$2okXWXx$1;;;;;;;;;;;;;;, + ;;;;;;$2:XWWo$1;;;;;;;;;;;$2ONNx$1;;;;;;;;;;;;;;. +,;;;;;;$2xWMk$1;;;;;;;;;;;;;$20NX:$1;;;;;;;;;;;;;; +;;;;;;;$2xMMk$1;;;;;;;;;;;;;$2oXNdcloooolc:$1;;;;; +,;;;;;;$2:NMWl$1;;;;;;;;;;;;$2ckodKK00000Oc$1;;;;; +.;;;;;;;$2cKMWOo:$1;;;;;$2cox0Xccdl:$1;;;;;:;;;;;' + ;;;;;;;;;$2o0WWNK000KXXKkodKKo$1;;;;;;;;;;;; + ,;;;;;;;;;$2:loxxxxdlc$1;;;;$2xKKxc$1;;;;;;;;; + ,;;;;;;;;;;;;;;;;;;;;;;;$2ckK0o;$1;;;;;; + ;;;;;;;;;;;;;;;;;;;;;;;;$2:l$1;;;;;;. + ;;;;;;;;;;;;;;;;;;;;;;;;;;;;. + ;;;;;;;;;;;;;;;;;;;;;;. + ';;;;;;;;;;;;, + ';;'. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 19ad305ef..56514bded 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -2332,6 +2332,17 @@ static const FFlogo L[] = { .colorKeys = FF_COLOR_FG_GREEN, .colorTitle = FF_COLOR_FG_YELLOW, }, + // Lingmo OS + { + .names = {"Lingmo", "lingmo", "LingmoOS", "lingmoos"}, + .lines = FASTFETCH_DATATEXT_LOGO_LINGMO, + .colors = { + FF_COLOR_FG_BLUE, + FF_COLOR_FG_WHITE, + }, + .colorKeys = FF_COLOR_FG_BLUE, + .colorTitle = FF_COLOR_FG_BLUE, + }, // Linspire { .names = {"Linspire", "Lindows"}, From f71c4f6d5a48bc16973dd18c954c6512c72587d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 17 Aug 2024 14:06:34 +0800 Subject: [PATCH 06/41] TerminalShell (Linux): improve performance of GNOME Terminal version detection --- src/detection/terminalshell/terminalshell.c | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index 4d0adf414..ae22bf7a2 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -3,6 +3,7 @@ #include "common/processing.h" #include "common/properties.h" #include "util/stringUtils.h" +#include "util/linux/elf.h" #include #ifdef __FreeBSD__ @@ -250,8 +251,24 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version) return version->length > 0; } -FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version) +static bool extractGnomeTerminalVersion(const char *str, FF_MAYBE_UNUSED uint32_t len, void *userdata) { + if (!ffCharIsDigit(str[0])) return true; + int count = 0; + sscanf(str, "%*d.%*d.%*d%n", &count); + if (count == 0) return true; + ffStrbufSetS((FFstrbuf*) userdata, str); + return false; +} + +FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* version) +{ + if (exe->chars[0] == '/') + { + ffElfExtractStrings(exe->chars, extractGnomeTerminalVersion, version); + if (version->length) return true; + } + if(ffProcessAppendStdOut(version, (char* const[]){ "gnome-terminal", "--version", @@ -590,7 +607,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe #if defined(__linux__) || defined(__FreeBSD__) || defined(__sun) if(ffStrbufStartsWithIgnCaseS(processName, "gnome-terminal")) - return getTerminalVersionGnome(version); + return getTerminalVersionGnome(exe, version); if(ffStrbufIgnCaseEqualS(processName, "konsole")) return getTerminalVersionKonsole(exe, version); From fbfe2b2d1a273633ed1be899210ec63d75e7faa9 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 18 Aug 2024 17:26:06 +0800 Subject: [PATCH 07/41] CPU (Linux): tidy --- src/detection/cpu/cpu_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 60ab31ac2..2c2334d9f 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -265,8 +265,8 @@ static double detectCPUTemp(void) { if( ffStrbufFirstIndexS(&value->name, "cpu") < value->name.length || - ffStrbufCompS(&value->name, "k10temp") == 0 || - ffStrbufCompS(&value->name, "coretemp") == 0 + ffStrbufEqualS(&value->name, "k10temp") || + ffStrbufEqualS(&value->name, "coretemp") ) return value->value; } From 418902512d523826820eb1714b15970fc4a0643a Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 18 Aug 2024 17:26:53 +0800 Subject: [PATCH 08/41] CPU: detect frequency by cpuid (x86 only) Ref: https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252 --- src/detection/cpu/cpu.h | 27 +++++++++++++++++++++++++++ src/detection/cpu/cpu_bsd.c | 2 ++ src/detection/cpu/cpu_linux.c | 2 ++ src/detection/cpu/cpu_sunos.c | 6 +++--- src/detection/cpu/cpu_windows.c | 27 +-------------------------- 5 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/detection/cpu/cpu.h b/src/detection/cpu/cpu.h index e27a437af..dd2d178ed 100644 --- a/src/detection/cpu/cpu.h +++ b/src/detection/cpu/cpu.h @@ -30,3 +30,30 @@ typedef struct FFCPUResult const char* ffDetectCPU(const FFCPUOptions* options, FFCPUResult* cpu); const char* ffCPUAppleCodeToName(uint32_t code); + + +#if defined(__x86_64__) || defined(__i386__) + +#include + +// WARNING: CPUID may report frequencies of efficient cores +inline static const char* ffCPUDetectSpeedByCpuid(FFCPUResult* cpu) +{ + uint32_t base = 0, max = 0, bus = 0, unused = 0; + if (!__get_cpuid(0x16, &base, &max, &bus, &unused)) + return "Unsupported instruction"; + + // cpuid returns 0 MHz when hyper-v is enabled + if (base) cpu->frequencyBase = base; + if (max) cpu->frequencyMax = max; + return NULL; +} + +#else + +inline static const char* ffCPUDetectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu) +{ + return "Unsupported platform"; +} + +#endif diff --git a/src/detection/cpu/cpu_bsd.c b/src/detection/cpu/cpu_bsd.c index 92773dcdc..0b17d595d 100644 --- a/src/detection/cpu/cpu_bsd.c +++ b/src/detection/cpu/cpu_bsd.c @@ -39,6 +39,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) } } + ffCPUDetectSpeedByCpuid(cpu); + for (uint16_t i = 0; i < cpu->coresLogical; ++i) { ffStrbufClear(&buffer); diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 2c2334d9f..39efe3fbe 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -340,6 +340,8 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) cpu->coresOnline = (uint16_t) get_nprocs(); cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, cpu->coresLogical); + // Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252 + ffCPUDetectSpeedByCpuid(cpu); if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0) cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0); diff --git a/src/detection/cpu/cpu_sunos.c b/src/detection/cpu/cpu_sunos.c index 67954ee30..e10dcb898 100644 --- a/src/detection/cpu/cpu_sunos.c +++ b/src/detection/cpu/cpu_sunos.c @@ -29,10 +29,10 @@ const char* ffDetectCPUImpl(FF_MAYBE_UNUSED const FFCPUOptions* options, FFCPURe kstat_named_t* kn = kstat_data_lookup(ks, "vendor_id"); ffStrbufSetNS(&cpu->vendor, KSTAT_NAMED_STR_BUFLEN(kn) - 1, KSTAT_NAMED_STR_PTR(kn)); } - { - kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz"); + ffCPUDetectSpeedByCpuid(cpu); + kstat_named_t* kn = kstat_data_lookup(ks, "clock_MHz"); + if (kn->value.ui32 > cpu->frequencyBase) cpu->frequencyBase = kn->value.ui32; - } ks = kstat_lookup(kc, "unix", -1, "system_misc"); if (ks && kstat_read(kc, ks, NULL) >= 0) diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index fa96bb6ff..411ffe6f7 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -54,31 +54,6 @@ typedef struct FFSmbiosProcessorInfo static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30, "FFSmbiosProcessorInfo: Wrong struct alignment"); -#if defined(__x86_64__) || defined(__i386__) - -#include - -inline static const char* detectSpeedByCpuid(FFCPUResult* cpu) -{ - uint32_t base = 0, max = 0, bus = 0, unused = 0; - if (!__get_cpuid(0x16, &base, &max, &bus, &unused)) - return "Unsupported instruction"; - - // cpuid returns 0 MHz when hyper-v is enabled - if (base) cpu->frequencyBase = base; - if (max) cpu->frequencyMax = max; - return NULL; -} - -#else - -inline static const char* detectSpeedByCpuid(FF_MAYBE_UNUSED FFCPUResult* cpu) -{ - return "Unsupported platform"; -} - -#endif - static const char* detectMaxSpeedBySmbios(FFCPUResult* cpu) { const FFSmbiosHeaderTable* smbiosTable = ffGetSmbiosHeaderTable(); @@ -193,7 +168,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) if (error) return error; - detectSpeedByCpuid(cpu); + ffCPUDetectSpeedByCpuid(cpu); if (options->showPeCoreCount) detectCoreTypes(cpu); if (cpu->frequencyMax == 0) From 8641442c3f18db00fa47a4c560ddc829c886acee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Aug 2024 14:32:53 +0800 Subject: [PATCH 09/41] CMake: fix build on Android --- CMakeLists.txt | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index e403b2376..52be34625 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF) cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF) cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF) -cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR SunOS" OFF) +cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR SunOS OR ANDROID" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF) option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF) @@ -543,6 +543,7 @@ elseif(ANDROID) src/detection/wmtheme/wmtheme_nosupport.c src/detection/camera/camera_android.c src/util/platform/FFPlatform_unix.c + src/util/linux/elf.c ) elseif(FreeBSD) list(APPEND LIBFASTFETCH_SRC From 31ead528f1c52bcf356d1bd09ea04c0a70097b1d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Aug 2024 14:33:00 +0800 Subject: [PATCH 10/41] Doc: update readme [ci skip] --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0ed074eb3..036e028e6 100644 --- a/README.md +++ b/README.md @@ -62,7 +62,7 @@ If fastfetch is not packaged for your distro or an outdated version is packaged, * [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch` * [Chocolatey](https://community.chocolatey.org/packages/fastfetch): `choco install fastfetch` * [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch` -* [MSYS2 MinGW](https://github.com/msys2/MINGW-packages/tree/master/mingw-w64-fastfetch): `pacman -S mingw-w64---fastfetch` +* [MSYS2 MinGW](https://packages.msys2.org/base/mingw-w64-fastfetch): `pacman -S mingw-w64---fastfetch` You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file. From 811485661ff5c29e414008536da5be5ef82d399c Mon Sep 17 00:00:00 2001 From: Princess-Sunset-Shimmer <102773277+Princess-Sunset-Shimmer@users.noreply.github.com> Date: Tue, 20 Aug 2024 16:01:34 +0800 Subject: [PATCH 11/41] Logo (Builtin): Sleeper OS zzzZZZ (#1199) * Create sleeperos.txt * Update builtin.c * Update builtin.c --------- Co-authored-by: Carter Li --- src/logo/ascii/sleeperos.txt | 16 ++++++++++++++++ src/logo/builtin.c | 9 +++++++++ 2 files changed, 25 insertions(+) create mode 100644 src/logo/ascii/sleeperos.txt diff --git a/src/logo/ascii/sleeperos.txt b/src/logo/ascii/sleeperos.txt new file mode 100644 index 000000000..4fdf57945 --- /dev/null +++ b/src/logo/ascii/sleeperos.txt @@ -0,0 +1,16 @@ + ______________ +/P$2aooooooooooooa$19\ +H$2EEEEEEEEEEEEEEEE$1H +H$2EEEEEEEEEEEEEEEE$1H +\baaaaaaap;$2ZZZZ$1,/* + x%"$2ZZZZ$1,%^ + >7'$2ZZZZ$1,%" + /7'$2ZZZZ$1/>' + ,//$2ZZZZ$1,// + ,%<$2ZZZZ$1,%< + >%^$2ZZZZ$1x%^_____ +4>'$2ZZZZ$1---------9b +H$2EEEEEEEEEEEEEEEE$1H +H$2EEEEEEEEEEEEEEEE$1H +Yq$2^************^$1pY + `````````````` diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 56514bded..a3d9691b8 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -3970,6 +3970,15 @@ static const FFlogo S[] = { FF_COLOR_FG_WHITE, }, }, + // SleeperOS + { + .names = {"SleeperOS"}, + .lines = FASTFETCH_DATATEXT_LOGO_SLEEPEROS, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + } + }, // Slitaz { .names = {"Slitaz"}, From 8559ab2dcdc4f6a2e89b14f67f2af7f089aeac6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Aug 2024 15:10:56 +0800 Subject: [PATCH 12/41] Colors (Linux): support tmux in linux TTY --- src/modules/colors/colors.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/modules/colors/colors.c b/src/modules/colors/colors.c index 55192eae5..7da162136 100644 --- a/src/modules/colors/colors.c +++ b/src/modules/colors/colors.c @@ -57,7 +57,8 @@ void ffPrintColors(FFColorsOptions* options) if (options->symbol == FF_COLORS_SYMBOL_BACKGROUND) { const char* term = getenv("TERM"); - if (term && ffStrEquals(term, "linux")) + // Should be "linux", however some terminal mulitplexer overrides $TERM + if (term && !ffStrStartsWith(term, "xterm")) ffStrbufAppendS(&result, "\e[5m"); } #endif From 4860bc35d67a908946677d1f613218988304f38f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Aug 2024 16:37:54 +0800 Subject: [PATCH 13/41] Editor: improve performance of version detection --- CMakeLists.txt | 1 + src/detection/editor/editor.c | 75 ++++++++++++++++++++++------------- src/util/linux/elf.c | 65 ++++++++++++++++++++---------- src/util/path.c | 56 ++++++++++++++++++++++++++ src/util/path.h | 6 +++ 5 files changed, 154 insertions(+), 49 deletions(-) create mode 100644 src/util/path.c create mode 100644 src/util/path.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 52be34625..52e0cb3c1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -401,6 +401,7 @@ set(LIBFASTFETCH_SRC src/util/base64.c src/util/FFlist.c src/util/FFstrbuf.c + src/util/path.c src/util/platform/FFPlatform.c src/util/smbiosHelper.c ) diff --git a/src/detection/editor/editor.c b/src/detection/editor/editor.c index f71544d60..a69e6c5c9 100644 --- a/src/detection/editor/editor.c +++ b/src/detection/editor/editor.c @@ -1,17 +1,45 @@ #include "editor.h" #include "common/processing.h" #include "util/stringUtils.h" +#include "util/path.h" +#include "util/linux/elf.h" #include #ifdef _WIN32 -#include static inline char* realpath(const char* restrict file_name, char* restrict resolved_name) { return _fullpath(resolved_name, file_name, _MAX_PATH); } #endif +#if __linux__ || __FreeBSD__ +static bool extractNvimVersion(const char* str, uint32_t len, void* userdata) +{ + if (len < strlen("NVIM v0.0.0")) return true; + if (!ffStrStartsWith(str, "NVIM v")) return true; + ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v")); + return false; +} + +static bool extractVimVersion(const char* str, uint32_t len, void* userdata) +{ + if (len < strlen("VIM - Vi IMproved 0.0")) return true; + if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true; + ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved ")); + ffStrbufSubstrBeforeFirstC(userdata, ' '); + return false; +} + +static bool extractNanoVersion(const char* str, uint32_t len, void* userdata) +{ + if (len < strlen("GNU nano 0.0")) return true; + if (!ffStrStartsWith(str, "GNU nano ")) return true; + ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano ")); + return false; +} +#endif + const char* ffDetectEditor(FFEditorResult* result) { ffStrbufSetS(&result->name, getenv("VISUAL")); @@ -26,35 +54,15 @@ const char* ffDetectEditor(FFEditorResult* result) return "$VISUAL or $EDITOR not set"; } - if (!instance.config.general.detectVersion) return NULL; - - #ifndef _WIN32 - if (result->name.chars[0] != '/') - { - if (ffProcessAppendStdOut(&result->path, (char* const[]){ - FASTFETCH_TARGET_DIR_USR "/bin/which", - result->name.chars, - NULL, - }) != NULL || result->path.length == 0) - return NULL; - } - #else - if (!(result->name.length > 3 && ffCharIsEnglishAlphabet(result->name.chars[0]) && result->name.chars[1] == ':' && result->name.chars[2] == '\\')) + if (ffIsAbsolutePath(result->name.chars)) + ffStrbufSet(&result->path, &result->name); + else { - char buf[32]; - uint32_t len = GetSystemDirectoryA(buf, sizeof(buf)); - if (len < strlen("C:\\WINDOWS\\system32")) return NULL; - strncpy(buf + len, "\\where.exe", sizeof(buf) - len); - if (ffProcessAppendStdOut(&result->path, (char* const[]){ - buf, - result->name.chars, - NULL, - }) != NULL || result->path.length == 0) - return NULL; + const char* error = ffFindExecutableInPath(result->name.chars, &result->path); + if (error) return error; } - #endif - else - ffStrbufSet(&result->path, &result->name); + + if (!instance.config.general.detectVersion) return NULL; char buf[PATH_MAX + 1]; if (!realpath(result->path.chars, buf)) @@ -82,6 +90,17 @@ const char* ffDetectEditor(FFEditorResult* result) #endif } + #if __linux__ || __FreeBSD__ + if (ffStrbufEqualS(&result->exe, "nvim")) + ffElfExtractStrings(buf, extractNvimVersion, &result->version); + else if (ffStrbufEqualS(&result->exe, "vim")) + ffElfExtractStrings(buf, extractVimVersion, &result->version); + else if (ffStrbufEqualS(&result->exe, "nano")) + ffElfExtractStrings(buf, extractNanoVersion, &result->version); + + if (result->version.length > 0) return NULL; + #endif + const char* param = NULL; if ( ffStrbufEqualS(&result->exe, "nano") || diff --git a/src/util/linux/elf.c b/src/util/linux/elf.c index 4e65c15db..1af384354 100644 --- a/src/util/linux/elf.c +++ b/src/util/linux/elf.c @@ -9,49 +9,72 @@ #include #include +struct FFElfData { + FF_LIBRARY_SYMBOL(elf_version) + FF_LIBRARY_SYMBOL(elf_begin) + FF_LIBRARY_SYMBOL(elf_getshdrstrndx) + FF_LIBRARY_SYMBOL(elf_nextscn) + FF_LIBRARY_SYMBOL(elf64_getshdr) + FF_LIBRARY_SYMBOL(elf32_getshdr) + FF_LIBRARY_SYMBOL(elf_getdata) + FF_LIBRARY_SYMBOL(elf_strptr) + FF_LIBRARY_SYMBOL(elf_end) + + bool inited; +} elfData; + const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata) { - FF_LIBRARY_LOAD(libelf, &instance.config.library.libelf, "dlopen libelf" FF_LIBRARY_EXTENSION " failed", "libelf" FF_LIBRARY_EXTENSION, 1); - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_version) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_begin) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_getshdrstrndx) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_nextscn) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf64_getshdr) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf32_getshdr) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_getdata) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_strptr) - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libelf, elf_end) - - if (ffelf_version(EV_CURRENT) == EV_NONE) return "elf_version() failed"; + if (!elfData.inited) + { + elfData.inited = true; + FF_LIBRARY_LOAD(libelf, &instance.config.library.libelf, "dlopen libelf" FF_LIBRARY_EXTENSION " failed", "libelf" FF_LIBRARY_EXTENSION, 1); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_version) + if (elfData.ffelf_version(EV_CURRENT) == EV_NONE) return "elf_version() failed"; + + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_begin) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_getshdrstrndx) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_nextscn) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf64_getshdr) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf32_getshdr) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_getdata) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_strptr) + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libelf, elfData, elf_end) + + libelf = NULL; + } + + if (elfData.ffelf_end == NULL) + return "load libelf failed"; FF_AUTO_CLOSE_FD int fd = open(elfFile, O_RDONLY, 0); if (fd < 0) return "open() failed"; - Elf* elf = ffelf_begin(fd, ELF_C_READ, NULL); + Elf* elf = elfData.ffelf_begin(fd, ELF_C_READ, NULL); if (elf == NULL) return "elf_begin() failed"; size_t shstrndx = 0; - if (ffelf_getshdrstrndx(elf, &shstrndx) < 0) + if (elfData.ffelf_getshdrstrndx(elf, &shstrndx) < 0) { - ffelf_end(elf); + elfData.ffelf_end(elf); return "elf_getshdrstrndx() failed"; } Elf_Scn* scn = NULL; - while ((scn = ffelf_nextscn(elf, scn)) != NULL) + while ((scn = elfData.ffelf_nextscn(elf, scn)) != NULL) { - Elf64_Shdr* shdr64 = ffelf64_getshdr(scn); + Elf64_Shdr* shdr64 = elfData.ffelf64_getshdr(scn); Elf32_Shdr* shdr32 = NULL; if (shdr64 == NULL) { - shdr32 = ffelf32_getshdr(scn); + shdr32 = elfData.ffelf32_getshdr(scn); if (shdr32 == NULL) continue; } - const char* name = ffelf_strptr(elf, shstrndx, shdr64 ? shdr64->sh_name : shdr32->sh_name); + const char* name = elfData.ffelf_strptr(elf, shstrndx, shdr64 ? shdr64->sh_name : shdr32->sh_name); if (name == NULL || !ffStrEquals(name, ".rodata")) continue; - Elf_Data* data = ffelf_getdata(scn, NULL); + Elf_Data* data = elfData.ffelf_getdata(scn, NULL); if (data == NULL) continue; for (size_t off = 0; off < data->d_size; ++off) @@ -69,7 +92,7 @@ const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, break; } - ffelf_end(elf); + elfData.ffelf_end(elf); return NULL; } diff --git a/src/util/path.c b/src/util/path.c new file mode 100644 index 000000000..e47cbe768 --- /dev/null +++ b/src/util/path.c @@ -0,0 +1,56 @@ +#include "path.h" + +#include "common/io/io.h" +#include "util/stringUtils.h" + +const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) +{ + char* path = getenv("PATH"); + if(!path) + return "$PATH not set"; + + #ifdef _WIN32 + const bool appendExe = !ffStrEndsWithIgnCase(name, ".exe"); + #endif + + for (char* token = NULL; (token = strchr(path, + #ifdef _WIN32 + ';' + #else + ':' + #endif + )) != NULL; path = token + 1) + { + ffStrbufSetNS(result, (uint32_t)(token - path), path); + ffStrbufEnsureEndsWithC(result, + #ifdef _WIN32 + '\\' + #else + '/' + #endif + ); + ffStrbufAppendS(result, name); + #ifdef _WIN32 + if (appendExe) ffStrbufAppendS(result, ".exe"); + if (!ffPathExists(result->chars, FF_PATHTYPE_FILE)) + continue; + #else + struct stat st; + if (stat(result->chars, &st) < 0 || !(st.st_mode & S_IXUSR)) + continue; + #endif + + return NULL; + } + ffStrbufClear(result); + return "Executable not found"; +} + +bool ffIsAbsolutePath(const char* path) +{ + #ifdef _WIN32 + return ffCharIsEnglishAlphabet(path[0]) && path[1] == ':' && (path[2] == '\\' || path[2] == '/'); + #else + return path[0] == '/'; + #endif +} diff --git a/src/util/path.h b/src/util/path.h new file mode 100644 index 000000000..7ff77631b --- /dev/null +++ b/src/util/path.h @@ -0,0 +1,6 @@ +#pragma once + +#include "fastfetch.h" + +const char* ffFindExecutableInPath(const char* name, FFstrbuf* result); +bool ffIsAbsolutePath(const char* path); From 543eed9a53525a9b80e004cc3e8d7dd7b1c51b85 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Aug 2024 23:36:36 +0800 Subject: [PATCH 14/41] Logo (Builtin): add SleeperOS_small --- src/logo/ascii/sleeperos_small.txt | 7 +++++++ src/logo/builtin.c | 10 ++++++++++ 2 files changed, 17 insertions(+) create mode 100644 src/logo/ascii/sleeperos_small.txt diff --git a/src/logo/ascii/sleeperos_small.txt b/src/logo/ascii/sleeperos_small.txt new file mode 100644 index 000000000..13c18f3cb --- /dev/null +++ b/src/logo/ascii/sleeperos_small.txt @@ -0,0 +1,7 @@ + _____ +[$2BBBBB$1] +`^^7$2&$1/` + ,/$2&$1/` +,/$2&$1Z__ +[$2BBBBB$1] +`^^^^^` diff --git a/src/logo/builtin.c b/src/logo/builtin.c index a3d9691b8..58f8348e0 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -3979,6 +3979,16 @@ static const FFlogo S[] = { FF_COLOR_FG_WHITE, } }, + // SleeperOS + { + .names = {"SleeperOS_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_SLEEPEROS_SMALL, + .colors = { + FF_COLOR_FG_CYAN, + FF_COLOR_FG_WHITE, + } + }, // Slitaz { .names = {"Slitaz"}, From dd2d3436305829da30d2d35d684718cd4fda00f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 20 Aug 2024 23:52:29 +0800 Subject: [PATCH 15/41] Global: fix build on Windows --- CMakeLists.txt | 10 ++++++---- src/detection/editor/editor.c | 8 ++++---- src/detection/initsystem/initsystem_linux.c | 4 ++-- src/detection/terminalfont/terminalfont_linux.c | 4 ++-- src/detection/terminalshell/terminalshell.c | 4 ++-- src/util/{linux/elf.c => binary.c} | 8 ++++---- src/util/{linux/elf.h => binary.h} | 2 +- 7 files changed, 21 insertions(+), 19 deletions(-) rename src/util/{linux/elf.c => binary.c} (92%) rename src/util/{linux/elf.h => binary.h} (61%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 52e0cb3c1..02db14ef3 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -482,7 +482,7 @@ if(LINUX) src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_linux.c src/util/platform/FFPlatform_unix.c - src/util/linux/elf.c + src/util/binary.c ) elseif(ANDROID) list(APPEND LIBFASTFETCH_SRC @@ -544,7 +544,7 @@ elseif(ANDROID) src/detection/wmtheme/wmtheme_nosupport.c src/detection/camera/camera_android.c src/util/platform/FFPlatform_unix.c - src/util/linux/elf.c + src/util/binary.c ) elseif(FreeBSD) list(APPEND LIBFASTFETCH_SRC @@ -623,7 +623,7 @@ elseif(FreeBSD) src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_linux.c src/util/platform/FFPlatform_unix.c - src/util/linux/elf.c + src/util/binary.c ) elseif(APPLE) list(APPEND LIBFASTFETCH_SRC @@ -689,6 +689,7 @@ elseif(APPLE) src/util/apple/cf_helpers.c src/util/apple/osascript.m src/util/platform/FFPlatform_unix.c + src/util/binary.c ) elseif(WIN32) list(APPEND LIBFASTFETCH_SRC @@ -755,6 +756,7 @@ elseif(WIN32) src/util/windows/unicode.c src/util/windows/wmi.cpp src/util/platform/FFPlatform_windows.c + src/util/binary.c ) elseif(SunOS) list(APPEND LIBFASTFETCH_SRC @@ -831,7 +833,7 @@ elseif(SunOS) src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_nosupport.c src/util/platform/FFPlatform_unix.c - src/util/linux/elf.c + src/util/binary.c ) endif() diff --git a/src/detection/editor/editor.c b/src/detection/editor/editor.c index a69e6c5c9..a37accb0d 100644 --- a/src/detection/editor/editor.c +++ b/src/detection/editor/editor.c @@ -2,7 +2,7 @@ #include "common/processing.h" #include "util/stringUtils.h" #include "util/path.h" -#include "util/linux/elf.h" +#include "util/binary.h" #include @@ -92,11 +92,11 @@ const char* ffDetectEditor(FFEditorResult* result) #if __linux__ || __FreeBSD__ if (ffStrbufEqualS(&result->exe, "nvim")) - ffElfExtractStrings(buf, extractNvimVersion, &result->version); + ffBinaryExtractStrings(buf, extractNvimVersion, &result->version); else if (ffStrbufEqualS(&result->exe, "vim")) - ffElfExtractStrings(buf, extractVimVersion, &result->version); + ffBinaryExtractStrings(buf, extractVimVersion, &result->version); else if (ffStrbufEqualS(&result->exe, "nano")) - ffElfExtractStrings(buf, extractNanoVersion, &result->version); + ffBinaryExtractStrings(buf, extractNanoVersion, &result->version); if (result->version.length > 0) return NULL; #endif diff --git a/src/detection/initsystem/initsystem_linux.c b/src/detection/initsystem/initsystem_linux.c index a16254595..d135dce87 100644 --- a/src/detection/initsystem/initsystem_linux.c +++ b/src/detection/initsystem/initsystem_linux.c @@ -1,6 +1,6 @@ #include "initsystem.h" #include "common/processing.h" -#include "util/linux/elf.h" +#include "util/binary.h" #include FF_MAYBE_UNUSED static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* data) @@ -49,7 +49,7 @@ const char* ffDetectInitSystem(FFInitSystemResult* result) #if __linux__ && !__ANDROID__ if (ffStrbufEqualS(&result->name, "systemd")) { - ffElfExtractStrings(result->exe.chars, elfExtractStringsCallBack, &result->version); + ffBinaryExtractStrings(result->exe.chars, elfExtractStringsCallBack, &result->version); if (result->version.length == 0) { if (ffProcessAppendStdOut(&result->version, (char* const[]) { diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 271243354..8dd15ee7a 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -8,7 +8,7 @@ #include "detection/displayserver/displayserver.h" #include "util/mallocHelper.h" #include "util/stringUtils.h" -#include "util/linux/elf.h" +#include "util/binary.h" static const char* getSystemMonospaceFont(void) { @@ -315,7 +315,7 @@ static void detectSt(FFTerminalFontResult* terminalFont, const FFTerminalResult* { ffStrbufClear(&font); - const char* error = ffElfExtractStrings(terminal->exePath.chars, elfExtractStringsCallBack, &font); + const char* error = ffBinaryExtractStrings(terminal->exePath.chars, elfExtractStringsCallBack, &font); if (error) { ffStrbufAppendS(&terminalFont->error, error); diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index ae22bf7a2..4073d7aef 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -3,7 +3,7 @@ #include "common/processing.h" #include "common/properties.h" #include "util/stringUtils.h" -#include "util/linux/elf.h" +#include "util/binary.h" #include #ifdef __FreeBSD__ @@ -265,7 +265,7 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* exe, FFstrbuf* ver { if (exe->chars[0] == '/') { - ffElfExtractStrings(exe->chars, extractGnomeTerminalVersion, version); + ffBinaryExtractStrings(exe->chars, extractGnomeTerminalVersion, version); if (version->length) return true; } diff --git a/src/util/linux/elf.c b/src/util/binary.c similarity index 92% rename from src/util/linux/elf.c rename to src/util/binary.c index 1af384354..24b6e0cab 100644 --- a/src/util/linux/elf.c +++ b/src/util/binary.c @@ -1,4 +1,4 @@ -#include "elf.h" +#include "binary.h" #ifdef FF_HAVE_ELF @@ -23,7 +23,7 @@ struct FFElfData { bool inited; } elfData; -const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata) +const char* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata) { if (!elfData.inited) { @@ -98,9 +98,9 @@ const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, #else -const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata) +const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata) { - FF_UNUSED(elfFile, cb, userdata); + FF_UNUSED(file, cb, userdata); return "Fastfetch was built without libelf support"; } diff --git a/src/util/linux/elf.h b/src/util/binary.h similarity index 61% rename from src/util/linux/elf.h rename to src/util/binary.h index 4cfdaeb45..2a0e0943d 100644 --- a/src/util/linux/elf.h +++ b/src/util/binary.h @@ -2,4 +2,4 @@ #include "fastfetch.h" -const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata); +const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata); From 099a390f2ffe7b765ee4a4ed8cfbc01c72657411 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Aug 2024 00:23:24 +0800 Subject: [PATCH 16/41] Disk (Linux): fix hang in WSL when custom format is used --- src/detection/disk/disk_linux.c | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 31b90adca..3836f6eb8 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -72,7 +72,7 @@ static bool isPhysicalDevice(const struct mntent* device) ) return false; // https://source.android.com/docs/core/ota/apex?hl=zh-cn - if(ffStrStartsWith(device->mnt_dir, "/apex/")) + if(ffStrStartsWith(device->mnt_dir, "/apex/")) return false; #endif // __ANDROID__ @@ -240,8 +240,16 @@ static void detectStats(FFDisk* disk) disk->bytesAvailable = fs.f_bavail * fs.f_frsize; disk->bytesUsed = 0; // To be filled in ./disk.c - disk->filesTotal = (uint32_t) fs.f_files; - disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); + if (fs.f_files >= fs.f_ffree) + { + disk->filesTotal = (uint32_t) fs.f_files; + disk->filesUsed = (uint32_t) (disk->filesTotal - fs.f_ffree); + } + else + { + // Windows filesystem in WSL + disk->filesTotal = disk->filesUsed = 0; + } if(fs.f_flag & ST_RDONLY) disk->type |= FF_DISK_VOLUME_TYPE_READONLY_BIT; From 1c8375908c86a8355e3e6f6796d3962985cab6fa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Aug 2024 00:24:12 +0800 Subject: [PATCH 17/41] Presets: update examples/23.jsonc Close #1200 --- presets/examples/23.jsonc | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/presets/examples/23.jsonc b/presets/examples/23.jsonc index c075b741b..effc39a7b 100644 --- a/presets/examples/23.jsonc +++ b/presets/examples/23.jsonc @@ -11,45 +11,51 @@ }, "separator": "" }, - "modules": [ + "modules": [ { "type": "kernel", - "key": "Vanilla ", + "key": "[_Kernel___> ", "keyColor": "blue" }, { "type": "packages", + "outputColor": "white", "key": " [_Packages_> ", "keyColor": "green" }, { "type": "localip", + "outputColor": "white", "key": " [_Local_IP_> ", "keyColor": "green" }, - { - "type": "cpu", - "key": " [_CPU______> ", - "keyColor": "magenta" - }, { "type": "memory", + "format": "[{3}] {1} / {2}", "key": " [_RAM______> ", "keyColor": "magenta" }, { "type": "swap", + "format": "[{3}] {1} / {2}", "key": " [_SWAP_____> ", "keyColor": "magenta" }, { "type": "disk", + "format": "[{3}] {1} / {2} {9}", "key": " [_Disk_____> ", "keyColor": "magenta" }, + { + "type": "battery", + "format": "[{4}] {5}", + "key": " [_Battery__> ", + "keyColor": "magenta" + }, "break", { - "type":"colors", + "type": "colors", "paddingLeft": 9, "symbol": "circle" } From 22e25d0c7834759fe21e407e194aa660ea55d37e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Aug 2024 15:31:47 +0800 Subject: [PATCH 18/41] Binary: support macOS --- CMakeLists.txt | 12 +- src/detection/editor/editor.c | 4 - src/util/binary_apple.c | 186 ++++++++++++++++++++++++++ src/util/{binary.c => binary_linux.c} | 0 4 files changed, 192 insertions(+), 10 deletions(-) create mode 100644 src/util/binary_apple.c rename src/util/{binary.c => binary_linux.c} (100%) diff --git a/CMakeLists.txt b/CMakeLists.txt index 02db14ef3..023c51919 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -482,7 +482,7 @@ if(LINUX) src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_linux.c src/util/platform/FFPlatform_unix.c - src/util/binary.c + src/util/binary_linux.c ) elseif(ANDROID) list(APPEND LIBFASTFETCH_SRC @@ -544,7 +544,7 @@ elseif(ANDROID) src/detection/wmtheme/wmtheme_nosupport.c src/detection/camera/camera_android.c src/util/platform/FFPlatform_unix.c - src/util/binary.c + src/util/binary_linux.c ) elseif(FreeBSD) list(APPEND LIBFASTFETCH_SRC @@ -623,7 +623,7 @@ elseif(FreeBSD) src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_linux.c src/util/platform/FFPlatform_unix.c - src/util/binary.c + src/util/binary_linux.c ) elseif(APPLE) list(APPEND LIBFASTFETCH_SRC @@ -689,7 +689,7 @@ elseif(APPLE) src/util/apple/cf_helpers.c src/util/apple/osascript.m src/util/platform/FFPlatform_unix.c - src/util/binary.c + src/util/binary_apple.c ) elseif(WIN32) list(APPEND LIBFASTFETCH_SRC @@ -756,7 +756,7 @@ elseif(WIN32) src/util/windows/unicode.c src/util/windows/wmi.cpp src/util/platform/FFPlatform_windows.c - src/util/binary.c + src/util/binary_linux.c ) elseif(SunOS) list(APPEND LIBFASTFETCH_SRC @@ -833,7 +833,7 @@ elseif(SunOS) src/detection/wmtheme/wmtheme_linux.c src/detection/camera/camera_nosupport.c src/util/platform/FFPlatform_unix.c - src/util/binary.c + src/util/binary_linux.c ) endif() diff --git a/src/detection/editor/editor.c b/src/detection/editor/editor.c index a37accb0d..269f567b8 100644 --- a/src/detection/editor/editor.c +++ b/src/detection/editor/editor.c @@ -13,7 +13,6 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso } #endif -#if __linux__ || __FreeBSD__ static bool extractNvimVersion(const char* str, uint32_t len, void* userdata) { if (len < strlen("NVIM v0.0.0")) return true; @@ -38,7 +37,6 @@ static bool extractNanoVersion(const char* str, uint32_t len, void* userdata) ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano ")); return false; } -#endif const char* ffDetectEditor(FFEditorResult* result) { @@ -90,7 +88,6 @@ const char* ffDetectEditor(FFEditorResult* result) #endif } - #if __linux__ || __FreeBSD__ if (ffStrbufEqualS(&result->exe, "nvim")) ffBinaryExtractStrings(buf, extractNvimVersion, &result->version); else if (ffStrbufEqualS(&result->exe, "vim")) @@ -99,7 +96,6 @@ const char* ffDetectEditor(FFEditorResult* result) ffBinaryExtractStrings(buf, extractNanoVersion, &result->version); if (result->version.length > 0) return NULL; - #endif const char* param = NULL; if ( diff --git a/src/util/binary_apple.c b/src/util/binary_apple.c new file mode 100644 index 000000000..940228af8 --- /dev/null +++ b/src/util/binary_apple.c @@ -0,0 +1,186 @@ +#include "binary.h" +#include "common/io/io.h" +#include "util/stringUtils.h" +#include "util/mallocHelper.h" + +#include +#include +#include +#include +#include +#include + +#pragma GCC diagnostic ignored "-Wdeprecated-declarations" // swap_fat_arch + +// Ref: https://github.com/AlexDenisov/segment_dumper/blob/master/main.c + +static inline bool readData(FILE *objFile, void *buf, size_t size, off_t offset) +{ + fseek(objFile, offset, SEEK_SET); + return fread(buf, 1, size, objFile) == size; +} + +static bool handleMachSection(FILE *objFile, const char *name, off_t offset, size_t size, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata) +{ + if (!ffStrEquals(name, "__cstring")) return true; + + FF_AUTO_FREE char* data = (char*) malloc(size); + if (!readData(objFile, data, size, offset)) + return true; + + for (size_t off = 0; off < size; ++off) + { + const char* p = (const char*) data + off; + if (*p == '\0') continue; + uint32_t len = (uint32_t) strlen(p); + if (*p >= ' ' && *p <= '~') // Ignore control characters + { + if (!cb(p, len, userdata)) return false; + } + off += len; + } + return true; +} + +static const char* dumpMachHeader(FILE *objFile, off_t offset, bool is_64, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata) +{ + uint32_t ncmds; + off_t loadCommandsOffset = offset; + + if (is_64) + { + struct mach_header_64 header; + if (!readData(objFile, &header, sizeof(header), offset)) + return "read mach header failed"; + + ncmds = header.ncmds; + loadCommandsOffset += sizeof(header); + } + else + { + struct mach_header header; + if (!readData(objFile, &header, sizeof(header), offset)) + return "read mach header failed"; + + ncmds = header.ncmds; + loadCommandsOffset += sizeof(header); + } + + off_t commandOffset = loadCommandsOffset; + struct load_command cmd = {}; + for (uint32_t i = 0U; i < ncmds; i++, commandOffset += cmd.cmdsize) + { + if (!readData(objFile, &cmd, sizeof(cmd), commandOffset)) + continue; + + if (cmd.cmd == LC_SEGMENT_64) + { + struct segment_command_64 segment; + if (!readData(objFile, &segment, sizeof(segment), commandOffset)) + continue; + + if (!ffStrEquals(segment.segname, "__TEXT")) continue; + + for (uint32_t j = 0U; j < segment.nsects; j++) + { + struct section_64 section; + if (!readData(objFile, §ion, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section)))) + continue; + + if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata)) + return NULL; + } + } + else if (cmd.cmd == LC_SEGMENT) + { + struct segment_command segment; + if (!readData(objFile, &segment, sizeof(segment), commandOffset)) + continue; + + if (!ffStrEquals(segment.segname, "__TEXT")) continue; + + for (uint32_t j = 0; j < segment.nsects; j++) + { + struct section section; + if (!readData(objFile, §ion, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section)))) + continue; + + if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata)) + return NULL; + } + } + + return NULL; + } + + return NULL; +} + +static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata) +{ + struct fat_header header; + if (!readData(objFile, &header, sizeof(header), 0)) + return "read fat header failed"; + + bool needSwap = header.magic == FAT_CIGAM || header.magic == FAT_CIGAM_64; + + if (needSwap) swap_fat_header(&header, NX_UnknownByteOrder); + + for (uint32_t i = 0U; i < header.nfat_arch; i++) + { + off_t machHeaderOffset = 0; + if (header.magic == FAT_MAGIC) + { + struct fat_arch arch; + if (!readData(objFile, &arch, sizeof(arch), (off_t) (sizeof(header) + i * sizeof(arch)))) + continue; + + if (needSwap) + swap_fat_arch(&arch, 1, NX_UnknownByteOrder); + machHeaderOffset = (off_t)arch.offset; + } + else + { + struct fat_arch_64 arch; + if (!readData(objFile, &arch, sizeof(arch), (off_t) (sizeof(header) + i * sizeof(arch)))) + continue; + + if (needSwap) + swap_fat_arch_64(&arch, 1, NX_UnknownByteOrder); + + machHeaderOffset = (off_t)arch.offset; + } + + uint32_t magic; + if (!readData(objFile, &magic, sizeof(magic), machHeaderOffset)) + continue; + + if (magic == MH_MAGIC_64 || magic == MH_MAGIC) + { + dumpMachHeader(objFile, machHeaderOffset, magic == MH_MAGIC_64, cb, userdata); + return NULL; + } + } + return "Unsupported fat header"; +} + +const char *ffBinaryExtractStrings(const char *machoFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata) +{ + FF_AUTO_CLOSE_FILE FILE *objFile = fopen(machoFile, "rb"); + if (objFile == NULL) + return "File could not be opened"; + + uint32_t magic; + if (!readData(objFile, &magic, sizeof(magic), 0)) + return "read magic number failed"; + + // MH_CIGAM and MH_CIGAM_64 seem to be no longer used, as `swap_mach_header` is marked as deprecated. + // However FAT_CIGAM and FAT_CIGAM_64 are still used (/usr/bin/vim). + if (magic != MH_MAGIC && magic != MH_MAGIC_64 && magic != FAT_CIGAM && magic != FAT_CIGAM_64 && magic != FAT_MAGIC && magic != FAT_MAGIC_64) + return "Unsupported format or big endian mach-o file"; + + if (magic == FAT_MAGIC || magic == FAT_MAGIC_64 || magic == FAT_CIGAM || magic == FAT_CIGAM_64) + return dumpFatHeader(objFile, cb, userdata); + else + return dumpMachHeader(objFile, 0, magic == MH_MAGIC_64, cb, userdata); +} diff --git a/src/util/binary.c b/src/util/binary_linux.c similarity index 100% rename from src/util/binary.c rename to src/util/binary_linux.c From d10dd2095a4464a6e6f3002b27f263210220ab39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 21 Aug 2024 15:46:12 +0800 Subject: [PATCH 19/41] CPU (Android): try support old armv7 smart phone Fix #1202 --- src/detection/cpu/cpu_linux.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 39efe3fbe..74d09bc16 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -144,8 +144,12 @@ static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physi while(getline(&line, &len, cpuinfo) != -1) { - //Stop after the first CPU - if(*line == '\0' || *line == '\n') + //Stop after reasonable information is acquired + if((*line == '\0' || *line == '\n') + #if __ANDROID__ && __arm__ + && cpu->name.length > 0 // #1202 + #endif + ) break; (void)( @@ -157,7 +161,7 @@ static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physi ffParsePropLine(line, "uarch :", cpuUarch) || #if __arm__ || __aarch64__ - (cpu->vendor.length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || + (cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || #endif #if __ANDROID__ (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices From 591dba88296cb639e24293e3f7be2f4148f2f67a Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 21 Aug 2024 16:42:40 +0800 Subject: [PATCH 20/41] CPU (Linux): don't parse unnecessary lines on certain platforms --- src/detection/cpu/cpu_linux.c | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 74d09bc16..efd57c826 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -137,7 +137,14 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId) } #endif -static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physicalCoresBuffer, FFstrbuf* cpuMHz, FFstrbuf* cpuIsa, FFstrbuf* cpuUarch, FF_MAYBE_UNUSED FFstrbuf* cpuImplementer) +static const char* parseCpuInfo( + FILE* cpuinfo, + FFCPUResult* cpu, + FFstrbuf* physicalCoresBuffer, + FFstrbuf* cpuMHz, + FF_MAYBE_UNUSED FFstrbuf* cpuIsa, + FF_MAYBE_UNUSED FFstrbuf* cpuUarch, + FF_MAYBE_UNUSED FFstrbuf* cpuImplementer) { FF_AUTO_FREE char* line = NULL; size_t len = 0; @@ -157,8 +164,11 @@ static const char* parseCpuInfo(FILE* cpuinfo, FFCPUResult* cpu, FFstrbuf* physi ffParsePropLine(line, "vendor_id :", &cpu->vendor) || ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) || ffParsePropLine(line, "cpu MHz :", cpuMHz) || + + #if !(__x86_64__ || __i386__ || __arm__ || __aarch64__) ffParsePropLine(line, "isa :", cpuIsa) || ffParsePropLine(line, "uarch :", cpuUarch) || + #endif #if __arm__ || __aarch64__ (cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || @@ -277,7 +287,7 @@ static double detectCPUTemp(void) return FF_CPU_TEMP_UNSET; } -static void parseIsa(FFstrbuf* cpuIsa) +FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa) { if(ffStrbufStartsWithS(cpuIsa, "rv")) { @@ -300,7 +310,7 @@ static void parseIsa(FFstrbuf* cpuIsa) } } -void detectAsahi(FFCPUResult* cpu) +FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu) { // In Asahi Linux, reading /proc/device-tree/compatible gives // information on the device model. It consists of 3 NUL terminated @@ -349,6 +359,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) if (!detectFrequency(cpu, options) || cpu->frequencyBase == 0) cpu->frequencyBase = (uint32_t) ffStrbufToUInt(&cpuMHz, 0); + #if !(__x86_64__ || __i386__ || __arm__ || __aarch64__) if(cpuUarch.length > 0) { if(cpu->name.length > 0) @@ -363,6 +374,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu) ffStrbufAppendC(&cpu->name, ' '); ffStrbufAppend(&cpu->name, &cpuIsa); } + #endif #if __arm__ || __aarch64__ uint32_t cpuImplementer = (uint32_t) strtoul(cpuImplementerStr.chars, NULL, 16); From 96905012a413f4ded49c33a182105f1d6a98b8cf Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 22 Aug 2024 09:16:20 +0800 Subject: [PATCH 21/41] CPU (Linux): support loongarch Fix #1204 --- src/detection/cpu/cpu_linux.c | 39 +++++++++++++++++++---------------- 1 file changed, 21 insertions(+), 18 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index efd57c826..75445c712 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -138,10 +138,10 @@ static void detectArmName(FILE* cpuinfo, FFCPUResult* cpu, uint32_t implId) #endif static const char* parseCpuInfo( - FILE* cpuinfo, - FFCPUResult* cpu, - FFstrbuf* physicalCoresBuffer, - FFstrbuf* cpuMHz, + FF_MAYBE_UNUSED FILE* cpuinfo, + FF_MAYBE_UNUSED FFCPUResult* cpu, + FF_MAYBE_UNUSED FFstrbuf* physicalCoresBuffer, + FF_MAYBE_UNUSED FFstrbuf* cpuMHz, FF_MAYBE_UNUSED FFstrbuf* cpuIsa, FF_MAYBE_UNUSED FFstrbuf* cpuUarch, FF_MAYBE_UNUSED FFstrbuf* cpuImplementer) @@ -153,21 +153,25 @@ static const char* parseCpuInfo( { //Stop after reasonable information is acquired if((*line == '\0' || *line == '\n') - #if __ANDROID__ && __arm__ - && cpu->name.length > 0 // #1202 + #if __arm__ || __loongarch__ + && cpu->name.length > 0 // #1202 #1204 #endif ) break; (void)( - ffParsePropLine(line, "model name :", &cpu->name) || - ffParsePropLine(line, "vendor_id :", &cpu->vendor) || - ffParsePropLine(line, "cpu cores :", physicalCoresBuffer) || - ffParsePropLine(line, "cpu MHz :", cpuMHz) || + // arm64 doesn't have "model name"; arm32 does have "model name" but its value is not useful. + // "Hardware" should always be used in this case + #if !(__arm__ || __aarch64__) + (cpu->name.length == 0 && ffParsePropLine(line, "model name :", &cpu->name)) || + (cpu->vendor.length == 0 && ffParsePropLine(line, "vendor_id :", &cpu->vendor)) || + (physicalCoresBuffer->length == 0 && ffParsePropLine(line, "cpu cores :", physicalCoresBuffer)) || + (cpuMHz->length == 0 && ffParsePropLine(line, "cpu MHz :", cpuMHz)) || + #endif #if !(__x86_64__ || __i386__ || __arm__ || __aarch64__) - ffParsePropLine(line, "isa :", cpuIsa) || - ffParsePropLine(line, "uarch :", cpuUarch) || + (cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) || + (cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) || #endif #if __arm__ || __aarch64__ @@ -177,10 +181,10 @@ static const char* parseCpuInfo( (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices #endif #if __powerpc__ || __powerpc - (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER + (cpu->name.length == 0 && ffParsePropLine(line, "cpu :", &cpu->name)) || //For POWER #endif #if __mips__ - (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS + (cpu->name.length == 0 && ffParsePropLine(line, "cpu model :", &cpu->name)) || //For MIPS #endif false ); @@ -289,6 +293,9 @@ static double detectCPUTemp(void) FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa) { + // Always use the last part of the ISA string. Ref: #590 #1204 + ffStrbufSubstrAfterLastC(cpuIsa, ' '); + if(ffStrbufStartsWithS(cpuIsa, "rv")) { // RISC-V ISA string example: "rv64imafdch_zicsr_zifencei". @@ -304,10 +311,6 @@ FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa) } // The final ISA output of the above example is "rv64gch". } - if(ffStrbufStartsWithS(cpuIsa, "mips")) - { - ffStrbufSubstrAfterLastC(cpuIsa, ' '); - } } FF_MAYBE_UNUSED static void detectAsahi(FFCPUResult* cpu) From e66a83a4cfc4b0aa63de7eaa011701e6800896ef Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 22 Aug 2024 09:17:03 +0800 Subject: [PATCH 22/41] Version: support loongarch --- src/detection/version/version.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/detection/version/version.c b/src/detection/version/version.c index 5c1fb0ae4..fe87e2e77 100644 --- a/src/detection/version/version.c +++ b/src/detection/version/version.c @@ -1,8 +1,8 @@ #include "version.h" -#if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) +#if defined(__x86_64__) #define FF_ARCHITECTURE "x86_64" -#elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686) +#elif defined(__i386__) #define FF_ARCHITECTURE "i386" #elif defined(__aarch64__) #define FF_ARCHITECTURE "aarch64" @@ -16,6 +16,8 @@ #define FF_ARCHITECTURE "riscv" #elif defined(__s390x__) #define FF_ARCHITECTURE "s390x" +#elif defined(__loongarch__) + #define FF_ARCHITECTURE "loongarch" #else #define FF_ARCHITECTURE "unknown" #endif From 17deaf963ed1860ae9aa280129ccd5a2e8a18fc8 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Thu, 22 Aug 2024 09:29:26 +0800 Subject: [PATCH 23/41] CPU (Linux): make "Hardware :" arm specific --- src/detection/cpu/cpu_linux.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/detection/cpu/cpu_linux.c b/src/detection/cpu/cpu_linux.c index 75445c712..7e9d92f7a 100644 --- a/src/detection/cpu/cpu_linux.c +++ b/src/detection/cpu/cpu_linux.c @@ -176,8 +176,6 @@ static const char* parseCpuInfo( #if __arm__ || __aarch64__ (cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) || - #endif - #if __ANDROID__ (cpu->name.length == 0 && ffParsePropLine(line, "Hardware :", &cpu->name)) || //For Android devices #endif #if __powerpc__ || __powerpc From cf9bd0f3735653648580a94989af2b6e07eb8475 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Aug 2024 23:36:38 +0800 Subject: [PATCH 24/41] Loadavg (Linux): read `/proc/loadavg` instead of `/proc/uptime` Fix #1206 --- src/detection/loadavg/loadavg_linux.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/detection/loadavg/loadavg_linux.c b/src/detection/loadavg/loadavg_linux.c index 47085a744..9e8b091c5 100644 --- a/src/detection/loadavg/loadavg_linux.c +++ b/src/detection/loadavg/loadavg_linux.c @@ -9,12 +9,12 @@ const char* ffDetectLoadavg(double result[3]) // Don't use syscall for container compatibility. #620 char buf[64]; - ssize_t nRead = ffReadFileData("/proc/uptime", sizeof(buf) - 1, buf); + ssize_t nRead = ffReadFileData("/proc/loadavg", sizeof(buf) - 1, buf); if (nRead > 0) { buf[nRead] = '\0'; - if (sscanf(buf, "%lf %lf %lf", &result[0], &result[1], &result[2]) == 3) + if (sscanf(buf, "%lf%lf%lf", &result[0], &result[1], &result[2]) == 3) return NULL; } From b4aac9d7d7290232c57cecfee35545adb35d46c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 22 Aug 2024 16:41:06 +0800 Subject: [PATCH 25/41] Binary: support Windows --- CMakeLists.txt | 3 ++- src/detection/editor/editor.c | 8 ++++--- src/util/binary_windows.c | 39 +++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 src/util/binary_windows.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 023c51919..718062d06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -756,7 +756,7 @@ elseif(WIN32) src/util/windows/unicode.c src/util/windows/wmi.cpp src/util/platform/FFPlatform_windows.c - src/util/binary_linux.c + src/util/binary_windows.c ) elseif(SunOS) list(APPEND LIBFASTFETCH_SRC @@ -1139,6 +1139,7 @@ elseif(WIN32) PRIVATE "setupapi" PRIVATE "hid" PRIVATE "wtsapi32" + PRIVATE "imagehlp" ) elseif(FreeBSD) target_link_libraries(libfastfetch diff --git a/src/detection/editor/editor.c b/src/detection/editor/editor.c index 269f567b8..6fd5258c5 100644 --- a/src/detection/editor/editor.c +++ b/src/detection/editor/editor.c @@ -57,15 +57,15 @@ const char* ffDetectEditor(FFEditorResult* result) else { const char* error = ffFindExecutableInPath(result->name.chars, &result->path); - if (error) return error; + if (error) return NULL; } - if (!instance.config.general.detectVersion) return NULL; - char buf[PATH_MAX + 1]; if (!realpath(result->path.chars, buf)) return NULL; + // WIN32: Should we handle scoop shim exe here? + ffStrbufSetS(&result->path, buf); { @@ -88,6 +88,8 @@ const char* ffDetectEditor(FFEditorResult* result) #endif } + if (!instance.config.general.detectVersion) return NULL; + if (ffStrbufEqualS(&result->exe, "nvim")) ffBinaryExtractStrings(buf, extractNvimVersion, &result->version); else if (ffStrbufEqualS(&result->exe, "vim")) diff --git a/src/util/binary_windows.c b/src/util/binary_windows.c new file mode 100644 index 000000000..6582d9e1d --- /dev/null +++ b/src/util/binary_windows.c @@ -0,0 +1,39 @@ +#include "binary.h" +#include "common/io/io.h" +#include "util/stringUtils.h" +#include "util/mallocHelper.h" + +#include +#include +#include +#include + +const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata) +{ + __attribute__((__cleanup__(UnMapAndLoad))) LOADED_IMAGE loadedImage = {}; + if (!MapAndLoad(peFile, NULL, &loadedImage, FALSE, TRUE)) + return "File could not be loaded"; + + for (ULONG i = 0; i < loadedImage.NumberOfSections; ++i) + { + PIMAGE_SECTION_HEADER section = &loadedImage.Sections[i]; + if ((section->Characteristics & IMAGE_SCN_CNT_INITIALIZED_DATA) && ffStrEquals((const char*) section->Name, ".rdata")) + { + uint8_t *data = (uint8_t *) loadedImage.MappedAddress + section->PointerToRawData; + + for (size_t off = 0; off < section->SizeOfRawData; ++off) + { + const char* p = (const char*) data + off; + if (*p == '\0') continue; + uint32_t len = (uint32_t) strlen(p); + if (*p >= ' ' && *p <= '~') // Ignore control characters + { + if (!cb(p, len, userdata)) break; + } + off += len; + } + } + } + + return NULL; +} From e199a2fb796bfbe0fb97cc08fa9fc603f11fdbdf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Aug 2024 10:17:06 +0800 Subject: [PATCH 26/41] Editor: fix bug of executable searching --- src/detection/editor/editor.c | 28 +++++++++++++++++----------- src/util/path.c | 17 ++++++++++------- 2 files changed, 27 insertions(+), 18 deletions(-) diff --git a/src/detection/editor/editor.c b/src/detection/editor/editor.c index 6fd5258c5..9ae00eea8 100644 --- a/src/detection/editor/editor.c +++ b/src/detection/editor/editor.c @@ -1,5 +1,6 @@ #include "editor.h" #include "common/processing.h" +#include "common/library.h" #include "util/stringUtils.h" #include "util/path.h" #include "util/binary.h" @@ -13,7 +14,7 @@ static inline char* realpath(const char* restrict file_name, char* restrict reso } #endif -static bool extractNvimVersion(const char* str, uint32_t len, void* userdata) +static bool extractNvimVersionFromBinary(const char* str, uint32_t len, void* userdata) { if (len < strlen("NVIM v0.0.0")) return true; if (!ffStrStartsWith(str, "NVIM v")) return true; @@ -21,7 +22,7 @@ static bool extractNvimVersion(const char* str, uint32_t len, void* userdata) return false; } -static bool extractVimVersion(const char* str, uint32_t len, void* userdata) +static bool extractVimVersionFromBinary(const char* str, uint32_t len, void* userdata) { if (len < strlen("VIM - Vi IMproved 0.0")) return true; if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true; @@ -30,7 +31,7 @@ static bool extractVimVersion(const char* str, uint32_t len, void* userdata) return false; } -static bool extractNanoVersion(const char* str, uint32_t len, void* userdata) +static bool extractNanoVersionFromBinary(const char* str, uint32_t len, void* userdata) { if (len < strlen("GNU nano 0.0")) return true; if (!ffStrStartsWith(str, "GNU nano ")) return true; @@ -60,13 +61,18 @@ const char* ffDetectEditor(FFEditorResult* result) if (error) return NULL; } - char buf[PATH_MAX + 1]; - if (!realpath(result->path.chars, buf)) - return NULL; + { + char buf[PATH_MAX + 1]; + if (!realpath(result->path.chars, buf)) + return NULL; - // WIN32: Should we handle scoop shim exe here? + // WIN32: Should we handle scoop shim exe here? - ffStrbufSetS(&result->path, buf); + #ifdef __linux__ + if (!ffStrEndsWith(buf, "/snap")) + #endif + ffStrbufSetS(&result->path, buf); + } { uint32_t index = ffStrbufLastIndexC(&result->path, @@ -91,11 +97,11 @@ const char* ffDetectEditor(FFEditorResult* result) if (!instance.config.general.detectVersion) return NULL; if (ffStrbufEqualS(&result->exe, "nvim")) - ffBinaryExtractStrings(buf, extractNvimVersion, &result->version); + ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version); else if (ffStrbufEqualS(&result->exe, "vim")) - ffBinaryExtractStrings(buf, extractVimVersion, &result->version); + ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version); else if (ffStrbufEqualS(&result->exe, "nano")) - ffBinaryExtractStrings(buf, extractNanoVersion, &result->version); + ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version); if (result->version.length > 0) return NULL; diff --git a/src/util/path.c b/src/util/path.c index e47cbe768..5a0b5964e 100644 --- a/src/util/path.c +++ b/src/util/path.c @@ -13,14 +13,17 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result) const bool appendExe = !ffStrEndsWithIgnCase(name, ".exe"); #endif - for (char* token = NULL; (token = strchr(path, - #ifdef _WIN32 - ';' - #else - ':' - #endif - )) != NULL; path = token + 1) + for (char* token = path; *token; path = token + 1) { + token = strchr(path, + #ifdef _WIN32 + ';' + #else + ':' + #endif + ); + if (!token) token = path + strlen(path); + ffStrbufSetNS(result, (uint32_t)(token - path), path); ffStrbufEnsureEndsWithC(result, #ifdef _WIN32 From 893b3a6bff589695740611ffa8781e261ec02f9b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Aug 2024 14:15:55 +0800 Subject: [PATCH 27/41] Fastfetch: don't enable locale for `LC_NUMERIC` Ref: #1206 --- src/common/init.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/common/init.c b/src/common/init.c index b4d5c1721..5ac6abf6b 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -54,7 +54,6 @@ void ffInitInstance(void) #else // Never use `setlocale(LC_ALL, "")` setlocale(LC_TIME, ""); - setlocale(LC_NUMERIC, ""); #ifdef LC_MESSAGES setlocale(LC_MESSAGES, ""); #endif From f22b8ede0297d5d028b1a0c1d2635307e13cf37b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Aug 2024 15:52:14 +0800 Subject: [PATCH 28/41] TerminalShell: ignore the parent process if `$FFTS_IGNORE_PARENT` is set to `1` Fix #1205 --- src/detection/terminalshell/terminalshell_linux.c | 8 ++++++++ src/detection/terminalshell/terminalshell_windows.c | 4 ++++ 2 files changed, 12 insertions(+) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 30e131904..18be4f3b8 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -384,6 +384,14 @@ const FFShellResult* ffDetectShell() result.tty = -1; pid_t ppid = getppid(); + + const char* ignoreParent = getenv("FFTS_IGNORE_PARENT"); + if (ignoreParent && ffStrEquals(ignoreParent, "1")) + { + FF_STRBUF_AUTO_DESTROY _ = ffStrbufCreate(); + ffProcessGetBasicInfoLinux(ppid, &_, &ppid, NULL); + } + ppid = getShellInfo(&result, ppid); getUserShellFromEnv(&result); setShellInfoDetails(&result); diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index f1e27d63e..f2ff3b1cd 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -345,6 +345,10 @@ const FFShellResult* ffDetectShell(void) if(!ffProcessGetInfoWindows(0, &ppid, NULL, NULL, NULL, NULL, NULL)) return &result; + const char* ignoreParent = getenv("FFTS_IGNORE_PARENT"); + if (ignoreParent && ffStrEquals(ignoreParent, "1")) + ffProcessGetInfoWindows(ppid, &ppid, NULL, NULL, NULL, NULL, NULL); + ppid = getShellInfo(&result, ppid); if (result.processName.length > 0) From b5695b50c2765f557b70fab88a400baea4678ac4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Aug 2024 16:03:52 +0800 Subject: [PATCH 29/41] CPU (Linux): add code name of Apple M4 --- src/detection/cpu/cpu.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/cpu/cpu.c b/src/detection/cpu/cpu.c index 68d23ac88..dc27da241 100644 --- a/src/detection/cpu/cpu.c +++ b/src/detection/cpu/cpu.c @@ -36,6 +36,7 @@ const char* ffCPUAppleCodeToName(uint32_t code) case 6030: return "Apple M3 Pro"; case 6031: case 6034: return "Apple M3 Max"; + case 8132: return "Apple M4"; default: return "Apple Silicon"; } } From df873a19e105436c8672266bd24d19ceaf13b56e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 23 Aug 2024 16:07:58 +0800 Subject: [PATCH 30/41] CPU (Windows): fix compiling errors --- src/detection/terminalshell/terminalshell_windows.c | 1 + 1 file changed, 1 insertion(+) diff --git a/src/detection/terminalshell/terminalshell_windows.c b/src/detection/terminalshell/terminalshell_windows.c index f2ff3b1cd..ecac82e1f 100644 --- a/src/detection/terminalshell/terminalshell_windows.c +++ b/src/detection/terminalshell/terminalshell_windows.c @@ -5,6 +5,7 @@ #include "util/mallocHelper.h" #include "util/windows/registry.h" #include "util/windows/unicode.h" +#include "util/stringUtils.h" #include #include From a54cbee79aa19dad7b51fa9059827d42a4d75384 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Aug 2024 00:24:50 +0800 Subject: [PATCH 31/41] Locale: remove usage of LC_MESSAGE --- src/common/init.c | 3 --- src/detection/locale/locale_linux.c | 10 ---------- 2 files changed, 13 deletions(-) diff --git a/src/common/init.c b/src/common/init.c index 5ac6abf6b..2da9f3027 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -54,9 +54,6 @@ void ffInitInstance(void) #else // Never use `setlocale(LC_ALL, "")` setlocale(LC_TIME, ""); - #ifdef LC_MESSAGES - setlocale(LC_MESSAGES, ""); - #endif #endif initState(&instance.state); diff --git a/src/detection/locale/locale_linux.c b/src/detection/locale/locale_linux.c index 4b5123059..34c1fb52f 100644 --- a/src/detection/locale/locale_linux.c +++ b/src/detection/locale/locale_linux.c @@ -8,19 +8,9 @@ void ffDetectLocale(FFstrbuf* result) if(result->length > 0) return; - ffStrbufAppendS(result, getenv("LC_MESSAGES")); - if(result->length > 0) - return; - ffStrbufAppendS(result, getenv("LANG")); if(result->length > 0) return; - #ifdef LC_MESSAGES - ffStrbufAppendS(result, setlocale(LC_MESSAGES, NULL)); - if(result->length > 0) - return; - #endif - ffStrbufAppendS(result, setlocale(LC_TIME, NULL)); } From 34bc66206535f6a2485ae2e95b345d86ddaf6ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Aug 2024 09:47:13 +0800 Subject: [PATCH 32/41] LocalIP: detect ethernet speed --- src/detection/localip/localip.h | 1 + src/detection/localip/localip_linux.c | 386 ++++++++++++++++++++++++ src/detection/localip/localip_windows.c | 7 +- src/modules/localip/localip.c | 1 + 4 files changed, 394 insertions(+), 1 deletion(-) diff --git a/src/detection/localip/localip.h b/src/detection/localip/localip.h index 4b4162604..859d5340f 100644 --- a/src/detection/localip/localip.h +++ b/src/detection/localip/localip.h @@ -9,6 +9,7 @@ typedef struct FFLocalIpResult FFstrbuf ipv6; FFstrbuf mac; int32_t mtu; + int32_t speed; bool defaultRoute; } FFLocalIpResult; diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 9939bbcd2..1dcaf02a5 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -12,7 +12,13 @@ #include #include +#ifdef __linux__ +#include +#include +#endif + #if defined(__FreeBSD__) || defined(__APPLE__) +#include #include #else #include @@ -40,6 +46,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type, ffStrbufInit(&ip->mac); ip->defaultRoute = defaultRoute; ip->mtu = -1; + ip->speed = -1; } switch (type) @@ -172,9 +179,388 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* 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; + #ifdef __linux__ + struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET }; + ifr.ifr_data = (__caddr_t) &edata; + if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0) + iface->speed = (int32_t) ethtool_cmd_speed(&edata); + #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 + #ifdef __sun if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0) { diff --git a/src/detection/localip/localip_windows.c b/src/detection/localip/localip_windows.c index 8ac766660..c378100f9 100644 --- a/src/detection/localip/localip_windows.c +++ b/src/detection/localip/localip_windows.c @@ -18,6 +18,7 @@ static void addNewIp(FFlist* list, const char* name, const char* addr, int type, ffStrbufInit(&ip->ipv6); ffStrbufInit(&ip->mac); ip->defaultRoute = defaultRoute; + ip->speed = -1; ip->mtu = -1; } else @@ -150,7 +151,11 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) } if (!newIp) - FF_LIST_GET(FFLocalIpResult, *results, results->length - 1)->mtu = (int32_t) adapter->Mtu; + { + FFLocalIpResult* result = FF_LIST_GET(FFLocalIpResult, *results, results->length - 1); + result->speed = (int32_t) (adapter->ReceiveLinkSpeed / 1000); + result->mtu = (int32_t) adapter->Mtu; + } } return NULL; diff --git a/src/modules/localip/localip.c b/src/modules/localip/localip.c index 0238b82e6..318c241d5 100644 --- a/src/modules/localip/localip.c +++ b/src/modules/localip/localip.c @@ -376,6 +376,7 @@ void ffGenerateLocalIpJsonResult(FF_MAYBE_UNUSED FFLocalIpOptions* options, yyjs yyjson_mut_obj_add_strbuf(doc, obj, "mac", &ip->mac); yyjson_mut_obj_add_strbuf(doc, obj, "name", &ip->name); yyjson_mut_obj_add_int(doc, obj, "mtu", ip->mtu); + yyjson_mut_obj_add_int(doc, obj, "speed", ip->speed); } FF_LIST_FOR_EACH(FFLocalIpResult, ip, results) From c8d85e09d7b0bae7ff18d5d4a0126a67ee1c97ce Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sat, 24 Aug 2024 13:52:53 +0800 Subject: [PATCH 33/41] Editor (SunOS): enable libelf on SunOS --- CMakeLists.txt | 2 +- src/util/binary_linux.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 718062d06..0c2a97b06 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -69,7 +69,7 @@ cmake_dependent_option(ENABLE_FREETYPE "Enable freetype" ON "ANDROID" OFF) cmake_dependent_option(ENABLE_PULSE "Enable pulse" ON "LINUX OR SunOS" OFF) cmake_dependent_option(ENABLE_DDCUTIL "Enable ddcutil" ON "LINUX" OFF) cmake_dependent_option(ENABLE_DIRECTX_HEADERS "Enable DirectX headers for WSL" ON "LINUX" OFF) -cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR SunOS OR ANDROID" OFF) +cmake_dependent_option(ENABLE_ELF "Enable libelf" ON "LINUX OR FreeBSD OR ANDROID" OFF) cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF) option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF) diff --git a/src/util/binary_linux.c b/src/util/binary_linux.c index 24b6e0cab..11aa2a209 100644 --- a/src/util/binary_linux.c +++ b/src/util/binary_linux.c @@ -1,6 +1,6 @@ #include "binary.h" -#ifdef FF_HAVE_ELF +#if defined(FF_HAVE_ELF) || defined(__sun) #include "common/io/io.h" #include "common/library.h" From ce7ecd3863c10ae59c4ae3608f78e7cc434a9ff3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Aug 2024 14:47:15 +0800 Subject: [PATCH 34/41] LocalIP: make link speed formattable Fix #1209 --- src/detection/localip/localip_linux.c | 2 +- src/modules/localip/localip.c | 12 +++++++++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/detection/localip/localip_linux.c b/src/detection/localip/localip_linux.c index 1dcaf02a5..dda8b1ffd 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -185,7 +185,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) #ifdef __linux__ struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET }; - ifr.ifr_data = (__caddr_t) &edata; + ifr.ifr_data = (caddr_t) &edata; if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0) iface->speed = (int32_t) ethtool_cmd_speed(&edata); #elif __FreeBSD__ || __APPLE__ diff --git a/src/modules/localip/localip.c b/src/modules/localip/localip.c index 318c241d5..2a5db4914 100644 --- a/src/modules/localip/localip.c +++ b/src/modules/localip/localip.c @@ -5,7 +5,7 @@ #include "util/stringUtils.h" #define FF_LOCALIP_DISPLAY_NAME "Local IP" -#define FF_LOCALIP_NUM_FORMAT_ARGS 6 +#define FF_LOCALIP_NUM_FORMAT_ARGS 7 #pragma GCC diagnostic ignored "-Wsign-conversion" static int sortIps(const FFLocalIpResult* left, const FFLocalIpResult* right) @@ -111,6 +111,14 @@ void ffPrintLocalIp(FFLocalIpOptions* options) } else { + FF_STRBUF_AUTO_DESTROY speedStr = ffStrbufCreate(); + if (ip->speed > 0) + { + if (ip->speed >= 1000) + ffStrbufSetF(&speedStr, "%g Gbps", ip->speed / 1000.0); + else + ffStrbufSetF(&speedStr, "%u Mbps", (unsigned) ip->speed); + } FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_LOCALIP_NUM_FORMAT_ARGS, ((FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv4, "ipv4"}, {FF_FORMAT_ARG_TYPE_STRBUF, &ip->ipv6, "ipv6"}, @@ -118,6 +126,7 @@ void ffPrintLocalIp(FFLocalIpOptions* options) {FF_FORMAT_ARG_TYPE_STRBUF, &ip->name, "ifname"}, {FF_FORMAT_ARG_TYPE_BOOL, &ip->defaultRoute, "is-default-route"}, {FF_FORMAT_ARG_TYPE_INT, &ip->mtu, "mtu"}, + {FF_FORMAT_ARG_TYPE_STRBUF, &speedStr, "speed"}, })); } ++index; @@ -397,6 +406,7 @@ void ffPrintLocalIpHelpFormat(void) "Interface name - ifname", "Is default route - is-default-route", "MTU size in bytes - mtu", + "Link speed (formatted) - speed", })); } From e6fb545d1d0290f49658716a4d3a713e21dd7f9d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Aug 2024 15:21:12 +0800 Subject: [PATCH 35/41] LocalIP (Linux): try fixing musl build --- 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 dda8b1ffd..011c4e7ed 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -185,7 +185,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) #ifdef __linux__ struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET }; - ifr.ifr_data = (caddr_t) &edata; + ifr.ifr_data = (void*) &edata; if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0) iface->speed = (int32_t) ethtool_cmd_speed(&edata); #elif __FreeBSD__ || __APPLE__ From f6ccbf7711ccaedc5cb6a5e5e0af63b0c784e52a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Aug 2024 17:34:41 +0800 Subject: [PATCH 36/41] LocalIP (Android): fix build --- 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 011c4e7ed..bdd91ac09 100644 --- a/src/detection/localip/localip_linux.c +++ b/src/detection/localip/localip_linux.c @@ -187,7 +187,7 @@ const char* ffDetectLocalIps(const FFLocalIpOptions* options, FFlist* results) struct ethtool_cmd edata = { .cmd = ETHTOOL_GSET }; ifr.ifr_data = (void*) &edata; if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0) - iface->speed = (int32_t) ethtool_cmd_speed(&edata); + 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); From 788cad3cbe4262e022774becf36f0df2847abf46 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 24 Aug 2024 18:00:49 +0800 Subject: [PATCH 37/41] DiskIO (Linux): fix possible segfault --- src/detection/diskio/diskio_linux.c | 29 +++++++++++++---------------- 1 file changed, 13 insertions(+), 16 deletions(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index f34345da9..456ff39d5 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -37,24 +37,23 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY)) continue; - FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); - ffStrbufInit(&device->name); + FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate(); { snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName); - if (ffAppendFileBuffer(pathSysBlock, &device->name)) + if (ffAppendFileBuffer(pathSysBlock, &name)) { - ffStrbufTrimRightSpace(&device->name); - if (device->name.length > 0) - ffStrbufAppendC(&device->name, ' '); + ffStrbufTrimRightSpace(&name); + if (name.length > 0) + ffStrbufAppendC(&name, ' '); } snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName); - ffAppendFileBuffer(pathSysBlock, &device->name); - ffStrbufTrimRightSpace(&device->name); + ffAppendFileBuffer(pathSysBlock, &name); + ffStrbufTrimRightSpace(&name); - if (device->name.length == 0) - ffStrbufSetS(&device->name, devName); + if (name.length == 0) + ffStrbufSetS(&name, devName); else if (ffStrStartsWith(devName, "nvme")) { int devid, nsid; @@ -69,17 +68,13 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) if (multiNs) { // In Asahi Linux, there are multiple namespaces for the same NVMe drive. - ffStrbufAppendF(&device->name, " - %d", nsid); + ffStrbufAppendF(&name, " - %d", nsid); } } } - if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) - { - ffStrbufDestroy(&device->name); - result->length--; + if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) continue; - } } // I/Os merges sectors ticks ... @@ -94,6 +89,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; } + FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); + ffStrbufInitMove(&device->name, &name); ffStrbufInitF(&device->devPath, "/dev/%s", devName); device->bytesRead = sectorRead * 512; device->bytesWritten = sectorWritten * 512; From d15d4c621cd866bd846eb311e43b84d99bb57276 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 25 Aug 2024 18:29:57 +0800 Subject: [PATCH 38/41] Display: honor `preciseRefreshRate` in custom format Fix #1211 --- src/modules/display/display.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/src/modules/display/display.c b/src/modules/display/display.c index 8d73a67ce..c180d338a 100644 --- a/src/modules/display/display.c +++ b/src/modules/display/display.c @@ -140,10 +140,21 @@ void ffPrintDisplay(FFDisplayOptions* options) { double ppi = sqrt(result->width * result->width + result->height * result->height) / inch; + char refreshRate[16]; + if(result->refreshRate > 0) + { + if(options->preciseRefreshRate) + snprintf(refreshRate, sizeof(refreshRate), "%g", ((int) (result->refreshRate * 1000 + 0.5)) / 1000.0); + else + snprintf(refreshRate, sizeof(refreshRate), "%i", (uint32_t) (result->refreshRate + 0.5)); + } + else + refreshRate[0] = 0; + FF_PRINT_FORMAT_CHECKED(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISPLAY_NUM_FORMAT_ARGS, ((FFformatarg[]) { {FF_FORMAT_ARG_TYPE_UINT, &result->width, "width"}, {FF_FORMAT_ARG_TYPE_UINT, &result->height, "height"}, - {FF_FORMAT_ARG_TYPE_DOUBLE, &result->refreshRate, "refresh-rate"}, + {FF_FORMAT_ARG_TYPE_STRING, refreshRate, "refresh-rate"}, {FF_FORMAT_ARG_TYPE_UINT, &result->scaledWidth, "scaled-width"}, {FF_FORMAT_ARG_TYPE_UINT, &result->scaledHeight, "scaled-height"}, {FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"}, From 773b8db337e43cfedcbcd9d67f95e17d49bbe3e5 Mon Sep 17 00:00:00 2001 From: "Md. Iftakhar Awal Chowdhury" <42291930+AtifChy@users.noreply.github.com> Date: Sun, 25 Aug 2024 19:58:47 +0600 Subject: [PATCH 39/41] Completion: add zsh-completion (#1213) * feat: add zsh-completion * zsh completion: added missing custom options * cmake: update CMakeList.txt to install zsh completion * Update CMakeLists.txt --------- Co-authored-by: Carter Li --- CMakeLists.txt | 6 +++ completions/fastfetch.zsh | 97 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 103 insertions(+) create mode 100644 completions/fastfetch.zsh diff --git a/CMakeLists.txt b/CMakeLists.txt index 0c2a97b06..5b00f8987 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1337,6 +1337,12 @@ install( RENAME "${CMAKE_PROJECT_NAME}" ) +install( + FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.zsh" + DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/zsh/site-functions" + RENAME "_${CMAKE_PROJECT_NAME}" +) + install( FILES "${CMAKE_SOURCE_DIR}/completions/${CMAKE_PROJECT_NAME}.fish" DESTINATION "${CMAKE_INSTALL_DATAROOTDIR}/fish/vendor_completions.d" diff --git a/completions/fastfetch.zsh b/completions/fastfetch.zsh new file mode 100644 index 000000000..924e4a338 --- /dev/null +++ b/completions/fastfetch.zsh @@ -0,0 +1,97 @@ +#compdef fastfetch + +function _fastfetch() { + local state + + local -a opts + opts=(${(f)"$( + python <modules") + elif type == "config": + print(f"{command_prefix}:presets:->presets") + elif type == "enum": + temp: str = " ".join(flag["arg"]["enum"]) + print(f'{command_prefix}:type:( {temp} )') + elif type == "logo": + print(f"{command_prefix}:logo:->logo") + elif type == "structure": + print(f"{command_prefix}:structure:->structure") + elif type == "path": + print(f"{command_prefix}:path:_files -/") + else: + print(f"{command_prefix}:") + else: + print(f"{command_prefix}") + + +if __name__ == "__main__": + try: + main() + except Exception: + sys.exit(1) +EOF + )"}) + + _arguments -C "$opts[@]" + + case $state in + modules) + local -a modules=( ${(f)"$(fastfetch --list-modules autocompletion)"} ) + modules=( ${(L)^modules%%:*}-format format color ) + _describe 'module' modules + ;; + presets) + local -a presets=( + ${$(fastfetch --list-presets autocompletion):#.*} + "none:Disable loading config file" + ) + _describe 'preset' presets + ;; + structure) + local -a structures=( ${(f)"$(fastfetch --list-modules autocompletion)"} ) + _describe 'structure' structures + ;; + logo) + local -a logos=( + $(fastfetch --list-logos autocompletion) + "none:Don't print logo" + "small:Print small ascii logo if available" + ) + _describe 'logo' logos + ;; + esac +} + +_fastfetch "$@" From 5b78b2e8973810d087daebb999eb6732f01ec31d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Amaro=20Mart=C3=ADnez?= Date: Sun, 25 Aug 2024 20:19:14 -0500 Subject: [PATCH 40/41] Packages (Linux): add Linglong support (#1214) Support for counting Linglong applications installed in Deepin, Ubuntu and Debian distros. Packages are installed using the ``ll-cli`` package manager frontend: https://linglong.dev/guide/ll-cli/introduction.html#ll-cli%E7%AE%80%E4%BB%8B --------- Co-authored-by: Carter Li --- src/detection/packages/packages.h | 1 + src/detection/packages/packages_linux.c | 1 + src/modules/packages/option.h | 1 + src/modules/packages/packages.c | 11 +++++++++-- 4 files changed, 12 insertions(+), 2 deletions(-) diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index fd0cbec0f..feffb0cea 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -17,6 +17,7 @@ typedef struct FFPackagesResult uint32_t guixHome; uint32_t guixSystem; uint32_t guixUser; + uint32_t linglong; uint32_t lpkg; uint32_t lpkgbuild; uint32_t nixDefault; diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 5af0226a3..ab07ff07b 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -471,6 +471,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, { packageCounts->guixSystem += getGuixPackages(baseDir, "/run/current-system/profile"); } + if (!(options->disabled & FF_PACKAGES_FLAG_LINGLONG_BIT)) packageCounts->linglong += getNumElements(baseDir, "/var/lib/linglong/repo/refs/heads/main", DT_DIR); } static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* packageCounts, FFPackagesOptions* options) diff --git a/src/modules/packages/option.h b/src/modules/packages/option.h index 2456ce85a..de28caa33 100644 --- a/src/modules/packages/option.h +++ b/src/modules/packages/option.h @@ -31,6 +31,7 @@ typedef enum FFPackagesFlags FF_PACKAGES_FLAG_LPKG_BIT = 1 << 21, FF_PACKAGES_FLAG_LPKGBUILD_BIT = 1 << 22, FF_PACKAGES_FLAG_GUIX_BIT = 1 << 23, + FF_PACKAGES_FLAG_LINGLONG_BIT = 1 << 24, } FFPackagesFlags; typedef struct FFPackagesOptions diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index 175a365ab..8593a9f46 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -4,7 +4,7 @@ #include "modules/packages/packages.h" #include "util/stringUtils.h" -#define FF_PACKAGES_NUM_FORMAT_ARGS 36 +#define FF_PACKAGES_NUM_FORMAT_ARGS 37 void ffPrintPackages(FFPackagesOptions* options) { @@ -71,6 +71,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE_NAME(guixSystem, "guix-system") FF_PRINT_PACKAGE_NAME(guixUser, "guix-user") FF_PRINT_PACKAGE_NAME(guixHome, "guix-home") + FF_PRINT_PACKAGE(linglong) putchar('\n'); } @@ -113,6 +114,7 @@ void ffPrintPackages(FFPackagesOptions* options) {FF_FORMAT_ARG_TYPE_UINT, &counts.guixSystem, "guix-system"}, {FF_FORMAT_ARG_TYPE_UINT, &counts.guixUser, "guix-user"}, {FF_FORMAT_ARG_TYPE_UINT, &counts.guixHome, "guix-home"}, + {FF_FORMAT_ARG_TYPE_UINT, &counts.linglong, "linglong"}, {FF_FORMAT_ARG_TYPE_UINT, &nixAll, "nix-all"}, {FF_FORMAT_ARG_TYPE_UINT, &flatpakAll, "flatpak-all"}, {FF_FORMAT_ARG_TYPE_UINT, &brewAll, "brew-all"}, @@ -171,6 +173,7 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key, case 'L': if (false); FF_TEST_PACKAGE_NAME(LPKG) FF_TEST_PACKAGE_NAME(LPKGBUILD) + FF_TEST_PACKAGE_NAME(LINGLONG) break; case 'M': if (false); FF_TEST_PACKAGE_NAME(MACPORTS) @@ -279,6 +282,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module) case 'L': if (false); FF_TEST_PACKAGE_NAME(LPKG) FF_TEST_PACKAGE_NAME(LPKGBUILD) + FF_TEST_PACKAGE_NAME(LINGLONG) break; case 'M': if (false); FF_TEST_PACKAGE_NAME(MACPORTS) @@ -356,6 +360,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do 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 } } @@ -406,12 +411,13 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy FF_APPEND_PACKAGE_COUNT(guixSystem) FF_APPEND_PACKAGE_COUNT(guixUser) FF_APPEND_PACKAGE_COUNT(guixHome) + FF_APPEND_PACKAGE_COUNT(linglong) yyjson_mut_obj_add_strbuf(doc, obj, "pacmanBranch", &counts.pacmanBranch); } void ffPrintPackagesHelpFormat(void) { - FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_PACKAGES_MODULE_NAME, "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (MacPorts), {20} (scoop), {21} (choco), {22} (pkgtool), {23} (paludis), {24} (winget), {25} (opkg), {26} (am), {27} (sorcery), {28} (lpkg), {29} (lpkgbuild), {30} (guix-system), {31} (guix-user), {32} (guix-home)", FF_PACKAGES_NUM_FORMAT_ARGS, ((const char* []) { + FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_PACKAGES_MODULE_NAME, "{2} (pacman){?3}[{3}]{?}, {4} (dpkg), {5} (rpm), {6} (emerge), {7} (eopkg), {8} (xbps), {9} (nix-system), {10} (nix-user), {11} (nix-default), {12} (apk), {13} (pkg), {14} (flatpak-system), {15} (flatpack-user), {16} (snap), {17} (brew), {18} (brew-cask), {19} (MacPorts), {20} (scoop), {21} (choco), {22} (pkgtool), {23} (paludis), {24} (winget), {25} (opkg), {26} (am), {27} (sorcery), {28} (lpkg), {29} (lpkgbuild), {30} (guix-system), {31} (guix-user), {32} (guix-home), {33} (linglong)", FF_PACKAGES_NUM_FORMAT_ARGS, ((const char* []) { "Number of all packages - all", "Number of pacman packages - pacman", "Pacman branch on manjaro - pacman-branch", @@ -444,6 +450,7 @@ void ffPrintPackagesHelpFormat(void) "Number of guix-system packages - guix-system", "Number of guix-user packages - guix-user", "Number of guix-home packages - guix-home", + "Number of linglong packages - linglong", "Total number of all nix packages - nix-all", "Total number of all flatpak app packages - flatpak-all", "Total number of all brew packages - brew-all", From 11cfdba5cbadc53f36fbd26be993929e39462c72 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 26 Aug 2024 09:47:31 +0800 Subject: [PATCH 41/41] Release: v2.22.0 --- CHANGELOG.md | 24 ++++++++++++++++++++++++ CMakeLists.txt | 2 +- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index faf5354d6..e57c6d662 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,27 @@ +# 2.22.0 + +Features: +* Small performance improvements (Terminal, Editor) +* Improve arm32 and loongarch support (CPU, Linux) +* Ignore the parent process if env `$FFTS_IGNORE_PARENT` is set to `1` (Shell) +* Add code name of Apple M4 (CPU, Linux) +* Add ethernet speed rate detection support (LocalIP) +* Add zsh completion script +* Add Linglong package manager detection support (Packages, Linux) + +Bugfixes: +* Fix building on macOS 10.14 +* Fix tmux in linux TTY (Colors) +* Fix hang in WSL when custom format is used (Disk, Linux) +* Fix `/proc/loadavg` parsing (Loadavg, Linux) +* Disable use of `LC_NUMERIC` locale settings to fix parsing of decimal numbers +* Fix possible segfault (DiskIO, Linux) +* Honor `preciseRefreshRate` in custom format (Display) + +Logos: +* Add Lingmo OS +* Add Sleeper OS + # 2.21.3 Bugfixes: diff --git a/CMakeLists.txt b/CMakeLists.txt index 5b00f8987..1abe943d2 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.21.3 + VERSION 2.22.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"