Compare commits

...

76 Commits

Author SHA1 Message Date
Carter Li 636126c57d Merge pull request #1239 from fastfetch-cli/dev
Release: v2.23.0
2024-09-03 10:34:07 +08:00
李通洲 2e475d590f JsonSchema: update zpool 2024-09-03 10:08:23 +08:00
李通洲 0cf45c1dcd Release: v2.23.0 2024-09-03 09:31:25 +08:00
李通洲 435516373d Logo (Image): better Windows support 2024-09-02 20:57:47 +08:00
李通洲 64735245e7 Presets: use string padding syntax
Fix #1237
2024-09-02 16:02:05 +08:00
李通洲 85d89395a9 Format: support syntax of padded string
Ref: #1237
2024-09-02 16:01:25 +08:00
李通洲 093940e504 Logo (Builtin): add Huawei Cloud EulerOS
Fix #1236
2024-09-02 09:36:57 +08:00
李通洲 e427a5112b Logo (Builtin): add small Steam Deck
Fix #1232
2024-09-02 09:31:14 +08:00
李通洲 1ab86a8ab9 TerminalTheme: fix hanging on screen 5.0 2024-09-02 09:26:54 +08:00
李通洲 99e0dc9aaa Zpool: don't break -DBINARY_LINK_TYPE=dynamic
Fix #1233
2024-08-31 12:44:35 +08:00
Carter Li 73e9db5b6e Zpool (SunOS): fix the dlsym error 2024-08-31 12:43:03 +08:00
Linus adc03bd792 Logo (Builtin): Add Steam Deck Logo (#1229)
* Logo (Builtin): Add Steam Deck Logo

* accidentally removed newline after steam deck oled block

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-30 22:06:10 +08:00
李通洲 10fdc8e4a7 Logo (Builtin): make ubuntu logo colorable 2024-08-30 12:13:33 +08:00
李通洲 d75803794e Terminal: improve performance of xfce4-terminal version 2024-08-30 12:13:33 +08:00
AIT MEDDOUR Fouad-Eddine d25ac86283 Logo (Builtin): Add Magix (#1228)
* Add Magix (Correctly this time)

* Update magix.txt

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-30 11:24:50 +08:00
李通洲 de8bbc9a5c Camera (FreeBSD): fix module was incorrectly disabled (v2) 2024-08-29 15:57:05 +08:00
Md. Iftakhar Awal Chowdhury 66977de5c7 Completion (Zsh): add completion for --logo-color-{1..9} (#1222) 2024-08-29 15:55:12 +08:00
李通洲 f828d3a9b9 Camera (FreeBSD): fix module was incorrectly disabled 2024-08-28 21:33:17 +08:00
李通洲 f0bc08e006 CI: run all modules on FreeBSD and SunOS 2024-08-28 21:14:54 +08:00
李通洲 e0f8e39a47 CI: add zpool 2024-08-28 20:56:59 +08:00
李通洲 8b9f787095 Zpool: fix build on SunOS 2024-08-28 20:56:23 +08:00
Carter Li d946cf27fe Zpool: add new module 2024-08-28 16:45:26 +08:00
Carter Li 5842ad1d56 Battery: print model name in key 2024-08-28 16:00:06 +08:00
Md. Iftakhar Awal Chowdhury 201047251d Completion: add optional completion support for certain flags (#1219) 2024-08-28 10:18:38 +08:00
李通洲 5c8e771939 Binary (Linux): fix building without libelf enabled 2024-08-28 09:41:08 +08:00
李通洲 b22e28b548 NetIO: don't print * if defaultRouteOnly is set 2024-08-27 21:36:57 +08:00
李通洲 8c51836a47 Logo (Builtin): update amogos 2024-08-27 21:18:25 +08:00
李通洲 df729938c5 Binary: improve performance 2024-08-27 16:41:23 +08:00
Carter Li 67d0dfcef0 DE (Linux): support unity version detection 2024-08-27 14:31:05 +08:00
李通洲 03c95e5cad Shell: improve performance of bash and zsh version detection 2024-08-27 14:06:45 +08:00
Md. Iftakhar Awal Chowdhury c0a07002f2 Completion: update zsh-completion to reflect latest upstream changes (#1217) 2024-08-26 17:39:49 +08:00
李通洲 5a9c3154fa IO (Unix): fix isDir condition checking; skip hidden files
Fix #1216
2024-08-26 16:10:44 +08:00
Carter Li e35aed761b Packaging: update debian stuff [ci skip] 2024-08-26 10:58:52 +08:00
Carter Li 823f2ef028 Merge pull request #1215 from fastfetch-cli/dev
Release: v2.22.0
2024-08-26 10:41:25 +08:00
李通洲 11cfdba5cb Release: v2.22.0 2024-08-26 09:47:31 +08:00
Amaro Martínez 5b78b2e897 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 <CarterLi@users.noreply.github.com>
2024-08-26 09:19:14 +08:00
Md. Iftakhar Awal Chowdhury 773b8db337 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 <CarterLi@users.noreply.github.com>
2024-08-25 21:58:47 +08:00
Carter Li d15d4c621c Display: honor preciseRefreshRate in custom format
Fix #1211
2024-08-25 18:29:57 +08:00
李通洲 788cad3cbe DiskIO (Linux): fix possible segfault 2024-08-24 18:00:49 +08:00
李通洲 f6ccbf7711 LocalIP (Android): fix build 2024-08-24 17:34:41 +08:00
李通洲 e6fb545d1d LocalIP (Linux): try fixing musl build 2024-08-24 15:21:12 +08:00
李通洲 ce7ecd3863 LocalIP: make link speed formattable
Fix #1209
2024-08-24 14:47:15 +08:00
Carter Li c8d85e09d7 Editor (SunOS): enable libelf on SunOS 2024-08-24 13:52:53 +08:00
李通洲 34bc662065 LocalIP: detect ethernet speed 2024-08-24 13:34:20 +08:00
李通洲 a54cbee79a Locale: remove usage of LC_MESSAGE 2024-08-24 09:47:50 +08:00
李通洲 df873a19e1 CPU (Windows): fix compiling errors 2024-08-23 16:34:56 +08:00
李通洲 b5695b50c2 CPU (Linux): add code name of Apple M4 2024-08-23 16:03:52 +08:00
李通洲 f22b8ede02 TerminalShell: ignore the parent process if $FFTS_IGNORE_PARENT is set to 1
Fix #1205
2024-08-23 15:52:14 +08:00
李通洲 893b3a6bff Fastfetch: don't enable locale for LC_NUMERIC
Ref: #1206
2024-08-23 14:15:55 +08:00
李通洲 e199a2fb79 Editor: fix bug of executable searching 2024-08-23 13:51:45 +08:00
李通洲 b4aac9d7d7 Binary: support Windows 2024-08-23 00:07:57 +08:00
李通洲 cf9bd0f373 Loadavg (Linux): read /proc/loadavg instead of /proc/uptime
Fix #1206
2024-08-22 23:37:04 +08:00
Carter Li 17deaf963e CPU (Linux): make "Hardware :" arm specific 2024-08-22 09:29:26 +08:00
Carter Li e66a83a4cf Version: support loongarch 2024-08-22 09:17:03 +08:00
Carter Li 96905012a4 CPU (Linux): support loongarch
Fix #1204
2024-08-22 09:16:44 +08:00
Carter Li 591dba8829 CPU (Linux): don't parse unnecessary lines on certain platforms 2024-08-21 16:42:40 +08:00
李通洲 d10dd2095a CPU (Android): try support old armv7 smart phone
Fix #1202
2024-08-21 16:40:40 +08:00
李通洲 22e25d0c78 Binary: support macOS 2024-08-21 15:33:14 +08:00
李通洲 1c8375908c Presets: update examples/23.jsonc
Close #1200
2024-08-21 00:24:12 +08:00
李通洲 099a390f2f Disk (Linux): fix hang in WSL when custom format is used 2024-08-21 00:23:24 +08:00
李通洲 dd2d343630 Global: fix build on Windows 2024-08-20 23:52:29 +08:00
李通洲 543eed9a53 Logo (Builtin): add SleeperOS_small 2024-08-20 23:36:36 +08:00
李通洲 4860bc35d6 Editor: improve performance of version detection 2024-08-20 20:30:22 +08:00
李通洲 8559ab2dcd Colors (Linux): support tmux in linux TTY 2024-08-20 16:36:44 +08:00
Princess-Sunset-Shimmer 811485661f Logo (Builtin): Sleeper OS zzzZZZ (#1199)
* Create sleeperos.txt

* Update builtin.c

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-20 16:01:34 +08:00
李通洲 31ead528f1 Doc: update readme [ci skip] 2024-08-20 14:33:00 +08:00
李通洲 8641442c3f CMake: fix build on Android 2024-08-20 14:32:53 +08:00
Carter Li 418902512d CPU: detect frequency by cpuid (x86 only)
Ref: https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
2024-08-18 19:24:24 +08:00
Carter Li fbfe2b2d1a CPU (Linux): tidy 2024-08-18 17:26:06 +08:00
李通洲 f71c4f6d5a TerminalShell (Linux): improve performance of GNOME Terminal version detection 2024-08-17 14:06:34 +08:00
Lingmo b46d9d8b8e Logo (Builtin): Add Lingmo OS Logo (#1192)
* Update builtin.c

* Create lingmo.txt

* Update lingmo.txt

* Update builtin.c

---------

Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2024-08-16 14:15:30 +08:00
Carter Li 9d27106964 Packaging: update debian stuff [ci skip] 2024-08-16 10:14:35 +08:00
AlbydS bbb873c27b 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 <CarterLi@users.noreply.github.com>
2024-08-15 23:07:45 +08:00
李通洲 da50a48dd5 Merge remote-tracking branch 'origin/master' into dev 2024-08-15 19:40:57 +08:00
李通洲 c8e4de9831 CPU (Linux): silence complier warnings 2024-08-15 19:40:39 +08:00
Carter Li e0d733f030 DisplayServer (macOS): fix building on ancient macOS version
Fix #1190
2024-08-15 19:01:33 +08:00
85 changed files with 2334 additions and 408 deletions
+4 -4
View File
@@ -388,8 +388,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch
time ./fastfetch --format json
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
@@ -426,8 +426,8 @@ jobs:
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
cmake --build . --target package --verbose -j4
./fastfetch --list-features
time ./fastfetch
time ./fastfetch --format json
time ./fastfetch -c presets/ci.jsonc --stat false
time ./fastfetch -c presets/ci.jsonc --format json
time ./flashfetch
ldd fastfetch
ctest
+52
View File
@@ -1,3 +1,55 @@
# 2.23.0
Features:
* Support unity version detection (DE, Linux)
* Print model name in Battery keys if available (Battery)
* Add module `Zpool`
* Improve performance (Shell / Terminal, Linux)
* Support syntax of padded strings in `--<module>-format`. `{variable<padlength}` and `{variable>padlength}` are supported.
* If pad length is greater than the length of the variable, the variable will be padded with spaces.
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1<20})'` prints `Command: output(12345 )`
* `fastfetch -l none -s command --command-text 'echo 12345' --command-format 'output({1>20})'` prints `Command: output( 12345)`
* If pad length is less than the length of the variable, the variable will be truncated.
Bugfixes:
* Fix broken `--list-presets`
* Update zsh completion script
* Don't print `*` if `defaultRouteOnly` is set (NetIO)
* Fix Camera module incorrectly disabled on FreeBSD (Camera, FreeBSD)
* Fix hanging on screen 5.0 (Terminal)
* Improve image logo support on Windows (Logo, Windows)
Logos:
* Update AmogOS
* Add Magix
* Make ubuntu logo colorable
* Add Steam Deck Logo
* add Huawei Cloud EulerOS
# 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:
+59 -6
View File
@@ -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.23.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -69,8 +69,9 @@ 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 ANDROID" OFF)
cmake_dependent_option(ENABLE_THREADS "Enable multithreading" ON "Threads_FOUND" OFF)
cmake_dependent_option(ENABLE_LIBZFS "Enable libzfs" ON "LINUX OR FreeBSD OR SunOS" OFF)
option(ENABLE_SYSTEM_YYJSON "Use system provided (instead of fastfetch embedded) yyjson library" OFF)
option(ENABLE_ASAN "Build fastfetch with ASAN (address sanitizer)" OFF)
@@ -392,6 +393,7 @@ set(LIBFASTFETCH_SRC
src/modules/wifi/wifi.c
src/modules/wm/wm.c
src/modules/wmtheme/wmtheme.c
src/modules/zpool/zpool.c
src/options/display.c
src/options/modules.c
src/options/logo.c
@@ -401,6 +403,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
)
@@ -480,8 +483,9 @@ if(LINUX)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/linux/elf.c
src/util/binary_linux.c
)
elseif(ANDROID)
list(APPEND LIBFASTFETCH_SRC
@@ -542,7 +546,9 @@ elseif(ANDROID)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_nosupport.c
src/detection/camera/camera_android.c
src/detection/zpool/zpool_nosupport.c
src/util/platform/FFPlatform_unix.c
src/util/binary_linux.c
)
elseif(FreeBSD)
list(APPEND LIBFASTFETCH_SRC
@@ -620,8 +626,9 @@ elseif(FreeBSD)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/linux/elf.c
src/util/binary_linux.c
)
elseif(APPLE)
list(APPEND LIBFASTFETCH_SRC
@@ -684,9 +691,11 @@ elseif(APPLE)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_apple.m
src/detection/camera/camera_apple.m
src/detection/zpool/zpool_nosupport.c
src/util/apple/cf_helpers.c
src/util/apple/osascript.m
src/util/platform/FFPlatform_unix.c
src/util/binary_apple.c
)
elseif(WIN32)
list(APPEND LIBFASTFETCH_SRC
@@ -747,12 +756,14 @@ elseif(WIN32)
src/detection/de/de_nosupport.c
src/detection/wmtheme/wmtheme_windows.c
src/detection/camera/camera_windows.cpp
src/detection/zpool/zpool_nosupport.c
src/util/windows/getline.c
src/util/windows/com.cpp
src/util/windows/registry.c
src/util/windows/unicode.c
src/util/windows/wmi.cpp
src/util/platform/FFPlatform_windows.c
src/util/binary_windows.c
)
elseif(SunOS)
list(APPEND LIBFASTFETCH_SRC
@@ -828,8 +839,9 @@ elseif(SunOS)
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_nosupport.c
src/detection/zpool/zpool_linux.c
src/util/platform/FFPlatform_unix.c
src/util/linux/elf.c
src/util/binary_linux.c
)
endif()
@@ -1087,6 +1099,25 @@ ff_lib_enable(DIRECTX_HEADERS
"DirectX-Headers"
"DirectX-Headers"
)
# The system <libzfs.h> is only usable on SunOS. We provide our local copy of it so it's always available.
if(ENABLE_LIBZFS)
if(BINARY_LINK_TYPE STREQUAL "dlopen")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
else()
set(CMAKE_REQUIRED_LIBRARIES_BACKUP ${CMAKE_REQUIRED_LIBRARIES})
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} zfs)
check_function_exists("libzfs_init" LIBZFS_FOUND)
set(CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES_BACKUP})
if(NOT LIBZFS_FOUND)
message(STATUS "Library: missing: LIBZFS")
else()
message(STATUS "Library: found LIBZFS")
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LIBZFS=1)
target_link_libraries(libfastfetch PRIVATE zfs)
endif()
endif()
endif()
if(ENABLE_THREADS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_THREADS)
@@ -1135,6 +1166,7 @@ elseif(WIN32)
PRIVATE "setupapi"
PRIVATE "hid"
PRIVATE "wtsapi32"
PRIVATE "imagehlp"
)
elseif(FreeBSD)
target_link_libraries(libfastfetch
@@ -1148,6 +1180,8 @@ elseif(SunOS)
PRIVATE "socket"
PRIVATE "kstat"
PRIVATE "proc"
PRIVATE "zfs"
PRIVATE "nvpair"
)
elseif(ANDROID)
CHECK_LIBRARY_EXISTS(-l:libandroid-wordexp.a wordexp "" HAVE_LIBANDROID_WORDEXP_STATIC)
@@ -1191,11 +1225,16 @@ if(WIN32)
endif()
set(CMAKE_CXX_STANDARD 17)
endif()
if(LINUX)
if(FreeBSD)
set(CMAKE_REQUIRED_INCLUDES "/usr/local/include" "/usr/include")
endif()
if(LINUX OR FreeBSD)
CHECK_INCLUDE_FILE("linux/videodev2.h" HAVE_LINUX_VIDEODEV2)
if(HAVE_LINUX_VIDEODEV2)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_VIDEODEV2=1)
endif()
endif()
if(LINUX)
CHECK_INCLUDE_FILE("linux/wireless.h" HAVE_LINUX_WIRELESS)
if(HAVE_LINUX_WIRELESS)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_LINUX_WIRELESS=1)
@@ -1303,9 +1342,17 @@ if (BUILD_TESTS)
PRIVATE libfastfetch
)
add_executable(fastfetch-test-format
tests/format.c
)
target_link_libraries(fastfetch-test-format
PRIVATE libfastfetch
)
enable_testing()
add_test(NAME test-strbuf COMMAND fastfetch-test-strbuf)
add_test(NAME test-list COMMAND fastfetch-test-list)
add_test(NAME test-format COMMAND fastfetch-test-format)
endif()
##################
@@ -1332,6 +1379,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"
+15 -8
View File
@@ -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-<proper architecture>.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,8 +60,9 @@ 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-<subsystem>-<arch>-fastfetch`
* [MSYS2 MinGW](https://packages.msys2.org/base/mingw-w64-fastfetch): `pacman -S mingw-w64-<subsystem>-<arch>-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.
+106
View File
@@ -0,0 +1,106 @@
#compdef fastfetch
function _fastfetch() {
local state
local -a opts=("${(f)$(
python3 <<EOF
import json
import subprocess
import sys
def main():
data: dict[str, list[dict]] = json.loads(
subprocess.check_output(["fastfetch", "--help-raw"])
)
for key in data:
for flag in data[key]:
if flag["long"] == "logo-color-[1-9]":
for i in range(1, 10):
command_prefix = f"--logo-color-{i}[{flag["desc"]} ({i})]"
print_command(command_prefix, flag)
continue
if flag.get("pseudo", False):
continue
if "short" in flag:
command_prefix = f"-{flag["short"]}[{flag["desc"]}]"
print_command(command_prefix, flag)
if "long" in flag:
command_prefix = f"--{flag["long"]}[{flag["desc"]}]"
print_command(command_prefix, flag)
def print_command(command_prefix: str, flag: dict):
if "arg" in flag:
type: str = flag["arg"]["type"]
if type == "bool":
print(f"{command_prefix}::bool:(true false)")
elif type == "color":
print(f"{command_prefix}:color:->colors")
elif type == "command":
print(f"{command_prefix}::module:->modules")
elif type == "config":
print(f"{command_prefix}:preset:->presets")
elif type == "enum":
temp: str = " ".join(flag["arg"]["enum"])
print(f'{command_prefix}:type:({temp})')
elif type == "logo":
print(f"{command_prefix}:logo:->logos")
elif type == "structure":
print(f"{command_prefix}:structure:->structures")
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 "$opts[@]"
case $state in
colors)
local -a colors=(black red green yellow blue magenta cyan white default)
_describe 'color' colors
;;
modules)
local -a modules=("${(f)$(fastfetch --list-modules autocompletion)}")
modules=(${(L)^modules[@]%%:*}-format format color)
_describe 'module' modules
;;
presets)
local -a presets=(
"${(f)$(fastfetch --list-presets autocompletion)}"
"none:Disable loading config file"
)
_describe 'preset' presets || _files
;;
structures)
local -a structures=("${(f)$(fastfetch --list-modules autocompletion)}")
_describe 'structure' structures
;;
logos)
local -a logos=(
"${(f)$(fastfetch --list-logos autocompletion)}"
"none:Don't print logo"
"small:Print small ascii logo if available"
)
_describe 'logo' logos
;;
esac
}
_fastfetch "$@"
+12
View File
@@ -1,3 +1,15 @@
fastfetch (2.22.0) jammy; urgency=medium
* Update to 2.22.0
-- Carter Li <zhangsongcui@live.cn> Mon, 26 Aug 2024 18:53:35 +0800
fastfetch (2.21.3) jammy; urgency=medium
* Update to 2.21.3
-- Carter Li <zhangsongcui@live.cn> Thu, 15 Aug 2024 16:14:52 +0800
fastfetch (2.21.2) jammy; urgency=medium
* Update to 2.21.2
+1 -1
View File
@@ -1 +1 @@
fastfetch_2.21.2_source.buildinfo universe/utils optional
fastfetch_2.22.0_source.buildinfo universe/utils optional
+6 -1
View File
@@ -820,7 +820,8 @@
"weather",
"wm",
"wifi",
"wmtheme"
"wmtheme",
"zpool"
]
},
{
@@ -993,6 +994,10 @@
{
"const": "wmtheme",
"description": "Print current theme of window manager"
},
{
"const": "zpool",
"description": "Print ZFS storage pools"
}
]
},
+1
View File
@@ -54,6 +54,7 @@
"physicalmemory",
"swap",
"disk",
"zpool",
"battery",
"poweradapter",
"player",
+1
View File
@@ -56,6 +56,7 @@
"physicalmemory",
"swap",
"disk",
"zpool",
"battery",
"poweradapter",
"player",
+1 -2
View File
@@ -111,8 +111,7 @@
{
"type": "loadavg",
"compact": false,
// {duration} is not fixed length, hack it
"key": "│ LOAD \u001b[s{duration}m\u001b[u\u001b[6C│{$1}"
"key": "│ LOAD {duration>2}m │{$1}" // pad duration to 2 chars
},
{
"type": "custom",
+14 -8
View File
@@ -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"
}
+58 -13
View File
@@ -265,18 +265,34 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
continue;
}
int32_t truncLength = INT32_MAX;
char* pColon = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pColon != NULL)
int32_t truncLength = 0;
char align = '\0';
char* pSep = memchr(placeholderValue.chars, ':', placeholderValue.length);
if (pSep)
align = ':';
else
{
pSep = memchr(placeholderValue.chars, '<', placeholderValue.length);
if (pSep)
align = '<';
else
{
pSep = memchr(placeholderValue.chars, '>', placeholderValue.length);
if (pSep)
align = '>';
}
}
if (pSep)
{
char* pEnd = NULL;
truncLength = (int32_t) strtol(pColon + 1, &pEnd, 10);
truncLength = (int32_t) strtol(pSep + 1, &pEnd, 10);
if (*pEnd != '\0')
{
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
*pColon = '\0';
*pSep = '\0';
}
uint32_t index = getArgumentIndex(placeholderValue.chars, numArgs, arguments);
@@ -287,7 +303,7 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
if (index > numArgs)
{
if (pColon) *pColon = ':';
if (pSep) *pSep = align;
appendInvalidPlaceholder(buffer, "{", &placeholderValue, i, formatstr->length);
continue;
}
@@ -299,14 +315,43 @@ void ffParseFormatString(FFstrbuf* buffer, const FFstrbuf* formatstr, uint32_t n
truncLength = -truncLength;
}
uint32_t oldLength = buffer->length;
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
if (buffer->length - oldLength > (uint32_t) truncLength)
if (!align)
ffFormatAppendFormatArg(buffer, &arguments[index - 1]);
else
{
ffStrbufSubstrBefore(buffer, oldLength + (uint32_t) truncLength);
ffStrbufTrimRightSpace(buffer);
if (ellipsis)
ffStrbufAppendS(buffer, "");
ffStrbufClear(&placeholderValue);
ffFormatAppendFormatArg(&placeholderValue, &arguments[index - 1]);
if (placeholderValue.length == (uint32_t) truncLength)
ffStrbufAppend(buffer, &placeholderValue);
else if (placeholderValue.length > (uint32_t) truncLength)
{
if (align == ':')
{
ffStrbufSubstrBefore(&placeholderValue, (uint32_t) truncLength);
ffStrbufTrimRightSpace(&placeholderValue);
}
else
ffStrbufSubstrBefore(&placeholderValue, (uint32_t) (!ellipsis? truncLength : truncLength - 1));
ffStrbufAppend(buffer, &placeholderValue);
if (ellipsis)
ffStrbufAppendS(buffer, "");
}
else if (align == ':')
ffStrbufAppend(buffer, &placeholderValue);
else
{
if (align == '<')
{
ffStrbufAppend(buffer, &placeholderValue);
ffStrbufAppendNC(buffer, (uint32_t) truncLength - placeholderValue.length, ' ');
}
else
{
ffStrbufAppendNC(buffer, (uint32_t) truncLength - placeholderValue.length, ' ');
ffStrbufAppend(buffer, &placeholderValue);
}
}
}
}
+3 -4
View File
@@ -54,10 +54,6 @@ void ffInitInstance(void)
#else
// Never use `setlocale(LC_ALL, "")`
setlocale(LC_TIME, "");
setlocale(LC_NUMERIC, "");
#ifdef LC_MESSAGES
setlocale(LC_MESSAGES, "");
#endif
#endif
initState(&instance.state);
@@ -251,6 +247,9 @@ void ffListFeatures(void)
#if FF_HAVE_ELF
"libelf\n"
#endif
#if FF_HAVE_LIBZFS
"libzfs\n"
#endif
#if FF_HAVE_DIRECTX_HEADERS
"Directx Headers\n"
#endif
+6 -7
View File
@@ -144,7 +144,7 @@ const char* ffGetTerminalResponse(const char* request, const char* format, ...)
{
if (ftty < 0)
{
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC);
ftty = open("/dev/tty", O_RDWR | O_NOCTTY | O_CLOEXEC | O_NONBLOCK);
if (ftty < 0)
return "open(\"/dev/tty\", O_RDWR | O_NOCTTY | O_CLOEXEC) failed";
@@ -232,12 +232,15 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
while((entry = readdir(dir)) != NULL)
{
if(entry->d_name[0] == '.') // skip hidden files
continue;
bool isDir = false;
#ifdef _DIRENT_HAVE_D_TYPE
#ifndef __sun
if(entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK)
isDir = entry->d_type == DT_DIR;
else
#else
#endif
{
struct stat stbuf;
if (fstatat(dfd, entry->d_name, &stbuf, 0) < 0)
@@ -245,12 +248,8 @@ void listFilesRecursively(uint32_t baseLength, FFstrbuf* folder, uint8_t indenta
else
isDir = S_ISDIR(stbuf.st_mode);
}
#endif
if (isDir)
{
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
continue;
ffStrbufAppendS(folder, entry->d_name);
ffStrbufAppendC(folder, '/');
listFilesRecursively(baseLength, folder, (uint8_t) (indentation + 1), entry->d_name, pretty);
+1
View File
@@ -169,6 +169,7 @@ static FFModuleBaseInfo* Y[] = {
};
static FFModuleBaseInfo* Z[] = {
(void*) &instance.config.modules.zpool,
NULL,
};
+4
View File
@@ -13,6 +13,10 @@ For example: "--title-format '{user-name:5}'" will truncate user name into 5-len
If '<trunc-length>' is negative, an ellipsis … will be appended at the end when the original string is truncated.
Note: The string length is counted in raw bytes. Multi-byte unicode characters and ANSI escape codes are not taken into account.
In 2.23.0 or newer, `<` or `>` can be specified instead of `:` to set a left or right padding.
For example: "--title-format '{user-name<20}'" will generate `<user-name> `;
"--title-format '{user-name>20}'" will generate ` <user-name>`
If the value index is missing, meaning the placeholder is "{}", an internal counter sets the value index.
This means that the format string "Values: {1} ({2})" is equivalent to "Values: {} ({})".
Note that this counter only counts empty placeholders, so the format string "{2} {} {}" will contain the second value, then the first, and then the second again.
+1
View File
@@ -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";
}
}
+27
View File
@@ -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 <cpuid.h>
// 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
+2
View File
@@ -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);
+41 -22
View File
@@ -137,36 +137,52 @@ 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(
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)
{
FF_AUTO_FREE char* line = NULL;
size_t len = 0;
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 __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) ||
ffParsePropLine(line, "isa :", cpuIsa) ||
ffParsePropLine(line, "uarch :", cpuUarch) ||
// 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__)
(cpuIsa->length == 0 && ffParsePropLine(line, "isa :", cpuIsa)) ||
(cpuUarch->length == 0 && ffParsePropLine(line, "uarch :", cpuUarch)) ||
#endif
#if __arm__ || __aarch64__
(cpu->vendor.length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
#endif
#if __ANDROID__
(cpuImplementer->length == 0 && ffParsePropLine(line, "CPU implementer :", cpuImplementer)) ||
(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
);
@@ -265,16 +281,19 @@ 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;
}
return FF_CPU_TEMP_UNSET;
}
static void parseIsa(FFstrbuf* cpuIsa)
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".
@@ -290,13 +309,9 @@ static void parseIsa(FFstrbuf* cpuIsa)
}
// The final ISA output of the above example is "rv64gch".
}
if(ffStrbufStartsWithS(cpuIsa, "mips"))
{
ffStrbufSubstrAfterLastC(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
@@ -340,9 +355,12 @@ 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);
#if !(__x86_64__ || __i386__ || __arm__ || __aarch64__)
if(cpuUarch.length > 0)
{
if(cpu->name.length > 0)
@@ -357,6 +375,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);
+3 -3
View File
@@ -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)
+1 -26
View File
@@ -54,31 +54,6 @@ typedef struct FFSmbiosProcessorInfo
static_assert(offsetof(FFSmbiosProcessorInfo, ThreadEnabled) == 0x30,
"FFSmbiosProcessorInfo: Wrong struct alignment");
#if defined(__x86_64__) || defined(__i386__)
#include <cpuid.h>
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)
+8
View File
@@ -178,6 +178,12 @@ static void getBudgie(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
ffParsePropFileData("budgie/budgie-version.xml", "<str>", result);
}
static void getUnity(FFstrbuf* result, FF_MAYBE_UNUSED FFDEOptions* options)
{
if (ffParsePropFile("/usr/bin/unity", "parser = OptionParser(version= \"%prog ", result))
ffStrbufSubstrBeforeFirstC(result, '"');
}
const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOptions* options)
{
if (!instance.config.general.detectVersion) return "Disabled by config";
@@ -196,6 +202,8 @@ const char* ffDetectDEVersion(const FFstrbuf* deName, FFstrbuf* result, FFDEOpti
getLXQt(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_BUDGIE))
getBudgie(result, options);
else if (ffStrbufEqualS(deName, FF_DE_PRETTY_UNITY))
getUnity(result, options);
else
return "Unsupported DE";
return NULL;
+11 -3
View File
@@ -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;
+13 -16
View File
@@ -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;
@@ -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);
}
+7
View File
@@ -238,6 +238,13 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
ffStrbufSetS(&result->deProcessName, "ukui-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UKUI);
}
else if(
ffStrStartsWithIgnCase(name, "Unity:Unity")
) {
ffStrbufSetS(&result->deProcessName, "unity-session");
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_UNITY);
}
}
+53 -33
View File
@@ -1,17 +1,41 @@
#include "editor.h"
#include "common/processing.h"
#include "common/library.h"
#include "util/stringUtils.h"
#include "util/path.h"
#include "util/binary.h"
#include <stdlib.h>
#ifdef _WIN32
#include <windows.h>
static inline char* realpath(const char* restrict file_name, char* restrict resolved_name)
{
return _fullpath(resolved_name, file_name, _MAX_PATH);
}
#endif
static bool extractNvimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (!ffStrStartsWith(str, "NVIM v")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("NVIM v"));
return false;
}
static bool extractVimVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (!ffStrStartsWith(str, "VIM - Vi IMproved ")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("VIM - Vi IMproved "));
ffStrbufSubstrBeforeFirstC(userdata, ' ');
return false;
}
static bool extractNanoVersionFromBinary(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (!ffStrStartsWith(str, "GNU nano ")) return true;
ffStrbufSetS((FFstrbuf*) userdata, str + strlen("GNU nano "));
return false;
}
const char* ffDetectEditor(FFEditorResult* result)
{
ffStrbufSetS(&result->name, getenv("VISUAL"));
@@ -26,41 +50,26 @@ 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] == '\\'))
{
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;
}
#endif
else
if (ffIsAbsolutePath(result->name.chars))
ffStrbufSet(&result->path, &result->name);
else
{
const char* error = ffFindExecutableInPath(result->name.chars, &result->path);
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;
ffStrbufSetS(&result->path, buf);
// WIN32: Should we handle scoop shim exe here?
#ifdef __linux__
if (!ffStrEndsWith(buf, "/snap"))
#endif
ffStrbufSetS(&result->path, buf);
}
{
uint32_t index = ffStrbufLastIndexC(&result->path,
@@ -82,6 +91,17 @@ const char* ffDetectEditor(FFEditorResult* result)
#endif
}
if (!instance.config.general.detectVersion) return NULL;
if (ffStrbufEqualS(&result->exe, "nvim"))
ffBinaryExtractStrings(result->path.chars, extractNvimVersionFromBinary, &result->version, (uint32_t) strlen("NVIM v0.0.0"));
else if (ffStrbufEqualS(&result->exe, "vim"))
ffBinaryExtractStrings(result->path.chars, extractVimVersionFromBinary, &result->version, (uint32_t) strlen("VIM - Vi IMproved 0.0"));
else if (ffStrbufEqualS(&result->exe, "nano"))
ffBinaryExtractStrings(result->path.chars, extractNanoVersionFromBinary, &result->version, (uint32_t) strlen("GNU nano 0.0"));
if (result->version.length > 0) return NULL;
const char* param = NULL;
if (
ffStrbufEqualS(&result->exe, "nano") ||
+11 -13
View File
@@ -1,20 +1,18 @@
#include "initsystem.h"
#include "common/processing.h"
#include "util/linux/elf.h"
#include "util/binary.h"
#include "util/stringUtils.h"
#include <unistd.h>
FF_MAYBE_UNUSED static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* data)
FF_MAYBE_UNUSED static bool extractSystemdVersion(const char* str, uint32_t len, void* userdata)
{
if (len > strlen("systemd 0.0 running in ") && memcmp(str, "systemd ", strlen("systemd ")) == 0)
{
const char* pend = memmem(str + strlen("systemd "), len - strlen("systemd "), " running in ", strlen(" running in "));
if (pend)
{
ffStrbufSetNS((FFstrbuf*) data, (uint32_t) (pend - str) - (uint32_t) strlen("systemd "), str + strlen("systemd "));
return false;
}
}
return true;
if (!ffStrStartsWith(str, "systemd ")) return true;
const char* pstart = str + strlen("systemd ");
const char* pend = memmem(pstart, len - strlen("systemd "), " running in ", strlen(" running in "));
if (!pend) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (pend - pstart), pstart);
return false;
}
const char* ffDetectInitSystem(FFInitSystemResult* result)
@@ -49,7 +47,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, extractSystemdVersion, &result->version, (uint32_t) strlen("systemd 0.0 running in x"));
if (result->version.length == 0)
{
if (ffProcessAppendStdOut(&result->version, (char* const[]) {
+2 -2
View File
@@ -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;
}
-10
View File
@@ -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));
}
+1
View File
@@ -9,6 +9,7 @@ typedef struct FFLocalIpResult
FFstrbuf ipv6;
FFstrbuf mac;
int32_t mtu;
int32_t speed;
bool defaultRoute;
} FFLocalIpResult;
+386
View File
@@ -12,7 +12,13 @@
#include <stdio.h>
#include <sys/ioctl.h>
#ifdef __linux__
#include <linux/ethtool.h>
#include <linux/sockios.h>
#endif
#if defined(__FreeBSD__) || defined(__APPLE__)
#include <net/if_media.h>
#include <net/if_dl.h>
#else
#include <netpacket/packet.h>
@@ -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 = (void*) &edata;
if (ioctl(sockfd, SIOCETHTOOL, &ifr) == 0)
iface->speed = (edata.speed_hi << 16) | edata.speed; // ethtool_cmd_speed is not available on Android
#elif __FreeBSD__ || __APPLE__
struct ifmediareq ifmr = {};
strncpy(ifmr.ifm_name, iface->name.chars, IFNAMSIZ - 1);
if (ioctl(sockfd, SIOCGIFMEDIA, &ifmr) == 0)
{
switch (IFM_SUBTYPE(ifmr.ifm_active))
{
#ifdef IFM_HPNA_1
case IFM_HPNA_1:
#endif
iface->speed = 1; break;
#ifdef IFM_1000_CX
case IFM_1000_CX:
#endif
#ifdef IFM_1000_CX_SGMII
case IFM_1000_CX_SGMII:
#endif
#ifdef IFM_1000_KX
case IFM_1000_KX:
#endif
#ifdef IFM_1000_LX
case IFM_1000_LX:
#endif
#ifdef IFM_1000_SGMII
case IFM_1000_SGMII:
#endif
#ifdef IFM_1000_SX
case IFM_1000_SX:
#endif
#ifdef IFM_1000_T
case IFM_1000_T:
#endif
iface->speed = 1000; break;
#ifdef IFM_100G_AUI2
case IFM_100G_AUI2:
#endif
#ifdef IFM_100G_AUI2_AC
case IFM_100G_AUI2_AC:
#endif
#ifdef IFM_100G_AUI4
case IFM_100G_AUI4:
#endif
#ifdef IFM_100G_AUI4_AC
case IFM_100G_AUI4_AC:
#endif
#ifdef IFM_100G_CAUI2
case IFM_100G_CAUI2:
#endif
#ifdef IFM_100G_CAUI2_AC
case IFM_100G_CAUI2_AC:
#endif
#ifdef IFM_100G_CAUI4
case IFM_100G_CAUI4:
#endif
#ifdef IFM_100G_CAUI4_AC
case IFM_100G_CAUI4_AC:
#endif
#ifdef IFM_100G_CP2
case IFM_100G_CP2:
#endif
#ifdef IFM_100G_CR4
case IFM_100G_CR4:
#endif
#ifdef IFM_100G_CR_PAM4
case IFM_100G_CR_PAM4:
#endif
#ifdef IFM_100G_DR
case IFM_100G_DR:
#endif
#ifdef IFM_100G_KR2_PAM4
case IFM_100G_KR2_PAM4:
#endif
#ifdef IFM_100G_KR4
case IFM_100G_KR4:
#endif
#ifdef IFM_100G_KR_PAM4
case IFM_100G_KR_PAM4:
#endif
#ifdef IFM_100G_LR4
case IFM_100G_LR4:
#endif
#ifdef IFM_100G_SR2
case IFM_100G_SR2:
#endif
#ifdef IFM_100G_SR4
case IFM_100G_SR4:
#endif
iface->speed = 100000; break;
#ifdef IFM_100_FX
case IFM_100_FX:
#endif
#ifdef IFM_100_SGMII
case IFM_100_SGMII:
#endif
#ifdef IFM_100_T
case IFM_100_T:
#endif
#ifdef IFM_100_T2
case IFM_100_T2:
#endif
#ifdef IFM_100_T4
case IFM_100_T4:
#endif
#ifdef IFM_100_TX
case IFM_100_TX:
#endif
#ifdef IFM_100_VG
case IFM_100_VG:
#endif
iface->speed = 100; break;
#ifdef IFM_10G_AOC
case IFM_10G_AOC:
#endif
#ifdef IFM_10G_CR1
case IFM_10G_CR1:
#endif
#ifdef IFM_10G_CX4
case IFM_10G_CX4:
#endif
#ifdef IFM_10G_ER
case IFM_10G_ER:
#endif
#ifdef IFM_10G_KR
case IFM_10G_KR:
#endif
#ifdef IFM_10G_KX4
case IFM_10G_KX4:
#endif
#ifdef IFM_10G_LR
case IFM_10G_LR:
#endif
#ifdef IFM_10G_LRM
case IFM_10G_LRM:
#endif
#ifdef IFM_10G_SFI
case IFM_10G_SFI:
#endif
#ifdef IFM_10G_SR
case IFM_10G_SR:
#endif
#ifdef IFM_10G_T
case IFM_10G_T:
#endif
#ifdef IFM_10G_TWINAX
case IFM_10G_TWINAX:
#endif
#ifdef IFM_10G_TWINAX_LONG
case IFM_10G_TWINAX_LONG:
#endif
iface->speed = 10000; break;
#ifdef IFM_10_2
case IFM_10_2:
#endif
#ifdef IFM_10_5
case IFM_10_5:
#endif
#ifdef IFM_10_FL
case IFM_10_FL:
#endif
#ifdef IFM_10_STP
case IFM_10_STP:
#endif
#ifdef IFM_10_T
case IFM_10_T:
#endif
iface->speed = 10; break;
#ifdef IFM_200G_AUI4
case IFM_200G_AUI4:
#endif
#ifdef IFM_200G_AUI4_AC
case IFM_200G_AUI4_AC:
#endif
#ifdef IFM_200G_AUI8
case IFM_200G_AUI8:
#endif
#ifdef IFM_200G_AUI8_AC
case IFM_200G_AUI8_AC:
#endif
#ifdef IFM_200G_CR4_PAM4
case IFM_200G_CR4_PAM4:
#endif
#ifdef IFM_200G_DR4
case IFM_200G_DR4:
#endif
#ifdef IFM_200G_FR4
case IFM_200G_FR4:
#endif
#ifdef IFM_200G_KR4_PAM4
case IFM_200G_KR4_PAM4:
#endif
#ifdef IFM_200G_LR4
case IFM_200G_LR4:
#endif
#ifdef IFM_200G_SR4
case IFM_200G_SR4:
#endif
iface->speed = 200000; break;
#ifdef IFM_20G_KR2
case IFM_20G_KR2:
#endif
iface->speed = 20000; break;
#ifdef IFM_2500_KX
case IFM_2500_KX:
#endif
#ifdef IFM_2500_SX
case IFM_2500_SX:
#endif
#ifdef IFM_2500_T
case IFM_2500_T:
#endif
#ifdef IFM_2500_X
case IFM_2500_X:
#endif
iface->speed = 2500; break;
#ifdef IFM_25G_ACC
case IFM_25G_ACC:
#endif
#ifdef IFM_25G_AOC
case IFM_25G_AOC:
#endif
#ifdef IFM_25G_AUI
case IFM_25G_AUI:
#endif
#ifdef IFM_25G_CR
case IFM_25G_CR:
#endif
#ifdef IFM_25G_CR1
case IFM_25G_CR1:
#endif
#ifdef IFM_25G_CR_S
case IFM_25G_CR_S:
#endif
#ifdef IFM_25G_KR
case IFM_25G_KR:
#endif
#ifdef IFM_25G_KR1
case IFM_25G_KR1:
#endif
#ifdef IFM_25G_KR_S
case IFM_25G_KR_S:
#endif
#ifdef IFM_25G_LR
case IFM_25G_LR:
#endif
#ifdef IFM_25G_PCIE
case IFM_25G_PCIE:
#endif
#ifdef IFM_25G_SR
case IFM_25G_SR:
#endif
#ifdef IFM_25G_T
case IFM_25G_T:
#endif
iface->speed = 25000; break;
#ifdef IFM_400G_AUI8
case IFM_400G_AUI8:
#endif
#ifdef IFM_400G_AUI8_AC
case IFM_400G_AUI8_AC:
#endif
#ifdef IFM_400G_DR4
case IFM_400G_DR4:
#endif
#ifdef IFM_400G_FR8
case IFM_400G_FR8:
#endif
#ifdef IFM_400G_LR8
case IFM_400G_LR8:
#endif
iface->speed = 400000; break;
#ifdef IFM_40G_CR4
case IFM_40G_CR4:
#endif
#ifdef IFM_40G_ER4
case IFM_40G_ER4:
#endif
#ifdef IFM_40G_KR4
case IFM_40G_KR4:
#endif
#ifdef IFM_40G_LR4
case IFM_40G_LR4:
#endif
#ifdef IFM_40G_SR4
case IFM_40G_SR4:
#endif
#ifdef IFM_40G_XLAUI
case IFM_40G_XLAUI:
#endif
#ifdef IFM_40G_XLAUI_AC
case IFM_40G_XLAUI_AC:
#endif
#ifdef IFM_40G_XLPPI
case IFM_40G_XLPPI:
#endif
#ifdef IFM_40G_LM4
case IFM_40G_LM4:
#endif
iface->speed = 40000; break;
#ifdef IFM_5000_KR
case IFM_5000_KR:
#endif
#ifdef IFM_5000_KR1
case IFM_5000_KR1:
#endif
#ifdef IFM_5000_KR_S
case IFM_5000_KR_S:
#endif
#ifdef IFM_5000_T
case IFM_5000_T:
#endif
iface->speed = 5000; break;
#ifdef IFM_50G_AUI1
case IFM_50G_AUI1:
#endif
#ifdef IFM_50G_AUI1_AC
case IFM_50G_AUI1_AC:
#endif
#ifdef IFM_50G_AUI2
case IFM_50G_AUI2:
#endif
#ifdef IFM_50G_AUI2_AC
case IFM_50G_AUI2_AC:
#endif
#ifdef IFM_50G_CP
case IFM_50G_CP:
#endif
#ifdef IFM_50G_CR2
case IFM_50G_CR2:
#endif
#ifdef IFM_50G_FR
case IFM_50G_FR:
#endif
#ifdef IFM_50G_KR2
case IFM_50G_KR2:
#endif
#ifdef IFM_50G_KR_PAM4
case IFM_50G_KR_PAM4:
#endif
#ifdef IFM_50G_LAUI2
case IFM_50G_LAUI2:
#endif
#ifdef IFM_50G_LAUI2_AC
case IFM_50G_LAUI2_AC:
#endif
#ifdef IFM_50G_LR
case IFM_50G_LR:
#endif
#ifdef IFM_50G_LR2
case IFM_50G_LR2:
#endif
#ifdef IFM_50G_PCIE
case IFM_50G_PCIE:
#endif
#ifdef IFM_50G_SR
case IFM_50G_SR:
#endif
#ifdef IFM_50G_SR2
case IFM_50G_SR2:
#endif
#ifdef IFM_50G_KR4
case IFM_50G_KR4:
#endif
iface->speed = 50000; break;
#ifdef IFM_56G_R4
case IFM_56G_R4:
#endif
iface->speed = 56000; break;
default:
iface->speed = -1;
}
}
#endif
#ifdef __sun
if ((options->showType & FF_LOCALIP_TYPE_MAC_BIT) && ioctl(sockfd, SIOCGIFHWADDR, &ifr) == 0)
{
+6 -1
View File
@@ -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;
+1
View File
@@ -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;
+1
View File
@@ -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)
@@ -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)
{
@@ -287,10 +287,10 @@ static void detectXterm(FFTerminalFontResult* terminalFont)
ffFontInitValues(&terminalFont->font, fontName.chars, fontSize.chars);
}
static bool elfExtractStringsCallBack(const char* str, uint32_t len, void* userData)
static bool extractStTermFont(const char* str, FF_MAYBE_UNUSED uint32_t len, void* userdata)
{
if (!ffStrContains(str, "size=")) return true;
ffStrbufSetNS((FFstrbuf*) userData, len, str);
ffStrbufSetNS((FFstrbuf*) userdata, len, str);
return false;
}
@@ -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, extractStTermFont, &font, (uint32_t) strlen("size=0"));
if (error)
{
ffStrbufAppendS(&terminalFont->error, error);
+75 -11
View File
@@ -3,6 +3,7 @@
#include "common/processing.h"
#include "common/properties.h"
#include "util/stringUtils.h"
#include "util/binary.h"
#include <ctype.h>
#ifdef __FreeBSD__
@@ -63,16 +64,29 @@ static bool getExeVersionGeneral(FFstrbuf* exe, FFstrbuf* version)
return true;
}
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* version)
static bool extractBashVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffStrStartsWith(line, "@(#)Bash version ")) return true;
const char* start = line + strlen("@(#)Bash version ");
const char* end = strchr(start, '(');
if (!end) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
return false;
}
static bool getShellVersionBash(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
{
const char* path = exePath->chars;
if (*path == '\0')
path = exe->chars;
ffBinaryExtractStrings(path, extractBashVersion, version, (uint32_t) strlen("@(#)Bash version 0.0.0(0) release GNU"));
if(!getExeVersionRaw(exe, version))
return false;
// GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)\nCopyright...
ffStrbufSubstrBeforeFirstC(version, '\n'); // GNU bash, version 5.1.16(1)-release (x86_64-pc-msys)
ffStrbufSubstrBeforeLastC(version, ' '); // GNU bash, version 5.1.16(1)-release
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16(1)-release
ffStrbufSubstrBeforeFirstC(version, '('); // 5.1.16
ffStrbufSubstrBeforeFirstC(version, '('); // GNU bash, version 5.1.16
ffStrbufSubstrAfterLastC(version, ' '); // 5.1.16
return true;
}
@@ -188,6 +202,29 @@ static bool getShellVersionXonsh(FFstrbuf* exe, FFstrbuf* version)
return true;
}
static bool extractZshVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata)
{
if (!ffStrStartsWith(line, "zsh-")) return true;
const char* start = line + strlen("zsh-");
const char* end = strchr(start, '-');
if (!end) return true;
ffStrbufSetNS((FFstrbuf*) userdata, (uint32_t) (end - start), start);
return false;
}
static bool getShellVersionZsh(FFstrbuf* exe, FFstrbuf* exePath, FFstrbuf* version)
{
const char* path = exePath->chars;
if (*path == '\0')
path = exe->chars;
ffBinaryExtractStrings(path, extractZshVersion, version, (uint32_t) strlen("zsh-0.0-0"));
if (version->length) return true;
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
}
#ifdef _WIN32
static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
{
@@ -202,7 +239,7 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
}
#endif
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version)
{
if (!instance.config.general.detectVersion) return false;
@@ -210,9 +247,9 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
return false;
if(ffStrEqualsIgnCase(exeName, "bash"))
return getShellVersionBash(exe, version);
return getShellVersionBash(exe, exePath, version);
if(ffStrEqualsIgnCase(exeName, "zsh"))
return getExeVersionGeneral(exe, version); //zsh 5.9 (arm-apple-darwin21.3.0)
return getShellVersionZsh(exe, exePath, version);
if(ffStrEqualsIgnCase(exeName, "fish"))
return getShellVersionFish(exe, version);
if(ffStrEqualsIgnCase(exeName, "pwsh"))
@@ -250,8 +287,24 @@ FF_MAYBE_UNUSED static bool getTerminalVersionTermux(FFstrbuf* version)
return version->length > 0;
}
FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
static bool extractGeneralVersion(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] == '/')
{
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length) return true;
}
if(ffProcessAppendStdOut(version, (char* const[]){
"gnome-terminal",
"--version",
@@ -264,6 +317,17 @@ FF_MAYBE_UNUSED static bool getTerminalVersionGnome(FFstrbuf* version)
return true;
}
FF_MAYBE_UNUSED static bool getTerminalVersionXfce4Terminal(FFstrbuf* exe, FFstrbuf* version)
{
if (exe->chars[0] == '/')
{
ffBinaryExtractStrings(exe->chars, extractGeneralVersion, version, (uint32_t) strlen("0.0.0"));
if (version->length) return true;
}
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
}
FF_MAYBE_UNUSED static bool getTerminalVersionKgx(FFstrbuf* version)
{
if(ffProcessAppendStdOut(version, (char* const[]){
@@ -590,7 +654,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);
@@ -599,7 +663,7 @@ bool fftsGetTerminalVersion(FFstrbuf* processName, FF_MAYBE_UNUSED FFstrbuf* exe
return getExeVersionGeneral(exe, version);//yakuake 22.12.3
if(ffStrbufIgnCaseEqualS(processName, "xfce4-terminal"))
return getExeVersionGeneral(exe, version);//xfce4-terminal 1.0.4 (Xfce 4.18)...
return getTerminalVersionXfce4Terminal(exe, version);
if(ffStrbufIgnCaseEqualS(processName, "terminator"))
return getExeVersionGeneral(exe, version);//terminator 2.1.3
@@ -274,14 +274,14 @@ static void getUserShellFromEnv(FFShellResult* result)
}
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* exePath, FFstrbuf* version);
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
static void setShellInfoDetails(FFShellResult* result)
{
ffStrbufClear(&result->version);
fftsGetShellVersion(&result->exe, result->exeName, &result->version);
fftsGetShellVersion(&result->exe, result->exeName, &result->exePath, &result->version);
if(ffStrbufEqualS(&result->processName, "pwsh"))
ffStrbufInitStatic(&result->prettyName, "PowerShell");
@@ -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);
@@ -5,6 +5,7 @@
#include "util/mallocHelper.h"
#include "util/windows/registry.h"
#include "util/windows/unicode.h"
#include "util/stringUtils.h"
#include <windows.h>
#include <wchar.h>
@@ -37,7 +38,7 @@ static bool getProductVersion(const wchar_t* filePath, FFstrbuf* version)
return false;
}
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, const FFstrbuf* exePath, FFstrbuf* version);
static uint32_t getShellInfo(FFShellResult* result, uint32_t pid)
{
@@ -345,6 +346,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)
@@ -354,7 +359,7 @@ const FFShellResult* ffDetectShell(void)
strcpy(tmp, result.exeName);
char* ext = strrchr(tmp, '.');
if (ext) *ext = '\0';
fftsGetShellVersion(&result.exe, tmp, &result.version);
fftsGetShellVersion(&result.exe, tmp, &result.exePath, &result.version);
}
return &result;
+4 -2
View File
@@ -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
+89
View File
@@ -0,0 +1,89 @@
#pragma once
#include "fastfetch.h"
// From https://github.com/openzfs/zfs/blob/master/include/libzfs.h
/*
* CDDL HEADER START
*
* The contents of this file are subject to the terms of the
* Common Development and Distribution License (the "License").
* You may not use this file except in compliance with the License.
*
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
* or https://opensource.org/licenses/CDDL-1.0.
* See the License for the specific language governing permissions
* and limitations under the License.
*
* When distributing Covered Code, include this CDDL HEADER in each
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
* If applicable, add the following below this CDDL HEADER, with the
* fields enclosed by brackets "[]" replaced with your own identifying
* information: Portions Copyright [yyyy] [name of copyright owner]
*
* CDDL HEADER END
*/
typedef enum {
ZPOOL_PROP_INVAL = -1,
ZPOOL_PROP_NAME,
ZPOOL_PROP_SIZE,
ZPOOL_PROP_CAPACITY,
ZPOOL_PROP_ALTROOT,
ZPOOL_PROP_HEALTH,
ZPOOL_PROP_GUID,
ZPOOL_PROP_VERSION,
ZPOOL_PROP_BOOTFS,
ZPOOL_PROP_DELEGATION,
ZPOOL_PROP_AUTOREPLACE,
ZPOOL_PROP_CACHEFILE,
ZPOOL_PROP_FAILUREMODE,
ZPOOL_PROP_LISTSNAPS,
ZPOOL_PROP_AUTOEXPAND,
ZPOOL_PROP_DEDUPDITTO,
ZPOOL_PROP_DEDUPRATIO,
ZPOOL_PROP_FREE,
ZPOOL_PROP_ALLOCATED,
ZPOOL_PROP_READONLY,
ZPOOL_PROP_ASHIFT,
ZPOOL_PROP_COMMENT,
ZPOOL_PROP_EXPANDSZ,
ZPOOL_PROP_FREEING,
ZPOOL_PROP_FRAGMENTATION,
ZPOOL_PROP_LEAKED,
ZPOOL_PROP_MAXBLOCKSIZE,
ZPOOL_PROP_TNAME,
ZPOOL_PROP_MAXDNODESIZE,
ZPOOL_PROP_MULTIHOST,
ZPOOL_PROP_CHECKPOINT,
ZPOOL_PROP_LOAD_GUID,
ZPOOL_PROP_AUTOTRIM,
ZPOOL_PROP_COMPATIBILITY,
ZPOOL_PROP_BCLONEUSED,
ZPOOL_PROP_BCLONESAVED,
ZPOOL_PROP_BCLONERATIO,
ZPOOL_NUM_PROPS
} zpool_prop_t;
typedef enum {
ZPROP_SRC_NONE = 0x1,
ZPROP_SRC_DEFAULT = 0x2,
ZPROP_SRC_TEMPORARY = 0x4,
ZPROP_SRC_LOCAL = 0x8,
ZPROP_SRC_INHERITED = 0x10,
ZPROP_SRC_RECEIVED = 0x20
} zprop_source_t;
typedef bool boolean_t;
typedef struct libzfs_handle libzfs_handle_t;
typedef struct zpool_handle zpool_handle_t;
typedef int (*zpool_iter_f)(zpool_handle_t *, void *);
extern int zpool_iter(libzfs_handle_t *, zpool_iter_f, void *);
extern libzfs_handle_t *libzfs_init(void);
extern void libzfs_fini(libzfs_handle_t *);
extern uint64_t zpool_get_prop_int(zpool_handle_t *, zpool_prop_t, zprop_source_t *);
extern const char *zpool_get_name(zpool_handle_t *);
extern const char *zpool_get_state_str(zpool_handle_t *);
+15
View File
@@ -0,0 +1,15 @@
#pragma once
#include "fastfetch.h"
typedef struct FFZpoolResult
{
FFstrbuf name;
FFstrbuf state;
uint64_t used;
uint64_t total;
uint64_t version;
uint64_t fragmentation;
} FFZpoolResult;
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */);
+111
View File
@@ -0,0 +1,111 @@
#include "zpool.h"
#ifdef FF_HAVE_LIBZFS
#ifdef __sun
#define FF_DISABLE_DLOPEN
#include <libzfs.h>
const char* zpool_get_state_str(zpool_handle_t* zpool)
{
if (zpool_get_state(zpool) == POOL_STATE_UNAVAIL)
return "FAULTED";
else
{
const char *str;
zpool_errata_t errata;
zpool_status_t status = zpool_get_status(zpool, (char**) &str, &errata);
if (status == ZPOOL_STATUS_IO_FAILURE_WAIT ||
status == ZPOOL_STATUS_IO_FAILURE_CONTINUE ||
status == ZPOOL_STATUS_IO_FAILURE_MMP)
return "SUSPENDED";
else
{
nvlist_t *nvroot = fnvlist_lookup_nvlist(zpool_get_config(zpool, NULL), ZPOOL_CONFIG_VDEV_TREE);
uint_t vsc;
vdev_stat_t *vs;
#ifdef __x86_64__
if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint64_t**) &vs, &vsc) != 0)
#else
if (nvlist_lookup_uint32_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint32_t**) &vs, &vsc) != 0)
#endif
return "UNKNOWN";
else
return zpool_state_to_name(vs->vs_state, vs->vs_aux);
}
}
}
#else
#include "libzfs_simplified.h"
#endif
#include "common/library.h"
typedef struct FFZfsData
{
FF_LIBRARY_SYMBOL(libzfs_fini)
FF_LIBRARY_SYMBOL(zpool_iter)
FF_LIBRARY_SYMBOL(zpool_get_prop_int)
FF_LIBRARY_SYMBOL(zpool_get_name)
FF_LIBRARY_SYMBOL(zpool_get_state_str)
libzfs_handle_t* handle;
FFlist* result;
} FFZfsData;
static inline void cleanLibzfs(FFZfsData* data)
{
if (data->fflibzfs_fini && data->handle)
{
data->fflibzfs_fini(data->handle);
data->handle = NULL;
}
}
static int enumZpoolCallback(zpool_handle_t* zpool, void* param)
{
FFZfsData* data = (FFZfsData*) param;
zprop_source_t source;
FFZpoolResult* item = ffListAdd(data->result);
ffStrbufInitS(&item->name, data->ffzpool_get_name(zpool));
ffStrbufInitS(&item->state, data->ffzpool_get_state_str(zpool));
item->version = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_VERSION, &source);
item->total = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_SIZE, &source);
item->used = item->total - data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FREE, &source);
item->fragmentation = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FRAGMENTATION, &source);
return 0;
}
const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */)
{
FF_LIBRARY_LOAD(libzfs, NULL, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 4);
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init);
libzfs_handle_t* handle = fflibzfs_init();
if (!handle) return "libzfs_init() failed";
__attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = {
.handle = handle,
.result = result,
};
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_name);
FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_state_str);
if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0)
return "zpool_iter() failed";
return NULL;
}
#else
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result)
{
return "Fastfetch was compiled without libzfs support";
}
#endif
+6
View File
@@ -0,0 +1,6 @@
#include "zpool.h"
const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result /* list of FFZpoolResult */)
{
return "Not supported on this platform";
}
+19 -19
View File
@@ -1,19 +1,19 @@
${c1} ___________
/ \
/ ${c2}______${c1} \
/ ${c2}/ \${c1} \
| ${c2}( )${c1} \
/ ${c2}\______/${c1} |
| |
/ \
| |
| |
/ |
| |
| _______ |
____/ / \ |
/ | | |
| / ____/ |
\_________/ / |
\ __/
\_______/
___________
/ \
/ ${c2}______${c1} \
/ ${c2}/ \${c1} \
| ${c2}( )${c1} \
/ ${c2}\______/${c1} |
| |
/ \
| |
| |
/ |
| |
| _______ |
____/ / \ |
/ | | |
| / ____/ |
\_________/ / |
\ __/
\_______/
+24
View File
@@ -0,0 +1,24 @@
ti
jGGGGj
tGGGGGGt
,LGGLGGGGGGGG,
jGGGGjGGGGGGGGGj
GGGGGGGGGGGGGGGGGGGG
iGGGGGGt tLLLLLLi
,GGGGGi iGGGGG,
,jGGGG LGGGG,
,LjGGj LLLL,
,LLGG. iiii.
,LLj
,LLj jLL,
,LLLL. GGLL,
,LLLLt GGLL,
,LGGGG LGGGj,
,GGGGGi iGGGGG,
iGGGGGGj tGGGGGG,
GGGGGGGGGGGGGGGGGGGG
jGGGGGGGGGjGGGGj
,LGGGGGGGGGGG,
tGGGGGGt
jGGGGj
it
+20
View File
@@ -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;;;;;;.
;;;;;;;;;;;;;;;;;;;;;;;;;;;;.
;;;;;;;;;;;;;;;;;;;;;;.
';;;;;;;;;;;;,
';;'.
+19
View File
@@ -0,0 +1,19 @@
${c2}@
@@--=====@@
@@--==@@ @@====+@
@-@@ @==@
@=@
@=@${c1} @=@ @-==== @=@${c2}
@=@${c1} @-===@==++@===+@${c2}
@=@${c1} @--====@@=====+@${c2}
-=@${c1} @--==========++@${c2}
==${c1} @--==========++@${c2} @=@
@==${c1} @--=======@==++@${c2} @=+@
@==${c1} @-==========++${c2} @=@
@==${c1} @-=======@=%${c2} @=@
@==${c1} @@@@@@${c2} @=@
@====@@@ @@===+%
@@=====@@==++++@@
=#@=@
@==@++@
@@@
+16
View File
@@ -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
``````````````
+7
View File
@@ -0,0 +1,7 @@
_____
[$2BBBBB$1]
`^^7$2&$1/`
,/$2&$1/`
,/$2&$1Z__
[$2BBBBB$1]
`^^^^^`
+24
View File
@@ -0,0 +1,24 @@
$2 .xXK0kdc'..
.OMMMMWNK0Odc'.
.OMMMMMMMMMMWNOl'.
.OMMMMMMMMMMMMMWXx;.
.:ddk0XWMMMMMMMMMMNx'
..;oxONMMMMMMMWKc.
$1 ..,;::::;,'.$2 .;xXMMMMMMMNo.
$1 .':looooooooool:,..$2 .;OWMMMMMMNl.
$1 .:oooooooooooooooooc'$2 .xWMMMMMMK:
$1 'coooooooooooooooooool,$2 'OMMMMMMWx.
$1.coooooooooooooooooooool.$2 cNMMMMMM0,
$1'loooooooooooooooooooooo,$2 ,KMMMMMMX:
$1'loooooooooooooooooooooo,$2 ,KMMMMMMX:
$1.:oooooooooooooooooooooc.$2 lNMMMMMM0,
$1 .coooooooooooooooooool'$2 ,0MMMMMMWd.
$1 .:looooooooooooooolc.$2 'OWMMMMMMK;
$1 ..;cloooooooooc;'..$2 .c0WMMMMMMXc.
$1 ..',;;;;,'..$2 ..cONMMMMMMMXc.
..,cxOKWMMMMMMMW0;.
.cxk0KNWMMMMMMMMMWXo.
.OMMMMMMMMMMMMMWKo'
.OMMMMMMMMMMWKx:.
.OMMMWNX0Oxl;.
.o0Oxoc,..
+5
View File
@@ -0,0 +1,5 @@
$2__
\
$1## $2\
$1## $2/
__/
+20 -20
View File
@@ -1,20 +1,20 @@
....
.',:clooo: .:looooo:.
.;looooooooc .oooooooooo'
.;looooool:,''. :ooooooooooc
;looool;. 'oooooooooo,
;clool' .cooooooc. ,,
... ...... .:oo,
.;clol:,. .loooo'
:ooooooooo, 'ooool
'ooooooooooo. loooo.
'ooooooooool coooo.
,loooooooc. .loooo.
.,;;;'. ;ooooc
... ,ooool.
.cooooc. ..',,'. .cooo.
;ooooo:. ;oooooooc. :l.
.coooooc,.. coooooooooo.
.:ooooooolc:. .ooooooooooo'
.':loooooo; ,oooooooooc
..';::c' .;loooo:'
....
$2.',:clooo: $1.:looooo:.
$2.;looooooooc $1.oooooooooo'
$2.;looooool:,''. $1:ooooooooooc
$2;looool;. $1'oooooooooo,
$2;clool' $1.cooooooc. $2,,
$2... $1...... $2.:oo,
$1.;clol:,. $2.loooo'
$1:ooooooooo, $2'ooool
$1'ooooooooooo. $2loooo.
$1'ooooooooool $2coooo.
$1,loooooooc. $2.loooo.
$1.,;;;'. $2;ooooc
$2... $2,ooool.
$2.cooooc. $1..',,'. $2.cooo.
$2;ooooo:. $1;oooooooc. $2:l.
$2.coooooc,.. $1coooooooooo.
$2.:ooooooolc:. $1.ooooooooooo'
$2.':loooooo; $1,oooooooooc
$2..';::c' $1.;loooo:'
-11
View File
@@ -1,11 +0,0 @@
..;,; .,;,.
.,lool: .ooooo,
;oo;: .coool.
.... ''' ,l;
:oooo, 'oo.
looooc :oo'
'::' ,oo:
,., .... co,
lo:;. :oooo; .
':ooo; cooooc
''' ''''
+5 -5
View File
@@ -3,16 +3,16 @@
-+ssssssssssssssssssyyssss+-
.ossssssssssssssssssd$2MMMNy$1sssso.
/sssssssssss$2hdmmNNmmyNMMMMh$1ssssss/
+sssssssss$2hmydMMMMMMMNddddy$1ssssssss+
/ssssssss$2hNMMMyhhyyyyhmNMMMNh$1ssssssss/
+sssssssss$2hm$1yd$2MMMMMMMNddddy$1ssssssss+
/ssssssss$2hNMMM$1yh$2hyyyyhmNMMMNh$1ssssssss/
.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.
+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+
oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso
oss$2yNMMMNyMMh$1ssssssssssssss$2hmmmh$1ssssssso
oss$2yNMMMNyMMh$1sssssssssssssshmmmhssssssso
+ssss$2hhhyNMMNy$1ssssssssssss$2yNMMMy$1sssssss+
.ssssssss$2dMMMNh$1ssssssssss$2hNMMMd$1ssssssss.
/ssssssss$2hNMMMyhhyyyyhdNMMMNh$1ssssssss/
+sssssssss$2dmydMMMMMMMMddddy$1ssssssss+
/ssssssss$2hNMMM$1yh$2hyyyyhdNMMMNh$1ssssssss/
+sssssssss$2dm$1yd$2MMMMMMMMddddy$1ssssssss+
/sssssssssss$2hdmNNNNmyNMMMMh$1ssssss/
.ossssssssssssssssss$2dMMMNy$1sssso.
-+sssssssssssssssss$2yyy$1ssss+-
+6
View File
@@ -0,0 +1,6 @@
_
---(_)
_/ --- \
(_) | |
\ --- _/
---(_)
+11 -6
View File
@@ -1,6 +1,11 @@
_
---(_)
_/ --- \
(_) | |
\ --- _/
---(_)
$2..;,; $1.,;,.
$2.,lool: $1.ooooo,
$2;oo;: $1.coool.
$1.... $1''' $2,l;
$1:oooo, $2'oo.
$1looooc $2:oo'
$1'::' $2,oo:
$2,., $1.... $2co,
$2lo:;. $1:oooo; $2.
$2':ooo; $1cooooc
$2''' $1''''
+129 -46
View File
@@ -1987,6 +1987,16 @@ static const FFlogo H[] = {
FF_COLOR_FG_256 "123",
},
},
// Huawei Cloud EulerOS
{
.names = {"Huawei Cloud EulerOS", "hce"},
.lines = FASTFETCH_DATATEXT_LOGO_HCE,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Huayra
{
.names = {"Huayra"},
@@ -2332,6 +2342,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"},
@@ -2612,6 +2633,17 @@ static const FFlogo M[] = {
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// Magix
{
.names = {"Magix","MagixOS"},
.lines = FASTFETCH_DATATEXT_LOGO_MAGIX,
.colors = {
FF_COLOR_FG_LIGHT_MAGENTA,
FF_COLOR_FG_CYAN,
},
.colorKeys = FF_COLOR_FG_CYAN,
.colorTitle = FF_COLOR_FG_LIGHT_MAGENTA,
},
// MagpieOS
{
.names = {"MagpieOS", "Magpie"},
@@ -3959,6 +3991,25 @@ 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,
}
},
// 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"},
@@ -4097,7 +4148,7 @@ static const FFlogo S[] = {
},
// SteamOS
{
.names = {"steamos"},
.names = {"SteamOS"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMOS,
.colors = {
FF_COLOR_FG_BLUE,
@@ -4106,6 +4157,39 @@ static const FFlogo S[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck
{
.names = {"SteamDeck"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck Small
{
.names = {"SteamDeck_small"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK_SMALL,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Steam Deck OLED
{
.names = {"SteamDeckOled"},
.lines = FASTFETCH_DATATEXT_LOGO_STEAMDECK,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Sulin
{
.names = {"Sulin"},
@@ -4243,6 +4327,26 @@ static const FFlogo U[] = {
{
.names = {"ubuntu", "ubuntu-linux"},
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_RED,
},
},
// UbuntuSmall
{
.names = {"ubuntu_small", "ubuntu-linux-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_RED,
},
},
// UbuntuOld
{
.names = {"ubuntu_old", "ubuntu-linux_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
@@ -4250,6 +4354,30 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuOld2
{
.names = {"ubuntu_old2"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_YELLOW,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuOld2Small
{
.names = {"ubuntu_old2_small", "ubuntu_old2-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD2_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuBudgie
{
.names = {"ubuntu budgie", "ubuntu-budgie"},
@@ -4307,18 +4435,6 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_WHITE,
},
// UbuntuOld
{
.names = {"ubuntu_old", "ubuntu-linux_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuKde
{
.names = {"ubuntu kde", "ubuntu-kde", "ubuntu-plasma"},
@@ -4330,17 +4446,6 @@ static const FFlogo U[] = {
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// UbuntuSmall
{
.names = {"ubuntu_small", "ubuntu-linux-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// UbuntuStudio
{
.names = {"ubuntu studio", "ubuntu-studio"},
@@ -4377,28 +4482,6 @@ static const FFlogo U[] = {
FF_COLOR_FG_WHITE,
},
},
// Ubuntu2Small
{
.names = {"ubuntu2_small", "ubuntu2-small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_SMALL,
.colors = {
FF_COLOR_FG_RED,
},
.colorKeys = FF_COLOR_FG_RED,
.colorTitle = FF_COLOR_FG_RED,
},
// Ubuntu2Old
{
.names = {"ubuntu2_old"},
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_UBUNTU2_OLD,
.colors = {
FF_COLOR_FG_RED,
FF_COLOR_FG_WHITE,
FF_COLOR_FG_YELLOW,
},
},
// Ultramarine
{
.names = {"Ultramarine", "Ultramarine Linux"},
+4
View File
@@ -83,6 +83,8 @@ static bool printImageIterm(bool printError)
fprintf(stderr, "\nLogo (iterm): fail to query cursor position: %s\n", error);
return true; // We already printed image logo, don't print ascii logo then
}
if (X < options->paddingLeft + options->width)
X = (uint16_t) (options->paddingLeft + options->width);
if (options->position == FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = X + options->paddingRight - 1;
instance.state.logoHeight = Y;
@@ -207,6 +209,8 @@ static bool printImageKittyDirect(bool printError)
fprintf(stderr, "\nLogo (kitty-direct): fail to query cursor position: %s\n", error);
return true; // We already printed image logo, don't print ascii logo then
}
if (X < options->paddingLeft + options->width)
X = (uint16_t) (options->paddingLeft + options->width);
if (options->position == FF_LOGO_POSITION_LEFT)
instance.state.logoWidth = X + options->paddingRight - 1;
instance.state.logoHeight = Y;
+19 -2
View File
@@ -11,9 +11,26 @@
static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uint8_t index)
{
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
if (options->moduleArgs.key.length == 0)
{
if (result->modelName.length > 0)
ffStrbufSetF(&key, "%s (%s)", FF_BATTERY_MODULE_NAME, result->modelName.chars);
else
ffStrbufSetS(&key, FF_BATTERY_MODULE_NAME);
}
else
{
ffStrbufClear(&key);
FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &index, "index"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName, "name"},
}));
}
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
ffPrintLogoAndKey(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate();
bool showStatus =
@@ -63,7 +80,7 @@ static void printBattery(FFBatteryOptions* options, FFBatteryResult* result, uin
ffPercentAppendBar(&capacityBar, result->capacity, options->percent, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY tempStr = ffStrbufCreate();
ffTempsAppendNum(result->temperature, &tempStr, options->tempConfig, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(FF_BATTERY_MODULE_NAME, index, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
FF_PRINT_FORMAT_CHECKED(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_BATTERY_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->manufacturer, "manufacturer"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->modelName, "model-name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->technology, "technology"},
+2 -1
View File
@@ -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
+12 -1
View File
@@ -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"},
+12 -1
View File
@@ -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;
@@ -376,6 +385,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)
@@ -396,6 +406,7 @@ void ffPrintLocalIpHelpFormat(void)
"Interface name - ifname",
"Is default route - is-default-route",
"MTU size in bytes - mtu",
"Link speed (formatted) - speed",
}));
}
+1
View File
@@ -70,3 +70,4 @@
#include "modules/wifi/wifi.h"
#include "modules/wm/wm.h"
#include "modules/wmtheme/wmtheme.h"
#include "modules/zpool/zpool.h"
+1 -1
View File
@@ -68,7 +68,7 @@ void ffPrintNetIO(FFNetIOOptions* options)
if (!options->detectTotal) ffStrbufAppendS(&buffer, "/s");
ffStrbufAppendS(&buffer, " (OUT)");
if (inf->defaultRoute)
if (inf->defaultRoute && !options->defaultRouteOnly)
ffStrbufAppendS(&buffer, " *");
ffStrbufPutTo(&buffer, stdout);
}
+1
View File
@@ -70,3 +70,4 @@
#include "modules/wifi/option.h"
#include "modules/wm/option.h"
#include "modules/wmtheme/option.h"
#include "modules/zpool/option.h"
+1
View File
@@ -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
+9 -2
View File
@@ -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",
+14
View File
@@ -0,0 +1,14 @@
#pragma once
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
#include "common/option.h"
#include "common/percent.h"
typedef struct FFZpoolOptions
{
FFModuleBaseInfo moduleInfo;
FFModuleArgs moduleArgs;
FFColorRangeConfig percent;
} FFZpoolOptions;
+214
View File
@@ -0,0 +1,214 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "common/percent.h"
#include "detection/zpool/zpool.h"
#include "modules/zpool/zpool.h"
#include "util/stringUtils.h"
#define FF_ZPOOL_NUM_FORMAT_ARGS 8
static void printZpool(FFZpoolOptions* options, FFZpoolResult* result, uint8_t index)
{
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (options->moduleArgs.key.length == 0)
{
if (result->name.length > 0)
ffStrbufSetF(&buffer, "%s (%s)", FF_ZPOOL_MODULE_NAME, result->name.chars);
else
ffStrbufSetS(&buffer, FF_ZPOOL_MODULE_NAME);
}
else
{
ffStrbufClear(&buffer);
FF_PARSE_FORMAT_STRING_CHECKED(&buffer, &options->moduleArgs.key, 2, ((FFformatarg[]){
{FF_FORMAT_ARG_TYPE_UINT8, &index, "index"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"},
}));
}
FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate();
ffParseSize(result->used, &usedPretty);
FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate();
ffParseSize(result->total, &totalPretty);
double bytesPercentage = result->total > 0 ? (double) result->used / (double) result->total * 100.0 : 0;
double fragPercentage = (double) result->fragmentation;
if(options->moduleArgs.outputFormat.length == 0)
{
ffPrintLogoAndKey(buffer.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY);
ffStrbufClear(&buffer);
ffStrbufSetF(&buffer, "%s / %s (", usedPretty.chars, totalPretty.chars);
ffPercentAppendNum(&buffer, bytesPercentage, options->percent, false, &options->moduleArgs);
ffStrbufAppendS(&buffer, ", ");
ffPercentAppendNum(&buffer, fragPercentage, options->percent, false, &options->moduleArgs);
ffStrbufAppendF(&buffer, " frag) - %s", result->state.chars);
ffStrbufPutTo(&buffer, stdout);
}
else
{
FF_STRBUF_AUTO_DESTROY bytesPercentageNum = ffStrbufCreate();
ffPercentAppendNum(&bytesPercentageNum, bytesPercentage, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY bytesPercentageBar = ffStrbufCreate();
ffPercentAppendBar(&bytesPercentageBar, bytesPercentage, options->percent, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY fragPercentageNum = ffStrbufCreate();
ffPercentAppendNum(&fragPercentageNum, fragPercentage, options->percent, false, &options->moduleArgs);
FF_STRBUF_AUTO_DESTROY fragPercentageBar = ffStrbufCreate();
ffPercentAppendBar(&fragPercentageBar, fragPercentage, options->percent, &options->moduleArgs);
FF_PRINT_FORMAT_CHECKED(buffer.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_ZPOOL_NUM_FORMAT_ARGS, ((FFformatarg[]) {
{FF_FORMAT_ARG_TYPE_STRBUF, &result->name, "name"},
{FF_FORMAT_ARG_TYPE_STRBUF, &result->state, "state"},
{FF_FORMAT_ARG_TYPE_STRBUF, &usedPretty, "size-used"},
{FF_FORMAT_ARG_TYPE_STRBUF, &totalPretty, "size-total"},
{FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageNum, "size-percentage"},
{FF_FORMAT_ARG_TYPE_STRBUF, &fragPercentage, "frag-percentage"},
{FF_FORMAT_ARG_TYPE_STRBUF, &bytesPercentageBar, "size-percentage-bar"},
{FF_FORMAT_ARG_TYPE_STRBUF, &fragPercentageBar, "frag-percentage-bar"},
}));
}
}
void ffPrintZpool(FFZpoolOptions* options)
{
FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFZpoolResult));
const char* error = ffDetectZpool(&results);
if (error)
{
ffPrintError(FF_ZPOOL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error);
return;
}
if(results.length == 0)
{
ffPrintError(FF_ZPOOL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", "No zpool found");
return;
}
for(uint32_t i = 0; i < results.length; i++)
{
FFZpoolResult* result = FF_LIST_GET(FFZpoolResult, results, i);
uint8_t index = results.length == 1 ? 0 : (uint8_t) (i + 1);
printZpool(options, result, index);
}
FF_LIST_FOR_EACH(FFZpoolResult, result, results)
{
ffStrbufDestroy(&result->name);
ffStrbufDestroy(&result->state);
}
}
bool ffParseZpoolCommandOptions(FFZpoolOptions* options, const char* key, const char* value)
{
const char* subKey = ffOptionTestPrefix(key, FF_ZPOOL_MODULE_NAME);
if (!subKey) return false;
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
return true;
if (ffPercentParseCommandOptions(key, subKey, value, &options->percent))
return true;
return false;
}
void ffParseZpoolJsonObject(FFZpoolOptions* options, yyjson_val* module)
{
yyjson_val *key_, *val;
size_t idx, max;
yyjson_obj_foreach(module, idx, max, key_, val)
{
const char* key = yyjson_get_str(key_);
if(ffStrEqualsIgnCase(key, "type"))
continue;
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
continue;
if (ffPercentParseJsonObject(key, val, &options->percent))
continue;
ffPrintError(FF_ZPOOL_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key);
}
}
void ffGenerateZpoolJsonConfig(FFZpoolOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
__attribute__((__cleanup__(ffDestroyZpoolOptions))) FFZpoolOptions defaultOptions;
ffInitZpoolOptions(&defaultOptions);
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
ffPercentGenerateJsonConfig(doc, module, defaultOptions.percent, options->percent);
}
void ffGenerateZpoolJsonResult(FF_MAYBE_UNUSED FFZpoolOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
{
FF_LIST_AUTO_DESTROY results = ffListCreate(sizeof(FFZpoolResult));
const char* error = ffDetectZpool(&results);
if (error)
{
yyjson_mut_obj_add_str(doc, module, "error", error);
return;
}
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
FF_LIST_FOR_EACH(FFZpoolResult, zpool, results)
{
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
yyjson_mut_obj_add_strbuf(doc, obj, "name", &zpool->name);
yyjson_mut_obj_add_strbuf(doc, obj, "state", &zpool->state);
yyjson_mut_obj_add_uint(doc, obj, "used", zpool->used);
yyjson_mut_obj_add_uint(doc, obj, "total", zpool->total);
yyjson_mut_obj_add_uint(doc, obj, "version", zpool->version);
yyjson_mut_obj_add_uint(doc, obj, "fragmentation", zpool->fragmentation);
}
FF_LIST_FOR_EACH(FFZpoolResult, battery, results)
{
ffStrbufDestroy(&battery->name);
ffStrbufDestroy(&battery->state);
}
}
void ffPrintZpoolHelpFormat(void)
{
FF_PRINT_MODULE_FORMAT_HELP_CHECKED(FF_ZPOOL_MODULE_NAME, "{3} / {4} ({5}, {6} frag)", FF_ZPOOL_NUM_FORMAT_ARGS, ((const char* []) {
"Zpool name - name",
"Zpool state - state",
"Size used - size-used",
"Size total - size-total",
"Size percentage num - size-percentage",
"Fragmentation percentage num - frag-percentage",
"Size percentage bar - size-percentage-bar",
"Fragmentation percentage bar - frag-percentage-bar",
}));
}
void ffInitZpoolOptions(FFZpoolOptions* options)
{
ffOptionInitModuleBaseInfo(
&options->moduleInfo,
FF_ZPOOL_MODULE_NAME,
"Print ZFS storage pools",
ffParseZpoolCommandOptions,
ffParseZpoolJsonObject,
ffPrintZpool,
ffGenerateZpoolJsonResult,
ffPrintZpoolHelpFormat,
ffGenerateZpoolJsonConfig
);
ffOptionInitModuleArg(&options->moduleArgs, "󱑛");
options->percent = (FFColorRangeConfig) { 50, 80 };
}
void ffDestroyZpoolOptions(FFZpoolOptions* options)
{
ffOptionDestroyModuleArg(&options->moduleArgs);
}
+9
View File
@@ -0,0 +1,9 @@
#pragma once
#include "fastfetch.h"
#define FF_ZPOOL_MODULE_NAME "Zpool"
void ffPrintZpool(FFZpoolOptions* options);
void ffInitZpoolOptions(FFZpoolOptions* options);
void ffDestroyZpoolOptions(FFZpoolOptions* options);
+2
View File
@@ -71,6 +71,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
ffInitWallpaperOptions(&options->wallpaper);
ffInitWeatherOptions(&options->weather);
ffInitWifiOptions(&options->wifi);
ffInitZpoolOptions(&options->zpool);
}
void ffOptionsDestroyModules(FFOptionsModules* options)
@@ -143,4 +144,5 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
ffDestroyWallpaperOptions(&options->wallpaper);
ffDestroyWeatherOptions(&options->weather);
ffDestroyWifiOptions(&options->wifi);
ffDestroyZpoolOptions(&options->zpool);
}
+1
View File
@@ -72,6 +72,7 @@ typedef struct FFOptionsModules
FFWallpaperOptions wallpaper;
FFWeatherOptions weather;
FFWifiOptions wifi;
FFZpoolOptions zpool;
} FFOptionsModules;
void ffOptionsInitModules(FFOptionsModules* options);
+5
View File
@@ -0,0 +1,5 @@
#pragma once
#include "fastfetch.h"
const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength);
+187
View File
@@ -0,0 +1,187 @@
#include "binary.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <mach-o/loader.h>
#include <mach-o/swap.h>
#include <mach-o/fat.h>
#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, uint32_t minLength)
{
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 (len < minLength) continue;
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 minLength)
{
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, &section, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section))))
continue;
if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata, minLength))
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, &section, sizeof(section), (off_t) ((size_t) commandOffset + sizeof(segment) + j * sizeof(section))))
continue;
if (!handleMachSection(objFile, section.sectname, section.offset, section.size, cb, userdata, minLength))
return NULL;
}
}
return NULL;
}
return NULL;
}
static const char* dumpFatHeader(FILE *objFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
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, minLength);
return NULL;
}
}
return "Unsupported fat header";
}
const char *ffBinaryExtractStrings(const char *machoFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
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, minLength);
else
return dumpMachHeader(objFile, 0, magic == MH_MAGIC_64, cb, userdata, minLength);
}
+108
View File
@@ -0,0 +1,108 @@
#include "binary.h"
#if defined(FF_HAVE_ELF) || defined(__sun)
#include "common/io/io.h"
#include "common/library.h"
#include "util/stringUtils.h"
#include <libelf.h>
#include <fcntl.h>
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* ffBinaryExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength)
{
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 = elfData.ffelf_begin(fd, ELF_C_READ, NULL);
if (elf == NULL) return "elf_begin() failed";
size_t shstrndx = 0;
if (elfData.ffelf_getshdrstrndx(elf, &shstrndx) < 0)
{
elfData.ffelf_end(elf);
return "elf_getshdrstrndx() failed";
}
Elf_Scn* scn = NULL;
while ((scn = elfData.ffelf_nextscn(elf, scn)) != NULL)
{
Elf64_Shdr* shdr64 = elfData.ffelf64_getshdr(scn);
Elf32_Shdr* shdr32 = NULL;
if (shdr64 == NULL)
{
shdr32 = elfData.ffelf32_getshdr(scn);
if (shdr32 == NULL) continue;
}
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 = elfData.ffelf_getdata(scn, NULL);
if (data == NULL) continue;
for (size_t off = 0; off < data->d_size; ++off)
{
const char* p = (const char*) data->d_buf + off;
if (*p == '\0') continue;
uint32_t len = (uint32_t) strlen(p);
if (len < minLength) continue;
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
if (!cb(p, len, userdata)) break;
}
off += len;
}
break;
}
elfData.ffelf_end(elf);
return NULL;
}
#else
const char* ffBinaryExtractStrings(const char* file, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata, uint32_t minLength)
{
FF_UNUSED(file, cb, userdata, minLength);
return "Fastfetch was built without libelf support";
}
#endif
+40
View File
@@ -0,0 +1,40 @@
#include "binary.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include <windows.h>
#include <imagehlp.h>
#include <stdlib.h>
#include <string.h>
const char* ffBinaryExtractStrings(const char *peFile, bool (*cb)(const char *str, uint32_t len, void *userdata), void *userdata, uint32_t minLength)
{
__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 (len < minLength) continue;
if (*p >= ' ' && *p <= '~') // Ignore control characters
{
if (!cb(p, len, userdata)) break;
}
off += len;
}
}
}
return NULL;
}
-84
View File
@@ -1,84 +0,0 @@
#include "elf.h"
#ifdef FF_HAVE_ELF
#include "common/io/io.h"
#include "common/library.h"
#include "util/stringUtils.h"
#include <libelf.h>
#include <fcntl.h>
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";
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);
if (elf == NULL) return "elf_begin() failed";
size_t shstrndx = 0;
if (ffelf_getshdrstrndx(elf, &shstrndx) < 0)
{
ffelf_end(elf);
return "elf_getshdrstrndx() failed";
}
Elf_Scn* scn = NULL;
while ((scn = ffelf_nextscn(elf, scn)) != NULL)
{
Elf64_Shdr* shdr64 = ffelf64_getshdr(scn);
Elf32_Shdr* shdr32 = NULL;
if (shdr64 == NULL)
{
shdr32 = ffelf32_getshdr(scn);
if (shdr32 == NULL) continue;
}
const char* name = 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);
if (data == NULL) continue;
for (size_t off = 0; off < data->d_size; ++off)
{
const char* p = (const char*) data->d_buf + 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;
}
break;
}
ffelf_end(elf);
return NULL;
}
#else
const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata)
{
FF_UNUSED(elfFile, cb, userdata);
return "Fastfetch was built without libelf support";
}
#endif
-5
View File
@@ -1,5 +0,0 @@
#pragma once
#include "fastfetch.h"
const char* ffElfExtractStrings(const char* elfFile, bool (*cb)(const char* str, uint32_t len, void* userdata), void* userdata);
+59
View File
@@ -0,0 +1,59 @@
#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 = 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
'\\'
#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
}
+6
View File
@@ -0,0 +1,6 @@
#pragma once
#include "fastfetch.h"
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result);
bool ffIsAbsolutePath(const char* path);
+80
View File
@@ -0,0 +1,80 @@
#include "common/format.h"
#include "util/textModifier.h"
#include "fastfetch.h"
static void verify(const char* format, const char* arg, const char* expected, int lineNo)
{
FF_STRBUF_AUTO_DESTROY result = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY formatter = ffStrbufCreateStatic(format);
const FFformatarg arguments[] = {
{ .type = FF_FORMAT_ARG_TYPE_STRING, arg }
};
ffParseFormatString(&result, &formatter, 1, arguments);
if (!ffStrbufEqualS(&result, expected))
{
fprintf(stderr, FASTFETCH_TEXT_MODIFIER_ERROR "[%d] %s: expected \"%s\", got \"%s\"\n" FASTFETCH_TEXT_MODIFIER_RESET, lineNo, format, expected, result.chars);
exit(1);
}
}
#define VERIFY(format, argument, expected) verify((format), (argument), (expected), __LINE__)
int main(void)
{
instance.config.display.pipe = true;
{
VERIFY("output({})", "12345 67890", "output(12345 67890)");
VERIFY("output({1})", "12345 67890", "output(12345 67890)");
VERIFY("output({})", "", "output()");
VERIFY("output({1})", "", "output()");
}
{
VERIFY("output({1:20})", "12345 67890", "output(12345 67890)");
VERIFY("output({1:11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1:-11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1:6})", "12345 67890", "output(12345)");
VERIFY("output({:6})", "12345 67890", "output(12345)");
VERIFY("output({:-6})", "12345 67890", "output(12345…)");
VERIFY("output({:0})", "12345 67890", "output()");
VERIFY("output({:})", "12345 67890", "output()");
}
{
VERIFY("output({1<20})", "12345 67890", "output(12345 67890 )");
VERIFY("output({1<-20})", "12345 67890", "output(12345 67890 )");
VERIFY("output({1<11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1<-11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1<6})", "12345 67890", "output(12345 )");
VERIFY("output({<6})", "12345 67890", "output(12345 )");
VERIFY("output({<-6})", "12345 67890", "output(12345…)");
VERIFY("output({<0})", "12345 67890", "output()");
VERIFY("output({<})", "12345 67890", "output()");
}
{
VERIFY("output({1>20})", "12345 67890", "output( 12345 67890)");
VERIFY("output({1>-20})", "12345 67890", "output( 12345 67890)");
VERIFY("output({1>11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1>-11})", "12345 67890", "output(12345 67890)");
VERIFY("output({1>6})", "12345 67890", "output(12345 )");
VERIFY("output({>6})", "12345 67890", "output(12345 )");
VERIFY("output({>-6})", "12345 67890", "output(12345…)");
VERIFY("output({>0})", "12345 67890", "output()");
VERIFY("output({>})", "12345 67890", "output()");
}
{
VERIFY("output({1n>20})", "12345 67890", "output({1n>20})");
VERIFY("output({120})", "12345 67890", "output({120})");
VERIFY("output({1:11})", "", "output()");
}
{
VERIFY("output({1:20}{1<20}{1>20})", "12345 67890", "output(12345 6789012345 67890 12345 67890)");
}
//Success
puts("\033[32mAll tests passed!" FASTFETCH_TEXT_MODIFIER_RESET);
}