Compare commits

...

44 Commits

Author SHA1 Message Date
Carter Li 5769791185 Merge pull request #1691 from fastfetch-cli/dev
Release: v2.41.0
2025-04-16 13:29:07 +08:00
李通洲 894c66d793 Processing (Windows): fix macro name __aarch64__
Found by AI
2025-04-16 11:12:36 +08:00
李通洲 75290154b0 Chore: remove Chinese comments [ci skip] 2025-04-16 11:09:03 +08:00
李通洲 b08eea76b1 CI (Linux): enable chafa on Linux aarch64 2025-04-16 10:45:25 +08:00
李通洲 61d83af9ea CI (Linux): bump GH runner for linux-amd64
Ref: https://github.com/actions/runner-images/issues/11101
2025-04-16 10:45:02 +08:00
李通洲 2d497038eb Release: v2.41.0 2025-04-16 09:24:20 +08:00
李通洲 f8a5d5561a Bluetooth (NetBSD): add base implementation
Ref: #1690
2025-04-15 19:06:39 +08:00
李通洲 2e7e68ef23 Doc: add installation instructions for pkgsrc [ci skip]
Fix #1689
2025-04-15 19:04:19 +08:00
李通洲 b812f3ccde Uptime (Windows): use QueryUnbiasedInterruptTime
As suggested by MSDN
2025-04-15 16:41:38 +08:00
李通洲 6da8181bbe CMake: use mincore on WoA 2025-04-15 16:41:38 +08:00
李通洲 a51dd641c1 Processing (Windows): use GetOverlappedResultEx on WoA 2025-04-15 16:41:38 +08:00
李通洲 0d20164d40 CI (Windows): add WoA 2025-04-15 10:59:10 +08:00
李通洲 3320532668 GPU (Linux): add temp detection for Intel GPU
Untested
2025-04-14 18:57:15 +08:00
Carter Li bcc6492115 NetIO (Linux): use openat 2025-04-14 18:48:04 +08:00
naix c60bc8ee5b Logo (Builtin): Add 2 more Alpine logos (#1687)
* Logo (Builtin): Add 2 more Alpine logos

* Remove unnecessary $1 in ASCII logo file

* Add type field to Alpine2 logo configuration

---------

Co-authored-by: naix <naix@noreply.codeberg.org>
Co-authored-by: Carter Li <CarterLi@users.noreply.github.com>
2025-04-14 00:50:45 -05:00
李通洲 4eefab8ccf CPU (Linux): fix build 2025-04-14 10:54:35 +08:00
李通洲 9cda7e20fb Chore: simplify fastfetch.h 2025-04-14 10:28:01 +08:00
李通洲 79d0197dcf Wifi (FreeBSD): remove unused sys headers 2025-04-14 10:04:11 +08:00
李通洲 ba01b1e4ce CPU (Linux): add new ARM part numbers 2025-04-14 09:27:01 +08:00
李通洲 58908f69ba Wifi (OpenBSD): add support
Completely untested.
2025-04-13 00:37:40 +08:00
李通洲 114088b845 Doc: add comments about displaying image logo on Windows [ci skip]
Fix  #1686
2025-04-12 20:38:42 +08:00
李通洲 6e77b592cb WM (FreeBSD): enable Hyprland version detection 2025-04-12 10:48:26 +08:00
李通洲 73bc71e922 CPU (Windows): use PDH to detect thermal temp
No Administrator privileges needed
2025-04-12 10:47:57 +08:00
Anduin Xue 090529ffef Logo (Builtin): Add support for anduinos (#1684)
* Add anduinos

* fix logo.

* Update anduinos.txt
2025-04-10 23:13:26 +08:00
李通洲 3c291f1af9 Platform: retrieve full user name 2025-04-09 16:15:23 +08:00
李通洲 fc31fe4aa4 Merge branch 'master' into dev 2025-04-09 14:39:51 +08:00
李通洲 563f9598be Release: v2.40.4 2025-04-09 14:24:27 +08:00
Carter Li 03bc2dade9 Fastfetch: fix loading presets in {exePath}/presets
Regression of v2.40.0
2025-04-09 14:15:06 +08:00
Carter Li 09d683b706 WM (Linux): remove v from Hyprland version 2025-04-09 14:14:56 +08:00
Carter Li 523a9590b8 Fastfetch: fix loading presets in {exePath}/presets
Regression of v2.40.0
2025-04-08 15:42:58 +08:00
李通洲 3c3188eb05 IO (Windows): support ~ expanding 2025-04-07 16:43:48 +08:00
李通洲 354062118f Chore: update comment 2025-04-07 16:43:48 +08:00
李通洲 85d7390fa8 Util (Windows): use native win32 functions 2025-04-07 16:38:54 +08:00
Carter Li 8509f97054 WM (Linux): remove v from Hyprland version 2025-04-06 17:21:32 +08:00
Rabindra Dhakal 8d5d8b4c90 Packages (Linux): add soar packages count (#1531)
* add soar packages count

* use || instead of concat for better compatibility with older SQLite versions

* convert package flags to 64-bit
2025-04-05 23:54:27 +08:00
李通洲 536ad9594e PhysicalDisk (Linux): add more disk types 2025-04-05 22:35:42 +08:00
李通洲 a57bbbadf4 PhysicalDisk (Linux): don't detect disk type for virtual disks
Fix #1669
2025-04-05 22:35:42 +08:00
李通洲 3def466ee0 Revert "CPU (FreeBSD): remove using of freq_levels"
This reverts commit ed2dd8f2ec.
2025-04-05 13:54:20 +08:00
李通洲 59868c66a0 CPU (FreeBSD): don't assume one SMT group has only two threads
Fix #1670
2025-04-05 13:48:18 +08:00
Carter Li e13eb05073 CPU (Linux): detect physical core count on non-x86 platforms 2025-04-05 12:08:35 +08:00
Carter Li cdda65e6ad Merge pull request #1673 from fastfetch-cli/dev
Release: v2.40.3
2025-04-05 09:14:34 +08:00
Carter Li a7ac89818c Logo (Image): mark kitty image protocol support for warp terminal on macOS 2025-04-05 08:59:35 +08:00
李通洲 06956d2cf4 Release: v2.40.3 2025-04-05 08:42:24 +08:00
李通洲 ac52ea1afb Fastfetch: fix loading example configs from presets directory
Fix #1672
2025-04-05 08:42:24 +08:00
45 changed files with 800 additions and 224 deletions
+72 -4
View File
@@ -60,7 +60,7 @@ jobs:
linux-amd64:
name: Linux-amd64
runs-on: ubuntu-20.04
runs-on: ubuntu-22.04
permissions:
security-events: write
contents: read
@@ -80,12 +80,12 @@ jobs:
run: cat /proc/cpuinfo
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev libddcutil-dev directx-headers-dev
- name: install linuxbrew packages
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa ddcutil --ignore-dependencies
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
@@ -151,8 +151,13 @@ jobs:
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev librpm-dev libegl-dev libglx-dev ocl-icd-opencl-dev libpulse-dev libdrm-dev libelf-dev directx-headers-dev libchafa-dev libddcutil-dev rpm
- name: install linuxbrew packages
run: |
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
/home/linuxbrew/.linuxbrew/bin/brew install imagemagick chafa --ignore-dependencies
- name: configure project
run: cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
run: PKG_CONFIG_PATH=/home/linuxbrew/.linuxbrew/lib/pkgconfig:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On -DCMAKE_INSTALL_PREFIX=/usr .
- name: build project
run: cmake --build . --target package --verbose -j4
@@ -654,6 +659,68 @@ jobs:
name: fastfetch-windows-amd64
path: ./fastfetch-windows-amd64.*
windows-aarch64:
name: Windows-aarch64
runs-on: windows-11-arm
permissions:
security-events: write
contents: read
defaults:
run:
shell: msys2 {0}
steps:
- name: checkout repository
uses: actions/checkout@v4
- name: setup-msys2
uses: msys2/setup-msys2@v2
with:
msystem: CLANGARM64
update: true
install: git mingw-w64-clang-aarch64-7zip mingw-w64-clang-aarch64-cmake mingw-w64-clang-aarch64-clang mingw-w64-clang-aarch64-vulkan-loader mingw-w64-clang-aarch64-vulkan-headers mingw-w64-clang-aarch64-opencl-icd mingw-w64-clang-aarch64-opencl-headers mingw-w64-clang-aarch64-cppwinrt mingw-w64-clang-aarch64-imagemagick
- name: print msys version
run: uname -a
- name: configure project
run: env PKG_CONFIG_PATH=/clangarm64/lib/pkgconfig/:$PKG_CONFIG_PATH cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
- name: build project
run: cmake --build . --verbose -j4
- name: copy necessary dlls
run: cp /clangarm64/bin/{OpenCL,vulkan-1}.dll .
- name: list features
run: ./fastfetch --list-features
- name: run fastfetch
run: time ./fastfetch -c presets/ci.jsonc --stat false
- name: run fastfetch --format json
run: time ./fastfetch -c presets/ci.jsonc --format json
- name: run flashfetch
run: time ./flashfetch
- name: print dependencies
run: ldd fastfetch
- name: run tests
run: ctest --output-on-failure
- name: create zip archive
run: 7z a -tzip -mx9 -bd -y fastfetch-windows-aarch64.zip LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: create 7z archive
run: 7z a -t7z -mx9 -bd -y fastfetch-windows-aarch64.7z LICENSE *.dll fastfetch.exe flashfetch.exe presets
- name: upload artifacts
uses: actions/upload-artifact@v4
with:
name: fastfetch-windows-aarch64
path: ./fastfetch-windows-aarch64.*
release:
if: github.event_name == 'push' && github.ref == 'refs/heads/master' && github.repository == 'fastfetch-cli/fastfetch'
name: Release
@@ -673,6 +740,7 @@ jobs:
- netbsd-amd64
- sunos-amd64
- windows-amd64
- windows-aarch64
permissions:
contents: write
steps:
+44
View File
@@ -1,3 +1,47 @@
# 2.41.0
Changes:
* Due to [the deprecation](https://github.com/actions/runner-images/issues/11101), Linux x86_64 binaries are now built with Ubuntu 22.04 (Glibc 2.35, Debian 12)
* You can always build fastfetch yourself on your own. Please don't report bugs related to this change.
Bugfixes:
* Don't detect disk type for virtual disks (PhysicalDisk, Linux, #1669)
Features:
* Support physical core count detection on non-x86 platforms (CPU, Linux / FreeBSD)
* Support CPU frequency detection on PPC64 (CPU, FreeBSD)
* Support soar packages count detection (Packages, Linux)
* Support `~` path expanding on Windows (Logo, Windows)
* Support retrieving full user name (Title)
* Exposed with `--title-format '{full-user-name}'`
* Improve CPU (thermal zone) temperature detection on Windows (CPU, Windows)
* Administrator privileges are no longer needed
* Support base Wifi info detection on OpenBSD (Wifi, OpenBSD)
* To be tested
* Support GPU temperature detection for Intel dGPU on Linux (GPU, Linux)
* To be tested
* Add new ARM CPU part numbers (CPU, Linux)
* Add base implementation of Bluetooth device detection (Bluetooth, NetBSD, #1690)
* Some small improvements
Logo:
* Add anduinos
* Add 2 more Alpine logos
# 2.40.4
Bugfixes:
* Fix loading presets config on Windows (Windows, #1682)
* Regression of v2.40.0
* Remove the prefix `v` of Hyprland version on Arch Linux (WM, Linux)
# 2.40.3
Bugfixes:
* Fix loading example configs from presets directory (#1672)
* Regression of v2.40.2
* Mark kitty image protocol support for warp terminal on macOS too (Logo)
# 2.40.2
Changes:
+14 -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.40.2
VERSION 2.41.0
LANGUAGES C
DESCRIPTION "Fast neofetch-like system information tool"
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
@@ -102,7 +102,7 @@ if(NOT BINARY_LINK_TYPE IN_LIST BINARY_LINK_TYPE_OPTIONS)
message(FATAL_ERROR "BINARY_LINK_TYPE must be one of ${BINARY_LINK_TYPE_OPTIONS}")
endif()
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SORCERY WINGET XBPS)
set(PACKAGE_MANAGERS AM APK BREW CHOCO DPKG EMERGE EOPKG FLATPAK GUIX LINGLONG LPKG LPKGBUILD MACPORTS NIX OPKG PACMAN PACSTALL PALUDIS PISI PKG PKGTOOL RPM SCOOP SNAP SOAR SORCERY WINGET XBPS)
foreach(package_manager ${PACKAGE_MANAGERS})
if(package_manager STREQUAL "WINGET")
option(PACKAGES_DISABLE_${package_manager} "Disable ${package_manager} package manager detection by default" ON)
@@ -705,7 +705,7 @@ elseif(FreeBSD)
src/detection/uptime/uptime_bsd.c
src/detection/users/users_linux.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wm/wm_nosupport.c
src/detection/wm/wm_linux.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
src/detection/camera/camera_linux.c
@@ -734,7 +734,7 @@ elseif(NetBSD)
src/common/sysctl.c
src/detection/battery/battery_nbsd.c
src/detection/bios/bios_nbsd.c
src/detection/bluetooth/bluetooth_nosupport.c
src/detection/bluetooth/bluetooth_bsd.c
src/detection/bluetoothradio/bluetoothradio_nosupport.c
src/detection/board/board_nbsd.c
src/detection/bootmgr/bootmgr_bsd.c
@@ -879,7 +879,7 @@ elseif(OpenBSD)
src/detection/uptime/uptime_bsd.c
src/detection/users/users_obsd.c
src/detection/wallpaper/wallpaper_linux.c
src/detection/wifi/wifi_nosupport.c
src/detection/wifi/wifi_nbsd.c
src/detection/wm/wm_nosupport.c
src/detection/de/de_linux.c
src/detection/wmtheme/wmtheme_linux.c
@@ -977,7 +977,6 @@ elseif(WIN32)
src/detection/btrfs/btrfs_nosupport.c
src/detection/chassis/chassis_windows.c
src/detection/cpu/cpu_windows.c
src/detection/cpu/cpu_windows.cpp
src/detection/cpucache/cpucache_windows.c
src/detection/cpuusage/cpuusage_windows.c
src/detection/cursor/cursor_windows.c
@@ -1589,7 +1588,15 @@ elseif(WIN32)
PRIVATE "cfgmgr32"
PRIVATE "winbrand"
PRIVATE "propsys"
PRIVATE "secur32"
PRIVATE "pdh"
)
if(CMAKE_SYSTEM_PROCESSOR STREQUAL "ARM64")
# WoA only works on Windows 10 or higher
target_link_libraries(libfastfetch
PRIVATE "mincore"
)
endif()
elseif(FreeBSD)
target_link_libraries(libfastfetch
PRIVATE "m"
@@ -1613,6 +1620,7 @@ elseif(OpenBSD)
)
elseif(NetBSD)
target_link_libraries(libfastfetch
PRIVATE "bluetooth"
PRIVATE "m"
PRIVATE "prop"
)
+54
View File
@@ -71,6 +71,10 @@ You may also download the program directly from [the GitHub releases page](https
* `pkg install fastfetch`
### NetBSD
* `pkgin in fastfetch`
### Android (Termux)
* `pkg install fastfetch`
@@ -230,6 +234,56 @@ Set the key to a white space.
}
```
### Q: How can I display images on Windows?
As of April 2025:
#### mintty and Wezterm
mintty (used by Bash on Windows and MSYS2) and Wezterm (nightly build only) support the iTerm image protocol on Windows.
In `config.jsonc`:
```json
{
"logo": {
"type": "iterm",
"source": "C:/path/to/image.png",
"width": <num-in-chars>
}
}
```
#### Windows Terminal
Windows Terminal supports the sixel image protocol only.
* If you installed fastfetch through MSYS2:
1. Install imagemagick: `pacman -S mingw-w64-<subsystem>-x86_64-imagemagick`
2. In `config.jsonc`:
```jsonc
{
"logo": {
"type": "sixel", // DO NOT USE "auto"
"source": "C:/path/to/image.png", // Do NOT use `~` as fastfetch is a native Windows program and doesn't apply cygwin path conversion
"width": <image-width-in-chars>, // Optional
"height": <image-height-in-chars> // Optional
}
}
```
* If you installed fastfetch via scoop or downloaded the binary directly from the GitHub Releases page:
1. Convert your image manually to sixel format using [any online image conversion service](https://www.google.com/search?q=convert+image+to+sixel)
2. In `config.jsonc`:
```jsonc
{
"logo": {
"type": "raw", // DO NOT USE "auto"
"source": "C:/path/to/image.sixel",
"width": <image-width-in-chars>, // Required
"height": <image-height-in-chars> // Required
}
}
```
### Q: I want feature A / B / C. Will fastfetch support it?
Fastfetch is a system information tool. We only accept hardware or system-level software feature requests. For most personal uses, I recommend using the `Command` module to implement custom functionality, which can be used to grab output from a custom shell script:
+1 -1
View File
@@ -279,7 +279,7 @@
"type": "string"
},
"packagesFormat": {
"description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop}: Number of scoop packages\n 21. {choco}: Number of choco packages\n 22. {pkgtool}: Number of pkgtool packages\n 23. {paludis}: Number of paludis packages\n 24. {winget}: Number of winget packages\n 25. {opkg}: Number of opkg packages\n 26. {am-system}: Number of am-system packages\n 27. {sorcery}: Number of sorcery packages\n 28. {lpkg}: Number of lpkg packages\n 29. {lpkgbuild}: Number of lpkgbuild packages\n 30. {guix-system}: Number of guix-system packages\n 31. {guix-user}: Number of guix-user packages\n 32. {guix-home}: Number of guix-home packages\n 33. {linglong}: Number of linglong packages\n 34. {pacstall}: Number of pacstall packages\n 35. {mport}: Number of mport packages\n 36. {qi}: Number of qi packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {nix-all}: Total number of all nix packages\n 43. {flatpak-all}: Total number of all flatpak app packages\n 44. {brew-all}: Total number of all brew packages\n 45. {guix-all}: Total number of all guix packages\n 46. {hpkg-all}: Total number of all hpkg packages",
"description": "Output format of the module `Packages`. See Wiki for formatting syntax\n 1. {all}: Number of all packages\n 2. {pacman}: Number of pacman packages\n 3. {pacman-branch}: Pacman branch on manjaro\n 4. {dpkg}: Number of dpkg packages\n 5. {rpm}: Number of rpm packages\n 6. {emerge}: Number of emerge packages\n 7. {eopkg}: Number of eopkg packages\n 8. {xbps}: Number of xbps packages\n 9. {nix-system}: Number of nix-system packages\n 10. {nix-user}: Number of nix-user packages\n 11. {nix-default}: Number of nix-default packages\n 12. {apk}: Number of apk packages\n 13. {pkg}: Number of pkg packages\n 14. {flatpak-system}: Number of flatpak-system app packages\n 15. {flatpak-user}: Number of flatpak-user app packages\n 16. {snap}: Number of snap packages\n 17. {brew}: Number of brew packages\n 18. {brew-cask}: Number of brew-cask packages\n 19. {macports}: Number of macports packages\n 20. {scoop}: Number of scoop packages\n 21. {choco}: Number of choco packages\n 22. {pkgtool}: Number of pkgtool packages\n 23. {paludis}: Number of paludis packages\n 24. {winget}: Number of winget packages\n 25. {opkg}: Number of opkg packages\n 26. {am-system}: Number of am-system packages\n 27. {sorcery}: Number of sorcery packages\n 28. {lpkg}: Number of lpkg packages\n 29. {lpkgbuild}: Number of lpkgbuild packages\n 30. {guix-system}: Number of guix-system packages\n 31. {guix-user}: Number of guix-user packages\n 32. {guix-home}: Number of guix-home packages\n 33. {linglong}: Number of linglong packages\n 34. {pacstall}: Number of pacstall packages\n 35. {mport}: Number of mport packages\n 36. {qi}: Number of qi packages\n 37. {am-user}: Number of am-user (aka appman) packages\n 38. {pkgsrc}: Number of pkgsrc packages\n 39. {hpkg-system}: Number of hpkg-system packages\n 40. {hpkg-user}: Number of hpkg-user packages\n 41. {pisi}: Number of pisi packages\n 42. {soar}: Number of soar packages\n 43. {nix-all}: Total number of all nix packages\n 44. {flatpak-all}: Total number of all flatpak app packages\n 45. {brew-all}: Total number of all brew packages\n 46. {guix-all}: Total number of all guix packages\n 47. {hpkg-all}: Total number of all hpkg packages",
"type": "string"
},
"physicaldiskFormat": {
+1
View File
@@ -1,4 +1,5 @@
#include "fastfetch.h"
#include "common/init.h"
#include "common/parsing.h"
#include "common/thread.h"
#include "detection/displayserver/displayserver.h"
+7
View File
@@ -0,0 +1,7 @@
#pragma once
void ffInitInstance(void);
void ffStart(void);
void ffFinish(void);
void ffDestroyInstance(void);
void ffListFeatures(void);
+8
View File
@@ -147,6 +147,14 @@ ssize_t ffReadFileDataRelative(HANDLE dfd, const char* fileName, size_t dataSize
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
{
if (in[0] == '~') {
if ((in[1] == '/' || in[1] == '\\' || in[1] == '\0') && !ffStrContainsC(in, '%')) {
ffStrbufSet(out, &instance.state.platform.homeDir);
ffStrbufAppendS(out, in + 1);
return true;
}
}
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
if (length <= 1) return false;
+1
View File
@@ -1,5 +1,6 @@
#include "fastfetch.h"
#include "common/printing.h"
#include "logo/logo.h"
#include "util/textModifier.h"
void ffPrintLogoAndKey(const char* moduleName, uint8_t moduleIndex, const FFModuleArgs* moduleArgs, FFPrintType printType)
+11 -2
View File
@@ -130,7 +130,11 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
switch (GetLastError())
{
case ERROR_IO_PENDING:
if (!timeout || WaitForSingleObject(hChildPipeRead, (DWORD) timeout) != WAIT_OBJECT_0)
#if __aarch64__
if (!GetOverlappedResultEx(hChildPipeRead, &overlapped, &nRead, timeout < 0 ? INFINITE : (DWORD) timeout, FALSE))
#else
// To support Windows 7
if (timeout >= 0 && WaitForSingleObject(hChildPipeRead, (DWORD) timeout) != WAIT_OBJECT_0)
{
CancelIo(hChildPipeRead);
TerminateProcess(hProcess, 1);
@@ -138,13 +142,18 @@ const char* ffProcessAppendOutput(FFstrbuf* buffer, char* const argv[], bool use
}
if (!GetOverlappedResult(hChildPipeRead, &overlapped, &nRead, FALSE))
#endif
{
if (GetLastError() == ERROR_BROKEN_PIPE)
return NULL;
CancelIo(hChildPipeRead);
TerminateProcess(hProcess, 1);
return "GetOverlappedResult(hChildPipeRead) failed";
return "GetOverlappedResult"
#if __aarch64__
"Ex"
#endif
"(hChildPipeRead) failed";
}
break;
+7 -1
View File
@@ -6,7 +6,13 @@
static int enumDev(FF_MAYBE_UNUSED int sockfd, struct bt_devinfo const* dev, FFlist* devices)
{
FFBluetoothResult* device = ffListAdd(devices);
ffStrbufInitS(&device->name, bt_devremote_name_gen(dev->devname, &dev->bdaddr));
ffStrbufInitS(&device->name,
#if __FreeBSD__
bt_devremote_name_gen(dev->devname, &dev->bdaddr)
#else
dev->devname
#endif
);
ffStrbufInitS(&device->address, bt_ntoa(&dev->bdaddr, NULL));
ffStrbufUpperCase(&device->address);
ffStrbufInit(&device->type);
+6
View File
@@ -106,9 +106,14 @@ static const char* armPartId2name(uint32_t partId)
case 0xd80: return "Cortex-A520";
case 0xd81: return "Cortex-A720";
case 0xd82: return "Cortex-X4";
case 0xd83: return "Neoverse-V3AE";
case 0xd84: return "Neoverse-V3";
case 0xd85: return "Cortex-X925";
case 0xd87: return "Cortex-A725";
case 0xd88: return "Cortex-A520AE";
case 0xd89: return "Cortex-A720AE";
case 0xd8e: return "Neoverse-N3";
case 0xd8f: return "Cortex-A320";
default: return NULL;
}
}
@@ -314,6 +319,7 @@ static const char* fujitsuPartId2name(uint32_t partId)
switch (partId)
{
case 0x001: return "A64FX";
case 0x003: return "MONAKA";
default: return NULL;
}
}
+65 -21
View File
@@ -1,5 +1,6 @@
#include "cpu.h"
#include "common/sysctl.h"
#include "util/stringUtils.h"
#include <sys/param.h>
#if __has_include(<sys/cpuset.h>)
@@ -34,35 +35,60 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
if (ffSysctlGetString("hw.model", &cpu->name) != NULL)
return "sysctlbyname(hw.model) failed";
cpu->coresPhysical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresLogical = cpu->coresPhysical;
cpu->coresLogical = (uint16_t) ffSysctlGetInt("hw.ncpu", 1);
cpu->coresPhysical = 0;
cpu->coresOnline = (uint16_t) ffSysctlGetInt("kern.smp.cpus", cpu->coresLogical);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
if (ffSysctlGetString("kern.sched.topology_spec", &buffer) == NULL && buffer.length > 0)
{
// <groups>
// <group level="1" cache-level="3">
// <cpu count="4" mask="f,0,0,0">0, 1, 2, 3</cpu>
// <children>
// <group level="2" cache-level="2">
// <cpu count="2" mask="3,0,0,0">0, 1</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// <group level="2" cache-level="2">
// <cpu count="2" mask="c,0,0,0">2, 3</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// </children>
// </group>
// <group level="1" cache-level="3">
// <cpu count="4" mask="f,0,0,0">0, 1, 2, 3</cpu>
// <children>
// <group level="2" cache-level="2">
// <cpu count="2" mask="3,0,0,0">0, 1</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// <group level="2" cache-level="2">
// <cpu count="2" mask="c,0,0,0">2, 3</cpu>
// <flags><flag name="THREAD">THREAD group</flag><flag name="SMT">SMT group</flag></flags>
// </group>
// </children>
// </group>
// </groups>
uint32_t i = 0;
while (true)
char* line = NULL;
size_t len = 0;
bool inLvl2 = false, threadGroup = false;
uint32_t cpuCount = 0;
while (ffStrbufGetline(&line, &len, &buffer))
{
i = ffStrbufNextIndexS(&buffer, i, "<flag name=\"THREAD\">THREAD group</flag>"); // Find physical core with hyper-threading enabled
if (i >= buffer.length) break;
cpu->coresPhysical--;
i += (uint32_t) strlen("<flag name=\"THREAD\">THREAD group</flag>");
if (!inLvl2)
{
if (ffStrStartsWith(line, " <group level=\"2\""))
{
inLvl2 = true;
cpuCount = 0;
threadGroup = false;
}
else if (ffStrStartsWith(line, " <group level=\"1\""))
cpu->packages++;
}
else
{
if (ffStrEquals(line, " </group>"))
{
cpu->coresPhysical += threadGroup ? 1 : cpuCount;
inLvl2 = false;
}
else if (cpuCount == 0 && ffStrStartsWith(line, " <cpu count=\""))
cpuCount = (uint32_t) strtoul(line + strlen(" <cpu count=\""), NULL, 10);
else if (cpuCount > 0 && ffStrStartsWith(line, " <flags>"))
{
if (ffStrContains(line, "<flag name=\"THREAD\">THREAD group</flag>"))
threadGroup = true;
}
}
}
}
@@ -79,6 +105,24 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
uint32_t clockrate = (uint32_t) ffSysctlGetInt("hw.clockrate", 0);
if (clockrate > cpu->frequencyBase) cpu->frequencyBase = clockrate;
for (uint16_t i = 0; i < cpu->coresLogical; ++i)
{
ffStrbufClear(&buffer);
char key[32];
snprintf(key, sizeof(key), "dev.cpu.%u.freq_levels", i);
if (ffSysctlGetString(key, &buffer) == NULL)
{
if (buffer.length == 0) continue;
// MHz/Watts pairs like: 2501/32000 2187/27125 2000/24000
uint32_t fmax = (uint32_t) strtoul(buffer.chars, NULL, 10);
if (cpu->frequencyMax < fmax) cpu->frequencyMax = fmax;
}
else
break;
}
cpu->temperature = FF_CPU_TEMP_UNSET;
if (options->temp)
+85 -7
View File
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <unistd.h>
#include <dirent.h>
#include <fcntl.h>
#define FF_CPUINFO_PATH "/proc/cpuinfo"
@@ -432,11 +433,11 @@ FF_MAYBE_UNUSED static uint16_t getPackageCount(FFstrbuf* cpuinfo)
{
p += strlen("\nphysical id\t:");
char* pend;
unsigned long id = strtoul(p, &pend, 10);
unsigned long long id = strtoul(p, &pend, 10);
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
high |= 1 << (id - 64);
high |= 1ULL << (id - 64);
else
low |= 1 << id;
low |= 1ULL << id;
p = pend;
}
@@ -458,9 +459,7 @@ FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFC
cpu->coresOnline = (uint16_t) get_nprocs();
cpu->packages = getPackageCount(&cpuinfo);
cpu->coresPhysical = (uint16_t) ffStrbufToUInt(&physicalCoresBuffer, 0); // physical cores in single package
if (cpu->coresPhysical == 0)
cpu->coresPhysical = cpu->coresLogical;
else if (cpu->packages > 1)
if (cpu->coresPhysical > 0 && cpu->packages > 1)
cpu->coresPhysical *= cpu->packages;
// Ref https://github.com/fastfetch-cli/fastfetch/issues/1194#issuecomment-2295058252
@@ -473,6 +472,82 @@ FF_MAYBE_UNUSED static const char* detectCPUX86(const FFCPUOptions* options, FFC
#else
static const char* detectPhysicalCores(FFCPUResult* cpu)
{
int dfd = open("/sys/devices/system/cpu/", O_RDONLY | O_DIRECTORY);
if (dfd < 0) return "open(\"/sys/devices/system/cpu/\") failed";
FF_AUTO_CLOSE_DIR DIR* dir = fdopendir(dfd);
if (!dir) return "fdopendir(dfd) failed";
uint64_t pkgLow = 0, pkgHigh = 0;
struct dirent* entry;
FF_LIST_AUTO_DESTROY cpuList = ffListCreate(sizeof(uint32_t));
while ((entry = readdir(dir)) != NULL)
{
if (entry->d_type != DT_DIR || !ffStrStartsWith(entry->d_name, "cpu") || !ffCharIsDigit(entry->d_name[strlen("cpu")]))
continue;
FF_AUTO_CLOSE_FD int cpuxfd = openat(dirfd(dir), entry->d_name, O_RDONLY | O_DIRECTORY);
if (cpuxfd < 0)
continue;
char buf[128];
// Check if the directory contains a file named "topology/physical_package_id"
// that lists the physical package id of the CPU.
ssize_t len = ffReadFileDataRelative(cpuxfd, "topology/physical_package_id", sizeof(buf) - 1, buf);
if (len > 0)
{
buf[len] = '\0';
unsigned long long id = strtoul(buf, NULL, 10);
if (__builtin_expect(id > 64, false)) // Do 129-socket boards exist?
pkgHigh |= 1ULL << (id - 64);
else
pkgLow |= 1ULL << id;
}
// Check if the directory contains a file named "topology/core_cpus_list"
// that lists the physical cores in the package.
len = ffReadFileDataRelative(cpuxfd, "topology/core_cpus_list", sizeof(buf) - 1, buf);
if (len > 0)
{
buf[len] = '\0'; // low-high or low
for (const char* p = buf; *p;)
{
char* pend;
uint32_t coreId = (uint32_t) strtoul(p, &pend, 10);
if (pend == p) break;
bool found = false;
FF_LIST_FOR_EACH(uint32_t, id, cpuList)
{
if (*id == coreId)
{
// This core is already counted
found = true;
break;
}
}
if (!found)
*(uint32_t*) ffListAdd(&cpuList) = coreId;
p = strchr(pend, ',');
if (!p) break;
++p;
}
}
}
cpu->coresPhysical = (uint16_t) cpuList.length;
cpu->packages = (uint16_t) (__builtin_popcountll(pkgLow) + __builtin_popcountll(pkgHigh));
return NULL;
}
FF_MAYBE_UNUSED static void parseIsa(FFstrbuf* cpuIsa)
{
// Always use the last part of the ISA string. Ref: #590 #1204
@@ -601,7 +676,7 @@ FF_MAYBE_UNUSED static uint16_t getLoongarchPropCount(FFstrbuf* cpuinfo, const c
FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options, FFCPUResult* cpu)
{
cpu->coresPhysical = cpu->coresLogical = (uint16_t) get_nprocs_conf();
cpu->coresLogical = (uint16_t) get_nprocs_conf();
cpu->coresOnline = (uint16_t) get_nprocs();
#if __ANDROID__
@@ -663,6 +738,9 @@ FF_MAYBE_UNUSED static const char* detectCPUOthers(const FFCPUOptions* options,
#endif
}
if (cpu->coresPhysical == 0)
detectPhysicalCores(cpu);
return NULL;
}
#endif
+41 -3
View File
@@ -4,6 +4,46 @@
#include "util/mallocHelper.h"
#include "util/smbiosHelper.h"
#include <pdh.h>
static void ffPdhOpenCloseQuery(HQUERY* query)
{
assert(query);
if (*query)
{
PdhCloseQuery(*query);
*query = NULL;
}
}
static const char* detectThermalTemp(double* result)
{
// typeperf.exe -sc 1 "\Thermal Zone Information(*)\Temperature"
__attribute__((__cleanup__(ffPdhOpenCloseQuery))) HQUERY query = NULL;
if (PdhOpenQuery(NULL, 0, &query) != ERROR_SUCCESS)
return "Failed to open PDH query";
HCOUNTER counter = NULL;
if (PdhAddEnglishCounter(query,
L"\\Thermal Zone Information(*)\\Temperature",
0,
&counter) != ERROR_SUCCESS)
return "Failed to add TZI temperature counter";
if (PdhCollectQueryData(query) != ERROR_SUCCESS)
return "Failed to collect query data";
PDH_FMT_COUNTERVALUE value;
if (PdhGetFormattedCounterValue(counter, PDH_FMT_DOUBLE, NULL, &value) != ERROR_SUCCESS)
return "Failed to format counter value";
*result = value.doubleValue - 273;
return NULL;
}
// 7.5
typedef struct FFSmbiosProcessorInfo
{
@@ -165,8 +205,6 @@ static const char* detectCoreTypes(FFCPUResult* cpu)
return NULL;
}
const char* detectThermalTemp(double* current, double* critical);
const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
{
detectNCores(cpu);
@@ -182,7 +220,7 @@ const char* ffDetectCPUImpl(const FFCPUOptions* options, FFCPUResult* cpu)
detectMaxSpeedBySmbios(cpu);
if(options->temp)
detectThermalTemp(&cpu->temperature, NULL);
detectThermalTemp(&cpu->temperature);
return NULL;
}
-34
View File
@@ -1,34 +0,0 @@
#include "util/windows/wmi.hpp"
extern "C"
const char* detectThermalTemp(double* current, double* critical)
{
// Requires Administrator privileges
// https://wutils.com/wmi/root/wmi/msacpi_thermalzonetemperature/#properties
FFWmiQuery query(L"SELECT CurrentTemperature, CriticalTripPoint FROM MSAcpi_ThermalZoneTemperature WHERE Active = TRUE", nullptr, FFWmiNamespace::WMI);
if(!query)
return "Query WMI service failed";
if(FFWmiRecord record = query.next())
{
if (current)
{
if(auto vtCurrent = record.get(L"CurrentTemperature"))
*current = vtCurrent.get<int32_t>() / 10 - 273.15; // In tenth of degrees Kelvin
else
*current = 0.0/0.0;
}
if (critical)
{
if(auto vtCritical = record.get(L"CriticalTripPoint"))
*critical = vtCritical.get<int32_t>() / 10 - 273.15; // In tenth of degrees Kelvin
else
*critical = 0.0/0.0;
}
return NULL;
}
return "No WMI result returned";
}
+37 -3
View File
@@ -228,7 +228,7 @@ static void pciDetectAmdSpecific(const FFGPUOptions* options, FFGPUResult* gpu,
}
}
static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const char* drmKey)
static void pciDetectIntelSpecific(const FFGPUOptions* options, FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf* buffer, const char* drmKey)
{
// Works for Intel GPUs
// https://patchwork.kernel.org/project/intel-gfx/patch/1422039866-11572-3-git-send-email-ville.syrjala@linux.intel.com/
@@ -238,12 +238,46 @@ static void pciDetectIntelSpecific(FFGPUResult* gpu, FFstrbuf* pciDir, FFstrbuf*
if (!drmKey) return;
if (ffStrbufEqualS(&gpu->driver, "xe"))
const uint32_t pciDirLen = pciDir->length;
bool isXE = ffStrbufEqualS(&gpu->driver, "xe");
if (isXE)
ffStrbufAppendS(pciDir, "/tile0/gt0/freq0/max_freq");
else
ffStrbufAppendF(pciDir, "/drm/%s/gt_max_freq_mhz", drmKey);
if (ffReadFileBuffer(pciDir->chars, buffer))
gpu->frequency = (uint32_t) ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(pciDir, pciDirLen);
if (options->temp)
{
ffStrbufAppendS(pciDir, "/hwmon/");
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(pciDir->chars);
if (dirp)
{
struct dirent* entry;
while ((entry = readdir(dirp)) != NULL)
{
if (entry->d_name[0] == '.') continue;
ffStrbufSubstrBefore(pciDir, pciDirLen + strlen("/hwmon/"));
ffStrbufAppendS(pciDir, entry->d_name);
// https://github.com/Syllo/nvtop/blob/73291884d926445e499d6b9b71cb7a9bdbc7c393/src/extract_gpuinfo_intel.c#L279-L281
ffStrbufAppendS(pciDir, isXE ? "/temp2_input" : "/temp1_input");
if (ffReadFileBuffer(pciDir->chars, buffer))
{
uint64_t value = ffStrbufToUInt(buffer, 0);
if (value > 0)
{
gpu->temperature = (double) value / 1000;
break;
}
}
}
}
ffStrbufSubstrBefore(pciDir, pciDirLen);
}
}
static inline int popcountBytes(uint8_t* bytes, uint32_t length)
@@ -500,7 +534,7 @@ static const char* detectPci(const FFGPUOptions* options, FFlist* gpus, FFstrbuf
}
else if (gpu->vendor.chars == FF_GPU_VENDOR_NAME_INTEL)
{
pciDetectIntelSpecific(gpu, deviceDir, buffer, drmKey);
pciDetectIntelSpecific(options, gpu, deviceDir, buffer, drmKey);
ffStrbufSubstrBefore(deviceDir, drmDirPathLength);
if (options->driverSpecific && drmKey)
drmDetectIntelSpecific(gpu, drmKey, buffer);
+18 -33
View File
@@ -4,60 +4,46 @@
#include "common/netif/netif.h"
#include "util/stringUtils.h"
#include <fcntl.h>
#include <net/if.h>
static void getData(FFstrbuf* buffer, const char* ifName, bool isDefaultRoute, FFstrbuf* path, FFlist* result)
static void getData(FFstrbuf* buffer, const char* ifName, bool isDefaultRoute, int basefd, FFlist* result)
{
ffStrbufSetF(path, "/sys/class/net/%s/operstate", ifName);
if(!ffReadFileBuffer(path->chars, buffer) || !ffStrbufEqualS(buffer, "up\n"))
FF_AUTO_CLOSE_FD int dfd = openat(basefd, ifName, O_RDONLY | O_DIRECTORY);
if (dfd < 0)
return;
char operstate;
if(!ffReadFileDataRelative(dfd, "operstate", 1, &operstate) || operstate != 'u' /* up or unknown */)
return;
FFNetIOResult* counters = (FFNetIOResult*) ffListAdd(result);
ffStrbufInitS(&counters->name, ifName);
counters->defaultRoute = isDefaultRoute;
ffStrbufSetF(path, "/sys/class/net/%s/statistics/", ifName);
uint32_t statLen = path->length;
ffStrbufAppendS(path, "rx_bytes");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/rx_bytes", buffer))
counters->rxBytes = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "tx_bytes");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/tx_bytes", buffer))
counters->txBytes = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "rx_packets");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/rx_packets", buffer))
counters->rxPackets = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "tx_packets");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/tx_packets", buffer))
counters->txPackets = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "rx_errors");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/rx_errors", buffer))
counters->rxErrors = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "tx_errors");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/tx_errors", buffer))
counters->txErrors = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "rx_dropped");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/rx_dropped", buffer))
counters->rxDrops = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
ffStrbufAppendS(path, "tx_dropped");
if (ffReadFileBuffer(path->chars, buffer))
if (ffReadFileBufferRelative(dfd, "statistics/tx_dropped", buffer))
counters->txDrops = ffStrbufToUInt(buffer, 0);
ffStrbufSubstrBefore(path, statLen);
}
const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
@@ -65,7 +51,6 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/sys/class/net");
if (!dirp) return "opendir(\"/sys/class/net\") == NULL";
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateA(64);
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
const char* defaultRouteIfName = ffNetifGetDefaultRouteIfName();
@@ -75,7 +60,7 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
if (options->namePrefix.length && strncmp(defaultRouteIfName, options->namePrefix.chars, options->namePrefix.length) != 0)
return NULL;
getData(&buffer, defaultRouteIfName, true, &path, result);
getData(&buffer, defaultRouteIfName, true, dirfd(dirp), result);
}
else
{
@@ -89,7 +74,7 @@ const char* ffNetIOGetIoCounters(FFlist* result, FFNetIOOptions* options)
if (options->namePrefix.length && strncmp(ifName, options->namePrefix.chars, options->namePrefix.length) != 0)
continue;
getData(&buffer, ifName, ffStrEquals(ifName, defaultRouteIfName), &path, result);
getData(&buffer, ifName, ffStrEquals(ifName, defaultRouteIfName), dirfd(dirp), result);
}
}
+1
View File
@@ -40,6 +40,7 @@ typedef struct FFPackagesResult
uint32_t rpm;
uint32_t scoop;
uint32_t snap;
uint32_t soar;
uint32_t sorcery;
uint32_t winget;
uint32_t xbps;
+3
View File
@@ -682,4 +682,7 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options)
if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT))
result->amUser = getAMUser();
if (!(options->disabled & FF_PACKAGES_FLAG_SOAR_BIT))
result->soar += getSQLite3Int(&baseDir, ".local/share/soar/db/soar.db", "SELECT COUNT(DISTINCT pkg_id || pkg_name) FROM packages WHERE is_installed = true", "soar");
}
@@ -78,10 +78,18 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption
ffStrbufInitMove(&device->name, &name);
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
bool isVirtual = false;
{
ffStrbufInit(&device->interconnect);
if (ffStrStartsWith(devName, "nvme"))
ffStrbufSetStatic(&device->interconnect, "NVMe");
else if (ffStrStartsWith(devName, "mmcblk"))
ffStrbufSetStatic(&device->interconnect, "MMC");
else if (ffStrStartsWith(devName, "md"))
{
ffStrbufSetStatic(&device->interconnect, "RAID");
isVirtual = true;
}
else
{
char pathSysDeviceLink[64];
@@ -97,6 +105,8 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption
ffStrbufSetStatic(&device->interconnect, "SCSI");
else if (strstr(pathSysDeviceReal, "/nvme") != NULL)
ffStrbufSetStatic(&device->interconnect, "NVMe");
else if (strstr(pathSysDeviceReal, "/virtio") != NULL)
ffStrbufSetStatic(&device->interconnect, "Virtual");
else
{
if (ffAppendFileBufferRelative(devfd, "transport", &device->interconnect))
@@ -106,6 +116,7 @@ static void parsePhysicalDisk(int dfd, const char* devName, FFPhysicalDiskOption
}
}
if (!isVirtual)
{
char isRotationalChar = '1';
if (ffReadFileDataRelative(dfd, "queue/rotational", 1, &isRotationalChar) > 0)
+4 -2
View File
@@ -1,11 +1,13 @@
#include "uptime.h"
#include "common/time.h"
#include <sysinfoapi.h>
#include <realtimeapiset.h>
const char* ffDetectUptime(FFUptimeResult* result)
{
result->uptime = GetTickCount64();
// According to MSDN, this function only fails if it's called with NULL
QueryUnbiasedInterruptTime(&result->uptime);
result->uptime /= 10000; // Convert from 100-nanosecond intervals to milliseconds
result->bootTime = ffTimeGetNow() - result->uptime;
return NULL;
}
-4
View File
@@ -2,15 +2,11 @@
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net80211/ieee80211_ioctl.h>
#include <unistd.h>
const char* ffDetectWifi(FFlist* result)
{
+111
View File
@@ -0,0 +1,111 @@
#include "wifi.h"
#include "common/io/io.h"
#include "util/stringUtils.h"
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <net/if.h>
#include <net80211/ieee80211.h>
#include <net80211/ieee80211_ioctl.h>
#include <unistd.h>
const char* ffDetectWifi(FFlist* result)
{
struct if_nameindex* infs = if_nameindex();
if(!infs) {
return "if_nameindex() failed";
}
FF_AUTO_CLOSE_FD int sock = socket(AF_INET, SOCK_DGRAM, 0);
if(sock < 0) {
return "socket() failed";
}
for(struct if_nameindex* i = infs; !(i->if_index == 0 && i->if_name == NULL); ++i)
{
if (!ffStrStartsWith(i->if_name, "iwm")) {
continue;
}
FFWifiResult* item = (FFWifiResult*) ffListAdd(result);
ffStrbufInitS(&item->inf.description, i->if_name);
ffStrbufInit(&item->inf.status);
ffStrbufInit(&item->conn.status);
ffStrbufInit(&item->conn.ssid);
ffStrbufInit(&item->conn.bssid);
ffStrbufInit(&item->conn.protocol);
ffStrbufInit(&item->conn.security);
item->conn.signalQuality = 0.0/0.0;
item->conn.rxRate = 0.0/0.0;
item->conn.txRate = 0.0/0.0;
item->conn.channel = 0;
item->conn.frequency = 0;
struct ieee80211_nodereq nr = {};
strlcpy(nr.nr_ifname, i->if_name, sizeof(nr.nr_ifname));
struct ifreq ifr = {};
strlcpy(ifr.ifr_name, i->if_name, sizeof(ifr.ifr_name));
if (ioctl(sock, SIOCGIFFLAGS, &ifr) < 0) {
ffStrbufSetStatic(&item->inf.status, "Unknown");
} else {
ffStrbufSetStatic(&item->inf.status, ifr.ifr_flags & IFF_UP ? "Up" : "Down");
}
if (ioctl(sock, SIOCG80211NODE, &nr) < 0) {
ffStrbufSetStatic(&item->conn.status, "Not associated");
continue;
}
if (nr.nr_nwid_len > 0) {
ffStrbufSetStatic(&item->conn.status, "Associated");
ffStrbufAppendNS(&item->conn.ssid, nr.nr_nwid_len, (char*)nr.nr_nwid);
} else {
ffStrbufSetStatic(&item->conn.status, "Not associated");
continue;
}
ffStrbufSetF(&item->conn.bssid, "%02X:%02X:%02X:%02X:%02X:%02X",
nr.nr_bssid[0], nr.nr_bssid[1], nr.nr_bssid[2],
nr.nr_bssid[3], nr.nr_bssid[4], nr.nr_bssid[5]);
item->conn.channel = nr.nr_channel;
if (nr.nr_max_rssi) {
item->conn.signalQuality = ((float)nr.nr_rssi / nr.nr_max_rssi) * 100.0;
}
if (nr.nr_flags & IEEE80211_NODEREQ_HT) {
ffStrbufSetStatic(&item->conn.protocol, "802.11n (Wi-Fi 4)");
} else if (nr.nr_flags & IEEE80211_NODEREQ_VHT) {
ffStrbufSetStatic(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
} else if (nr.nr_chan_flags & IEEE80211_CHANINFO_5GHZ) {
ffStrbufSetStatic(&item->conn.protocol, "802.11a");
} else if (nr.nr_chan_flags & IEEE80211_CHANINFO_2GHZ) {
ffStrbufSetStatic(&item->conn.protocol, "802.11g");
}
struct ieee80211_wpaparams wpa = {};
strlcpy(wpa.i_name, i->if_name, sizeof(wpa.i_name));
if (ioctl(sock, SIOCG80211WPAPARMS, &wpa) >= 0 && wpa.i_enabled) {
if (wpa.i_protos & IEEE80211_WPA_PROTO_WPA2)
ffStrbufSetStatic(&item->conn.security, "WPA2");
else if (wpa.i_protos & IEEE80211_WPA_PROTO_WPA1)
ffStrbufSetStatic(&item->conn.security, "WPA");
} else {
struct ieee80211_nwkey nwkey = {};
strlcpy(nwkey.i_name, i->if_name, sizeof(nwkey.i_name));
if (ioctl(sock, SIOCG80211NWKEY, &nwkey) >= 0) {
if (nwkey.i_wepon)
ffStrbufSetStatic(&item->conn.security, "WEP");
else
ffStrbufSetStatic(&item->conn.security, "Open");
}
}
}
if_freenameindex(infs);
return NULL;
}
+1
View File
@@ -38,6 +38,7 @@ static const char* getHyprland(FFstrbuf* result)
{
ffStrbufSubstrAfterFirstC(result, '"');
ffStrbufSubstrBeforeFirstC(result, '"');
ffStrbufTrimLeft(result, 'v');
FF_DEBUG("Extracted version from version.h: %s", result->chars);
return NULL;
}
+30 -26
View File
@@ -1,9 +1,11 @@
#include "fastfetch.h"
#include "common/commandoption.h"
#include "common/init.h"
#include "common/io/io.h"
#include "common/jsonconfig.h"
#include "common/printing.h"
#include "detection/version/version.h"
#include "logo/logo.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
#include "fastfetch_datatext.h"
@@ -466,38 +468,40 @@ static void optionParseConfigFile(FFdata* data, const char* key, const char* val
if (parseJsoncFile(absolutePath.chars, strictJson)) return;
if (!ffStrbufContainC(&absolutePath, '/')
#ifdef _WIN32
&& !ffStrbufContainC(&absolutePath, '\\')
#endif
)
//Try to load as a relative path
FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs)
{
//Try to load as a relative path
ffStrbufSet(&absolutePath, path);
ffStrbufAppendS(&absolutePath, "fastfetch/presets/");
ffStrbufAppendS(&absolutePath, value);
if (needExtension)
ffStrbufAppendS(&absolutePath, ".jsonc");
FF_LIST_FOR_EACH(FFstrbuf, path, instance.state.platform.dataDirs)
{
ffStrbufSet(&absolutePath, path);
ffStrbufAppendS(&absolutePath, "fastfetch/presets/");
ffStrbufAppendS(&absolutePath, value);
if (needExtension)
ffStrbufAppendS(&absolutePath, ".jsonc");
if (parseJsoncFile(absolutePath.chars, strictJson)) return;
}
if (parseJsoncFile(absolutePath.chars, strictJson)) return;
}
//Try to load as a relative path with the directory of fastfetch binary
//Try to load as a relative path with the directory of fastfetch binary
if (instance.state.platform.exePath.length)
{
uint32_t lastSlash = ffStrbufLastIndexC(&instance.state.platform.exePath, '/') + 1;
assert(lastSlash < instance.state.platform.exePath.length);
if (instance.state.platform.exePath.length)
{
ffStrbufSet(&absolutePath, &instance.state.platform.exePath);
ffStrbufSubstrBeforeLastC(&absolutePath, '/');
ffStrbufAppendS(&absolutePath, "/");
ffStrbufAppendS(&absolutePath, value);
if (needExtension)
ffStrbufAppendS(&absolutePath, ".jsonc");
// Try {exePath}/
ffStrbufSetNS(&absolutePath, lastSlash, instance.state.platform.exePath.chars);
ffStrbufAppendS(&absolutePath, value);
if (needExtension)
ffStrbufAppendS(&absolutePath, ".jsonc");
if (parseJsoncFile(absolutePath.chars, strictJson)) return;
if (parseJsoncFile(absolutePath.chars, strictJson)) return;
}
// Try {exePath}/presets/
ffStrbufSubstrBefore(&absolutePath, lastSlash);
ffStrbufAppendS(&absolutePath, "presets/");
ffStrbufAppendS(&absolutePath, value);
if (needExtension)
ffStrbufAppendS(&absolutePath, ".jsonc");
if (parseJsoncFile(absolutePath.chars, strictJson)) return;
}
//File not found
-24
View File
@@ -63,27 +63,3 @@ typedef struct FFinstance
} FFinstance;
extern FFinstance instance; // Defined in `common/init.c`
extern FFModuleBaseInfo** ffModuleInfos[];
//////////////////////
// Init functions //
//////////////////////
//common/init.c
void ffInitInstance();
void ffStart();
void ffFinish();
void ffDestroyInstance();
void ffListFeatures();
////////////////////
// Logo functions //
////////////////////
void ffLogoPrint();
void ffLogoPrintRemaining();
void ffLogoPrintLine();
void ffLogoBuiltinPrint();
void ffLogoBuiltinList();
void ffLogoBuiltinListAutocompletion();
+1
View File
@@ -1,5 +1,6 @@
#include "fastfetch.h"
#include "common/init.h"
#include "modules/modules.h"
int main(void)
+16
View File
@@ -0,0 +1,16 @@
.:::::::::::::::::::::.
.:::::::::::::::::::::::.
.:::::::::::::::::::::::::.
.:::::::::::::::::::::::::::.
.:::::::::$2,db,$1::::::::::::::::.
.::::::::$2,d%%%%b,$1::$2,db,$1:::::::::.
.:::::::$2,%%%%P'%%%b,d%%%b,$1::::::::.
.::::::$2,%%%%P,$1:::$2`%%%b'^q%%b,$1:::::::.
'::::$2,%%%%P,d|$1:::::$2`%%%b:'^%%b,$1:::::'
'::$2`%%%'$1:$2'q$|$1:::::::$2'q%%b'`q%%b'$1::'
':::::::::::::::::::::::::::::::'
':::::::::::::::::::::::::::::'
':::::::::::::::::::::::::::'
':::::::::::::::::::::::::'
':::::::::::::::::::::::'
':::::::::::::::::::::'
+6
View File
@@ -0,0 +1,6 @@
,db,
,d%%%%b, ,db,
,%%%%P'%%%b,d%%%b,
,%%%%P, `%%%b'^q%%b,
,%%%%P,d| `%%%b '^%%b,
`%%%' 'q$| 'q%%b'`q%%b
+19
View File
@@ -0,0 +1,19 @@
$1+++++++++++
+++++++++++++++++++++
+++++++++++++++++++++++++++++++
=+++++++++++++++++++++++++++++++++++++++=
+++++++++++++++++++++++++++++++++++++++++++++
=++++++++++++++++++++++++++++++++++++++++++++
==+++++++++++++++++++++++++++++++++==
+++++++++++++++++++++++++++
$2**** $1++=+++++++++++=++ $2****
********** $1+++++++ $2**********
************** **************
**************** ****************
***********************
****** ************* ******
*********** *** ***********
*************** ***************
*************** ***************
*********************
***********
+35 -1
View File
@@ -89,6 +89,18 @@ static const FFlogo A[] = {
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Alpine2
{
.names = {"Alpine2"},
.lines = FASTFETCH_DATATEXT_LOGO_ALPINE2,
.type = FF_LOGO_LINE_TYPE_ALTER_BIT,
.colors = {
FF_COLOR_FG_BLUE,
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// AlpineSmall
{
.names = {"Alpine_small"},
@@ -113,6 +125,17 @@ static const FFlogo A[] = {
.colorKeys = FF_COLOR_FG_MAGENTA,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Alpine3Small
{
.names = {"alpine3_small"},
.type = FF_LOGO_LINE_TYPE_SMALL_BIT | FF_LOGO_LINE_TYPE_ALTER_BIT,
.lines = FASTFETCH_DATATEXT_LOGO_ALPINE3_SMALL,
.colors = {
FF_COLOR_FG_WHITE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_BLUE,
},
// Alter
{
.names = {"Alter"},
@@ -197,6 +220,17 @@ static const FFlogo A[] = {
.colorKeys = FF_COLOR_FG_GREEN,
.colorTitle = FF_COLOR_FG_GREEN,
},
//AnduinOS
{
.names = {"anduinos"},
.lines = FASTFETCH_DATATEXT_LOGO_ANDUINOS,
.colors = {
FF_COLOR_FG_CYAN,
FF_COLOR_FG_BLUE,
},
.colorKeys = FF_COLOR_FG_BLUE,
.colorTitle = FF_COLOR_FG_WHITE,
},
// Antergos
{
.names = {"Antergos"},
@@ -2365,7 +2399,7 @@ static const FFlogo K[] = {
},
// KDE Neon
{
.names = {"KDE Neon"}, // Distro ID is `neon`; Distro name is `KDE Neon`
.names = {"KDE Neon"}, // Distro ID is "neon"; Distro name is "KDE Neon"
.lines = FASTFETCH_DATATEXT_LOGO_KDENEON,
.colors = {
FF_COLOR_FG_GREEN,
+6 -1
View File
@@ -627,7 +627,12 @@ void ffLogoPrint(void)
ffStrbufIgnCaseEqualS(&terminal->processName, "wezterm") ||
ffStrbufIgnCaseEqualS(&terminal->processName, "wayst") ||
ffStrbufIgnCaseEqualS(&terminal->processName, "ghostty") ||
ffStrbufIgnCaseEqualS(&terminal->processName, "warp");
#ifdef __APPLE__
ffStrbufIgnCaseEqualS(&terminal->processName, "WarpTerminal") ||
#else
ffStrbufIgnCaseEqualS(&terminal->processName, "warp") ||
#endif
false;
//Try to load the logo as an image. If it succeeds, print it and return.
if(logoPrintImageIfExists(supportsKitty ? FF_LOGO_TYPE_IMAGE_KITTY : FF_LOGO_TYPE_IMAGE_CHAFA, false))
+6
View File
@@ -21,7 +21,13 @@ typedef struct FFlogo
} FFlogo;
//logo.c
void ffLogoPrint(void);
void ffLogoPrintChars(const char* data, bool doColorReplacement);
void ffLogoPrintLine(void);
void ffLogoPrintRemaining(void);
void ffLogoBuiltinPrint(void);
void ffLogoBuiltinList(void);
void ffLogoBuiltinListAutocompletion(void);
//builtin.c
extern const FFlogo* ffLogoBuiltins[];
+1
View File
@@ -1,4 +1,5 @@
#include "common/printing.h"
#include "logo/logo.h"
#include "modules/break/break.h"
void ffPrintBreak(FF_MAYBE_UNUSED FFBreakOptions* options)
+2 -1
View File
@@ -1,7 +1,8 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "util/textModifier.h"
#include "logo/logo.h"
#include "modules/colors/colors.h"
#include "util/textModifier.h"
#include "util/stringUtils.h"
static inline uint8_t min(uint8_t a, uint8_t b)
+34 -33
View File
@@ -7,40 +7,41 @@
typedef enum __attribute__((__packed__)) FFPackagesFlags
{
FF_PACKAGES_FLAG_NONE = 0,
FF_PACKAGES_FLAG_APK_BIT = 1 << 0,
FF_PACKAGES_FLAG_BREW_BIT = 1 << 1,
FF_PACKAGES_FLAG_CHOCO_BIT = 1 << 2,
FF_PACKAGES_FLAG_DPKG_BIT = 1 << 3,
FF_PACKAGES_FLAG_EMERGE_BIT = 1 << 4,
FF_PACKAGES_FLAG_EOPKG_BIT = 1 << 5,
FF_PACKAGES_FLAG_FLATPAK_BIT = 1 << 6,
FF_PACKAGES_FLAG_NIX_BIT = 1 << 7,
FF_PACKAGES_FLAG_OPKG_BIT = 1 << 8,
FF_PACKAGES_FLAG_PACMAN_BIT = 1 << 9,
FF_PACKAGES_FLAG_PALUDIS_BIT = 1 << 10,
FF_PACKAGES_FLAG_PKG_BIT = 1 << 11,
FF_PACKAGES_FLAG_PKGTOOL_BIT = 1 << 12,
FF_PACKAGES_FLAG_MACPORTS_BIT = 1 << 13,
FF_PACKAGES_FLAG_RPM_BIT = 1 << 14,
FF_PACKAGES_FLAG_SCOOP_BIT = 1 << 15,
FF_PACKAGES_FLAG_SNAP_BIT = 1 << 16,
FF_PACKAGES_FLAG_WINGET_BIT = 1 << 17,
FF_PACKAGES_FLAG_XBPS_BIT = 1 << 18,
FF_PACKAGES_FLAG_AM_BIT = 1 << 19,
FF_PACKAGES_FLAG_SORCERY_BIT = 1 << 20,
FF_PACKAGES_FLAG_LPKG_BIT = 1 << 21,
FF_PACKAGES_FLAG_LPKGBUILD_BIT = 1 << 22,
FF_PACKAGES_FLAG_GUIX_BIT = 1 << 23,
FF_PACKAGES_FLAG_LINGLONG_BIT = 1 << 24,
FF_PACKAGES_FLAG_PACSTALL_BIT = 1 << 25,
FF_PACKAGES_FLAG_MPORT_BIT = 1 << 26,
FF_PACKAGES_FLAG_QI_BIT = 1 << 27,
FF_PACKAGES_FLAG_PKGSRC_BIT = 1 << 28,
FF_PACKAGES_FLAG_HPKG_BIT = 1 << 29,
FF_PACKAGES_FLAG_PISI_BIT = 1 << 30,
FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT32_MAX,
FF_PACKAGES_FLAG_APK_BIT = 1ULL << 0,
FF_PACKAGES_FLAG_BREW_BIT = 1ULL << 1,
FF_PACKAGES_FLAG_CHOCO_BIT = 1ULL << 2,
FF_PACKAGES_FLAG_DPKG_BIT = 1ULL << 3,
FF_PACKAGES_FLAG_EMERGE_BIT = 1ULL << 4,
FF_PACKAGES_FLAG_EOPKG_BIT = 1ULL << 5,
FF_PACKAGES_FLAG_FLATPAK_BIT = 1ULL << 6,
FF_PACKAGES_FLAG_NIX_BIT = 1ULL << 7,
FF_PACKAGES_FLAG_OPKG_BIT = 1ULL << 8,
FF_PACKAGES_FLAG_PACMAN_BIT = 1ULL << 9,
FF_PACKAGES_FLAG_PALUDIS_BIT = 1ULL << 10,
FF_PACKAGES_FLAG_PKG_BIT = 1ULL << 11,
FF_PACKAGES_FLAG_PKGTOOL_BIT = 1ULL << 12,
FF_PACKAGES_FLAG_MACPORTS_BIT = 1ULL << 13,
FF_PACKAGES_FLAG_RPM_BIT = 1ULL << 14,
FF_PACKAGES_FLAG_SCOOP_BIT = 1ULL << 15,
FF_PACKAGES_FLAG_SNAP_BIT = 1ULL << 16,
FF_PACKAGES_FLAG_WINGET_BIT = 1ULL << 17,
FF_PACKAGES_FLAG_XBPS_BIT = 1ULL << 18,
FF_PACKAGES_FLAG_AM_BIT = 1ULL << 19,
FF_PACKAGES_FLAG_SORCERY_BIT = 1ULL << 20,
FF_PACKAGES_FLAG_LPKG_BIT = 1ULL << 21,
FF_PACKAGES_FLAG_LPKGBUILD_BIT = 1ULL << 22,
FF_PACKAGES_FLAG_GUIX_BIT = 1ULL << 23,
FF_PACKAGES_FLAG_LINGLONG_BIT = 1ULL << 24,
FF_PACKAGES_FLAG_PACSTALL_BIT = 1ULL << 25,
FF_PACKAGES_FLAG_MPORT_BIT = 1ULL << 26,
FF_PACKAGES_FLAG_QI_BIT = 1ULL << 27,
FF_PACKAGES_FLAG_PKGSRC_BIT = 1ULL << 28,
FF_PACKAGES_FLAG_HPKG_BIT = 1ULL << 29,
FF_PACKAGES_FLAG_PISI_BIT = 1ULL << 30,
FF_PACKAGES_FLAG_SOAR_BIT = 1ULL << 31,
FF_PACKAGES_FLAG_FORCE_UNSIGNED = UINT64_MAX,
} FFPackagesFlags;
static_assert(sizeof(FFPackagesFlags) == sizeof(uint32_t), "");
static_assert(sizeof(FFPackagesFlags) == sizeof(uint64_t), "");
typedef struct FFPackagesOptions
{
+7
View File
@@ -78,6 +78,7 @@ void ffPrintPackages(FFPackagesOptions* options)
FF_PRINT_PACKAGE(mport)
FF_PRINT_PACKAGE(qi)
FF_PRINT_PACKAGE(pisi)
FF_PRINT_PACKAGE(soar)
putchar('\n');
}
@@ -130,6 +131,7 @@ void ffPrintPackages(FFPackagesOptions* options)
FF_FORMAT_ARG(counts.hpkgSystem, "hpkg-system"),
FF_FORMAT_ARG(counts.hpkgUser, "hpkg-user"),
FF_FORMAT_ARG(counts.pisi, "pisi"),
FF_FORMAT_ARG(counts.soar, "soar"),
FF_FORMAT_ARG(nixAll, "nix-all"),
FF_FORMAT_ARG(flatpakAll, "flatpak-all"),
FF_FORMAT_ARG(brewAll, "brew-all"),
@@ -222,6 +224,7 @@ bool ffParsePackagesCommandOptions(FFPackagesOptions* options, const char* key,
case 'S': if (false);
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(SOAR)
FF_TEST_PACKAGE_NAME(SORCERY)
break;
case 'W': if (false);
@@ -341,6 +344,7 @@ void ffParsePackagesJsonObject(FFPackagesOptions* options, yyjson_val* module)
case 'S': if (false);
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(SOAR)
FF_TEST_PACKAGE_NAME(SORCERY)
break;
case 'W': if (false);
@@ -400,6 +404,7 @@ void ffGeneratePackagesJsonConfig(FFPackagesOptions* options, yyjson_mut_doc* do
FF_TEST_PACKAGE_NAME(RPM)
FF_TEST_PACKAGE_NAME(SCOOP)
FF_TEST_PACKAGE_NAME(SNAP)
FF_TEST_PACKAGE_NAME(SOAR)
FF_TEST_PACKAGE_NAME(SORCERY)
FF_TEST_PACKAGE_NAME(WINGET)
FF_TEST_PACKAGE_NAME(XBPS)
@@ -459,6 +464,7 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy
FF_APPEND_PACKAGE_COUNT(rpm)
FF_APPEND_PACKAGE_COUNT(scoop)
FF_APPEND_PACKAGE_COUNT(snap)
FF_APPEND_PACKAGE_COUNT(soar)
FF_APPEND_PACKAGE_COUNT(sorcery)
FF_APPEND_PACKAGE_COUNT(winget)
FF_APPEND_PACKAGE_COUNT(xbps)
@@ -515,6 +521,7 @@ static FFModuleBaseInfo ffModuleInfo = {
{"Number of hpkg-system packages", "hpkg-system"},
{"Number of hpkg-user packages", "hpkg-user"},
{"Number of pisi packages", "pisi"},
{"Number of soar packages", "soar"},
{"Total number of all nix packages", "nix-all"},
{"Total number of all flatpak app packages", "flatpak-all"},
{"Total number of all brew packages", "brew-all"},
+1
View File
@@ -1,5 +1,6 @@
#include "common/printing.h"
#include "common/jsonconfig.h"
#include "logo/logo.h"
#include "modules/separator/separator.h"
#include "util/stringUtils.h"
#include "util/mallocHelper.h"
+3
View File
@@ -63,6 +63,7 @@ void ffPrintTitle(FFTitleOptions* options)
FF_FORMAT_ARG(userNameColored, "user-name-colored"),
FF_FORMAT_ARG(atColored, "at-symbol-colored"),
FF_FORMAT_ARG(hostNameColored, "host-name-colored"),
FF_FORMAT_ARG(instance.state.platform.fullUserName, "full-user-name"),
}));
}
}
@@ -170,6 +171,7 @@ void ffGenerateTitleJsonResult(FF_MAYBE_UNUSED FFTitleOptions* options, yyjson_m
{
yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result");
yyjson_mut_obj_add_strbuf(doc, obj, "userName", &instance.state.platform.userName);
yyjson_mut_obj_add_strbuf(doc, obj, "fullUserName", &instance.state.platform.fullUserName);
yyjson_mut_obj_add_strbuf(doc, obj, "hostName", &instance.state.platform.hostName);
yyjson_mut_obj_add_strbuf(doc, obj, "homeDir", &instance.state.platform.homeDir);
yyjson_mut_obj_add_strbuf(doc, obj, "exePath", &instance.state.platform.exePath);
@@ -193,6 +195,7 @@ static FFModuleBaseInfo ffModuleInfo = {
{"User name (colored)", "user-name-colored"},
{"@ symbol (colored)", "at-symbol-colored"},
{"Host name (colored)", "host-name-colored"},
{"Full user name", "full-user-name"},
}))
};
+17
View File
@@ -3,6 +3,7 @@
#include "common/io/io.h"
#include "util/stringUtils.h"
#if !_WIN32
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
{
char* path = getenv("PATH");
@@ -47,6 +48,22 @@ const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
ffStrbufClear(result);
return "Executable not found";
}
#else
#include <windows.h>
const char* ffFindExecutableInPath(const char* name, FFstrbuf* result)
{
char buffer[MAX_PATH + 1];
DWORD length = SearchPathA(NULL, name, ".exe", sizeof(buffer), buffer, NULL);
if (length == 0)
{
ffStrbufClear(result);
return "Executable not found";
}
ffStrbufSetS(result, buffer);
return NULL;
}
#endif
bool ffIsAbsolutePath(const char* path)
{
+1
View File
@@ -12,6 +12,7 @@ void ffPlatformInit(FFPlatform* platform)
ffStrbufInit(&platform->exePath);
ffStrbufInit(&platform->userName);
ffStrbufInit(&platform->fullUserName);
ffStrbufInit(&platform->hostName);
ffStrbufInit(&platform->userShell);
+1
View File
@@ -22,6 +22,7 @@ typedef struct FFPlatform
FFstrbuf exePath; // The real path of current exe
FFstrbuf userName;
FFstrbuf fullUserName;
FFstrbuf hostName;
FFstrbuf userShell;
+2 -8
View File
@@ -172,14 +172,6 @@ static void getDataDirs(FFPlatform* platform)
#endif
ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/local/share/");
ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR "/share/");
if (platform->exePath.length > 0)
{
// Add ${currentExePath}
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&platform->exePath);
ffStrbufSubstrBeforeLastC(&path, '/');
ffPlatformPathAddAbsolute(&platform->dataDirs, path.chars);
}
}
static void getUserName(FFPlatform* platform, const struct passwd* pwd)
@@ -189,6 +181,8 @@ static void getUserName(FFPlatform* platform, const struct passwd* pwd)
user = pwd->pw_name;
ffStrbufAppendS(&platform->userName, user);
if (pwd) ffStrbufAppendS(&platform->fullUserName, pwd->pw_gecos);
}
static void getHostName(FFPlatform* platform, const struct utsname* uts)
+9 -9
View File
@@ -9,6 +9,9 @@
#include <Windows.h>
#include <shlobj.h>
#define SECURITY_WIN32 1 // For secext.h
#include <secext.h>
static void getExePath(FFPlatform* platform)
{
wchar_t exePathW[MAX_PATH];
@@ -129,14 +132,6 @@ static void getDataDirs(FFPlatform* platform)
platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_RoamingAppData);
platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_LocalAppData);
ffPlatformPathAddHome(&platform->dataDirs, platform, "");
if (platform->exePath.length > 0)
{
// Add ${currentExePath}
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreateCopy(&platform->exePath);
ffStrbufSubstrBeforeLastC(&path, '/');
ffPlatformPathAddAbsolute(&platform->dataDirs, path.chars);
}
}
static void getUserName(FFPlatform* platform)
@@ -146,11 +141,16 @@ static void getUserName(FFPlatform* platform)
ffStrbufSetS(&platform->userName, userName);
else
{
wchar_t buffer[128];
wchar_t buffer[256];
DWORD len = ARRAY_SIZE(buffer);
if(GetUserNameW(buffer, &len))
ffStrbufSetWS(&platform->userName, buffer);
}
wchar_t buffer[256];
DWORD len = ARRAY_SIZE(buffer);
if (GetUserNameExW(NameDisplay, buffer, &len))
ffStrbufSetWS(&platform->fullUserName, buffer);
}
static void getHostName(FFPlatform* platform)