diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6480487a1e..5414375470 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -383,7 +383,7 @@ jobs: run: | cat /etc/alpine-release uname -a - apk add cmake samurai vulkan-loader-dev libxcb-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++ + apk add cmake samurai vulkan-loader-dev libxcb-dev libxrandr-dev rpm-dev wayland-dev libdrm-dev dconf-dev imagemagick-dev chafa-dev zlib-dev dbus-dev mesa-dev opencl-dev xfconf-dev sqlite-dev networkmanager-dev pulseaudio-dev ddcutil-dev elfutils-dev gcc g++ shell: alpine.sh --root {0} - name: build @@ -597,6 +597,80 @@ jobs: name: fastfetch-netbsd-amd64 path: ./fastfetch-*.* + dragonfly-amd64: + name: DragonFly-amd64 + runs-on: ubuntu-latest + if: false + permissions: + security-events: write + contents: read + steps: + - name: checkout repository + uses: actions/checkout@v4 + + - name: run VM + uses: vmactions/dragonflybsd-vm@v1 + with: + usesh: yes + prepare: | + uname -a + pkg update + pkg install -y cmake git pkgconf binutils wayland vulkan-headers vulkan-loader libxcb libXrandr libX11 libdrm glib dconf dbus sqlite3-tcl xfce4-conf egl opencl ocl-icd v4l_compat chafa libelf + + run: | + cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On . + cmake --build . --target package --verbose -j4 + ./fastfetch --list-features + time ./fastfetch -c presets/ci.jsonc --stat false + time ./fastfetch -c presets/ci.jsonc --format json + time ./flashfetch + ldd fastfetch + ctest --output-on-failure + + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: fastfetch-dragonfly-amd64 + path: ./fastfetch-*.* + + haiku-amd64: + name: Haiku-amd64 + runs-on: ubuntu-latest + if: false + permissions: + security-events: write + contents: read + steps: + - name: checkout repository + uses: actions/checkout@v4 + + - name: run VM + uses: cross-platform-actions/action@master + with: + operating_system: haiku + architecture: x86-64 + cpu_count: 4 + shell: bash + version: 'r1beta5' + run: | + uname -a + ls -l + pkgman install -y git dbus_devel mesa_devel libelf_devel imagemagick_devel opencl_headers ocl_icd_devel vulkan_devel zlib_devel chafa_devel cmake gcc make pkgconfig python3.10 + cmake -DSET_TWEAK=Off -DBUILD_TESTS=On -DENABLE_EMBEDDED_PCIIDS=On -DENABLE_EMBEDDED_AMDGPUIDS=On . + cmake --build . --target package --verbose -j4 + ./fastfetch --list-features + time ./fastfetch -c presets/ci.jsonc --stat false + time ./fastfetch -c presets/ci.jsonc --format json + time ./flashfetch + ldd fastfetch + ctest --output-on-failure + + - name: upload artifacts + uses: actions/upload-artifact@v4 + with: + name: fastfetch-haiku-amd64 + path: ./fastfetch-*.* + windows-amd64: name: Windows-amd64 runs-on: windows-latest diff --git a/CHANGELOG.md b/CHANGELOG.md index 19697e00da..46c61d5523 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,29 @@ +# 2.45.0 + +Features: +* Support OnePlus marketing name detection (#1768, Host, Android) +* Recognize additional GPU vendors (GPU, Linux) +* Support CTWM, FVWM and I3 window manager version detection (WM) +* Support KDE version detection on *BSD (DE, FreeBSD) +* Support `"logo": { "type": "command-raw" }` to run a command and display its output as logo (#1780, Logo) + * Useful for displaying custom logos generated by other programs such as `pokeget`: `{ "type": "command-raw", "source": "pokeget random --hide-name" }` + * Supported in JSONC config file only. `pokeget random --hide-name | fastfetch --file-raw -` should be used in shell. +* Acquire SMBIOS information on DragonFly BSD from `/dev/mem`; legacy BIOS only (PhysicalMemory, DragonFly) +* Support swap usage detection on DragonFly BSD (Swap, DragonFly) +* Support `--swap-separate` to display detailed swap devices on separate lines (Swap) + +Bugfixes +* Fix MacBook Air model name (#1779, Host, macOS) +* Don't ignore sshfs mountpoints (#1776, Disk, Linux / FreeBSD) +* Fix dnf package count detection (#1777, Packages, Linux) + +Logos: +* Add Starry Linux (#1771) +* Add rhel_small (#1774) +* Update color palette of voidlinux (#1775) +* Add void2 +* Update Xenia Linux (#1783) + # 2.44.0 Features: diff --git a/CMakeLists.txt b/CMakeLists.txt index b2103fbb72..8f3359d949 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.44.0 + VERSION 2.45.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch" @@ -787,7 +787,7 @@ elseif(NetBSD) src/detection/netio/netio_bsd.c src/detection/opengl/opengl_linux.c src/detection/os/os_nbsd.c - src/detection/packages/packages_obsd.c + src/detection/packages/packages_nbsd.c src/detection/poweradapter/poweradapter_nosupport.c src/detection/processes/processes_nbsd.c src/detection/gtk_qt/qt.c @@ -802,7 +802,7 @@ elseif(NetBSD) src/detection/users/users_linux.c src/detection/wallpaper/wallpaper_linux.c src/detection/wifi/wifi_nbsd.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 @@ -884,7 +884,7 @@ elseif(OpenBSD) src/detection/users/users_obsd.c src/detection/wallpaper/wallpaper_linux.c src/detection/wifi/wifi_obsd.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 @@ -1961,12 +1961,17 @@ if(LINUX) endif() endif() - find_program(HAVE_RPMBUILD "rpmbuild") - if(HAVE_RPMBUILD) - set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") + if(NOT IS_MUSL) + find_program(HAVE_RPMBUILD "rpmbuild") + if(HAVE_RPMBUILD) + set(CPACK_GENERATOR "${CPACK_GENERATOR};RPM") - set(CPACK_RPM_PACKAGE_LICENSE "MIT") + set(CPACK_RPM_PACKAGE_LICENSE "MIT") + endif() endif() +elseif(FreeBSD) + set(CPACK_FREEBSD_PACKAGE_LICENSE "MIT") + set(CPACK_GENERATOR "${CPACK_GENERATOR};FREEBSD") endif() set(CPACK_SET_DESTDIR ON) diff --git a/debian/changelog b/debian/changelog index b42192fbdb..d3df85c445 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,9 @@ +fastfetch (2.44.0) jammy; urgency=medium + + * Update to 2.44.0 + + -- Carter Li Mon, 26 May 2025 14:59:01 +0800 + fastfetch (2.43.0) jammy; urgency=medium * Update to 2.43.0 diff --git a/debian/files b/debian/files index 0a32d4a5d2..4ce3a4475f 100644 --- a/debian/files +++ b/debian/files @@ -1 +1 @@ -fastfetch_2.43.0_source.buildinfo universe/utils optional +fastfetch_2.44.0_source.buildinfo universe/utils optional diff --git a/doc/json_schema.json b/doc/json_schema.json index 10634242c8..66e4715926 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -115,7 +115,7 @@ "type": "string" }, "biosFormat": { - "description": "Output format of the module `Bios`. See Wiki for formatting syntax\n 1. {date}: Bios date\n 2. {release}: Bios release\n 3. {vendor}: Bios vendor\n 4. {version}: Bios version\n 5. {type}: Firmware type", + "description": "Output format of the module `BIOS`. See Wiki for formatting syntax\n 1. {date}: Bios date\n 2. {release}: Bios release\n 3. {vendor}: Bios vendor\n 4. {version}: Bios version\n 5. {type}: Firmware type", "type": "string" }, "bluetoothFormat": { @@ -339,7 +339,7 @@ "type": "string" }, "titleFormat": { - "description": "Output format of the module `Title`. See Wiki for formatting syntax\n 1. {user-name}: User name\n 2. {host-name}: Host name\n 3. {home-dir}: Home directory\n 4. {exe-path}: Executable path of current process\n 5. {user-shell}: User's default shell\n 6. {user-name-colored}: User name (colored)\n 7. {at-symbol-colored}: @ symbol (colored)\n 8. {host-name-colored}: Host name (colored)", + "description": "Output format of the module `Title`. See Wiki for formatting syntax\n 1. {user-name}: User name\n 2. {host-name}: Host name\n 3. {home-dir}: Home directory\n 4. {exe-path}: Executable path of current process\n 5. {user-shell}: User's default shell\n 6. {user-name-colored}: User name (colored)\n 7. {at-symbol-colored}: @ symbol (colored)\n 8. {host-name-colored}: Host name (colored)\n 9. {full-user-name}: Full user name", "type": "string" }, "themeFormat": { @@ -429,6 +429,7 @@ "file-raw", "data", "data-raw", + "command-raw", "sixel", "kitty", "kitty-direct", diff --git a/src/detection/cpu/cpu_windows.c b/src/detection/cpu/cpu_windows.c index cf95798f78..515262158e 100644 --- a/src/detection/cpu/cpu_windows.c +++ b/src/detection/cpu/cpu_windows.c @@ -151,7 +151,7 @@ static const char* detectNCores(FFCPUResult* cpu) else if (ptr->Relationship == RelationProcessorCore) ++cpu->coresPhysical; else if (ptr->Relationship == RelationProcessorPackage) - cpu->packages++; + ++cpu->packages; } return NULL; diff --git a/src/detection/de/de_linux.c b/src/detection/de/de_linux.c index a1bb98480c..2f3570e193 100644 --- a/src/detection/de/de_linux.c +++ b/src/detection/de/de_linux.c @@ -10,18 +10,29 @@ #include "util/stringUtils.h" #include +#ifdef __FreeBSD__ + #include + #ifndef _PATH_LOCALBASE + #define _PATH_LOCALBASE "/usr/local" + #endif +#elif __OpenBSD__ + #define _PATH_LOCALBASE "/usr/local" +#elif __NetBSD__ + #define _PATH_LOCALBASE "/usr/pkg" +#endif static void getKDE(FFstrbuf* result, FFDEOptions* options) { - ffParsePropFileValues(FASTFETCH_TARGET_DIR_USR "/share/wayland-sessions/plasma.desktop", 1, (FFpropquery[]) { - {"X-KDE-PluginInfo-Version =", result} - }); +#ifdef _PATH_LOCALBASE + ffParsePropFile(_PATH_LOCALBASE "/share/wayland-sessions/plasma.desktop", "X-KDE-PluginInfo-Version =", result); if(result->length == 0) - { - ffParsePropFileValues(FASTFETCH_TARGET_DIR_USR "/share/xsessions/plasmax11.desktop", 1, (FFpropquery[]) { - {"X-KDE-PluginInfo-Version =", result} - }); - } + ffParsePropFile(_PATH_LOCALBASE "/share/xsessions/plasmax11.desktop", "X-KDE-PluginInfo-Version =", result); +#else + ffParsePropFile(FASTFETCH_TARGET_DIR_USR "/share/wayland-sessions/plasma.desktop", "X-KDE-PluginInfo-Version =", result); + if(result->length == 0) + ffParsePropFile(FASTFETCH_TARGET_DIR_USR "/share/xsessions/plasmax11.desktop", "X-KDE-PluginInfo-Version =", result); +#endif + if(result->length == 0) ffParsePropFileData("xsessions/plasma.desktop", "X-KDE-PluginInfo-Version =", result); if(result->length == 0) diff --git a/src/detection/disk/disk_bsd.c b/src/detection/disk/disk_bsd.c index f2964234a9..6a4860283c 100644 --- a/src/detection/disk/disk_bsd.c +++ b/src/detection/disk/disk_bsd.c @@ -52,7 +52,7 @@ static const char* detectFsLabel(struct statfs* fs, FFDisk* disk) return NULL; } #else -static const char* detectFsLabel(struct statfs* fs, FFDisk* disk) +static const char* detectFsLabel(FF_MAYBE_UNUSED struct statfs* fs, FF_MAYBE_UNUSED FFDisk* disk) { return "Fastfetch was compiled without libgeom support"; } @@ -148,7 +148,7 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) if(!ffDiskMatchMountpoint(&options->folders, fs->f_mntonname)) continue; } - else if(!ffStrEquals(fs->f_mntonname, "/") && !ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs")) + else if(!ffStrEquals(fs->f_mntonname, "/") && !ffStrStartsWith(fs->f_mntfromname, "/dev/") && !ffStrEquals(fs->f_fstypename, "zfs") && !ffStrEquals(fs->f_fstypename, "fusefs.sshfs")) continue; #ifdef __FreeBSD__ @@ -159,13 +159,13 @@ const char* ffDetectDisksImpl(FFDiskOptions* options, FFlist* disks) FFDisk* disk = ffListAdd(disks); - disk->bytesTotal = (uint64_t)fs->f_blocks * fs->f_bsize; - disk->bytesFree = (uint64_t)fs->f_bfree * fs->f_bsize; - disk->bytesAvailable = (uint64_t)fs->f_bavail * fs->f_bsize; + disk->bytesTotal = (uint64_t)fs->f_blocks * (uint64_t)fs->f_bsize; + disk->bytesFree = (uint64_t)fs->f_bfree * (uint64_t)fs->f_bsize; + disk->bytesAvailable = (uint64_t)fs->f_bavail * (uint64_t)fs->f_bsize; disk->bytesUsed = 0; // To be filled in ./disk.c disk->filesTotal = (uint32_t) fs->f_files; - disk->filesUsed = (uint32_t) (fs->f_files - fs->f_ffree); + disk->filesUsed = (uint32_t) fs->f_files - (uint32_t) fs->f_ffree; ffStrbufInitS(&disk->mountFrom, fs->f_mntfromname); ffStrbufInitS(&disk->mountpoint, fs->f_mntonname); diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 6fb7ed6c5b..ae3c688534 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -37,6 +37,10 @@ static bool isPhysicalDevice(const struct mntent* device) if(ffStrEquals(device->mnt_type, "zfs")) return true; + //sshfs + if(ffStrEquals(device->mnt_type, "fuse.sshfs")) + return true; + //Pseudo filesystems don't have a device in /dev if(!ffStrStartsWith(device->mnt_fsname, "/dev/")) return false; diff --git a/src/detection/gpu/gpu.c b/src/detection/gpu/gpu.c index bbf83e52df..a27ab01c76 100644 --- a/src/detection/gpu/gpu.c +++ b/src/detection/gpu/gpu.c @@ -15,6 +15,11 @@ const char* FF_GPU_VENDOR_NAME_PARALLEL = "Parallel"; const char* FF_GPU_VENDOR_NAME_MICROSOFT = "Microsoft"; const char* FF_GPU_VENDOR_NAME_REDHAT = "RedHat"; const char* FF_GPU_VENDOR_NAME_ORACLE = "Oracle"; +const char* FF_GPU_VENDOR_NAME_BROADCOM = "Broadcom"; +const char* FF_GPU_VENDOR_NAME_LOONGSON = "Loongson"; +const char* FF_GPU_VENDOR_NAME_JINGJIA_MICRO = "Jingjia Micro"; +const char* FF_GPU_VENDOR_NAME_HUAWEI = "Huawei"; +const char* FF_GPU_VENDOR_NAME_ZHAOXIN = "Zhaoxin"; const char* ffGPUGetVendorString(unsigned vendorId) { @@ -22,17 +27,22 @@ const char* ffGPUGetVendorString(unsigned vendorId) switch (vendorId) { case 0x106b: return FF_GPU_VENDOR_NAME_APPLE; - case 0x1002: case 0x1022: return FF_GPU_VENDOR_NAME_AMD; + case 0x1002: case 0x1022: case 0x1dd8: return FF_GPU_VENDOR_NAME_AMD; case 0x8086: case 0x8087: case 0x03e7: return FF_GPU_VENDOR_NAME_INTEL; case 0x0955: case 0x10de: case 0x12d2: return FF_GPU_VENDOR_NAME_NVIDIA; case 0x1ed5: return FF_GPU_VENDOR_NAME_MTHREADS; - case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM; + case 0x17cb: case 0x5143: return FF_GPU_VENDOR_NAME_QUALCOMM; case 0x14c3: return FF_GPU_VENDOR_NAME_MTK; case 0x15ad: return FF_GPU_VENDOR_NAME_VMWARE; case 0x1af4: return FF_GPU_VENDOR_NAME_REDHAT; case 0x1ab8: return FF_GPU_VENDOR_NAME_PARALLEL; case 0x1414: return FF_GPU_VENDOR_NAME_MICROSOFT; case 0x108e: return FF_GPU_VENDOR_NAME_ORACLE; + case 0x182f: case 0x14e4: return FF_GPU_VENDOR_NAME_BROADCOM; + case 0x0014: return FF_GPU_VENDOR_NAME_LOONGSON; + case 0x0731: return FF_GPU_VENDOR_NAME_JINGJIA_MICRO; + case 0x19e5: return FF_GPU_VENDOR_NAME_HUAWEI; + case 0x1d17: return FF_GPU_VENDOR_NAME_ZHAOXIN; default: return NULL; } } diff --git a/src/detection/gpu/gpu_linux.c b/src/detection/gpu/gpu_linux.c index ad2f0d4a22..681845f1f9 100644 --- a/src/detection/gpu/gpu_linux.c +++ b/src/detection/gpu/gpu_linux.c @@ -351,10 +351,7 @@ static const char* drmDetectIntelSpecific(FFGPUResult* gpu, const char* drmKey, { { struct drm_xe_device_query query = { - .extensions = 0, .query = DRM_XE_DEVICE_QUERY_GT_TOPOLOGY, - .size = 0, - .data = 0, }; if (ioctl(fd, DRM_IOCTL_XE_DEVICE_QUERY, &query) >= 0) { diff --git a/src/detection/host/host_android.c b/src/detection/host/host_android.c index 7e6d9638ba..940b46c6a5 100644 --- a/src/detection/host/host_android.c +++ b/src/detection/host/host_android.c @@ -12,6 +12,7 @@ const char* ffDetectHost(FFHostResult* host) || ffSettingsGetAndroidProperty("ro.vivo.market.name", &host->name) || ffSettingsGetAndroidProperty("ro.product.oppo_model", &host->name) || ffSettingsGetAndroidProperty("ro.oppo.market.name", &host->name) + || ffSettingsGetAndroidProperty("ro.vendor.oplus.market.enname", &host->name) || ffSettingsGetAndroidProperty("ro.config.devicename", &host->name) || ffSettingsGetAndroidProperty("ro.config.marketing_name", &host->name) || ffSettingsGetAndroidProperty("ro.product.vendor.model", &host->name) diff --git a/src/detection/host/host_mac.c b/src/detection/host/host_mac.c index d1703da281..ecea1681d7 100644 --- a/src/detection/host/host_mac.c +++ b/src/detection/host/host_mac.c @@ -121,7 +121,7 @@ const char* ffHostGetMacProductNameWithHwModel(const FFstrbuf* hwModel) ffStrEquals(version, "16,5")) return "MacBook Pro (16-inch, 2024, Three Thunderbolt 5 ports)"; if(ffStrEquals(version, "15,14")) return "Mac Studio (M3 Ultra, 2025)"; if(ffStrEquals(version, "15,13")) return "MacBook Air (15-inch, M3, 2024)"; - if(ffStrEquals(version, "15,2")) return "MacBook Air (13-inch, M3, 2024)"; + if(ffStrEquals(version, "15,12")) return "MacBook Air (13-inch, M3, 2024)"; if(ffStrEquals(version, "15,3")) return "MacBook Pro (14-inch, Nov 2023, Two Thunderbolt / USB 4 ports)"; if(ffStrEquals(version, "15,4")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports)"; if(ffStrEquals(version, "15,5")) return "iMac (24-inch, 2023, Two Thunderbolt / USB 4 ports, Two USB 3 ports)"; diff --git a/src/detection/memory/memory_haiku.c b/src/detection/memory/memory_haiku.c index b69ddfa346..ec88814552 100644 --- a/src/detection/memory/memory_haiku.c +++ b/src/detection/memory/memory_haiku.c @@ -8,8 +8,9 @@ const char* ffDetectMemory(FFMemoryResult* ram) if (get_system_info(&info) != B_OK) return "Error getting system info"; - ram->bytesTotal = B_PAGE_SIZE * info.max_pages; - ram->bytesUsed = B_PAGE_SIZE * info.used_pages; + uint32_t pageSize = instance.state.platform.sysinfo.pageSize; + ram->bytesTotal = pageSize * info.max_pages; + ram->bytesUsed = pageSize * info.used_pages; return NULL; } diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index fa5c0aee62..844b3de914 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -554,7 +554,11 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, if (!(options->disabled & FF_PACKAGES_FLAG_PACMAN_BIT)) packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", true); if (!(options->disabled & FF_PACKAGES_FLAG_LPKGBUILD_BIT)) packageCounts->lpkgbuild += getNumElements(baseDir, "/opt/Loc-OS-LPKG/lpkgbuild/remove", false); if (!(options->disabled & FF_PACKAGES_FLAG_PKGTOOL_BIT)) packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", false); - if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages", "rpm"); + if (!(options->disabled & FF_PACKAGES_FLAG_RPM_BIT)) + { + // `Sigmd5` is the only table that doesn't contain the virtual `gpg-pubkey` package + packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Sigmd5", "rpm"); + } if (!(options->disabled & FF_PACKAGES_FLAG_SNAP_BIT)) packageCounts->snap += getSnap(baseDir); if (!(options->disabled & FF_PACKAGES_FLAG_XBPS_BIT)) packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps"); if (!(options->disabled & FF_PACKAGES_FLAG_BREW_BIT)) diff --git a/src/detection/packages/packages_nbsd.c b/src/detection/packages/packages_nbsd.c new file mode 100644 index 0000000000..e4004bde62 --- /dev/null +++ b/src/detection/packages/packages_nbsd.c @@ -0,0 +1,9 @@ +#include "packages.h" + +#include "common/io/io.h" + +void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) +{ + if (!(options->disabled & FF_PACKAGES_FLAG_PKGSRC_BIT)) + result->pkgsrc = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/usr/pkg/pkgdb", true); +} diff --git a/src/detection/packages/packages_obsd.c b/src/detection/packages/packages_obsd.c index 46ec94d351..422b402a19 100644 --- a/src/detection/packages/packages_obsd.c +++ b/src/detection/packages/packages_obsd.c @@ -4,11 +4,6 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) { - #if __OpenBSD__ if (!(options->disabled & FF_PACKAGES_FLAG_PKG_BIT)) result->pkg = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg", true); - #elif __NetBSD__ - if (!(options->disabled & FF_PACKAGES_FLAG_PKGSRC_BIT)) - result->pkgsrc = ffPackagesGetNumElements(FASTFETCH_TARGET_DIR_ROOT "/usr/pkg/pkgdb", true); - #endif } diff --git a/src/detection/swap/swap.h b/src/detection/swap/swap.h index 1bbcf1766f..227b4968e4 100644 --- a/src/detection/swap/swap.h +++ b/src/detection/swap/swap.h @@ -4,8 +4,9 @@ typedef struct FFSwapResult { + FFstrbuf name; uint64_t bytesUsed; uint64_t bytesTotal; } FFSwapResult; -const char* ffDetectSwap(FFSwapResult* swap); +const char* ffDetectSwap(FFlist* result /* List of FFSwapResult */); diff --git a/src/detection/swap/swap_apple.c b/src/detection/swap/swap_apple.c index 07bb477ee7..b9e7f7b9cb 100644 --- a/src/detection/swap/swap_apple.c +++ b/src/detection/swap/swap_apple.c @@ -3,13 +3,15 @@ #include #include -const char* ffDetectSwap(FFSwapResult* swap) +const char* ffDetectSwap(FFlist* result) { struct xsw_usage xsw; size_t size = sizeof(xsw); if(sysctl((int[]){ CTL_VM, VM_SWAPUSAGE }, 2, &xsw, &size, NULL, 0) != 0) return "Failed to read vm.swapusage"; + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitStatic(&swap->name, xsw.xsu_encrypted ? "Encrypted" : "Normal"); swap->bytesTotal = xsw.xsu_total; swap->bytesUsed = xsw.xsu_used; return NULL; diff --git a/src/detection/swap/swap_bsd.c b/src/detection/swap/swap_bsd.c index c50885bc9d..c3e40b3df9 100644 --- a/src/detection/swap/swap_bsd.c +++ b/src/detection/swap/swap_bsd.c @@ -2,15 +2,57 @@ #include "common/sysctl.h" #include +#include +#include -const char* ffDetectSwap(FFSwapResult* swap) +static void addSwapEntry(FFlist* result, struct xswdev* xsw, uint32_t pageSize) +{ + if (xsw->xsw_nblks == 0) // DFBSD reports some /dev/wdog devices with nblks == 0 + return; + + FFSwapResult* swap = ffListAdd(result); + if (xsw->xsw_dev == NODEV) + ffStrbufInitStatic(&swap->name, "[NFS]"); + else + ffStrbufInitF(&swap->name, "/dev/%s", devname(xsw->xsw_dev, S_IFCHR)); + swap->bytesUsed = (uint64_t) xsw->xsw_used * pageSize; + swap->bytesTotal = (uint64_t) xsw->xsw_nblks * pageSize; +} + +#if __DragonFly__ + +const char* ffDetectSwap(FFlist* result) +{ + struct xswdev xsws[32]; + size_t size = sizeof(xsws); + if (sysctlbyname("vm.swap_info_array", xsws, &size, NULL, 0) < 0) + return "sysctlbyname(\"vm.swap_info_array\") failed"; + + uint32_t pageSize = instance.state.platform.sysinfo.pageSize; + + size_t count = size / sizeof(struct xswdev); + if (count == 0) + return NULL; + + if (xsws->xsw_version != XSWDEV_VERSION) + return "xswdev version mismatch"; + + for (uint32_t i = 0; i < count; ++i) + addSwapEntry(result, &xsws[i], pageSize); + + return NULL; +} + +#elif __FreeBSD__ + +const char* ffDetectSwap(FFlist* result) { int mib[16]; size_t mibsize = ARRAY_SIZE(mib); if (sysctlnametomib("vm.swap_info", mib, &mibsize) < 0) return "sysctlnametomib(\"vm.swap_info\") failed"; - swap->bytesUsed = swap->bytesTotal = 0; + uint32_t pageSize = instance.state.platform.sysinfo.pageSize; for (int n = 0; ; ++n) { @@ -21,12 +63,11 @@ const char* ffDetectSwap(FFSwapResult* swap) break; if (xsw.xsw_version != XSWDEV_VERSION) return "xswdev version mismatch"; - swap->bytesUsed += (uint64_t) xsw.xsw_used; - swap->bytesTotal += (uint64_t) xsw.xsw_nblks; - } - swap->bytesUsed *= instance.state.platform.sysinfo.pageSize; - swap->bytesTotal *= instance.state.platform.sysinfo.pageSize; + addSwapEntry(result, &xsw, pageSize); + } return NULL; } + +#endif diff --git a/src/detection/swap/swap_haiku.c b/src/detection/swap/swap_haiku.c index a9502c9158..b483668b36 100644 --- a/src/detection/swap/swap_haiku.c +++ b/src/detection/swap/swap_haiku.c @@ -1,15 +1,27 @@ #include "swap.h" #include +#include -const char* ffDetectSwap(FFSwapResult* swap) +const char* ffDetectSwap(FFlist* result) { system_info info; if (get_system_info(&info) != B_OK) return "Error getting system info"; - swap->bytesTotal = B_PAGE_SIZE * (uint64_t) info.max_swap_pages; - swap->bytesUsed = B_PAGE_SIZE * (uint64_t) (info.max_swap_pages - info.free_swap_pages); + uint32_t pageSize = instance.state.platform.sysinfo.pageSize; + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitStatic(&swap->name, "System"); + void* kvms = load_driver_settings("virtual_memory"); // /boot/home/config/settings/kernel/drivers/virtual_memory + if (kvms) + { + const char* swapAuto = get_driver_parameter(kvms, "swap_auto", NULL, NULL); + if (swapAuto) + ffStrbufSetStatic(&swap->name, swapAuto[0] == 'y' ? "Auto" : "Manual"); + unload_driver_settings(kvms); + } + swap->bytesTotal = pageSize * (uint64_t) info.max_swap_pages; + swap->bytesUsed = pageSize * (uint64_t) (info.max_swap_pages - info.free_swap_pages); return NULL; } diff --git a/src/detection/swap/swap_linux.c b/src/detection/swap/swap_linux.c index d86bad19be..5c4971d8fa 100644 --- a/src/detection/swap/swap_linux.c +++ b/src/detection/swap/swap_linux.c @@ -5,8 +5,9 @@ #include -const char* ffDetectSwap(FFSwapResult* swap) +static const char* detectByProcMeminfo(FFlist* result) { + // For Android // Ref: #620 char buf[PROC_FILE_BUFFSIZ]; ssize_t nRead = ffReadFileData("/proc/meminfo", ARRAY_SIZE(buf) - 1, buf); @@ -23,8 +24,59 @@ const char* ffDetectSwap(FFSwapResult* swap) if ((token = strstr(buf, "SwapFree:")) != NULL) swapFree = strtoul(token + strlen("SwapFree:"), NULL, 10); + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitStatic(&swap->name, "Total"); swap->bytesTotal = swapTotal * 1024lu; swap->bytesUsed = (swapTotal - swapFree) * 1024lu; return NULL; } + +static const char* detectByProcSwaps(FFlist* result) +{ + // Ref: #620 + char buf[PROC_FILE_BUFFSIZ]; + ssize_t nRead = ffReadFileData("/proc/swaps", ARRAY_SIZE(buf) - 1, buf); + if(nRead <= 0) + return "ffReadFileData(\"/proc/swaps\", ARRAY_SIZE(buf)-1, buf) failed"; + buf[nRead] = '\0'; + + // Skip header + char* line = memchr(buf, '\n', (size_t) nRead); + + while(line && *++line) + { + uint64_t total, used; + char name[256]; + if(sscanf(line, "%255s %*[^\t]%" SCNu64 "%" SCNu64, name, &total, &used) != 3) + return "Invalid /proc/swaps format found"; + + uint32_t nameLen = (uint32_t) strnlen(name, sizeof(name)); + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitA(&swap->name, nameLen); + for (size_t i = 0; i < nameLen; ++i) + { + if(name[i] == '\\') + { + char octal[4] = { name[i + 1], name[i + 2], name[i + 3], '\0' }; + ffStrbufAppendC(&swap->name, (char) strtol(octal, NULL, 8)); + i += 3; + } + else + ffStrbufAppendC(&swap->name, name[i]); + } + swap->bytesTotal = total * 1024u; + swap->bytesUsed = used * 1024u; + + line = memchr(line, '\n', (size_t) (nRead - (line - buf))); + } + + return NULL; +} + +const char* ffDetectSwap(FFlist* result) +{ + if (detectByProcSwaps(result) == NULL) + return NULL; + return detectByProcMeminfo(result); +} diff --git a/src/detection/swap/swap_obsd.c b/src/detection/swap/swap_obsd.c index 414971d397..fff233ae32 100644 --- a/src/detection/swap/swap_obsd.c +++ b/src/detection/swap/swap_obsd.c @@ -1,4 +1,5 @@ #include "swap.h" +#include "util/FFlist.h" #include "util/mallocHelper.h" #include @@ -6,7 +7,7 @@ #include #include -const char* ffDetectSwap(FFSwapResult* swap) +const char* ffDetectSwap(FFlist* result) { int nswap = swapctl(SWAP_NSWAP, 0, 0); if (nswap < 0) return "swapctl(SWAP_NSWAP) failed"; @@ -17,17 +18,16 @@ const char* ffDetectSwap(FFSwapResult* swap) if (swapctl(SWAP_STATS, swdev, nswap) < 0) return "swapctl(SWAP_STATS) failed"; - uint64_t swapTotal = 0, swapUsed = 0; for (int i = 0; i < nswap; i++) { if (swdev[i].se_flags & SWF_ENABLE) { - swapUsed += (uint64_t) swdev[i].se_inuse; - swapTotal += (uint64_t) swdev[i].se_nblks; + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitS(&swap->name, swdev[i].se_path); + swap->bytesUsed = (uint64_t) swdev[i].se_inuse * DEV_BSIZE; + swap->bytesTotal = (uint64_t) swdev[i].se_nblks * DEV_BSIZE; } } - swap->bytesUsed = swapUsed * DEV_BSIZE; - swap->bytesTotal = swapTotal * DEV_BSIZE; return NULL; } diff --git a/src/detection/swap/swap_sunos.c b/src/detection/swap/swap_sunos.c index 1866cdcd9c..c5e5548445 100644 --- a/src/detection/swap/swap_sunos.c +++ b/src/detection/swap/swap_sunos.c @@ -5,7 +5,7 @@ enum { FFMaxNSwap = 8 }; -const char* ffDetectSwap(FFSwapResult* swap) +const char* ffDetectSwap(FFlist* result) { char strings[FFMaxNSwap][PATH_MAX]; uint8_t buffer[sizeof(swaptbl_t) + sizeof(swapent_t) * (FFMaxNSwap - 1)] = {}; @@ -18,16 +18,14 @@ const char* ffDetectSwap(FFSwapResult* swap) if (size < 0) return "swapctl() failed"; - swap->bytesTotal = swap->bytesUsed = 0; - + uint32_t pageSize = instance.state.platform.sysinfo.pageSize; for (int i = 0; i < size; ++i) { - swap->bytesTotal += (uint64_t) table->swt_ent[i].ste_pages; - swap->bytesUsed += (uint64_t) table->swt_ent[i].ste_free; + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitS(&swap->name, table->swt_ent[i].ste_path); + swap->bytesTotal = (uint64_t) table->swt_ent[i].ste_pages * pageSize; + swap->bytesUsed = swap->bytesTotal - (uint64_t) table->swt_ent[i].ste_free * pageSize; } - swap->bytesUsed = swap->bytesTotal - swap->bytesUsed; - swap->bytesTotal *= instance.state.platform.sysinfo.pageSize; - swap->bytesUsed *= instance.state.platform.sysinfo.pageSize; return NULL; } diff --git a/src/detection/swap/swap_windows.c b/src/detection/swap/swap_windows.c index cd6e0d88e4..26be6d204d 100644 --- a/src/detection/swap/swap_windows.c +++ b/src/detection/swap/swap_windows.c @@ -1,11 +1,12 @@ #include "swap.h" #include "util/mallocHelper.h" +#include "util/windows/unicode.h" #include #include #include -const char* ffDetectSwap(FFSwapResult* swap) +const char* ffDetectSwap(FFlist* result) { uint8_t buffer[4096]; ULONG size = sizeof(buffer); @@ -13,16 +14,18 @@ const char* ffDetectSwap(FFSwapResult* swap) if(!NT_SUCCESS(NtQuerySystemInformation(SystemPagefileInformation, pstart, size, &size))) return "NtQuerySystemInformation(SystemPagefileInformation, size) failed"; + uint32_t pageSize = instance.state.platform.sysinfo.pageSize; for (SYSTEM_PAGEFILE_INFORMATION* current = pstart; ; current = (SYSTEM_PAGEFILE_INFORMATION*)((uint8_t*) current + current->NextEntryOffset)) { - swap->bytesUsed += current->TotalUsed; - swap->bytesTotal += current->CurrentSize; + FFSwapResult* swap = ffListAdd(result); + ffStrbufInitNWS(&swap->name, current->FileName.Length / sizeof(wchar_t), current->FileName.Buffer); + if (ffStrbufStartsWithS(&swap->name, "\\??\\")) + ffStrbufSubstrAfter(&swap->name, strlen("\\??\\") - 1); + swap->bytesUsed = current->TotalUsed * pageSize; + swap->bytesTotal = current->CurrentSize * pageSize; if (current->NextEntryOffset == 0) break; } - uint32_t pageSize = instance.state.platform.sysinfo.pageSize; - swap->bytesUsed *= pageSize; - swap->bytesTotal *= pageSize; return NULL; } diff --git a/src/detection/wm/wm_linux.c b/src/detection/wm/wm_linux.c index 60ff5a3b83..6d7e7b8f79 100644 --- a/src/detection/wm/wm_linux.c +++ b/src/detection/wm/wm_linux.c @@ -128,6 +128,39 @@ static const char* getSway(FFstrbuf* result) return "Failed to run command `sway --version`"; } +static bool extractI3Version(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata) +{ + int count = 0; + sscanf(line, "%*d.%*d%n", &count); + if (count == 0) return true; + + ffStrbufSetNS((FFstrbuf*) userdata, len, line); + return false; +} + +static const char* getI3(FFstrbuf* result) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + const char* error = ffFindExecutableInPath("i3", &path); + if (error) return "Failed to find i3 executable path"; + + ffBinaryExtractStrings(path.chars, extractI3Version, result, (uint32_t) strlen("0.0")); + if (result->length > 0) return NULL; + + if (ffProcessAppendStdOut(result, (char* const[]){ + path.chars, + "--version", + NULL + }) == NULL) + { // i3 version 1.10 C 2009... + ffStrbufSubstrAfterFirstS(result, "version "); + ffStrbufSubstrBeforeFirstC(result, ' '); + return NULL; + } + + return "Failed to run command `i3 --version`"; +} + static const char* getWslg(FFstrbuf* result) { if (!ffAppendFileBuffer("/mnt/wslg/versions.txt", result)) @@ -143,6 +176,62 @@ static const char* getWslg(FFstrbuf* result) return NULL; } +static bool extractCtFvWmVersion(const char* line, FF_MAYBE_UNUSED uint32_t len, void *userdata) +{ + int count = 0; + sscanf(line, "%*d.%*d.%*d%n", &count); + if (count == 0) return true; + + ffStrbufSetNS((FFstrbuf*) userdata, len, line); + return false; +} + +static const char* getCtwm(FFstrbuf* result) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + const char* error = ffFindExecutableInPath("ctwm", &path); + if (error) return "Failed to find ctwm executable path"; + + ffBinaryExtractStrings(path.chars, extractCtFvWmVersion, result, (uint32_t) strlen("0.0.0")); + if (result->length > 0) return NULL; + + if (ffProcessAppendStdOut(result, (char* const[]){ + path.chars, + "--version", + NULL + }) == NULL) + { // ctwm version 4.0.1\n... + ffStrbufSubstrBeforeFirstC(result, '\n'); + ffStrbufSubstrAfterLastC(result, ' '); + return NULL; + } + + return "Failed to run command `ctwm --version`"; +} + +static const char* getFvwm(FFstrbuf* result) +{ + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + const char* error = ffFindExecutableInPath("fvwm", &path); + if (error) return "Failed to find fvwm executable path"; + + ffBinaryExtractStrings(path.chars, extractCtFvWmVersion, result, (uint32_t) strlen("0.0.0")); + if (result->length > 0) return NULL; + + if (ffProcessAppendStdOut(result, (char* const[]){ + path.chars, + "-version", + NULL + }) == NULL) + { // [FVWM][main]: fvwm Version 2.2.5\n... + ffStrbufSubstrBeforeFirstC(result, '\n'); + ffStrbufSubstrAfterLastC(result, ' '); + return NULL; + } + + return "Failed to run command `fvwm -version`"; +} + const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE_UNUSED FFWMOptions* options) { if (!wmName) @@ -154,8 +243,17 @@ const char* ffDetectWMVersion(const FFstrbuf* wmName, FFstrbuf* result, FF_MAYBE if (ffStrbufEqualS(wmName, "sway")) return getSway(result); + if (ffStrbufEqualS(wmName, "i3")) + return getI3(result); + if (ffStrbufEqualS(wmName, "WSLg")) return getWslg(result); + if (ffStrbufEqualS(wmName, "ctwm")) + return getCtwm(result); + + if (ffStrbufEqualS(wmName, "fvwm")) + return getFvwm(result); + return "Unsupported WM"; } diff --git a/src/logo/ascii/rhel_small.txt b/src/logo/ascii/rhel_small.txt new file mode 100644 index 0000000000..f0841b7bf3 --- /dev/null +++ b/src/logo/ascii/rhel_small.txt @@ -0,0 +1,9 @@ + .M.:MMM + MMMMMMMMMM. + ,MMMMMMMMMMM + .MM MMMMMMMMMMM +MMMM MMMMMMMMM +MMMMMM MM + MMMMMMMMM ,MMMM + MMMMMMMMMMMMMMMM: + `MMMMMMMMMMMM \ No newline at end of file diff --git a/src/logo/ascii/starry.txt b/src/logo/ascii/starry.txt new file mode 100644 index 0000000000..32a70050c6 --- /dev/null +++ b/src/logo/ascii/starry.txt @@ -0,0 +1,14 @@ + */ + *,*,*( + ,,,,,,,,,,,,,,,,,,,,,,,, + ,*,*,*,*,*,*,*,*,*,*,*,* + ,,,,,,,,,,,,,,,,,,,,,,,, + *,*,*,*,*,*,*,*,*,*,*,*,*,*,* +*,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + ,*,*,*,*,*,*,*,*,*,*,*,*,*,*,*,, + ,,,,,,,,,,,,,,,,,,,,,,,,,,,* + ,*,*,*,*,*,*,*,*,*,*,*,*,*,* + ,,,,,,,,,,,,,,,,,,,,,,,,,,,,,, + (*,*,*,*,*,*,*,*,*,*,*,*,*, + ,,,,,,,,,,,,,,,, + &*,*,*#@@*,*,*, \ No newline at end of file diff --git a/src/logo/ascii/void2.txt b/src/logo/ascii/void2.txt new file mode 100644 index 0000000000..f00a568aa9 --- /dev/null +++ b/src/logo/ascii/void2.txt @@ -0,0 +1,25 @@ + .......... + .::::::::::::::::::.. + ..:::::::::::::::::::::::::. + '::::::::::::::::::::::::::::. + ':::::'' '':::::::::::::. +$3 .. $1' '':::::::::. +$3 .||. $1'::::::::: +$3 .|||||. $1':::::::: +$3 .|||||||: $1:::::::: +$3 |||||||: $1.::::::::. :::::::: +$2 ######$3||||||' $2##^ v##########v$1::. $2##### #############v +$2 ######$3||||| $2##^ v####$1::::::$2####v$1::$2##### #####$1:::::$2##### +$2 ######$3||$2##^ #####$1::::::$2#####$1::$2##### #####$1:::::$2###### +$2 ######^$3|| $2#####$1:::::$2####^$1::$2##### #####$1:::::$2#####^ +$2 ##^$3||||| $2^###########^$1:::$2##### ##############^ +$3 |||||||: $1'::::::::' .:::::::: +$3 '|||||||: $1.::::::::' +$3 '|||||||:. $1':::::: +$3 '||||||||:. $1'::: +$3 ':|||||||||. . $1' +$3 '|||||||||||:... ...:||||. + ':||||||||||||||||||||||||||. + ':|||||||||||||||||||||||'' + '':||||||||||||||:'' + '''''' diff --git a/src/logo/ascii/xenia.txt b/src/logo/ascii/xenia.txt index 6ddf64b181..50764b4acc 100644 --- a/src/logo/ascii/xenia.txt +++ b/src/logo/ascii/xenia.txt @@ -1,21 +1,15 @@ -$2 ,c. .c; -$2 .$1KMMMk$2.... ....$1kMMMK$2. -$2 .$1WMMMMMX$2..... .....$1KMMMMMW. -$1 XMMMMMMM0$2..... ....$1OMMMMMMMN -$1 dMMMMMMMMM;$2.... ..... ....,$1MMMMMMMMMd -$1 WMMMMMMMMMl;$3okKKKKKKKKKOo$1;cMMMMMMMMMM -$1 'MMMMMMMNX$2K0$3KKKKKKKKKKKKKKK$20K$1XNMMMMMMM; -$1 oMMMMMMM$2Oxo$3KKKKKKKKKKKKKKKKK$2oxO$1MMMMMMMd -$1 dMMMMMMM$2dxxx$3KKKKKKKKKKKKKKK$2xxxd$1NMMMMMMk -$1 :MMMMX0$2xxxxxx$30KKKKKKKK0KK0$2xxxxxx0$1XMMMMc -$1 MMMO$2xxxxxxxxdx$3kdd$20x0$3ddk$2xdxxxxxxxx$1OMMM -$1 ;$2xxkxddxxxxdodxxxxdxdxxxxdodxxxxddxkxx$1; -$1dxd$2KMMMWXo$1'.....'$2cdxxxdc$1'.....'$2lXWMMMX$1dxd -$1cxd$2XMMMN$1,..........$2dxd$1'.........'$2XMMMN$1dxl -$1 .xx$2WMMl$1...''....'.;k:.'....''...$2lMMW$1xx. -$1..:kXMMx..'....''..kMk..''....'..xMMXkc.. -$1 dMMMMMMd.....'...xMMMx...''....dMMMMMMx -$1 kMMMMWOoc:coOkolllokOoc:coOWMMMMO -$1 .MMMMMMMMl$2...$1lNMMMMMMM. -$1 KMMMMMMX$2l$1KMMMMMMX -$1 .MMMMMMMMM. \ No newline at end of file +$1 ** + * ** */ + $2@$1///// / *** *** **** ***/ + //////////////**** ** * ** *** **/ + ,, ,,//////////* ****** ** ** ** / + , , ,,, /////******* ********* / + , ,,,,, ** ** *********** + ., ,,,**** ******* *** /// + ,, *********** ** //// + ,,,,, ******* //// // + ,,,,,,. ///// // + ,,, , /////// + ,,,, ///// + ,, / / + / diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 0401f58438..6b409065aa 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -4060,7 +4060,7 @@ static const FFlogo R[] = { }, // RedHatEnterpriseLinux { - .names = {"rhel", "redhat", "redhat-linux"}, + .names = {"rhel", "redhat"}, .lines = FASTFETCH_DATATEXT_LOGO_RHEL, .colors = { FF_COLOR_FG_RED, @@ -4068,9 +4068,20 @@ static const FFlogo R[] = { .colorKeys = FF_COLOR_FG_RED, .colorTitle = FF_COLOR_FG_RED, }, + // RedHatEnterpriseLinux + { + .names = {"rhel_small", "redhat_small"}, + .type = FF_LOGO_LINE_TYPE_SMALL_BIT, + .lines = FASTFETCH_DATATEXT_LOGO_RHEL_SMALL, + .colors = { + FF_COLOR_FG_RED, + }, + .colorKeys = FF_COLOR_FG_RED, + .colorTitle = FF_COLOR_FG_RED, + }, // RedHatEnterpriseLinux_old { - .names = {"rhel_old", "redhat_old", "redhat-linux_old"}, + .names = {"rhel_old", "redhat_old"}, .type = FF_LOGO_LINE_TYPE_ALTER_BIT, .lines = FASTFETCH_DATATEXT_LOGO_RHEL_OLD, .colors = { @@ -4082,11 +4093,10 @@ static const FFlogo R[] = { { .names = {"RedOS", "RED OS", "red-os", "redos"}, .lines = FASTFETCH_DATATEXT_LOGO_REDOS, - .colors = - { - FF_COLOR_FG_RED, - FF_COLOR_FG_WHITE, - }, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, .colorTitle = FF_COLOR_FG_RED, .colorKeys = FF_COLOR_FG_RED, }, @@ -4095,11 +4105,10 @@ static const FFlogo R[] = { .names = {"RedOS_small", "RED OS_small", "red-os_small", "redos_small"}, .type = FF_LOGO_LINE_TYPE_SMALL_BIT, .lines = FASTFETCH_DATATEXT_LOGO_REDOS_SMALL, - .colors = - { - FF_COLOR_FG_RED, - FF_COLOR_FG_WHITE, - }, + .colors = { + FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, + }, .colorTitle = FF_COLOR_FG_RED, .colorKeys = FF_COLOR_FG_RED, }, @@ -4527,6 +4536,16 @@ static const FFlogo S[] = { FF_COLOR_FG_WHITE, }, }, + // Starry + { + .names = {"Starry"}, + .lines = FASTFETCH_DATATEXT_LOGO_STARRY, + .colors = { + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_GREEN, + .colorTitle = FF_COLOR_FG_WHITE, + }, // StockLinux { .names = {"Stock Linux"}, @@ -5089,9 +5108,9 @@ static const FFlogo V[] = { .lines = FASTFETCH_DATATEXT_LOGO_VOID, .colors = { FF_COLOR_FG_GREEN, - FF_COLOR_FG_BLACK, + FF_COLOR_FG_LIGHT_BLACK, }, - .colorKeys = FF_COLOR_FG_WHITE, + .colorKeys = FF_COLOR_FG_DEFAULT, .colorTitle = FF_COLOR_FG_GREEN, }, // VoidSmall @@ -5102,7 +5121,19 @@ static const FFlogo V[] = { .colors = { FF_COLOR_FG_GREEN, }, - .colorKeys = FF_COLOR_FG_WHITE, + .colorKeys = FF_COLOR_FG_DEFAULT, + .colorTitle = FF_COLOR_FG_GREEN, + }, + // Void2 + { + .names = {"void2"}, + .lines = FASTFETCH_DATATEXT_LOGO_VOID2, + .colors = { + FF_COLOR_FG_YELLOW, + FF_COLOR_FG_DEFAULT, + FF_COLOR_FG_GREEN, + }, + .colorKeys = FF_COLOR_FG_DEFAULT, .colorTitle = FF_COLOR_FG_GREEN, }, // Void2Small @@ -5230,9 +5261,8 @@ static const FFlogo X[] = { .names = {"Xenia"}, .lines = FASTFETCH_DATATEXT_LOGO_XENIA, .colors = { - FF_COLOR_FG_YELLOW, - FF_COLOR_FG_GREEN, FF_COLOR_FG_RED, + FF_COLOR_FG_WHITE, } }, // XCP-ng diff --git a/src/logo/logo.c b/src/logo/logo.c index 7d80aa40fc..abf8be9e24 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -1,6 +1,7 @@ #include "logo/logo.h" #include "common/io/io.h" #include "common/printing.h" +#include "common/processing.h" #include "detection/os/os.h" #include "detection/terminalshell/terminalshell.h" #include "util/textModifier.h" @@ -455,14 +456,13 @@ static inline void logoPrintDetected(FFLogoSize size) logoPrintStruct(logoGetBuiltinDetected(size)); } -static bool logoPrintData(bool doColorReplacement) +static bool logoPrintData(bool doColorReplacement, FFstrbuf* source) { - FFOptionsLogo* options = &instance.config.logo; - if(options->source.length == 0) + if(source->length == 0) return false; logoApplyColors(logoGetBuiltinDetected(FF_LOGO_SIZE_NORMAL), doColorReplacement); - ffLogoPrintChars(options->source.chars, doColorReplacement); + ffLogoPrintChars(source->chars, doColorReplacement); return true; } @@ -510,7 +510,7 @@ static bool logoPrintFileIfExists(bool doColorReplacement, bool raw) ) { if (instance.config.display.showErrors) - fprintf(stderr, "Logo: Failed to load file content from logo source: %s \n", options->source.chars); + fprintf(stderr, "Logo: Failed to load file content from logo source: %s\n", options->source.chars); return false; } @@ -548,10 +548,36 @@ static bool logoTryKnownType(void) return logoPrintBuiltinIfExists(&options->source, FF_LOGO_SIZE_SMALL); if(options->type == FF_LOGO_TYPE_DATA) - return logoPrintData(true); + return logoPrintData(true, &options->source); if(options->type == FF_LOGO_TYPE_DATA_RAW) - return logoPrintData(false); + return logoPrintData(false, &options->source); + + if(options->type == FF_LOGO_TYPE_COMMAND_RAW) + { + FF_STRBUF_AUTO_DESTROY source = ffStrbufCreate(); + + FFCommandOptions* commandOptions = &instance.config.modules.command; + const char* error = ffProcessAppendStdOut(&source, commandOptions->param.length ? (char* const[]){ + commandOptions->shell.chars, + commandOptions->param.chars, + options->source.chars, + NULL + } : (char* const[]){ + commandOptions->shell.chars, + options->source.chars, + NULL + }); + + if (error) + { + if (instance.config.display.showErrors) + fprintf(stderr, "Logo: failed to execute command `%s`: %s\n", options->source.chars, error); + return false; + } + + return logoPrintData(false, &source); + } updateLogoPath(); //We sure have a file, resolve relative paths @@ -603,7 +629,7 @@ void ffLogoPrint(void) { // Image logo should have been handled if(options->type == FF_LOGO_TYPE_BUILTIN || options->type == FF_LOGO_TYPE_SMALL) - fprintf(stderr, "Logo: Failed to load %s logo: %s \n", options->type == FF_LOGO_TYPE_BUILTIN ? "builtin" : "builtin small", options->source.chars); + fprintf(stderr, "Logo: Failed to load %s logo: %s\n", options->type == FF_LOGO_TYPE_BUILTIN ? "builtin" : "builtin small", options->source.chars); } logoPrintDetected(FF_LOGO_SIZE_UNKNOWN); diff --git a/src/modules/swap/option.h b/src/modules/swap/option.h index d6e7965ad2..e0f44e02a0 100644 --- a/src/modules/swap/option.h +++ b/src/modules/swap/option.h @@ -11,4 +11,5 @@ typedef struct FFSwapOptions FFModuleArgs moduleArgs; FFPercentageModuleConfig percent; + bool separate; } FFSwapOptions; diff --git a/src/modules/swap/swap.c b/src/modules/swap/swap.c index e6cfa8c0c7..1f864562ae 100644 --- a/src/modules/swap/swap.c +++ b/src/modules/swap/swap.c @@ -6,34 +6,44 @@ #include "modules/swap/swap.h" #include "util/stringUtils.h" -void ffPrintSwap(FFSwapOptions* options) +void printSwap(FFSwapOptions* options, uint8_t index, FFSwapResult* storage) { - FFSwapResult storage = {}; - const char* error = ffDetectSwap(&storage); + FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate(); - if(error) + if (options->moduleArgs.key.length == 0) { - ffPrintError(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error); - return; + if (storage->name.length > 0) + ffStrbufSetF(&key, "%s (%s)", FF_SWAP_MODULE_NAME, storage->name.chars); + else + ffStrbufSetS(&key, FF_SWAP_MODULE_NAME); + } + else + { + ffStrbufClear(&key); + FF_PARSE_FORMAT_STRING_CHECKED(&key, &options->moduleArgs.key, ((FFformatarg[]) { + FF_FORMAT_ARG(index, "index"), + FF_FORMAT_ARG(storage->name, "name"), + FF_FORMAT_ARG(options->moduleArgs.keyIcon, "icon"), + })); } FF_STRBUF_AUTO_DESTROY usedPretty = ffStrbufCreate(); - ffParseSize(storage.bytesUsed, &usedPretty); + ffParseSize(storage->bytesUsed, &usedPretty); FF_STRBUF_AUTO_DESTROY totalPretty = ffStrbufCreate(); - ffParseSize(storage.bytesTotal, &totalPretty); + ffParseSize(storage->bytesTotal, &totalPretty); - double percentage = storage.bytesTotal == 0 + double percentage = storage->bytesTotal == 0 ? 0 - : (double) storage.bytesUsed / (double) storage.bytesTotal * 100.0; + : (double) storage->bytesUsed / (double) storage->bytesTotal * 100.0; FFPercentageTypeFlags percentType = options->percent.type == 0 ? instance.config.display.percentType : options->percent.type; if(options->moduleArgs.outputFormat.length == 0) { - ffPrintLogoAndKey(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT); + ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY); FF_STRBUF_AUTO_DESTROY str = ffStrbufCreate(); - if (storage.bytesTotal == 0) + if (storage->bytesTotal == 0) { if(percentType & FF_PERCENTAGE_TYPE_BAR_BIT) { @@ -71,15 +81,56 @@ void ffPrintSwap(FFSwapOptions* options) FF_STRBUF_AUTO_DESTROY percentageBar = ffStrbufCreate(); if (percentType & FF_PERCENTAGE_TYPE_BAR_BIT) ffPercentAppendBar(&percentageBar, percentage, options->percent, &options->moduleArgs); - FF_PRINT_FORMAT_CHECKED(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, ((FFformatarg[]){ + FF_PRINT_FORMAT_CHECKED(key.chars, index, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, ((FFformatarg[]){ FF_FORMAT_ARG(usedPretty, "used"), FF_FORMAT_ARG(totalPretty, "total"), FF_FORMAT_ARG(percentageNum, "percentage"), FF_FORMAT_ARG(percentageBar, "percentage-bar"), + FF_FORMAT_ARG(storage->name, "name"), })); } } +void ffPrintSwap(FFSwapOptions* options) +{ + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFSwapResult)); + const char* error = ffDetectSwap(&result); + + if(error) + { + ffPrintError(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "%s", error); + return; + } + + if (options->separate) + { + uint8_t index = 0; + FF_LIST_FOR_EACH(FFSwapResult, storage, result) + { + ++index; + printSwap(options, index, storage); + } + } + else + { + FFSwapResult total = { + .name = ffStrbufCreate(), + }; + FF_LIST_FOR_EACH(FFSwapResult, storage, result) + { + total.bytesUsed += storage->bytesUsed; + total.bytesTotal += storage->bytesTotal; + } + printSwap(options, 0, &total); + ffStrbufDestroy(&total.name); + } + + FF_LIST_FOR_EACH(FFSwapResult, storage, result) + { + ffStrbufDestroy(&storage->name); + } +} + bool ffParseSwapCommandOptions(FFSwapOptions* options, const char* key, const char* value) { const char* subKey = ffOptionTestPrefix(key, FF_SWAP_MODULE_NAME); @@ -90,6 +141,12 @@ bool ffParseSwapCommandOptions(FFSwapOptions* options, const char* key, const ch if (ffPercentParseCommandOptions(key, subKey, value, &options->percent)) return true; + if (ffStrEqualsIgnCase(subKey, "separate")) + { + options->separate = ffOptionParseBoolean(value); + return true; + } + return false; } @@ -109,6 +166,12 @@ void ffParseSwapJsonObject(FFSwapOptions* options, yyjson_val* module) if (ffPercentParseJsonObject(key, val, &options->percent)) continue; + if (ffStrEqualsIgnCase(key, "separate")) + { + options->separate = yyjson_get_bool(val); + continue; + } + ffPrintError(FF_SWAP_MODULE_NAME, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT, "Unknown JSON key %s", key); } } @@ -125,8 +188,8 @@ void ffGenerateSwapJsonConfig(FFSwapOptions* options, yyjson_mut_doc* doc, yyjso void ffGenerateSwapJsonResult(FF_MAYBE_UNUSED FFSwapOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module) { - FFSwapResult storage = {}; - const char* error = ffDetectSwap(&storage); + FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFSwapResult)); + const char* error = ffDetectSwap(&result); if(error) { @@ -134,9 +197,19 @@ void ffGenerateSwapJsonResult(FF_MAYBE_UNUSED FFSwapOptions* options, yyjson_mut return; } - yyjson_mut_val* obj = yyjson_mut_obj_add_obj(doc, module, "result"); - yyjson_mut_obj_add_uint(doc, obj, "total", storage.bytesTotal); - yyjson_mut_obj_add_uint(doc, obj, "used", storage.bytesUsed); + yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result"); + FF_LIST_FOR_EACH(FFSwapResult, storage, result) + { + yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr); + yyjson_mut_obj_add_strbuf(doc, obj, "name", &storage->name); + yyjson_mut_obj_add_uint(doc, obj, "used", storage->bytesUsed); + yyjson_mut_obj_add_uint(doc, obj, "total", storage->bytesTotal); + } + + FF_LIST_FOR_EACH(FFSwapResult, storage, result) + { + ffStrbufDestroy(&storage->name); + } } static FFModuleBaseInfo ffModuleInfo = { @@ -152,6 +225,7 @@ static FFModuleBaseInfo ffModuleInfo = { {"Total size", "total"}, {"Percentage used (num)", "percentage"}, {"Percentage used (bar)", "percentage-bar"}, + {"Name", "name"}, })) }; @@ -160,6 +234,7 @@ void ffInitSwapOptions(FFSwapOptions* options) options->moduleInfo = ffModuleInfo; ffOptionInitModuleArg(&options->moduleArgs, "󰓡"); options->percent = (FFPercentageModuleConfig) { 50, 80, 0 }; + options->separate = false; } void ffDestroySwapOptions(FFSwapOptions* options) diff --git a/src/options/logo.c b/src/options/logo.c index 66e652db32..5b3aed829b 100644 --- a/src/options/logo.c +++ b/src/options/logo.c @@ -60,6 +60,7 @@ bool ffOptionsParseLogoCommandLine(FFOptionsLogo* options, const char* key, cons { "file-raw", FF_LOGO_TYPE_FILE_RAW }, { "data", FF_LOGO_TYPE_DATA }, { "data-raw", FF_LOGO_TYPE_DATA_RAW }, + { "command-raw", FF_LOGO_TYPE_COMMAND_RAW }, { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, { "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT }, @@ -286,6 +287,7 @@ const char* ffOptionsParseLogoJsonConfig(FFOptionsLogo* options, yyjson_val* roo { "file-raw", FF_LOGO_TYPE_FILE_RAW }, { "data", FF_LOGO_TYPE_DATA }, { "data-raw", FF_LOGO_TYPE_DATA_RAW }, + { "command-raw", FF_LOGO_TYPE_COMMAND_RAW }, { "sixel", FF_LOGO_TYPE_IMAGE_SIXEL }, { "kitty", FF_LOGO_TYPE_IMAGE_KITTY }, { "kitty-direct", FF_LOGO_TYPE_IMAGE_KITTY_DIRECT }, @@ -492,6 +494,9 @@ void ffOptionsGenerateLogoJsonConfig(FFOptionsLogo* options, yyjson_mut_doc* doc case FF_LOGO_TYPE_DATA_RAW: yyjson_mut_obj_add_str(doc, obj, "type", "data-raw"); break; + case FF_LOGO_TYPE_COMMAND_RAW: + yyjson_mut_obj_add_str(doc, obj, "type", "command-raw"); + break; case FF_LOGO_TYPE_IMAGE_SIXEL: yyjson_mut_obj_add_str(doc, obj, "type", "sixel"); break; diff --git a/src/options/logo.h b/src/options/logo.h index c2a180b7b6..94dd2a95b0 100644 --- a/src/options/logo.h +++ b/src/options/logo.h @@ -14,6 +14,7 @@ typedef enum __attribute__((__packed__)) FFLogoType FF_LOGO_TYPE_FILE_RAW, //text file, printed as is FF_LOGO_TYPE_DATA, //text data, printed with color code replacement FF_LOGO_TYPE_DATA_RAW, //text data, printed as is + FF_LOGO_TYPE_COMMAND_RAW, //command to generate text data, printed as is FF_LOGO_TYPE_IMAGE_SIXEL, //image file, printed as sixel codes FF_LOGO_TYPE_IMAGE_KITTY, //image file, printed as kitty graphics protocol FF_LOGO_TYPE_IMAGE_KITTY_DIRECT, //image file, tell the terminal emulator to read image data from the specified file (Supported by kitty and wezterm) diff --git a/src/util/smbiosHelper.c b/src/util/smbiosHelper.c index c0db8dc49f..1171d27786 100644 --- a/src/util/smbiosHelper.c +++ b/src/util/smbiosHelper.c @@ -143,7 +143,7 @@ const FFSmbiosHeaderTable* ffGetSmbiosHeaderTable() { FF_DEBUG("Initializing SMBIOS buffer"); ffStrbufInit(&buffer); - #if !__HAIKU__ && !__OpenBSD__ + #if !__HAIKU__ && !__OpenBSD__ && !__DragonFly__ #ifdef __linux__ FF_DEBUG("Using Linux implementation - trying /sys/firmware/dmi/tables/DMI"); if (!ffAppendFileBuffer("/sys/firmware/dmi/tables/DMI", &buffer))