mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-12 18:06:11 +02:00
Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 5ede47fede | |||
| d84ae91f59 | |||
| 70160d324f | |||
| 600f6c7f24 | |||
| 11b1b97567 | |||
| 4ae0c43c6f | |||
| e89d475a3b | |||
| 4f3cd46f96 | |||
| c076f5ae98 | |||
| 064d7d3c3a | |||
| 9937eeab1d | |||
| e8326306f8 | |||
| 89bc7eb015 | |||
| 3cd81ec3ad | |||
| 0f497a53ad | |||
| 569883a1a1 | |||
| 04a41cbd6b | |||
| 4e4246a46a | |||
| c3a28064f6 | |||
| ce9f9ed7ed | |||
| fb8c7d6e4a | |||
| 70f39e641c | |||
| 1dbd8474c2 | |||
| e7c787159a | |||
| 9339a0fb4e | |||
| b692b759c7 | |||
| 529f94c64a | |||
| e071a1eeb2 | |||
| 3400e40e47 | |||
| d32125e988 | |||
| b3484088e9 | |||
| f91a8aea4d | |||
| 335022e034 | |||
| 8fa073b1e4 | |||
| 10e1753c03 | |||
| 224a6a9881 | |||
| e804dfc49e | |||
| 8048101eca | |||
| 833727f333 | |||
| 8ed5d30b3e | |||
| f62cdff924 | |||
| 25a792743b | |||
| b63e6a3053 | |||
| a565dcfb9e | |||
| 453f4757ed | |||
| 0555fb97e8 | |||
| 663d568927 | |||
| 165c213ed0 | |||
| a28dc8a9bf | |||
| f20b6d4387 | |||
| 4925222dab | |||
| 77cc0c61d7 | |||
| a19888bb33 | |||
| 40aa4a60d6 | |||
| c4824b2b5d | |||
| dcbda6c0d5 | |||
| 91e4e94aaa | |||
| 1504e26e38 | |||
| a9c5c2892c | |||
| 923997f0a2 | |||
| 0182e32f00 | |||
| bd40205427 |
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Bug report
|
||||
about: Create a report to help us improve
|
||||
title: ''
|
||||
title: '[BUG] '
|
||||
labels: bug
|
||||
assignees: ''
|
||||
|
||||
@@ -24,12 +24,9 @@ The content of the configuration file you use (if any)
|
||||
//paste here
|
||||
```
|
||||
|
||||
Output of `env NO_CONFIG=1 fastfetch --load-config all --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false`:
|
||||
Output of `fastfetch -c ci.jsonc --format json`:
|
||||
<!--
|
||||
Note that this output will contain you public IP. If it is not relevant for the issue, feel free to remove it before uploading.
|
||||
|
||||
If you get the following error: `Error: couldn't find config: [...]`, copy the files in [presets](../../presets/) to `/usr/share/fastfetch/presets/` or `~/.local/share/fastfetch/presets/`.
|
||||
If this isn't possible (or too much work) for you, post the output of `env NO_CONFIG=1 fastfetch --show-errors --stat --multithreading false --disable-linewrap false --hide-cursor false && fastfetch --version`.
|
||||
-->
|
||||
|
||||
```
|
||||
|
||||
@@ -1,12 +1,14 @@
|
||||
---
|
||||
name: Feature request
|
||||
about: Suggest an idea for this project
|
||||
title: ''
|
||||
title: '[FEAT] '
|
||||
labels: enhancement
|
||||
assignees: ''
|
||||
|
||||
---
|
||||
|
||||
<!-- Before requesting a new feature, please try `fastfetch -c all.jsonc` to see if it has been supported -->
|
||||
|
||||
# Current state:
|
||||
|
||||
# Wanted state:
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
---
|
||||
name: Logo request
|
||||
about: Request a new logo
|
||||
title: ''
|
||||
title: '[LOGO] '
|
||||
labels: logo request
|
||||
assignees: ''
|
||||
|
||||
@@ -9,10 +9,10 @@ assignees: ''
|
||||
|
||||
# OS
|
||||
```
|
||||
paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
|
||||
Paste content of /etc/os-release here. If this file doesn't exist, describe a way to identify the distro.
|
||||
```
|
||||
|
||||
# Ascii
|
||||
```
|
||||
paste ascii art here. If you leave this empty, i will try to find the logo myself.
|
||||
Paste ascii art here.
|
||||
```
|
||||
|
||||
@@ -215,8 +215,8 @@ jobs:
|
||||
cmake -DSET_TWEAK=Off -DBUILD_TESTS=On .
|
||||
cmake --build . --target package --verbose
|
||||
./fastfetch --list-features
|
||||
time ./fastfetch -c presets/ci.jsonc
|
||||
time ./fastfetch -c presets/ci.jsonc --format json
|
||||
time ./fastfetch
|
||||
time ./fastfetch --format json
|
||||
time ./flashfetch
|
||||
ldd fastfetch
|
||||
ctest
|
||||
|
||||
@@ -7,3 +7,4 @@
|
||||
cscope.*
|
||||
tags
|
||||
fastfetch.kdev4
|
||||
*.user
|
||||
|
||||
@@ -1,3 +1,43 @@
|
||||
# 2.4.0
|
||||
|
||||
**We are deprecating flags based config files (will be removed in v3.0.0). We suggest you migrate to json based config files.** One may use `-c /path/to/config.conf --gen-config` to migrate existing flag based config files.
|
||||
|
||||
Changes:
|
||||
* All flag based presets are removed
|
||||
|
||||
Features:
|
||||
* Improve performance of detecting rpm and pkg package count (Packages, Linux / FreeBSD)
|
||||
* Support Apple M3X temperature detection (CPU / GPU, macOS)
|
||||
* `--ds-force-drm` support a new option `sysfs-only`
|
||||
* Improve xfce4 version detection
|
||||
* Detect WM and DE by enumerating running processes (WM / DE, FreeBSD)
|
||||
* Add a new module `Physical Disk`, which detects product name, full size, serial number and so on.
|
||||
|
||||
Bugfixes:
|
||||
* Fix crashes sometimes when `--logo-padding-top` is not set (Logo)
|
||||
* Fix memory usage counting algorithm (Memory, macOS)
|
||||
* Fix the behavior of `--no-buffer` in Windows
|
||||
* Fix possible segfault in some devices (Display, Linux)
|
||||
* Fix segfaults on first use of new images with Sixel flag (Image)
|
||||
|
||||
Logo:
|
||||
* Remove unnecessary escaping for Adelie logo
|
||||
* Add EshanizedOS
|
||||
|
||||
# 2.3.4
|
||||
|
||||
Bugfixes:
|
||||
* Fix `--help` doesn't work when built without python
|
||||
|
||||
Features:
|
||||
* Use `MemAvailable` if available (Memory, Linux)
|
||||
* Improve performance of detecting dpkg package count (Packages, Linux)
|
||||
|
||||
# 2.3.3
|
||||
|
||||
Bugfixes:
|
||||
* Fix `--help` doesn't work in Windows and some other platforms
|
||||
|
||||
# 2.3.2
|
||||
|
||||
Bugfixes:
|
||||
|
||||
+15
-6
@@ -1,7 +1,7 @@
|
||||
cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url
|
||||
|
||||
project(fastfetch
|
||||
VERSION 2.3.2
|
||||
VERSION 2.4.0
|
||||
LANGUAGES C
|
||||
DESCRIPTION "Fast neofetch-like system information tool"
|
||||
HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"
|
||||
@@ -206,7 +206,7 @@ endif()
|
||||
#############
|
||||
|
||||
function(fastfetch_encode_c_string STR OUTVAR)
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
|
||||
string(REGEX REPLACE "\n$" "" TEMP "${STR}") # Remove trailing newline
|
||||
string(REPLACE "\\" "\\\\" TEMP "${TEMP}") # Escape backslashes
|
||||
string(REPLACE "\n" "\\n" TEMP "${TEMP}") # Replace newlines with \n
|
||||
string(REPLACE "\"" "\\\"" TEMP "${TEMP}") # Replace quotes with \"
|
||||
@@ -221,12 +221,15 @@ endfunction(fastfetch_load_text)
|
||||
|
||||
find_package(Python)
|
||||
if(Python_FOUND)
|
||||
# Minify JSON string. `io.open(0,encoding='utf-8')` is needed to avoid encoding issues on Windows
|
||||
execute_process(COMMAND ${Python_EXECUTABLE} -c "import io,json,sys;json.dump(json.load(io.open(0,encoding='utf-8')),sys.stdout,separators=(',', ':'),ensure_ascii=False)"
|
||||
execute_process(COMMAND ${Python_EXECUTABLE} -c "import json,sys;json.dump(json.load(sys.stdin),sys.stdout,separators=(',',':'))"
|
||||
INPUT_FILE "${CMAKE_CURRENT_SOURCE_DIR}/src/data/help.json"
|
||||
OUTPUT_VARIABLE DATATEXT_JSON_HELP)
|
||||
if(DATATEXT_JSON_HELP STREQUAL "")
|
||||
message(ERROR "DATATEXT_JSON_HELP is empty, which should not happen!")
|
||||
endif()
|
||||
else()
|
||||
file(READ "src/data/help.json" TEMP)
|
||||
message(STATUS "Python3 is not found, 'help.json' will not be minified")
|
||||
file(READ "src/data/help.json" DATATEXT_JSON_HELP)
|
||||
endif()
|
||||
|
||||
fastfetch_encode_c_string("${DATATEXT_JSON_HELP}" DATATEXT_JSON_HELP)
|
||||
@@ -337,6 +340,7 @@ set(LIBFASTFETCH_SRC
|
||||
src/modules/opengl/opengl.c
|
||||
src/modules/os/os.c
|
||||
src/modules/packages/packages.c
|
||||
src/modules/physicaldisk/physicaldisk.c
|
||||
src/modules/processes/processes.c
|
||||
src/modules/player/player.c
|
||||
src/modules/poweradapter/poweradapter.c
|
||||
@@ -391,6 +395,7 @@ if(LINUX)
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/bluetooth/bluetooth_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_linux.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
@@ -450,6 +455,7 @@ elseif(ANDROID)
|
||||
src/detection/cursor/cursor_nosupport.c
|
||||
src/detection/cpuusage/cpuusage_linux.c
|
||||
src/detection/disk/disk_linux.c
|
||||
src/detection/physicaldisk/physicaldisk_linux.c
|
||||
src/detection/diskio/diskio_linux.c
|
||||
src/detection/displayserver/displayserver_android.c
|
||||
src/detection/font/font_nosupport.c
|
||||
@@ -503,6 +509,7 @@ elseif(BSD)
|
||||
src/detection/cpuusage/cpuusage_bsd.c
|
||||
src/detection/cursor/cursor_linux.c
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/physicaldisk/physicaldisk_bsd.c
|
||||
src/detection/diskio/diskio_bsd.c
|
||||
src/detection/displayserver/linux/displayserver_linux.c
|
||||
src/detection/displayserver/linux/drm.c
|
||||
@@ -526,7 +533,7 @@ elseif(BSD)
|
||||
src/detection/netio/netio_bsd.c
|
||||
src/detection/opengl/opengl_linux.c
|
||||
src/detection/os/os_linux.c
|
||||
src/detection/packages/packages_linux.c
|
||||
src/detection/packages/packages_bsd.c
|
||||
src/detection/poweradapter/poweradapter_nosupport.c
|
||||
src/detection/processes/processes_bsd.c
|
||||
src/detection/gtk_qt/qt.c
|
||||
@@ -563,6 +570,7 @@ elseif(APPLE)
|
||||
src/detection/cpuusage/cpuusage_apple.c
|
||||
src/detection/cursor/cursor_apple.m
|
||||
src/detection/disk/disk_bsd.c
|
||||
src/detection/physicaldisk/physicaldisk_apple.c
|
||||
src/detection/diskio/diskio_apple.c
|
||||
src/detection/displayserver/displayserver_apple.c
|
||||
src/detection/font/font_apple.m
|
||||
@@ -616,6 +624,7 @@ elseif(WIN32)
|
||||
src/detection/cpuusage/cpuusage_windows.c
|
||||
src/detection/cursor/cursor_windows.c
|
||||
src/detection/disk/disk_windows.c
|
||||
src/detection/physicaldisk/physicaldisk_windows.c
|
||||
src/detection/diskio/diskio_windows.c
|
||||
src/detection/displayserver/displayserver_windows.c
|
||||
src/detection/font/font_windows.c
|
||||
|
||||
@@ -89,3 +89,15 @@ Q: Why do you need a very performant version of neofetch?
|
||||
|
||||
Q: It does not display [*] correctly for me, what can I do?
|
||||
> This is most likely because your system is not implemented (yet). At the moment I am focusing more on making the core app better, than adding more configurations. Feel free to open a pull request if you want to add support for your configuration
|
||||
|
||||
## Star History
|
||||
|
||||
Give it a star to support us!
|
||||
|
||||
<a href="https://star-history.com/#fastfetch-cli/fastfetch&Date">
|
||||
<picture>
|
||||
<source media="(prefers-color-scheme: dark)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date&theme=dark" />
|
||||
<source media="(prefers-color-scheme: light)" srcset="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||
<img alt="Star History Chart" src="https://api.star-history.com/svg?repos=fastfetch-cli/fastfetch&type=Date" />
|
||||
</picture>
|
||||
</a>
|
||||
|
||||
+45
-2
@@ -251,8 +251,24 @@
|
||||
"description": "Set the path to the file containing OS information. Linux only"
|
||||
},
|
||||
"dsForceDrm": {
|
||||
"type": "boolean",
|
||||
"description": "Force display detection to use `/sys/class/drm`. Linux only",
|
||||
"description": "Force display detection to use DRM. Linux only",
|
||||
"oneOf": [
|
||||
{
|
||||
"type": "bool",
|
||||
"const": false,
|
||||
"description": "Try `wayland`, then `x11`, then `drm`"
|
||||
},
|
||||
{
|
||||
"type": "string",
|
||||
"description": "Use `/sys/class/drm` only.",
|
||||
"const": "sysfs-only"
|
||||
},
|
||||
{
|
||||
"type": "bool",
|
||||
"const": true,
|
||||
"description": "Try `libdrm` first, then `sysfs` if libdrm failed"
|
||||
}
|
||||
],
|
||||
"default": false
|
||||
},
|
||||
"wmiTimeout": {
|
||||
@@ -584,6 +600,7 @@
|
||||
"opengl",
|
||||
"os",
|
||||
"packages",
|
||||
"physicaldisk",
|
||||
"player",
|
||||
"poweradapter",
|
||||
"processes",
|
||||
@@ -1353,6 +1370,32 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
{
|
||||
"title": "Physical Disk",
|
||||
"properties": {
|
||||
"type": {
|
||||
"description": "Print physical disk information",
|
||||
"const": "physicaldisk"
|
||||
},
|
||||
"namePrefix": {
|
||||
"description": "Show disks with given name prefix only",
|
||||
"type": "string"
|
||||
},
|
||||
"key": {
|
||||
"$ref": "#/$defs/key"
|
||||
},
|
||||
"keyColor": {
|
||||
"$ref": "#/$defs/keyColor"
|
||||
},
|
||||
"keyWidth": {
|
||||
"$ref": "#/$defs/keyWidth"
|
||||
},
|
||||
"format": {
|
||||
"$ref": "#/$defs/format"
|
||||
}
|
||||
},
|
||||
"additionalProperties": false
|
||||
},
|
||||
{
|
||||
"title": "Public IP",
|
||||
"properties": {
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
--structure Title:Separator:OS:Host:Bios:Board:Chassis:Kernel:Uptime:Processes:Packages:Shell:Display:Brightness:Monitor:LM:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Wallpaper:Terminal:TerminalFont:TerminalSize:CPU:CPUUsage:GPU:Memory:Swap:Disk:Battery:PowerAdapter:Player:Media:PublicIP:LocalIP:Wifi:DateTime:Locale:Vulkan:OpenGL:OpenCL:Users:Bluetooth:Sound:Gamepad:Weather:NetIO:DiskIO:Version:Break:Colors
|
||||
@@ -53,6 +53,7 @@
|
||||
"weather",
|
||||
"netio",
|
||||
"diskio",
|
||||
"physicaldisk",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
--logo arch
|
||||
--os-format "Arch Linux ({12})"
|
||||
--packages-format "{} (pacman)"
|
||||
@@ -62,6 +62,7 @@
|
||||
},
|
||||
"netio",
|
||||
"diskio",
|
||||
"physicaldisk",
|
||||
"version",
|
||||
"break",
|
||||
"colors"
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
# Load with --load-config examples/1
|
||||
@@ -1,24 +0,0 @@
|
||||
# Load with --load-config examples/2
|
||||
# Note that you must replace the image path to an existing image to display it.
|
||||
|
||||
--kitty /home/linus/Bilder/Gentoo.png
|
||||
--logo-width 28
|
||||
|
||||
--separator " "
|
||||
|
||||
--set-keyless HardwareStart=┌───────── \e[1mHardware Information\e[0m ─────────┐
|
||||
--set-keyless SoftwareStart=├───────── \e[1mSoftware Information\e[0m ─────────┤
|
||||
--set-keyless InformationEnd=└────────────────────────────────────────┘
|
||||
--set-keyless Colors= \e[38m \e[37m \e[36m \e[35m \e[34m \e[33m \e[32m \e[31m
|
||||
--structure HardwareStart:Host:CPU:GPU:SoftwareStart:OS:Kernel:WM:Shell:Terminal:TerminalFont:Packages:InformationEnd:Colors
|
||||
|
||||
--host-key " "
|
||||
--cpu-key " "
|
||||
--gpu-key " "
|
||||
--os-key " "
|
||||
--kernel-key " "
|
||||
--wm-key " "
|
||||
--shell-key " "
|
||||
--terminal-key " "
|
||||
--terminalfont-key " "
|
||||
--packages-key " "
|
||||
@@ -1,7 +0,0 @@
|
||||
# Load with --load-config example/3
|
||||
|
||||
--logo debian_small
|
||||
--structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP
|
||||
--binary-prefix si
|
||||
--localip-show-loop false
|
||||
--disk-folders /:/home:/boot:/efi
|
||||
@@ -1,7 +0,0 @@
|
||||
# Load with --load-config examples/4
|
||||
|
||||
--color blue
|
||||
--logo arch_small
|
||||
--logo-padding-right 1
|
||||
--separator " "
|
||||
--structure DateTime:Break:Player:Media
|
||||
@@ -1,11 +0,0 @@
|
||||
# Load with --load-config examples/5
|
||||
|
||||
--logo none
|
||||
--color reset_magenta
|
||||
--structure Theme:Icons:Font:Cursor
|
||||
--theme-key T
|
||||
--theme-format {7}
|
||||
--icons-key I
|
||||
--icons-format {5}
|
||||
--font-key F
|
||||
--cursor-key C
|
||||
@@ -1,4 +0,0 @@
|
||||
--structure Host:Display:CPU:GPU:Memory:Disk:Battery
|
||||
--memory-format "{?2}{2}{?}"
|
||||
--disk-format "{?2}{2}{?}"
|
||||
--battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}"
|
||||
@@ -1,9 +0,0 @@
|
||||
--structure "Title:Separator:OS:Host:Kernel:Uptime:Packages:Shell:Display:DE:WM:WMTheme:Theme:Icons:Terminal:TerminalFont:CPU:GPU:Memory:Break:Colors"
|
||||
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--os-format "{3} {12}"
|
||||
--display-key Resolution
|
||||
--display-compact-type original
|
||||
--de-format "{2} {3}"
|
||||
--theme-format "{?1}{1}{?3} {3}{?} [Plasma], {?}{7}"
|
||||
--terminalfont-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--memory-format "{/1}{-}{/}{/2}{-}{/}{} / {}"
|
||||
@@ -1,5 +0,0 @@
|
||||
--structure Title:Separator:OS:Host:Kernel:Uptime:Battery:Break:Packages:Shell:Display:Terminal:Break:CPU:GPU:Memory:Break:Colors
|
||||
--host-format "{/2}{-}{/}{2}{?3} {3}{?}"
|
||||
--battery-format "{/4}{-}{/}{4}%{?5} [{5}]{?}"
|
||||
--display-key "Display"
|
||||
--gpu-key "GPU"
|
||||
@@ -1 +0,0 @@
|
||||
--structure OS:Kernel:Shell:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont
|
||||
+4
-1
@@ -94,7 +94,10 @@ void ffStart(void)
|
||||
ffHideCursor = instance.config.display.hideCursor && !instance.config.display.pipe && !instance.state.resultDoc;
|
||||
|
||||
#ifdef _WIN32
|
||||
setvbuf(stdout, NULL, _IOFBF, instance.config.display.noBuffer ? 0 : 4096);
|
||||
if (instance.config.display.noBuffer)
|
||||
setvbuf(stdout, NULL, _IONBF, 0);
|
||||
else
|
||||
setvbuf(stdout, NULL, _IOFBF, 4096);
|
||||
SetConsoleCtrlHandler(consoleHandler, TRUE);
|
||||
HANDLE hStdout = GetStdHandle(STD_OUTPUT_HANDLE);
|
||||
DWORD mode = 0;
|
||||
|
||||
+37
-6
@@ -10,6 +10,7 @@
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
typedef int FFNativeFD;
|
||||
// procfs's file can be changed between read calls such as /proc/meminfo and /proc/uptime.
|
||||
// one safe way to read correct data is reading the whole file in a single read syscall
|
||||
@@ -75,15 +76,45 @@ static inline bool ffReadFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
//Bit flags, combine with |
|
||||
typedef enum FFPathType
|
||||
{
|
||||
FF_PATHTYPE_REGULAR = 1,
|
||||
FF_PATHTYPE_LINK = 2,
|
||||
FF_PATHTYPE_DIRECTORY = 4
|
||||
FF_PATHTYPE_FILE = 1 << 0,
|
||||
FF_PATHTYPE_DIRECTORY = 1 << 1,
|
||||
FF_PATHTYPE_ANY = FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY,
|
||||
} FFPathType;
|
||||
|
||||
#define FF_PATHTYPE_FILE (FF_PATHTYPE_REGULAR | FF_PATHTYPE_LINK)
|
||||
#define FF_PATHTYPE_ANY (FF_PATHTYPE_FILE | FF_PATHTYPE_DIRECTORY)
|
||||
static inline bool ffPathExists(const char* path, FFPathType pathType)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
|
||||
DWORD attr = GetFileAttributesA(path);
|
||||
|
||||
if(attr == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
if(pathType & FF_PATHTYPE_FILE && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
if(pathType & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
#else
|
||||
|
||||
struct stat fileStat;
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
|
||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||
|
||||
if(pathType & FF_PATHTYPE_FILE && mode == S_IFREG)
|
||||
return true;
|
||||
|
||||
if(pathType & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||
return true;
|
||||
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffPathExists(const char* path, FFPathType pathType);
|
||||
bool ffPathExpandEnv(const char* in, FFstrbuf* out);
|
||||
|
||||
#define FF_IO_TERM_RESP_WAIT_MS 100 // #554
|
||||
|
||||
+9
-24
@@ -3,10 +3,10 @@
|
||||
#include "util/unused.h"
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <poll.h>
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
|
||||
#if __has_include(<wordexp.h>)
|
||||
#include <wordexp.h>
|
||||
@@ -33,9 +33,14 @@ bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
int FF_AUTO_CLOSE_FD fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
if (errno == ENOENT)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
fd = open(fileName, openFlagsModes, openFlagsRights);
|
||||
if(fd == -1)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -103,26 +108,6 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
return ffAppendFDBuffer(fd, buffer);
|
||||
}
|
||||
|
||||
bool ffPathExists(const char* path, FFPathType type)
|
||||
{
|
||||
struct stat fileStat;
|
||||
if(stat(path, &fileStat) != 0)
|
||||
return false;
|
||||
|
||||
unsigned int mode = fileStat.st_mode & S_IFMT;
|
||||
|
||||
if(type & FF_PATHTYPE_REGULAR && mode == S_IFREG)
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_DIRECTORY && mode == S_IFDIR)
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_LINK && mode == S_IFLNK)
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffPathExpandEnv(FF_MAYBE_UNUSED const char* in, FF_MAYBE_UNUSED FFstrbuf* out)
|
||||
{
|
||||
bool result = false;
|
||||
|
||||
+10
-23
@@ -18,11 +18,16 @@ static void createSubfolders(const char* fileName)
|
||||
bool ffWriteFileData(const char* fileName, size_t dataSize, const void* data)
|
||||
{
|
||||
HANDLE FF_AUTO_CLOSE_FD handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if(handle == INVALID_HANDLE_VALUE)
|
||||
if (GetLastError() == ERROR_PATH_NOT_FOUND)
|
||||
{
|
||||
createSubfolders(fileName);
|
||||
handle = CreateFileA(fileName, GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
if (handle == INVALID_HANDLE_VALUE)
|
||||
return false;
|
||||
}
|
||||
else
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -37,7 +42,7 @@ bool ffAppendFDBuffer(HANDLE handle, FFstrbuf* buffer)
|
||||
LARGE_INTEGER fileSize;
|
||||
if(!GetFileSizeEx(handle, &fileSize))
|
||||
fileSize.QuadPart = 0;
|
||||
|
||||
|
||||
if (fileSize.QuadPart > 0)
|
||||
{
|
||||
// optimize for files has a fixed length,
|
||||
@@ -87,24 +92,6 @@ bool ffAppendFileBuffer(const char* fileName, FFstrbuf* buffer)
|
||||
return ffAppendFDBuffer(handle, buffer);
|
||||
}
|
||||
|
||||
bool ffPathExists(const char* path, FFPathType type)
|
||||
{
|
||||
DWORD attr = GetFileAttributesA(path);
|
||||
if(attr == INVALID_FILE_ATTRIBUTES)
|
||||
return false;
|
||||
|
||||
if(type & FF_PATHTYPE_REGULAR && !(attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_DIRECTORY && (attr & FILE_ATTRIBUTE_DIRECTORY))
|
||||
return true;
|
||||
|
||||
if(type & FF_PATHTYPE_LINK && (attr & FILE_ATTRIBUTE_REPARSE_POINT))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool ffPathExpandEnv(const char* in, FFstrbuf* out)
|
||||
{
|
||||
DWORD length = ExpandEnvironmentStringsA(in, NULL, 0);
|
||||
|
||||
@@ -96,6 +96,7 @@ static FFModuleBaseInfo* O[] = {
|
||||
|
||||
static FFModuleBaseInfo* P[] = {
|
||||
(void*) &instance.config.modules.packages,
|
||||
(void*) &instance.config.modules.physicalDisk,
|
||||
(void*) &instance.config.modules.player,
|
||||
(void*) &instance.config.modules.powerAdapter,
|
||||
(void*) &instance.config.modules.processes,
|
||||
|
||||
+21
-9
@@ -124,9 +124,14 @@
|
||||
"desc": "Set if only DRM should be used to detect displays",
|
||||
"remark": "Use this option if you encountered problems with other detection method. Linux only",
|
||||
"arg": {
|
||||
"type": "bool",
|
||||
"type": "enum",
|
||||
"optional": true,
|
||||
"default": false
|
||||
"default": "false",
|
||||
"enum": {
|
||||
"true": "Try `libdrm` first, then `sysfs` if libdrm failed",
|
||||
"sysfs-only": "Use `/sys/class/drm` only",
|
||||
"false": "Try `wayland`, then `x11`, then `drm`"
|
||||
}
|
||||
}
|
||||
}
|
||||
],
|
||||
@@ -548,7 +553,7 @@
|
||||
"desc": "Set the character to use in elapsed part of percentage bars",
|
||||
"arg": {
|
||||
"type": "str",
|
||||
"default": "■"
|
||||
"default": "\u25a0"
|
||||
}
|
||||
},
|
||||
{
|
||||
@@ -942,6 +947,13 @@
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "physicaldisk-name-prefix",
|
||||
"desc": "Show disks with given name prefix only",
|
||||
"arg": {
|
||||
"type": "str"
|
||||
}
|
||||
},
|
||||
{
|
||||
"long": "bluetooth-show-disconnected",
|
||||
"desc": "Set if disconnected bluetooth devices should be printed",
|
||||
@@ -1290,12 +1302,12 @@
|
||||
"arg": {
|
||||
"type": "enum",
|
||||
"enum": {
|
||||
"block": "███",
|
||||
"circle": "●",
|
||||
"diamond": "◆",
|
||||
"triangle": "▲",
|
||||
"square": "■",
|
||||
"star": "★"
|
||||
"block": "\u2588\u2588\u2588",
|
||||
"circle": "\u25cf",
|
||||
"diamond": "\u25c6",
|
||||
"triangle": "\u25b2",
|
||||
"square": "\u25a0",
|
||||
"star": "\u2605"
|
||||
},
|
||||
"default": "block"
|
||||
}
|
||||
|
||||
@@ -7,10 +7,16 @@ static double detectCpuTemp(const FFstrbuf* cpuName)
|
||||
double result = 0;
|
||||
|
||||
const char* error = NULL;
|
||||
if(ffStrbufStartsWithS(cpuName, "Apple M1"))
|
||||
error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result);
|
||||
else if(ffStrbufStartsWithS(cpuName, "Apple M2"))
|
||||
error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result);
|
||||
if (ffStrbufStartsWithS(cpuName, "Apple M"))
|
||||
{
|
||||
switch (strtol(cpuName->chars + strlen("Apple M"), NULL, 10))
|
||||
{
|
||||
case 1: error = ffDetectCoreTemps(FF_TEMP_CPU_M1X, &result); break;
|
||||
case 2: error = ffDetectCoreTemps(FF_TEMP_CPU_M2X, &result); break;
|
||||
case 3: error = ffDetectCoreTemps(FF_TEMP_CPU_M3X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon CPU";
|
||||
}
|
||||
}
|
||||
else // PPC?
|
||||
error = ffDetectCoreTemps(FF_TEMP_CPU_X64, &result);
|
||||
|
||||
|
||||
+13
-20
@@ -1,6 +1,7 @@
|
||||
#include "de.h"
|
||||
|
||||
#include "common/io/io.h"
|
||||
#include "common/library.h"
|
||||
#include "common/parsing.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/processing.h"
|
||||
@@ -87,26 +88,18 @@ static void getMate(FFstrbuf* result, FFDEOptions* options)
|
||||
}
|
||||
}
|
||||
|
||||
static const char* getXfce4ByLib(FFstrbuf* result)
|
||||
{
|
||||
const char* xfce_version_string(void); // from `xfce4/libxfce4util/xfce-misutils.h
|
||||
FF_LIBRARY_LOAD(xfce4util, NULL, "dlopen libxfce4util" FF_LIBRARY_EXTENSION "failed", "libxfce4util" FF_LIBRARY_EXTENSION, 7);
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(xfce4util, xfce_version_string);
|
||||
ffStrbufSetS(result, ffxfce_version_string());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
||||
{
|
||||
ffParsePropFileData("gtk-doc/html/libxfce4ui/index.html", "<div><p class=\"releaseinfo\">Version", result);
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
if(result->length == 0)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir("/usr/local/share/licenses/");
|
||||
if (dirp)
|
||||
{
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(!ffStrStartsWith(entry->d_name, "xfce-") || !isdigit(entry->d_name[5]))
|
||||
continue;
|
||||
ffStrbufAppendS(result, &entry->d_name[5]);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
getXfce4ByLib(result);
|
||||
|
||||
if(result->length == 0 && options->slowVersionDetection)
|
||||
{
|
||||
@@ -117,8 +110,8 @@ static void getXFCE4(FFstrbuf* result, FFDEOptions* options)
|
||||
NULL
|
||||
});
|
||||
|
||||
ffStrbufSubstrBeforeFirstC(result, '(');
|
||||
ffStrbufSubstrAfterFirstC(result, ' ');
|
||||
ffStrbufSubstrBeforeFirstC(result, ')');
|
||||
ffStrbufSubstrAfterLastC(result, ' ');
|
||||
ffStrbufTrim(result, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -106,14 +106,6 @@ static void detectName(FFDisk* disk)
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreate();
|
||||
|
||||
//Detect USB devices. Code is put here to reuse deviceStat
|
||||
//https://stackoverflow.com/a/73302717
|
||||
ffStrbufAppendS(&basePath, "/dev/disk/by-id/");
|
||||
detectNameFromPath(disk, &deviceStat, &basePath);
|
||||
if (ffStrbufStartsWithS(&disk->name, "usb-"))
|
||||
disk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
ffStrbufClear(&disk->name);
|
||||
|
||||
//Try label first
|
||||
ffStrbufSetS(&basePath, "/dev/disk/by-label/");
|
||||
detectNameFromPath(disk, &deviceStat, &basePath);
|
||||
@@ -197,9 +189,6 @@ static bool isSubvolume(const FFlist* disks, FFDisk* currentDisk)
|
||||
|
||||
static bool isRemovable(FFDisk* currentDisk)
|
||||
{
|
||||
// https://stackoverflow.com/a/73302025
|
||||
// Note my USB mobile hard disk isn't detected as removable, but my USB flash disk does.
|
||||
// USB devices should be handled in detectName
|
||||
FF_STRBUF_AUTO_DESTROY basePath = ffStrbufCreateS("/sys/block/");
|
||||
|
||||
FF_AUTO_CLOSE_DIR DIR* dir = opendir(basePath.chars);
|
||||
@@ -218,11 +207,10 @@ static bool isRemovable(FFDisk* currentDisk)
|
||||
|
||||
if (!ffStrStartsWith(partitionName, entry->d_name)) continue;
|
||||
|
||||
// /sys/block/sdx/removable
|
||||
// /sys/block/sdx/device/delete
|
||||
ffStrbufAppendS(&basePath, entry->d_name);
|
||||
ffStrbufAppendS(&basePath, "/removable");
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
return ffReadFileBuffer(basePath.chars, &buffer) && ffStrbufEqualS(&buffer, "1");
|
||||
ffStrbufAppendS(&basePath, "/device/delete");
|
||||
return ffPathExists(basePath.chars, FF_PATHTYPE_FILE);
|
||||
}
|
||||
|
||||
return false;
|
||||
@@ -230,14 +218,12 @@ static bool isRemovable(FFDisk* currentDisk)
|
||||
|
||||
static void detectType(const FFlist* disks, FFDisk* currentDisk)
|
||||
{
|
||||
if(currentDisk->type != FF_DISK_VOLUME_TYPE_NONE) return;
|
||||
|
||||
if(isRemovable(currentDisk))
|
||||
if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/boot") || ffStrbufStartsWithS(¤tDisk->mountpoint, "/efi"))
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else if(isRemovable(currentDisk))
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_EXTERNAL_BIT;
|
||||
else if(isSubvolume(disks, currentDisk))
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_SUBVOLUME_BIT;
|
||||
else if(ffStrbufStartsWithS(¤tDisk->mountpoint, "/boot") || ffStrbufStartsWithS(¤tDisk->mountpoint, "/efi"))
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_HIDDEN_BIT;
|
||||
else
|
||||
currentDisk->type = FF_DISK_VOLUME_TYPE_REGULAR_BIT;
|
||||
}
|
||||
|
||||
@@ -47,8 +47,8 @@ const char* ffDetectDiskIO(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
FFDiskIOResult* icPrev = (FFDiskIOResult*)ffListGet(&ioCounters1, i);
|
||||
FFDiskIOResult* icCurr = (FFDiskIOResult*)ffListGet(result, i);
|
||||
if (!ffStrbufEqual(&icPrev->name, &icCurr->name))
|
||||
return "Network interface name changed";
|
||||
if (!ffStrbufEqual(&icPrev->devPath, &icCurr->devPath))
|
||||
return "Physical disk device path changed";
|
||||
|
||||
static_assert(sizeof(FFDiskIOResult) - offsetof(FFDiskIOResult, bytesRead) == sizeof(uint64_t) * 4, "Unexpected struct FFDiskIOResult layout");
|
||||
for (size_t off = offsetof(FFDiskIOResult, bytesRead); off < sizeof(FFDiskIOResult); off += sizeof(uint64_t))
|
||||
|
||||
@@ -2,19 +2,9 @@
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef enum FFDiskIOPhysicalType
|
||||
{
|
||||
FF_DISKIO_PHYSICAL_TYPE_UNKNOWN,
|
||||
FF_DISKIO_PHYSICAL_TYPE_HDD,
|
||||
FF_DISKIO_PHYSICAL_TYPE_SSD,
|
||||
} FFDiskIOPhysicalType;
|
||||
|
||||
typedef struct FFDiskIOResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf interconnect;
|
||||
FFDiskIOPhysicalType type;
|
||||
uint64_t size;
|
||||
FFstrbuf devPath;
|
||||
uint64_t bytesRead;
|
||||
uint64_t readCount;
|
||||
|
||||
@@ -48,8 +48,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitS(&device->name, deviceName);
|
||||
ffStrbufInit(&device->devPath);
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
device->size = 0;
|
||||
|
||||
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead);
|
||||
ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten);
|
||||
@@ -62,34 +60,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
ffCfStrGetString(bsdName, &device->devPath);
|
||||
ffStrbufPrependS(&device->devPath, "/dev/");
|
||||
}
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (mediaSize)
|
||||
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
|
||||
else
|
||||
device->size = 0;
|
||||
|
||||
ffStrbufInit(&device->interconnect);
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
|
||||
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (protocolCharacteristics)
|
||||
ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->interconnect);
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (deviceCharacteristics)
|
||||
{
|
||||
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
|
||||
if (mediumType)
|
||||
{
|
||||
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_SSD;
|
||||
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_HDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -32,35 +32,25 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
if (provider->lg_geom->lg_rank != 1)
|
||||
continue;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
|
||||
FFDiskIOPhysicalType type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
|
||||
{
|
||||
if (ffStrEquals(ptr->lg_name, "descr"))
|
||||
ffStrbufSetS(&name, ptr->lg_val);
|
||||
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
|
||||
type = ffStrEquals(ptr->lg_val, "0") ? FF_DISKIO_PHYSICAL_TYPE_SSD : FF_DISKIO_PHYSICAL_TYPE_HDD;
|
||||
}
|
||||
if (name.length == 0)
|
||||
ffStrbufSetS(&name, provider->lg_name);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
|
||||
{
|
||||
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
|
||||
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
|
||||
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
|
||||
}
|
||||
device->bytesRead = snapIter->bytes[DEVSTAT_READ];
|
||||
device->readCount = snapIter->operations[DEVSTAT_READ];
|
||||
device->bytesWritten = snapIter->bytes[DEVSTAT_WRITE];
|
||||
device->writeCount = snapIter->operations[DEVSTAT_WRITE];
|
||||
device->size = (uint64_t) provider->lg_mediasize;
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
device->type = type;
|
||||
}
|
||||
|
||||
geom_stats_snapshot_free(snap);
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
#include "diskio.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
@@ -7,107 +8,75 @@
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateS("/dev/disk/by-id/");
|
||||
uint32_t baseDirLength = baseDir.length;
|
||||
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
|
||||
if(sysBlockDirp == NULL)
|
||||
return "opendir(\"/sys/block/\") == NULL";
|
||||
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir.chars);
|
||||
if(dirp == NULL)
|
||||
return "opendir(batteryDir) == NULL";
|
||||
|
||||
struct dirent* entry;
|
||||
while ((entry = readdir(dirp)) != NULL)
|
||||
struct dirent* sysBlockEntry;
|
||||
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
|
||||
{
|
||||
if (entry->d_name[0] == '.')
|
||||
const char* const devName = sysBlockEntry->d_name;
|
||||
|
||||
if (devName[0] == '.')
|
||||
continue;
|
||||
|
||||
char* part = strstr(entry->d_name, "-part");
|
||||
if (part && isdigit(part[strlen("-part")]))
|
||||
continue;
|
||||
|
||||
if (ffStrStartsWith(entry->d_name, "nvme-eui.")) // NVMe drive identifier
|
||||
continue;
|
||||
|
||||
// Other exceptions?
|
||||
|
||||
ffStrbufAppendS(&baseDir, entry->d_name);
|
||||
char pathDev[PATH_MAX];
|
||||
ssize_t pathLen = readlink(baseDir.chars, pathDev, PATH_MAX);
|
||||
ffStrbufSubstrBefore(&baseDir, baseDirLength);
|
||||
|
||||
if (pathLen < 0) continue;
|
||||
pathDev[pathLen] = '\0'; // ../../nvme0n1
|
||||
|
||||
char pathDev1[PATH_MAX];
|
||||
const char* devName = basename(pathDev);
|
||||
snprintf(pathDev1, PATH_MAX, "/dev/%s", devName);
|
||||
|
||||
// Avoid duplicated disks
|
||||
bool flag = false;
|
||||
FF_LIST_FOR_EACH(FFDiskIOResult, disk, *result)
|
||||
{
|
||||
if (ffStrbufEqualS(&disk->devPath, pathDev1))
|
||||
{
|
||||
flag = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (flag) continue;
|
||||
|
||||
char pathSysBlock[PATH_MAX];
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
|
||||
|
||||
FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r");
|
||||
if (!sysBlockStat) continue;
|
||||
char pathSysDeviceReal[PATH_MAX];
|
||||
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
|
||||
if (pathLength < 0)
|
||||
continue;
|
||||
pathSysDeviceReal[pathLength] = '\0';
|
||||
|
||||
// I/Os merges sectors ticks ...
|
||||
uint64_t nRead, sectorRead, nWritten, sectorWritten;
|
||||
if (fscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, §orRead, &nWritten, §orWritten) == 0)
|
||||
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
|
||||
continue;
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
|
||||
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||
continue;
|
||||
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
char* slash = strchr(entry->d_name, '-');
|
||||
if (slash)
|
||||
{
|
||||
char* slash2 = strchr(slash + 1, '-');
|
||||
if (slash2)
|
||||
ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1);
|
||||
else
|
||||
ffStrbufInitS(&device->name, slash + 1);
|
||||
ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufInitS(&device->name, entry->d_name);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
}
|
||||
ffStrbufReplaceAllC(&device->name, '_', ' ');
|
||||
ffStrbufInit(&device->name);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
ffStrbufDestroy(&device->interconnect);
|
||||
result->length--;
|
||||
continue;
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
if (device->name.length > 0)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
|
||||
if (device->name.length == 0)
|
||||
ffStrbufSetS(&device->name, devName);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ffStrbufInitS(&device->devPath, pathDev1);
|
||||
// I/Os merges sectors ticks ...
|
||||
uint64_t nRead, sectorRead, nWritten, sectorWritten;
|
||||
{
|
||||
char sysBlockStat[PROC_FILE_BUFFSIZ];
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/stat", devName);
|
||||
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(sysBlockStat) - 1, sysBlockStat);
|
||||
if (fileSize <= 0) continue;
|
||||
sysBlockStat[fileSize] = '\0';
|
||||
if (sscanf(sysBlockStat, "%lu%*u%lu%*u%lu%*u%lu%*u", &nRead, §orRead, &nWritten, §orWritten) <= 0)
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||
device->bytesRead = sectorRead * 512;
|
||||
device->bytesWritten = sectorWritten * 512;
|
||||
device->readCount = nRead;
|
||||
device->writeCount = nWritten;
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
if (ffReadFileBuffer(pathSysBlock, &buffer))
|
||||
device->type = ffStrbufEqualS(&buffer, "1") ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
|
||||
else
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
|
||||
if (ffReadFileBuffer(pathSysBlock, &buffer))
|
||||
device->size = ffStrbufToUInt(&buffer, 0);
|
||||
else
|
||||
device->size = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
|
||||
@@ -1,101 +1,82 @@
|
||||
#include "diskio.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/windows/registry.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options)
|
||||
{
|
||||
FF_HKEY_AUTO_DESTROY hKey = NULL;
|
||||
if (!ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum", &hKey, NULL))
|
||||
return "ffRegOpenKeyForRead(HKEY_LOCAL_MACHINE, L\"SYSTEM\\CurrentControlSet\\Services\\disk\\Enum\") failed";
|
||||
|
||||
uint32_t nDevices;
|
||||
if (!ffRegReadUint(hKey, L"Count", &nDevices, NULL))
|
||||
return "ffRegReadUint(hKey, L\"Count\", &nDevices) failed";
|
||||
|
||||
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
|
||||
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
|
||||
for (uint32_t idev = 0; idev <= nDevices; ++idev) {
|
||||
for (uint32_t idev = 0; ; ++idev)
|
||||
{
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevice == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
DWORD retSize;
|
||||
char sddBuffer[4096];
|
||||
if(!DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&(STORAGE_PROPERTY_QUERY) {
|
||||
.PropertyId = StorageDeviceProperty,
|
||||
.QueryType = PropertyStandardQuery,
|
||||
},
|
||||
sizeof(STORAGE_PROPERTY_QUERY),
|
||||
&sddBuffer,
|
||||
sizeof(sddBuffer),
|
||||
&retSize,
|
||||
NULL
|
||||
) || retSize == 0)
|
||||
continue;
|
||||
|
||||
DISK_PERFORMANCE diskPerformance;
|
||||
DWORD ioctrlSize = sizeof(diskPerformance);
|
||||
DWORD dwSize;
|
||||
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL))
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||
|
||||
ffStrbufInit(&device->name);
|
||||
if (sdd->VendorIdOffset != 0)
|
||||
{
|
||||
FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->name);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
if (ffRegReadStrbuf(hKey, pNum, &device->name, NULL))
|
||||
{
|
||||
// SCSI\Disk&Ven_NVMe&Prod_WDC_PC_SN810_SDC\5&19cebb7&0&000000
|
||||
uint32_t index = ffStrbufFirstIndexC(&device->name, '\\');
|
||||
if (index != device->name.length)
|
||||
{
|
||||
ffStrbufAppendNS(&device->interconnect, index, device->name.chars); // SCSI
|
||||
ffStrbufSubstrAfter(&device->name, index);
|
||||
}
|
||||
ffStrbufSubstrBeforeLastC(&device->name, '\\');
|
||||
ffStrbufSubstrAfterFirstS(&device->name, "&Ven_");
|
||||
ffStrbufRemoveS(&device->name, "&Prod");
|
||||
ffStrbufReplaceAllC(&device->name, '_', ' ');
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
}
|
||||
else
|
||||
ffStrbufSetWS(&device->name, szDevice);
|
||||
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
}
|
||||
if (sdd->ProductIdOffset != 0)
|
||||
{
|
||||
if (device->name.length)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
ffStrbufDestroy(&device->interconnect);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
}
|
||||
|
||||
ffStrbufInitWS(&device->devPath, szDevice);
|
||||
device->bytesRead = (uint64_t) diskPerformance.BytesRead.QuadPart;
|
||||
device->readCount = (uint64_t) diskPerformance.ReadCount;
|
||||
device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart;
|
||||
device->writeCount = (uint64_t) diskPerformance.WriteCount;
|
||||
if (!device->name.length)
|
||||
ffStrbufAppendF(&device->name, "PhysicalDrive%u", (unsigned) idev);
|
||||
|
||||
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
|
||||
DWORD retSize = 0;
|
||||
if(DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&(STORAGE_PROPERTY_QUERY) {
|
||||
.PropertyId = StorageDeviceSeekPenaltyProperty,
|
||||
.QueryType = PropertyStandardQuery,
|
||||
},
|
||||
sizeof(STORAGE_PROPERTY_QUERY),
|
||||
&dspd,
|
||||
sizeof(dspd),
|
||||
&retSize,
|
||||
NULL
|
||||
) && retSize == sizeof(dspd))
|
||||
device->type = dspd.IncursSeekPenalty ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD;
|
||||
else
|
||||
device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN;
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
|
||||
DISK_GEOMETRY_EX dge = {};
|
||||
if(DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
||||
NULL,
|
||||
0,
|
||||
&dge,
|
||||
sizeof(dge),
|
||||
&retSize,
|
||||
NULL))
|
||||
device->size = (uint64_t) dge.DiskSize.QuadPart;
|
||||
else
|
||||
device->size = 0;
|
||||
ffStrbufInitWS(&device->devPath, szDevice);
|
||||
|
||||
DISK_PERFORMANCE dp = {};
|
||||
if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL))
|
||||
{
|
||||
device->bytesRead = (uint64_t) dp.BytesRead.QuadPart;
|
||||
device->readCount = (uint64_t) dp.ReadCount;
|
||||
device->bytesWritten = (uint64_t) dp.BytesWritten.QuadPart;
|
||||
device->writeCount = (uint64_t) dp.WriteCount;
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
#define FF_DE_PRETTY_LXDE "LXDE"
|
||||
#define FF_DE_PRETTY_LXQT "LXQT"
|
||||
#define FF_DE_PRETTY_BUDGIE "Budgie"
|
||||
#define FF_DE_PRETTY_CDE "CDE"
|
||||
#define FF_DE_PRETTY_UNITY "Unity"
|
||||
|
||||
#define FF_WM_PRETTY_KWIN "KWin"
|
||||
@@ -32,6 +33,7 @@
|
||||
#define FF_WM_PRETTY_HERBSTLUFTWM "herbstluftwm"
|
||||
#define FF_WM_PRETTY_ICEWM "IceWM"
|
||||
#define FF_WM_PRETTY_SPECTRWM "spectrwm"
|
||||
#define FF_WM_PRETTY_DTWM "dtwm"
|
||||
|
||||
|
||||
#define FF_WM_PROTOCOL_TTY "TTY"
|
||||
|
||||
@@ -10,7 +10,7 @@ void ffConnectDisplayServerImpl(FFDisplayServerResult* ds)
|
||||
ffStrbufInit(&ds->dePrettyName);
|
||||
ffListInitA(&ds->displays, sizeof(FFDisplayResult), 4);
|
||||
|
||||
if (!instance.config.general.dsForceDrm)
|
||||
if (instance.config.general.dsForceDrm == FF_DS_FORCE_DRM_TYPE_FALSE)
|
||||
{
|
||||
//We try wayland as our preferred display server, as it supports the most features.
|
||||
//This method can't detect the name of our WM / DE
|
||||
|
||||
@@ -27,10 +27,10 @@ static const char* drmParseSysfs(FFDisplayServerResult* result)
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
uint32_t drmDirWithDnameLength = drmDir.length;
|
||||
|
||||
ffStrbufAppendS(&drmDir, "/enabled");
|
||||
char enabled = 'd'; // disabled
|
||||
ffReadFileData(drmDir.chars, sizeof(enabled), &enabled);
|
||||
if (enabled != 'e') // enabled
|
||||
ffStrbufAppendS(&drmDir, "/status");
|
||||
char status = 'd'; // disconnected
|
||||
ffReadFileData(drmDir.chars, sizeof(status), &status);
|
||||
if (status != 'c') // connected
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
@@ -152,6 +152,49 @@ static inline const char* drmType2Name(uint32_t connector_type)
|
||||
}
|
||||
}
|
||||
|
||||
static const char* drmGetNameByConnId(uint32_t connId, FFstrbuf* name)
|
||||
{
|
||||
const char* drmDirPath = "/sys/class/drm/";
|
||||
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(drmDirPath);
|
||||
if(dirp == NULL)
|
||||
return "opendir(drmDirPath) failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY drmDir = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&drmDir, drmDirPath);
|
||||
|
||||
uint32_t drmDirLength = drmDir.length;
|
||||
|
||||
struct dirent* entry;
|
||||
while((entry = readdir(dirp)) != NULL)
|
||||
{
|
||||
if(ffStrEquals(entry->d_name, ".") || ffStrEquals(entry->d_name, ".."))
|
||||
continue;
|
||||
|
||||
ffStrbufAppendS(&drmDir, entry->d_name);
|
||||
uint32_t drmDirWithDnameLength = drmDir.length;
|
||||
|
||||
ffStrbufAppendS(&drmDir, "/connector_id");
|
||||
ffReadFileBuffer(drmDir.chars, name);
|
||||
if (ffStrbufToUInt(name, 0) != connId)
|
||||
{
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirLength);
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufSubstrBefore(&drmDir, drmDirWithDnameLength);
|
||||
ffStrbufClear(name);
|
||||
ffStrbufAppendS(&drmDir, "/edid");
|
||||
uint8_t edidData[128];
|
||||
if(ffReadFileData(drmDir.chars, sizeof(edidData), edidData) == sizeof(edidData))
|
||||
ffEdidGetName(edidData, name);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ffStrbufClear(name);
|
||||
return "Failed to match connector ID";
|
||||
}
|
||||
|
||||
static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
{
|
||||
FF_LIBRARY_LOAD(libdrm, &instance.config.library.libdrm, "dlopen(libdrm)" FF_LIBRARY_EXTENSION " failed", "libdrm" FF_LIBRARY_EXTENSION, 2)
|
||||
@@ -162,6 +205,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetEncoder)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetProperty)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeGetPropertyBlob)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeResources)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeCrtc)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeEncoder)
|
||||
FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libdrm, drmModeFreeConnector)
|
||||
@@ -196,18 +240,56 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
if (!conn)
|
||||
continue;
|
||||
|
||||
if (conn->connection != DRM_MODE_CONNECTED)
|
||||
goto next_conn;
|
||||
|
||||
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
|
||||
if (!encoder)
|
||||
goto next_conn;
|
||||
|
||||
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
|
||||
if (!crtc)
|
||||
goto next_encoder;
|
||||
|
||||
if (conn->connection == DRM_MODE_CONNECTED)
|
||||
{
|
||||
drmModeEncoder* encoder = ffdrmModeGetEncoder(fd, conn->encoder_id);
|
||||
uint32_t width = 0, height = 0, refreshRate = 0;
|
||||
|
||||
if (encoder)
|
||||
{
|
||||
drmModeCrtc* crtc = ffdrmModeGetCrtc(fd, encoder->crtc_id);
|
||||
if (crtc)
|
||||
{
|
||||
width = crtc->mode.vdisplay;
|
||||
height = crtc->mode.hdisplay;
|
||||
refreshRate = crtc->mode.vrefresh;
|
||||
if (refreshRate == 0)
|
||||
{
|
||||
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
|
||||
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
||||
{
|
||||
drmModeModeInfo* mode = &conn->modes[iMode];
|
||||
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
|
||||
{
|
||||
refreshRate = mode->vrefresh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ffdrmModeFreeCrtc(crtc);
|
||||
}
|
||||
|
||||
ffdrmModeFreeEncoder(encoder);
|
||||
}
|
||||
|
||||
if (width == 0 || height == 0)
|
||||
{
|
||||
// NVIDIA DRM driver seems incomplete and conn->encoder_id == 0
|
||||
// Assume preferred resolution is used as what we do in drmParseSys
|
||||
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
||||
{
|
||||
drmModeModeInfo* mode = &conn->modes[iMode];
|
||||
|
||||
if (mode->type & DRM_MODE_TYPE_PREFERRED)
|
||||
{
|
||||
width = mode->hdisplay;
|
||||
height = mode->vdisplay;
|
||||
refreshRate = mode->vrefresh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreate();
|
||||
|
||||
for (int iProp = 0; iProp < conn->count_props; ++iProp)
|
||||
@@ -219,60 +301,58 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
uint32_t type = prop->flags & (DRM_MODE_PROP_LEGACY_TYPE | DRM_MODE_PROP_EXTENDED_TYPE);
|
||||
if (type == DRM_MODE_PROP_BLOB && ffStrEquals(prop->name, "EDID"))
|
||||
{
|
||||
// Stangely, prop->count_blobs is 0 and prop->blob_ids is NULL
|
||||
drmModePropertyBlobPtr blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
|
||||
if (blob->length >= 128)
|
||||
ffEdidGetName(blob->data, &name);
|
||||
ffdrmModeFreePropertyBlob(blob);
|
||||
drmModePropertyBlobPtr blob = NULL;
|
||||
|
||||
if (prop->count_blobs > 0 && prop->blob_ids != NULL)
|
||||
blob = ffdrmModeGetPropertyBlob(fd, prop->blob_ids[0]);
|
||||
else
|
||||
blob = ffdrmModeGetPropertyBlob(fd, (uint32_t) conn->prop_values[iProp]);
|
||||
|
||||
if (blob)
|
||||
{
|
||||
if (blob->length >= 128)
|
||||
ffEdidGetName(blob->data, &name);
|
||||
ffdrmModeFreePropertyBlob(blob);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ffdrmModeFreeProperty(prop);
|
||||
}
|
||||
|
||||
if (name.length == 0)
|
||||
{
|
||||
drmGetNameByConnId(conn->connector_id, &name);
|
||||
}
|
||||
|
||||
if (name.length == 0)
|
||||
{
|
||||
const char* connectorTypeName = drmType2Name(conn->connector_type);
|
||||
if (connectorTypeName == NULL)
|
||||
connectorTypeName = "Unknown";
|
||||
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn);
|
||||
ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn + 1);
|
||||
}
|
||||
|
||||
uint32_t refreshRate = crtc->mode.vrefresh;
|
||||
if (refreshRate == 0)
|
||||
{
|
||||
// There are weird cases that we can't get the refresh rate from the CRTC but from the modes
|
||||
for (int iMode = 0; iMode < conn->count_modes; ++iMode)
|
||||
{
|
||||
drmModeModeInfo* mode = &conn->modes[iMode];
|
||||
if (mode->clock == crtc->mode.clock && mode->htotal == crtc->mode.htotal)
|
||||
{
|
||||
refreshRate = mode->vrefresh;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ffdsAppendDisplay(
|
||||
result,
|
||||
crtc->width, crtc->height,
|
||||
ffdsAppendDisplay(result,
|
||||
width,
|
||||
height,
|
||||
refreshRate,
|
||||
0, 0,
|
||||
0,
|
||||
0,
|
||||
0,
|
||||
&name,
|
||||
FF_DISPLAY_TYPE_UNKNOWN,
|
||||
conn->connector_type == DRM_MODE_CONNECTOR_eDP
|
||||
? FF_DISPLAY_TYPE_BUILTIN
|
||||
: conn->connector_type == DRM_MODE_CONNECTOR_HDMIA || conn->connector_type == DRM_MODE_CONNECTOR_HDMIB
|
||||
? FF_DISPLAY_TYPE_EXTERNAL : FF_DISPLAY_TYPE_UNKNOWN,
|
||||
false,
|
||||
0
|
||||
conn->connector_id
|
||||
);
|
||||
}
|
||||
|
||||
ffdrmModeFreeCrtc(crtc);
|
||||
|
||||
next_encoder:
|
||||
ffdrmModeFreeEncoder(encoder);
|
||||
|
||||
next_conn:
|
||||
ffdrmModeFreeConnector(conn);
|
||||
}
|
||||
|
||||
ffdrmModeFreeResources(res);
|
||||
}
|
||||
|
||||
ffdrmFreeDevices(devices, nDevices);
|
||||
@@ -285,8 +365,11 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result)
|
||||
void ffdsConnectDrm(FFDisplayServerResult* result)
|
||||
{
|
||||
#ifdef FF_HAVE_DRM
|
||||
if (drmConnectLibdrm(result) == NULL)
|
||||
return;
|
||||
if (instance.config.general.dsForceDrm != FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY)
|
||||
{
|
||||
if (drmConnectLibdrm(result) == NULL)
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
drmParseSysfs(result);
|
||||
|
||||
@@ -1,14 +1,20 @@
|
||||
#include "displayserver_linux.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "common/processing.h"
|
||||
#include "util/stringUtils.h"
|
||||
#include "util/mallocHelper.h"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <dirent.h>
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/user.h>
|
||||
#else
|
||||
#include "common/io/io.h"
|
||||
#endif
|
||||
|
||||
static const char* parseEnv(void)
|
||||
{
|
||||
@@ -46,10 +52,12 @@ static const char* parseEnv(void)
|
||||
if(getenv("TDE_FULL_SESSION") != NULL)
|
||||
return "Trinity";
|
||||
|
||||
#ifdef __linux__
|
||||
if(
|
||||
getenv("WAYLAND_DISPLAY") != NULL &&
|
||||
ffPathExists("/mnt/wslg/", FF_PATHTYPE_DIRECTORY)
|
||||
) return "WSLg";
|
||||
#endif
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -60,52 +68,54 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name)
|
||||
return;
|
||||
|
||||
if(
|
||||
strcasecmp(name, "kwin_wayland") == 0 ||
|
||||
strcasecmp(name, "kwin_wayland_wrapper") == 0 ||
|
||||
strcasecmp(name, "kwin_x11") == 0 ||
|
||||
strcasecmp(name, "kwin_x11_wrapper") == 0 ||
|
||||
strcasecmp(name, "kwin") == 0
|
||||
ffStrEqualsIgnCase(name, "kwin_wayland") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_wayland_wrapper") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_x11") ||
|
||||
ffStrEqualsIgnCase(name, "kwin_x11_wrapper") ||
|
||||
ffStrEqualsIgnCase(name, "kwin")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_KWIN);
|
||||
else if(
|
||||
strcasecmp(name, "gnome-shell") == 0 ||
|
||||
strcasecmp(name, "gnome shell") == 0 ||
|
||||
strcasecmp(name, "gnome-session-binary") == 0 ||
|
||||
strcasecmp(name, "Mutter") == 0
|
||||
ffStrEqualsIgnCase(name, "gnome-shell") ||
|
||||
ffStrEqualsIgnCase(name, "gnome shell") ||
|
||||
ffStrEqualsIgnCase(name, "gnome-session-binary") ||
|
||||
ffStrEqualsIgnCase(name, "Mutter")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUTTER);
|
||||
else if(
|
||||
strcasecmp(name, "cinnamon-session") == 0 ||
|
||||
strcasecmp(name, "Muffin") == 0 ||
|
||||
strcasecmp(name, "Mutter (Muffin)") == 0
|
||||
ffStrEqualsIgnCase(name, "cinnamon-session") ||
|
||||
ffStrEqualsIgnCase(name, "Muffin") ||
|
||||
ffStrEqualsIgnCase(name, "Mutter (Muffin)")
|
||||
) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MUFFIN);
|
||||
else if(strcasecmp(name, "sway") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "sway"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_SWAY);
|
||||
else if(strcasecmp(name, "weston") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "weston"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WESTON);
|
||||
else if(strcasecmp(name, "wayfire") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "wayfire"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WAYFIRE);
|
||||
else if(strcasecmp(name, "openbox") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "openbox"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_OPENBOX);
|
||||
else if(strcasecmp(name, "xfwm4") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "xfwm4"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XFWM4);
|
||||
else if(strcasecmp(name, "Marco") == 0 ||
|
||||
strcasecmp(name, "Metacity (Marco)") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "Marco") ||
|
||||
ffStrEqualsIgnCase(name, "Metacity (Marco)"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_MARCO);
|
||||
else if(strcasecmp(name, "xmonad") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "xmonad"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_XMONAD);
|
||||
else if(strcasecmp(name, "WSLg") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "WSLg"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_WSLG);
|
||||
else if(strcasecmp(name, "dwm") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "dwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DWM);
|
||||
else if(strcasecmp(name, "bspwm") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "bspwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_BSPWM);
|
||||
else if(strcasecmp(name, "tinywm") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "tinywm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_TINYWM);
|
||||
else if(strcasecmp(name, "qtile") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "qtile"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_QTILE);
|
||||
else if(strcasecmp(name, "herbstluftwm") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "herbstluftwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM);
|
||||
else if(strcasecmp(name, "icewm") == 0)
|
||||
else if(ffStrEqualsIgnCase(name, "icewm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM);
|
||||
else if(ffStrEqualsIgnCase(name, "dtwm"))
|
||||
ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM);
|
||||
}
|
||||
|
||||
static void applyNameIfWM(FFDisplayServerResult* result, const char* processName)
|
||||
@@ -136,10 +146,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
return;
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "KDE") == 0 ||
|
||||
strcasecmp(name, "plasma") == 0 ||
|
||||
strcasecmp(name, "plasmashell") == 0 ||
|
||||
strcasecmp(name, "plasmawayland") == 0
|
||||
ffStrEqualsIgnCase(name, "KDE") ||
|
||||
ffStrEqualsIgnCase(name, "plasma") ||
|
||||
ffStrEqualsIgnCase(name, "plasmashell") ||
|
||||
ffStrEqualsIgnCase(name, "plasmawayland")
|
||||
) {
|
||||
ffStrbufSetStatic(&result->deProcessName, "plasmashell");
|
||||
ffStrbufSetStatic(&result->dePrettyName, FF_DE_PRETTY_PLASMA);
|
||||
@@ -147,10 +157,10 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
}
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "Gnome") == 0 ||
|
||||
strcasecmp(name, "ubuntu:GNOME") == 0 ||
|
||||
strcasecmp(name, "ubuntu") == 0 ||
|
||||
strcasecmp(name, "gnome-shell") == 0
|
||||
ffStrEqualsIgnCase(name, "Gnome") ||
|
||||
ffStrEqualsIgnCase(name, "ubuntu:GNOME") ||
|
||||
ffStrEqualsIgnCase(name, "ubuntu") ||
|
||||
ffStrEqualsIgnCase(name, "gnome-shell")
|
||||
) {
|
||||
ffStrbufSetStatic(&result->deProcessName, "gnome-shell");
|
||||
const char* sessionMode = getenv("GNOME_SHELL_SESSION_MODE");
|
||||
@@ -161,37 +171,37 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
}
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "X-Cinnamon") == 0 ||
|
||||
strcasecmp(name, "Cinnamon") == 0
|
||||
ffStrEqualsIgnCase(name, "X-Cinnamon") ||
|
||||
ffStrEqualsIgnCase(name, "Cinnamon")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "cinnamon");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CINNAMON);
|
||||
}
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "XFCE") == 0 ||
|
||||
strcasecmp(name, "X-XFCE") == 0 ||
|
||||
strcasecmp(name, "XFCE4") == 0 ||
|
||||
strcasecmp(name, "X-XFCE4") == 0 ||
|
||||
strcasecmp(name, "xfce4-session") == 0
|
||||
ffStrEqualsIgnCase(name, "XFCE") ||
|
||||
ffStrEqualsIgnCase(name, "X-XFCE") ||
|
||||
ffStrEqualsIgnCase(name, "XFCE4") ||
|
||||
ffStrEqualsIgnCase(name, "X-XFCE4") ||
|
||||
ffStrEqualsIgnCase(name, "xfce4-session")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "xfce4-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_XFCE4);
|
||||
}
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "MATE") == 0 ||
|
||||
strcasecmp(name, "X-MATE") == 0 ||
|
||||
strcasecmp(name, "mate-session") == 0
|
||||
ffStrEqualsIgnCase(name, "MATE") ||
|
||||
ffStrEqualsIgnCase(name, "X-MATE") ||
|
||||
ffStrEqualsIgnCase(name, "mate-session")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "mate-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_MATE);
|
||||
}
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "LXQt") == 0 ||
|
||||
strcasecmp(name, "X-LXQT") == 0 ||
|
||||
strcasecmp(name, "lxqt-session") == 0
|
||||
ffStrEqualsIgnCase(name, "LXQt") ||
|
||||
ffStrEqualsIgnCase(name, "X-LXQT") ||
|
||||
ffStrEqualsIgnCase(name, "lxqt-session")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "lxqt-session");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_LXQT);
|
||||
@@ -201,14 +211,21 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name)
|
||||
}
|
||||
|
||||
else if(
|
||||
strcasecmp(name, "Budgie") == 0 ||
|
||||
strcasecmp(name, "X-Budgie") == 0 ||
|
||||
strcasecmp(name, "budgie-desktop") == 0 ||
|
||||
strcasecmp(name, "Budgie:GNOME") == 0
|
||||
ffStrEqualsIgnCase(name, "Budgie") ||
|
||||
ffStrEqualsIgnCase(name, "X-Budgie") ||
|
||||
ffStrEqualsIgnCase(name, "budgie-desktop") ||
|
||||
ffStrEqualsIgnCase(name, "Budgie:GNOME")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "budgie-desktop");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE);
|
||||
}
|
||||
|
||||
else if(
|
||||
ffStrEqualsIgnCase(name, "dtsession")
|
||||
) {
|
||||
ffStrbufSetS(&result->deProcessName, "dtsession");
|
||||
ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CDE);
|
||||
}
|
||||
}
|
||||
|
||||
static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
||||
@@ -219,9 +236,9 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
||||
const char* env = getenv("XDG_SESSION_TYPE");
|
||||
if(ffStrSet(env))
|
||||
{
|
||||
if(strcasecmp(env, "x11") == 0)
|
||||
if(ffStrEqualsIgnCase(env, "x11"))
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_X11);
|
||||
else if(strcasecmp(env, "tty") == 0)
|
||||
else if(ffStrEqualsIgnCase(env, "tty"))
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
|
||||
else
|
||||
ffStrbufSetS(&result->wmProtocolName, env);
|
||||
@@ -237,30 +254,56 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result)
|
||||
}
|
||||
|
||||
env = getenv("TERM");
|
||||
if(ffStrSet(env) && strcasecmp(env, "linux") == 0)
|
||||
if(ffStrSet(env) && ffStrEqualsIgnCase(env, "linux"))
|
||||
{
|
||||
ffStrbufSetS(&result->wmProtocolName, FF_WM_PROTOCOL_TTY);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
static void getFromProcDir(FFDisplayServerResult* result)
|
||||
static const char* getFromProcesses(FFDisplayServerResult* result)
|
||||
{
|
||||
DIR* proc = opendir("/proc");
|
||||
if(proc == NULL)
|
||||
return;
|
||||
uint32_t userId = getuid();
|
||||
|
||||
#ifdef __FreeBSD__
|
||||
int request[] = {CTL_KERN, KERN_PROC, KERN_PROC_UID, (int) userId};
|
||||
size_t length = 0;
|
||||
|
||||
if(sysctl(request, sizeof(request) / sizeof(*request), NULL, &length, NULL, 0) != 0)
|
||||
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, NULL) failed";
|
||||
|
||||
FF_AUTO_FREE struct kinfo_proc* procs = (struct kinfo_proc*) malloc(length);
|
||||
if(sysctl(request, sizeof(request) / sizeof(*request), procs, &length, NULL, 0) != 0)
|
||||
return "sysctl({CTL_KERN, KERN_PROC, KERN_PROC_UID}, procs) failed";
|
||||
|
||||
length /= sizeof(*procs);
|
||||
|
||||
for (struct kinfo_proc* proc = procs; proc < procs + length; ++proc)
|
||||
{
|
||||
if(result->dePrettyName.length == 0)
|
||||
applyPrettyNameIfDE(result, proc->ki_comm);
|
||||
|
||||
if(result->wmPrettyName.length == 0)
|
||||
applyNameIfWM(result, proc->ki_comm);
|
||||
|
||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||
break;
|
||||
}
|
||||
#else
|
||||
FF_AUTO_CLOSE_DIR DIR* procdir = opendir("/proc");
|
||||
if(procdir == NULL)
|
||||
return "opendir(\"/proc\") failed";
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY procPath = ffStrbufCreateA(64);
|
||||
ffStrbufAppendS(&procPath, "/proc/");
|
||||
|
||||
uint32_t procPathLength = procPath.length;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY userID = ffStrbufCreateF("%i", getuid());
|
||||
FF_STRBUF_AUTO_DESTROY loginuid = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY processName = ffStrbufCreateA(256); //Some processes have large command lines (looking at you chrome)
|
||||
|
||||
struct dirent* dirent;
|
||||
while((dirent = readdir(proc)) != NULL)
|
||||
while((dirent = readdir(procdir)) != NULL)
|
||||
{
|
||||
//Match only folders starting with a number (the pid folders)
|
||||
if(dirent->d_type != DT_DIR || !isdigit(dirent->d_name[0]))
|
||||
@@ -272,7 +315,7 @@ static void getFromProcDir(FFDisplayServerResult* result)
|
||||
//Don't check for processes not owend by the current user.
|
||||
ffStrbufAppendS(&procPath, "/loginuid");
|
||||
ffReadFileBuffer(procPath.chars, &loginuid);
|
||||
if(ffStrbufComp(&userID, &loginuid) != 0)
|
||||
if(ffStrbufToUInt(&loginuid, (uint64_t) -1) != userId)
|
||||
{
|
||||
ffStrbufSubstrBefore(&procPath, procPathLength);
|
||||
continue;
|
||||
@@ -297,8 +340,9 @@ static void getFromProcDir(FFDisplayServerResult* result)
|
||||
if(result->dePrettyName.length > 0 && result->wmPrettyName.length > 0)
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
closedir(proc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void ffdsDetectWMDE(FFDisplayServerResult* result)
|
||||
@@ -338,7 +382,7 @@ void ffdsDetectWMDE(FFDisplayServerResult* result)
|
||||
return;
|
||||
|
||||
//Get missing WM / DE from processes.
|
||||
getFromProcDir(result);
|
||||
getFromProcesses(result);
|
||||
|
||||
//Return if both wm and de are set, or if env doesn't contain anything
|
||||
if(
|
||||
|
||||
@@ -9,20 +9,26 @@
|
||||
static double detectGpuTemp(const FFstrbuf* gpuName)
|
||||
{
|
||||
double result = 0;
|
||||
const char* error;
|
||||
const char* error = NULL;
|
||||
|
||||
if(ffStrbufStartsWithS(gpuName, "Apple M1"))
|
||||
error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result);
|
||||
else if(ffStrbufStartsWithS(gpuName, "Apple M2"))
|
||||
error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result);
|
||||
else if(ffStrbufStartsWithS(gpuName, "Intel"))
|
||||
if (ffStrbufStartsWithS(gpuName, "Apple M"))
|
||||
{
|
||||
switch (strtol(gpuName->chars + strlen("Apple M"), NULL, 10))
|
||||
{
|
||||
case 1: error = ffDetectCoreTemps(FF_TEMP_GPU_M1X, &result); break;
|
||||
case 2: error = ffDetectCoreTemps(FF_TEMP_GPU_M2X, &result); break;
|
||||
case 3: error = ffDetectCoreTemps(FF_TEMP_GPU_M3X, &result); break;
|
||||
default: error = "Unsupported Apple Silicon GPU";
|
||||
}
|
||||
}
|
||||
else if (ffStrbufStartsWithS(gpuName, "Intel"))
|
||||
error = ffDetectCoreTemps(FF_TEMP_GPU_INTEL, &result);
|
||||
else if(ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
|
||||
else if (ffStrbufStartsWithS(gpuName, "Radeon") || ffStrbufStartsWithS(gpuName, "AMD"))
|
||||
error = ffDetectCoreTemps(FF_TEMP_GPU_AMD, &result);
|
||||
else
|
||||
error = ffDetectCoreTemps(FF_TEMP_GPU_UNKNOWN, &result);
|
||||
|
||||
if(error)
|
||||
if (error)
|
||||
return FF_GPU_TEMP_UNSET;
|
||||
|
||||
return result;
|
||||
|
||||
@@ -16,7 +16,16 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
if(host_statistics64(mach_host_self(), HOST_VM_INFO64, (host_info64_t) (&vmstat), &count) != KERN_SUCCESS)
|
||||
return "Failed to read host_statistics64";
|
||||
|
||||
ram->bytesUsed = ((uint64_t) vmstat.active_count + vmstat.wire_count) * instance.state.platform.pageSize;
|
||||
// https://github.com/exelban/stats/blob/master/Modules/RAM/readers.swift#L56
|
||||
ram->bytesUsed = ((uint64_t)
|
||||
+ vmstat.active_count
|
||||
+ vmstat.inactive_count
|
||||
+ vmstat.speculative_count
|
||||
+ vmstat.wire_count
|
||||
+ vmstat.compressor_page_count
|
||||
- vmstat.purgeable_count
|
||||
- vmstat.external_page_count
|
||||
) * instance.state.platform.pageSize;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -13,33 +13,43 @@ const char* ffDetectMemory(FFMemoryResult* ram)
|
||||
buf[nRead] = '\0';
|
||||
|
||||
uint64_t memTotal = 0,
|
||||
memAvailable = 0,
|
||||
shmem = 0,
|
||||
memFree = 0,
|
||||
buffers = 0,
|
||||
cached = 0,
|
||||
sReclaimable = 0;
|
||||
|
||||
|
||||
char *token = NULL;
|
||||
if((token = strstr(buf, "MemTotal:")) != NULL)
|
||||
memTotal = strtoul(token + strlen("MemTotal:"), NULL, 10);
|
||||
else
|
||||
return "MemTotal not found in /proc/meminfo";
|
||||
|
||||
if((token = strstr(buf, "MemFree:")) != NULL)
|
||||
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
|
||||
if((token = strstr(buf, "MemAvailable:")) != NULL)
|
||||
memAvailable = strtoul(token + strlen("MemAvailable:"), NULL, 10);
|
||||
else
|
||||
{
|
||||
if((token = strstr(buf, "MemFree:")) != NULL)
|
||||
memFree = strtoul(token + strlen("MemFree:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "Buffers:")) != NULL)
|
||||
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "Cached:")) != NULL)
|
||||
cached = strtoul(token + strlen("Cached:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "Shmem:")) != NULL)
|
||||
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "SReclaimable:")) != NULL)
|
||||
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
|
||||
if((token = strstr(buf, "Buffers:")) != NULL)
|
||||
buffers = strtoul(token + strlen("Buffers:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "Cached:")) != NULL)
|
||||
cached = strtoul(token + strlen("Cached:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "Shmem:")) != NULL)
|
||||
shmem = strtoul(token + strlen("Shmem:"), NULL, 10);
|
||||
|
||||
if((token = strstr(buf, "SReclaimable:")) != NULL)
|
||||
sReclaimable = strtoul(token + strlen("SReclaimable:"), NULL, 10);
|
||||
|
||||
memAvailable = memFree + buffers + cached + sReclaimable - shmem;
|
||||
}
|
||||
|
||||
ram->bytesTotal = memTotal * 1024lu;
|
||||
ram->bytesUsed = (memTotal + shmem - memFree - buffers - cached - sReclaimable) * 1024lu;
|
||||
ram->bytesUsed = (memTotal - memAvailable) * 1024lu;
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#include "packages.h"
|
||||
|
||||
#include "common/settings.h"
|
||||
|
||||
void ffDetectPackagesImpl(FFPackagesResult* result, FF_MAYBE_UNUSED FFPackagesOptions* options)
|
||||
{
|
||||
result->pkg = (uint32_t) ffSettingsGetSQLite3Int(FASTFETCH_TARGET_DIR_ROOT "/var/db/pkg/local.sqlite", "SELECT count(*) FROM packages");
|
||||
}
|
||||
@@ -11,7 +11,7 @@
|
||||
|
||||
static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
||||
{
|
||||
DIR* dirp = opendir(dirname);
|
||||
FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname);
|
||||
if(dirp == NULL)
|
||||
return 0;
|
||||
|
||||
@@ -26,8 +26,6 @@ static uint32_t getNumElementsImpl(const char* dirname, unsigned char type)
|
||||
if(type == DT_DIR && num_elements >= 2)
|
||||
num_elements -= 2; // accounting for . and ..
|
||||
|
||||
closedir(dirp);
|
||||
|
||||
return num_elements;
|
||||
}
|
||||
|
||||
@@ -42,26 +40,19 @@ static uint32_t getNumElements(FFstrbuf* baseDir, const char* dirname, unsigned
|
||||
|
||||
static uint32_t getNumStringsImpl(const char* filename, const char* needle)
|
||||
{
|
||||
FILE* file = fopen(filename, "r");
|
||||
if(file == NULL)
|
||||
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate();
|
||||
if (!ffReadFileBuffer(filename, &content))
|
||||
return 0;
|
||||
|
||||
uint32_t count = 0;
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
while(getline(&line, &len, file) != EOF)
|
||||
char *iter = content.chars;
|
||||
size_t needleLength = strlen(needle);
|
||||
while ((iter = memmem(iter, content.length - (size_t)(iter - content.chars), needle, needleLength)) != NULL)
|
||||
{
|
||||
if(strstr(line, needle) != NULL)
|
||||
++count;
|
||||
++count;
|
||||
iter += needleLength;
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
fclose(file);
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
@@ -272,9 +263,8 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts)
|
||||
packageCounts->nixDefault += getNixPackages(baseDir, "/nix/var/nix/profiles/default");
|
||||
packageCounts->nixSystem += getNixPackages(baseDir, "/run/current-system");
|
||||
packageCounts->pacman += getNumElements(baseDir, "/var/lib/pacman/local", DT_DIR);
|
||||
packageCounts->pkg += getSQLite3Int(baseDir, "/var/db/pkg/local.sqlite", "SELECT count(id) FROM packages");
|
||||
packageCounts->pkgtool += getNumElements(baseDir, "/var/log/packages", DT_REG);
|
||||
packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages");
|
||||
packageCounts->rpm += getSQLite3Int(baseDir, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(*) FROM Packages");
|
||||
packageCounts->snap += getSnap(baseDir);
|
||||
packageCounts->xbps += getXBPS(baseDir, "/var/db/xbps");
|
||||
packageCounts->brewCask += getNumElements(baseDir, "/home/linuxbrew/.linuxbrew/Caskroom", DT_DIR);
|
||||
@@ -288,7 +278,7 @@ static void getPackageCountsRegular(FFstrbuf* baseDir, FFPackagesResult* package
|
||||
getPackageCounts(baseDir, packageCounts);
|
||||
|
||||
uint32_t baseDirLength = baseDir->length;
|
||||
ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC"/pacman-mirrors.conf");
|
||||
ffStrbufAppendS(baseDir, FASTFETCH_TARGET_DIR_ETC "/pacman-mirrors.conf");
|
||||
if(ffParsePropFile(baseDir->chars, "Branch =", &packageCounts->pacmanBranch) && packageCounts->pacmanBranch.length == 0)
|
||||
ffStrbufAppendS(&packageCounts->pacmanBranch, "stable");
|
||||
ffStrbufSubstrBefore(baseDir, baseDirLength);
|
||||
|
||||
@@ -0,0 +1,25 @@
|
||||
#include "fastfetch.h"
|
||||
|
||||
typedef enum FFPhysicalDiskType
|
||||
{
|
||||
FF_PHYSICALDISK_TYPE_NONE = 0,
|
||||
|
||||
// If neither is set, it's unknown
|
||||
FF_PHYSICALDISK_TYPE_HDD = 1 << 0,
|
||||
FF_PHYSICALDISK_TYPE_SSD = 1 << 1,
|
||||
|
||||
FF_PHYSICALDISK_TYPE_FIXED = 1 << 2,
|
||||
FF_PHYSICALDISK_TYPE_REMOVABLE = 1 << 3,
|
||||
} FFPhysicalDiskType;
|
||||
|
||||
typedef struct FFPhysicalDiskResult
|
||||
{
|
||||
FFstrbuf name;
|
||||
FFstrbuf interconnect;
|
||||
FFstrbuf serial;
|
||||
FFstrbuf devPath;
|
||||
FFPhysicalDiskType type;
|
||||
uint64_t size;
|
||||
} FFPhysicalDiskResult;
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options);
|
||||
@@ -0,0 +1,93 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "util/apple/cf_helpers.h"
|
||||
|
||||
#include <IOKit/IOKitLib.h>
|
||||
#include <IOKit/IOBSD.h>
|
||||
#include <IOKit/storage/IOMedia.h>
|
||||
#include <IOKit/storage/IOBlockStorageDriver.h>
|
||||
#include <IOKit/storage/IOStorageDeviceCharacteristics.h>
|
||||
#include <IOKit/storage/IOStorageProtocolCharacteristics.h>
|
||||
|
||||
static inline void wrapIoObjectRelease(io_service_t* service)
|
||||
{
|
||||
assert(service);
|
||||
if (*service)
|
||||
IOObjectRelease(*service);
|
||||
}
|
||||
#define FF_IOOBJECT_AUTO_RELEASE __attribute__((__cleanup__(wrapIoObjectRelease)))
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
{
|
||||
FF_IOOBJECT_AUTO_RELEASE io_iterator_t iterator = 0;
|
||||
if(IOServiceGetMatchingServices(MACH_PORT_NULL, IOServiceMatching(kIOMediaClass), &iterator) != KERN_SUCCESS)
|
||||
return "IOServiceGetMatchingServices() failed";
|
||||
|
||||
io_registry_entry_t registryEntry;
|
||||
while((registryEntry = IOIteratorNext(iterator)) != 0)
|
||||
{
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPartition = registryEntry;
|
||||
|
||||
io_name_t deviceName;
|
||||
if (IORegistryEntryGetName(registryEntry, deviceName) != KERN_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (options->namePrefix.length && strncmp(deviceName, options->namePrefix.chars, options->namePrefix.length) != 0)
|
||||
continue;
|
||||
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryDriver = 0;
|
||||
if (IORegistryEntryGetParentEntry(entryPartition, kIOServicePlane, &entryDriver) != KERN_SUCCESS)
|
||||
continue;
|
||||
|
||||
if (!IOObjectConformsTo(entryDriver, kIOBlockStorageDriverClass)) // physical disk only
|
||||
continue;
|
||||
|
||||
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||
ffStrbufInit(&device->serial);
|
||||
ffStrbufInitS(&device->name, deviceName);
|
||||
ffStrbufInit(&device->devPath);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
device->size = 0;
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions);
|
||||
device->type |= CFBooleanGetValue(removable) ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFStringRef bsdName = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOBSDNameKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (bsdName)
|
||||
{
|
||||
ffCfStrGetString(bsdName, &device->devPath);
|
||||
ffStrbufPrependS(&device->devPath, "/dev/");
|
||||
}
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFNumberRef mediaSize = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaSizeKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (mediaSize)
|
||||
ffCfNumGetInt64(mediaSize, (int64_t*) &device->size);
|
||||
else
|
||||
device->size = 0;
|
||||
|
||||
FF_IOOBJECT_AUTO_RELEASE io_registry_entry_t entryPhysical = 0;
|
||||
if (IORegistryEntryGetParentEntry(entryDriver, kIOServicePlane, &entryPhysical) == KERN_SUCCESS)
|
||||
{
|
||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (protocolCharacteristics)
|
||||
ffCfDictGetString(protocolCharacteristics, CFSTR(kIOPropertyPhysicalInterconnectTypeKey), &device->interconnect);
|
||||
|
||||
FF_CFTYPE_AUTO_RELEASE CFDictionaryRef deviceCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyDeviceCharacteristicsKey), kCFAllocatorDefault, kNilOptions);
|
||||
if (deviceCharacteristics)
|
||||
{
|
||||
ffCfDictGetString(deviceCharacteristics, CFSTR(kIOPropertyProductSerialNumberKey), &device->serial);
|
||||
|
||||
CFStringRef mediumType = (CFStringRef) CFDictionaryGetValue(deviceCharacteristics, CFSTR(kIOPropertyMediumTypeKey));
|
||||
if (mediumType)
|
||||
{
|
||||
if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeSolidStateKey), 0) == 0)
|
||||
device->type |= FF_PHYSICALDISK_TYPE_SSD;
|
||||
else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0)
|
||||
device->type |= FF_PHYSICALDISK_TYPE_HDD;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <devstat.h>
|
||||
#include <memory.h>
|
||||
#include <fcntl.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/disk.h>
|
||||
#include <libgeom.h>
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
{
|
||||
struct gmesh geomTree;
|
||||
if (geom_gettree(&geomTree) < 0)
|
||||
return "geom_gettree() failed";
|
||||
|
||||
if (geom_stats_open() < 0)
|
||||
return "geom_stats_open() failed";
|
||||
|
||||
void* snap = geom_stats_snapshot_get();
|
||||
struct devstat* snapIter;
|
||||
while ((snapIter = geom_stats_snapshot_next(snap)) != NULL)
|
||||
{
|
||||
if (snapIter->device_type & DEVSTAT_TYPE_PASS)
|
||||
continue;
|
||||
struct gident* geomId = geom_lookupid(&geomTree, snapIter->id);
|
||||
if (geomId == NULL)
|
||||
continue;
|
||||
if (geomId->lg_what != ISPROVIDER)
|
||||
continue;
|
||||
struct gprovider* provider = (struct gprovider*) geomId->lg_ptr;
|
||||
if (provider->lg_geom->lg_rank != 1)
|
||||
continue;
|
||||
|
||||
FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name);
|
||||
FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate();
|
||||
FFPhysicalDiskType type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next)
|
||||
{
|
||||
if (ffStrEquals(ptr->lg_name, "descr"))
|
||||
ffStrbufSetS(&name, ptr->lg_val);
|
||||
else if (ffStrEquals(ptr->lg_name, "rotationrate") && !ffStrEquals(ptr->lg_val, "unknown"))
|
||||
type |= ffStrEquals(ptr->lg_val, "0") ? FF_PHYSICALDISK_TYPE_SSD : FF_PHYSICALDISK_TYPE_HDD;
|
||||
else if (ffStrEquals(ptr->lg_name, "ident"))
|
||||
ffStrbufSetS(&identifier, ptr->lg_val);
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix))
|
||||
continue;
|
||||
|
||||
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name);
|
||||
ffStrbufInitMove(&device->serial, &identifier);
|
||||
ffStrbufInit(&device->interconnect);
|
||||
switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK)
|
||||
{
|
||||
case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break;
|
||||
case DEVSTAT_TYPE_IF_IDE: ffStrbufAppendS(&device->interconnect, "IDE"); break;
|
||||
case DEVSTAT_TYPE_IF_OTHER: ffStrbufAppendS(&device->interconnect, "OTHER"); break;
|
||||
}
|
||||
device->size = (uint64_t) provider->lg_mediasize;
|
||||
ffStrbufInitMove(&device->name, &name);
|
||||
device->type = type;
|
||||
}
|
||||
|
||||
geom_stats_snapshot_free(snap);
|
||||
geom_stats_close();
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "common/io/io.h"
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <limits.h>
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
{
|
||||
FF_AUTO_CLOSE_DIR DIR* sysBlockDirp = opendir("/sys/block/");
|
||||
if(sysBlockDirp == NULL)
|
||||
return "opendir(\"/sys/block/\") == NULL";
|
||||
|
||||
struct dirent* sysBlockEntry;
|
||||
while ((sysBlockEntry = readdir(sysBlockDirp)) != NULL)
|
||||
{
|
||||
const char* const devName = sysBlockEntry->d_name;
|
||||
|
||||
if (devName[0] == '.')
|
||||
continue;
|
||||
|
||||
char pathSysBlock[PATH_MAX];
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName);
|
||||
|
||||
char pathSysDeviceReal[PATH_MAX];
|
||||
ssize_t pathLength = readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1);
|
||||
if (pathLength < 0)
|
||||
continue;
|
||||
pathSysDeviceReal[pathLength] = '\0';
|
||||
|
||||
if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device
|
||||
continue;
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName);
|
||||
if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY))
|
||||
continue;
|
||||
|
||||
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
ffStrbufInit(&device->name);
|
||||
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/vendor", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
if (device->name.length > 0)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/model", devName);
|
||||
ffAppendFileBuffer(pathSysBlock, &device->name);
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
|
||||
if (device->name.length == 0)
|
||||
ffStrbufSetS(&device->name, devName);
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
ffStrbufInitF(&device->devPath, "/dev/%s", devName);
|
||||
|
||||
{
|
||||
ffStrbufInit(&device->interconnect);
|
||||
if (strstr(pathSysDeviceReal, "/usb") != NULL)
|
||||
ffStrbufSetS(&device->interconnect, "usb");
|
||||
else
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName);
|
||||
if (!ffAppendFileBuffer(pathSysBlock, &device->interconnect))
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/uevent", devName);
|
||||
if (ffParsePropFile(pathSysBlock, "DEVTYPE=", &device->interconnect))
|
||||
ffStrbufSubstrBeforeLastC(&device->interconnect, '_');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName);
|
||||
char isRotationalChar = '1';
|
||||
if (ffReadFileData(pathSysBlock, 1, &isRotationalChar) > 0)
|
||||
device->type |= isRotationalChar == '1' ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
|
||||
}
|
||||
|
||||
{
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName);
|
||||
char blkSize[32];
|
||||
ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize);
|
||||
if (fileSize > 0)
|
||||
{
|
||||
blkSize[fileSize] = 0;
|
||||
device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512;
|
||||
}
|
||||
else
|
||||
device->size = 0;
|
||||
}
|
||||
|
||||
{
|
||||
char removableChar = '0';
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName);
|
||||
if (ffReadFileData(pathSysBlock, 1, &removableChar) > 0)
|
||||
device->type |= removableChar == '1' ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
}
|
||||
|
||||
{
|
||||
ffStrbufInit(&device->serial);
|
||||
snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName);
|
||||
ffReadFileBuffer(pathSysBlock, &device->serial);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,131 @@
|
||||
#include "physicaldisk.h"
|
||||
#include "common/io/io.h"
|
||||
#include "util/windows/unicode.h"
|
||||
|
||||
#include <windows.h>
|
||||
#include <winioctl.h>
|
||||
|
||||
const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options)
|
||||
{
|
||||
wchar_t szDevice[32] = L"\\\\.\\PhysicalDrive";
|
||||
wchar_t* pNum = szDevice + strlen("\\\\.\\PhysicalDrive");
|
||||
for (uint32_t idev = 0; ; ++idev)
|
||||
{
|
||||
_ultow(idev, pNum, 10);
|
||||
|
||||
FF_AUTO_CLOSE_FD HANDLE hDevice = CreateFileW(szDevice, FILE_READ_ATTRIBUTES, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);
|
||||
if (hDevice == INVALID_HANDLE_VALUE)
|
||||
break;
|
||||
|
||||
DWORD retSize;
|
||||
char sddBuffer[4096];
|
||||
if(!DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&(STORAGE_PROPERTY_QUERY) {
|
||||
.PropertyId = StorageDeviceProperty,
|
||||
.QueryType = PropertyStandardQuery,
|
||||
},
|
||||
sizeof(STORAGE_PROPERTY_QUERY),
|
||||
&sddBuffer,
|
||||
sizeof(sddBuffer),
|
||||
&retSize,
|
||||
NULL
|
||||
) || retSize == 0)
|
||||
continue;
|
||||
|
||||
FFPhysicalDiskResult* device = (FFPhysicalDiskResult*) ffListAdd(result);
|
||||
device->type = FF_PHYSICALDISK_TYPE_NONE;
|
||||
STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer;
|
||||
|
||||
ffStrbufInit(&device->name);
|
||||
if (sdd->VendorIdOffset != 0)
|
||||
{
|
||||
ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset);
|
||||
ffStrbufTrim(&device->name, ' ');
|
||||
}
|
||||
if (sdd->ProductIdOffset != 0)
|
||||
{
|
||||
if (device->name.length)
|
||||
ffStrbufAppendC(&device->name, ' ');
|
||||
|
||||
ffStrbufAppendS(&device->name, (const char*) sddBuffer + sdd->ProductIdOffset);
|
||||
ffStrbufTrimRight(&device->name, ' ');
|
||||
}
|
||||
|
||||
if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix))
|
||||
{
|
||||
ffStrbufDestroy(&device->name);
|
||||
result->length--;
|
||||
continue;
|
||||
}
|
||||
|
||||
ffStrbufInitWS(&device->devPath, szDevice);
|
||||
ffStrbufInit(&device->serial);
|
||||
if (sdd->SerialNumberOffset != 0)
|
||||
{
|
||||
ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset);
|
||||
ffStrbufTrim(&device->serial, ' ');
|
||||
}
|
||||
|
||||
device->type |= sdd->RemovableMedia ? FF_PHYSICALDISK_TYPE_REMOVABLE : FF_PHYSICALDISK_TYPE_FIXED;
|
||||
|
||||
ffStrbufInit(&device->interconnect);
|
||||
switch (sdd->BusType)
|
||||
{
|
||||
case BusTypeUnknown: ffStrbufSetStatic(&device->interconnect, "Unknown"); break;
|
||||
case BusTypeScsi: ffStrbufSetStatic(&device->interconnect, "Scsi"); break;
|
||||
case BusTypeAtapi: ffStrbufSetStatic(&device->interconnect, "Atapi"); break;
|
||||
case BusTypeAta: ffStrbufSetStatic(&device->interconnect, "Ata"); break;
|
||||
case BusType1394: ffStrbufSetStatic(&device->interconnect, "1394"); break;
|
||||
case BusTypeSsa: ffStrbufSetStatic(&device->interconnect, "Ssa"); break;
|
||||
case BusTypeFibre: ffStrbufSetStatic(&device->interconnect, "Fibra"); break;
|
||||
case BusTypeUsb: ffStrbufSetStatic(&device->interconnect, "Usb"); break;
|
||||
case BusTypeRAID: ffStrbufSetStatic(&device->interconnect, "RAID"); break;
|
||||
case BusTypeiScsi: ffStrbufSetStatic(&device->interconnect, "iScsi"); break;
|
||||
case BusTypeSas: ffStrbufSetStatic(&device->interconnect, "Sas"); break;
|
||||
case BusTypeSata: ffStrbufSetStatic(&device->interconnect, "Sata"); break;
|
||||
case BusTypeSd: ffStrbufSetStatic(&device->interconnect, "Sd"); break;
|
||||
case BusTypeMmc: ffStrbufSetStatic(&device->interconnect, "Mmc"); break;
|
||||
case BusTypeVirtual: ffStrbufSetStatic(&device->interconnect, "Virtual"); break;
|
||||
case BusTypeFileBackedVirtual: ffStrbufSetStatic(&device->interconnect, "FileBackedVirtual"); break;
|
||||
case BusTypeSpaces: ffStrbufSetStatic(&device->interconnect, "Spaces"); break;
|
||||
case BusTypeNvme: ffStrbufSetStatic(&device->interconnect, "Nvme"); break;
|
||||
case BusTypeSCM: ffStrbufSetStatic(&device->interconnect, "SCM"); break;
|
||||
case BusTypeUfs: ffStrbufSetStatic(&device->interconnect, "Ufs"); break;
|
||||
default: ffStrbufSetF(&device->interconnect, "Unknown (%d)", (int) sdd->BusType); break;
|
||||
}
|
||||
|
||||
DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {};
|
||||
if(DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_STORAGE_QUERY_PROPERTY,
|
||||
&(STORAGE_PROPERTY_QUERY) {
|
||||
.PropertyId = StorageDeviceSeekPenaltyProperty,
|
||||
.QueryType = PropertyStandardQuery,
|
||||
},
|
||||
sizeof(STORAGE_PROPERTY_QUERY),
|
||||
&dspd,
|
||||
sizeof(dspd),
|
||||
&retSize,
|
||||
NULL
|
||||
) && retSize == sizeof(dspd))
|
||||
device->type |= dspd.IncursSeekPenalty ? FF_PHYSICALDISK_TYPE_HDD : FF_PHYSICALDISK_TYPE_SSD;
|
||||
|
||||
DISK_GEOMETRY_EX dge = {};
|
||||
if(DeviceIoControl(
|
||||
hDevice,
|
||||
IOCTL_DISK_GET_DRIVE_GEOMETRY_EX,
|
||||
NULL,
|
||||
0,
|
||||
&dge,
|
||||
sizeof(dge),
|
||||
&retSize,
|
||||
NULL))
|
||||
device->size = (uint64_t) dge.DiskSize.QuadPart;
|
||||
else
|
||||
device->size = 0;
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
@@ -333,6 +333,25 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
|
||||
count += detectTemp(conn, "Tp09", result); // CPU core 8
|
||||
break;
|
||||
|
||||
case FF_TEMP_CPU_M3X:
|
||||
count += detectTemp(conn, "Te05", result); // CPU efficiency core 1
|
||||
count += detectTemp(conn, "Te0L", result); // CPU efficiency core 2
|
||||
count += detectTemp(conn, "Te0P", result); // CPU efficiency core 3
|
||||
count += detectTemp(conn, "Te0S", result); // CPU efficiency core 4
|
||||
count += detectTemp(conn, "Tf04", result); // CPU performance core 1
|
||||
count += detectTemp(conn, "Tf09", result); // CPU performance core 2
|
||||
count += detectTemp(conn, "Tf0A", result); // CPU performance core 3
|
||||
count += detectTemp(conn, "Tf0B", result); // CPU performance core 4
|
||||
count += detectTemp(conn, "Tf0D", result); // CPU performance core 5
|
||||
count += detectTemp(conn, "Tf0E", result); // CPU performance core 6
|
||||
count += detectTemp(conn, "Tf44", result); // CPU performance core 7
|
||||
count += detectTemp(conn, "Tf49", result); // CPU performance core 8
|
||||
count += detectTemp(conn, "Tf4A", result); // CPU performance core 9
|
||||
count += detectTemp(conn, "Tf4B", result); // CPU performance core 10
|
||||
count += detectTemp(conn, "Tf4D", result); // CPU performance core 11
|
||||
count += detectTemp(conn, "Tf4E", result); // CPU performance core 12
|
||||
break;
|
||||
|
||||
case FF_TEMP_GPU_INTEL:
|
||||
count += detectTemp(conn, "TCGC", result); // GPU Intel Graphics
|
||||
goto gpu_unknown;
|
||||
@@ -359,12 +378,27 @@ const char *ffDetectCoreTemps(enum FFTempType type, double *result)
|
||||
count += detectTemp(conn, "Tg0j", result); // GPU 2
|
||||
break;
|
||||
|
||||
case FF_TEMP_GPU_M3X:
|
||||
count += detectTemp(conn, "Tf14", result); // GPU 1
|
||||
count += detectTemp(conn, "Tf18", result); // GPU 2
|
||||
count += detectTemp(conn, "Tf19", result); // GPU 3
|
||||
count += detectTemp(conn, "Tf1A", result); // GPU 4
|
||||
count += detectTemp(conn, "Tf24", result); // GPU 5
|
||||
count += detectTemp(conn, "Tf28", result); // GPU 6
|
||||
count += detectTemp(conn, "Tf29", result); // GPU 7
|
||||
count += detectTemp(conn, "Tf2A", result); // GPU 8
|
||||
break;
|
||||
|
||||
case FF_TEMP_BATTERY:
|
||||
count += detectTemp(conn, "TB1T", result); // Battery
|
||||
count += detectTemp(conn, "TB2T", result); // Battery
|
||||
break;
|
||||
|
||||
case FF_TEMP_MEMORY:
|
||||
count += detectTemp(conn, "Tm02", result); // Memory
|
||||
count += detectTemp(conn, "Tm02", result); // Memory 1
|
||||
count += detectTemp(conn, "Tm06", result); // Memory 2
|
||||
count += detectTemp(conn, "Tm08", result); // Memory 3
|
||||
count += detectTemp(conn, "Tm09", result); // Memory 4
|
||||
break;
|
||||
}
|
||||
|
||||
|
||||
@@ -15,12 +15,14 @@ enum FFTempType
|
||||
FF_TEMP_CPU_X64,
|
||||
FF_TEMP_CPU_M1X,
|
||||
FF_TEMP_CPU_M2X,
|
||||
FF_TEMP_CPU_M3X,
|
||||
|
||||
FF_TEMP_GPU_INTEL,
|
||||
FF_TEMP_GPU_AMD,
|
||||
FF_TEMP_GPU_UNKNOWN,
|
||||
FF_TEMP_GPU_M1X,
|
||||
FF_TEMP_GPU_M2X,
|
||||
FF_TEMP_GPU_M3X,
|
||||
|
||||
FF_TEMP_BATTERY,
|
||||
|
||||
|
||||
@@ -4,6 +4,8 @@
|
||||
#include "common/properties.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
|
||||
#include "util/mallocHelper.h"
|
||||
@@ -162,6 +164,28 @@ static bool getShellVersionWinPowerShell(FFstrbuf* exe, FFstrbuf* version)
|
||||
NULL
|
||||
}) == NULL;
|
||||
}
|
||||
#else
|
||||
static bool getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
|
||||
ffStrbufAppendS(&command, "printf \"%s\" \"$");
|
||||
ffStrbufAppendTransformS(&command, exeName, toupper);
|
||||
ffStrbufAppendS(&command, "_VERSION\"");
|
||||
|
||||
if (ffProcessAppendStdOut(version, (char* const[]) {
|
||||
"env",
|
||||
"-i",
|
||||
exe->chars,
|
||||
"-c",
|
||||
command.chars,
|
||||
NULL
|
||||
}) != NULL)
|
||||
return false;
|
||||
|
||||
ffStrbufSubstrBeforeFirstC(version, '(');
|
||||
ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
@@ -198,7 +222,7 @@ bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
|
||||
return getFileVersion(exe->chars, version);
|
||||
#else
|
||||
return false;
|
||||
return getShellVersionGeneric(exe, exeName, version);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
#include "common/thread.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
@@ -68,8 +67,6 @@ static void getProcessInformation(pid_t pid, FFstrbuf* processName, FFstrbuf* ex
|
||||
|
||||
static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
||||
{
|
||||
const char* error = NULL;
|
||||
|
||||
#ifdef __linux__
|
||||
|
||||
char statFilePath[64];
|
||||
@@ -86,20 +83,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
||||
!ffStrSet(name) ||
|
||||
*ppid == 0
|
||||
)
|
||||
error = "sscanf(stat) failed";
|
||||
return "sscanf(stat) failed";
|
||||
|
||||
#elif defined(__APPLE__)
|
||||
|
||||
struct proc_bsdshortinfo proc;
|
||||
if(proc_pidinfo(pid, PROC_PIDT_SHORTBSDINFO, 0, &proc, PROC_PIDT_SHORTBSDINFO_SIZE) <= 0)
|
||||
error = "proc_pidinfo(pid) failed";
|
||||
else
|
||||
{
|
||||
*ppid = (pid_t)proc.pbsi_ppid;
|
||||
strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
|
||||
}
|
||||
return "proc_pidinfo(pid) failed";
|
||||
|
||||
#else
|
||||
*ppid = (pid_t)proc.pbsi_ppid;
|
||||
strncpy(name, proc.pbsi_comm, 16); //trancated to 16 chars
|
||||
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
struct kinfo_proc proc;
|
||||
size_t size = sizeof(proc);
|
||||
@@ -108,16 +103,18 @@ static const char* getProcessNameAndPpid(pid_t pid, char* name, pid_t* ppid)
|
||||
&proc, &size,
|
||||
NULL, 0
|
||||
))
|
||||
error = "sysctl(KERN_PROC_PID) failed";
|
||||
else
|
||||
{
|
||||
*ppid = (pid_t)proc.ki_ppid;
|
||||
strncpy(name, proc.ki_comm, COMMLEN);
|
||||
}
|
||||
return "sysctl(KERN_PROC_PID) failed";
|
||||
|
||||
*ppid = (pid_t)proc.ki_ppid;
|
||||
strncpy(name, proc.ki_comm, COMMLEN);
|
||||
|
||||
#else
|
||||
|
||||
return "Unsupported platform";
|
||||
|
||||
#endif
|
||||
|
||||
return error;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void getTerminalShell(FFTerminalShellResult* result, pid_t pid)
|
||||
@@ -286,34 +283,8 @@ static void getUserShellFromEnv(FFTerminalShellResult* result)
|
||||
}
|
||||
}
|
||||
|
||||
static void getShellVersionGeneric(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
{
|
||||
FF_STRBUF_AUTO_DESTROY command = ffStrbufCreate();
|
||||
ffStrbufAppendS(&command, "printf \"%s\" \"$");
|
||||
ffStrbufAppendTransformS(&command, exeName, toupper);
|
||||
ffStrbufAppendS(&command, "_VERSION\"");
|
||||
|
||||
ffProcessAppendStdOut(version, (char* const[]) {
|
||||
"env",
|
||||
"-i",
|
||||
exe->chars,
|
||||
"-c",
|
||||
command.chars,
|
||||
NULL
|
||||
});
|
||||
ffStrbufSubstrBeforeFirstC(version, '(');
|
||||
ffStrbufRemoveStrings(version, 2, (const char*[]) { "-release", "release" });
|
||||
}
|
||||
|
||||
bool fftsGetShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version);
|
||||
|
||||
static void getShellVersion(FFstrbuf* exe, const char* exeName, FFstrbuf* version)
|
||||
{
|
||||
ffStrbufClear(version);
|
||||
if(!fftsGetShellVersion(exe, exeName, version))
|
||||
getShellVersionGeneric(exe, exeName, version);
|
||||
}
|
||||
|
||||
bool fftsGetTerminalVersion(FFstrbuf* processName, FFstrbuf* exe, FFstrbuf* version);
|
||||
|
||||
const FFTerminalShellResult* ffDetectTerminalShell()
|
||||
@@ -350,7 +321,8 @@ const FFTerminalShellResult* ffDetectTerminalShell()
|
||||
getTerminalFromEnv(&result);
|
||||
getUserShellFromEnv(&result);
|
||||
|
||||
getShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
|
||||
ffStrbufClear(&result.shellVersion);
|
||||
fftsGetShellVersion(&result.shellExe, result.shellExeName, &result.shellVersion);
|
||||
|
||||
if(ffStrbufEqualS(&result.shellProcessName, "pwsh"))
|
||||
ffStrbufInitStatic(&result.shellPrettyName, "PowerShell");
|
||||
|
||||
@@ -18,22 +18,22 @@ static void convertIfStateToString(WLAN_INTERFACE_STATE state, FFstrbuf* result)
|
||||
ffStrbufAppendS(result, "Connected");
|
||||
break;
|
||||
case wlan_interface_state_ad_hoc_network_formed:
|
||||
ffStrbufAppendS(result, "First node in a ad hoc network");
|
||||
ffStrbufAppendS(result, "Ad hoc network formed");
|
||||
break;
|
||||
case wlan_interface_state_disconnecting:
|
||||
ffStrbufAppendS(result, "Disconnecting");
|
||||
break;
|
||||
case wlan_interface_state_disconnected:
|
||||
ffStrbufAppendS(result, "Not connected");
|
||||
ffStrbufAppendS(result, "Disconnected");
|
||||
break;
|
||||
case wlan_interface_state_associating:
|
||||
ffStrbufAppendS(result, "Attempting to associate with a network");
|
||||
ffStrbufAppendS(result, "Associating");
|
||||
break;
|
||||
case wlan_interface_state_discovering:
|
||||
ffStrbufAppendS(result, "Auto configuration is discovering settings for the network");
|
||||
ffStrbufAppendS(result, "Discovering");
|
||||
break;
|
||||
case wlan_interface_state_authenticating:
|
||||
ffStrbufAppendS(result, "In process of authenticating");
|
||||
ffStrbufAppendS(result, "Authenticating");
|
||||
break;
|
||||
default:
|
||||
ffStrbufAppendS(result, "Unknown");
|
||||
@@ -133,16 +133,16 @@ const char* ffDetectWifi(FFlist* result)
|
||||
case dot11_phy_type_ht:
|
||||
ffStrbufAppendS(&item->conn.protocol, "802.11n (Wi-Fi 4)");
|
||||
break;
|
||||
case 8 /*dot11_phy_type_vht*/:
|
||||
case dot11_phy_type_vht:
|
||||
ffStrbufAppendS(&item->conn.protocol, "802.11ac (Wi-Fi 5)");
|
||||
break;
|
||||
case 9 /*dot11_phy_type_dmg*/:
|
||||
case dot11_phy_type_dmg:
|
||||
ffStrbufAppendS(&item->conn.protocol, "802.11ad (WiGig)");
|
||||
break;
|
||||
case 10 /*dot11_phy_type_he*/:
|
||||
case dot11_phy_type_he:
|
||||
ffStrbufAppendS(&item->conn.protocol, "802.11ax (Wi-Fi 6)");
|
||||
break;
|
||||
case 11 /*dot11_phy_type_eht*/:
|
||||
case dot11_phy_type_eht:
|
||||
ffStrbufAppendS(&item->conn.protocol, "802.11be (Wi-Fi 7)");
|
||||
break;
|
||||
default:
|
||||
@@ -179,10 +179,10 @@ const char* ffDetectWifi(FFlist* result)
|
||||
case DOT11_AUTH_ALGO_RSNA_PSK:
|
||||
ffStrbufAppendS(&item->conn.security, "WPA2-PSK");
|
||||
break;
|
||||
case 8 /* DOT11_AUTH_ALGO_WPA3 */:
|
||||
case DOT11_AUTH_ALGO_WPA3:
|
||||
ffStrbufAppendS(&item->conn.security, "WPA3");
|
||||
break;
|
||||
case 9 /* DOT11_AUTH_ALGO_WPA3_SAE */:
|
||||
case DOT11_AUTH_ALGO_WPA3_SAE:
|
||||
ffStrbufAppendS(&item->conn.security, "WPA3-SAE");
|
||||
break;
|
||||
case 10 /* DOT11_AUTH_ALGO_OWE */:
|
||||
|
||||
+14
-14
@@ -1,16 +1,16 @@
|
||||
${c3} ,-^-___
|
||||
${c3} /\\\\\\///
|
||||
${c2}refined.${c1} /\\\\\\\\//
|
||||
${c2}reliable.${c1} /\\\\\\///
|
||||
${c2}ready.${c1} /\\\\/////\\
|
||||
__///\\\\\\\\/////\\
|
||||
${c3} _//////\\\\\\\\\\\\\\////
|
||||
${c1} ///////${c3}\\\\\\\\\\\\\\\\\\\\//
|
||||
//////${c1}\\\\\\\\\\/
|
||||
/////\\\\\\\\\\/
|
||||
/////${c3}\\\\\\\\/
|
||||
/\\\\///\\\\\\/
|
||||
/\\\\\\/${c1}\\\/
|
||||
/\\\\\\\\//
|
||||
${c3} /\\\///
|
||||
${c2}refined.${c1} /\\\\//
|
||||
${c2}reliable.${c1} /\\\///
|
||||
${c2}ready.${c1} /\\/////\
|
||||
__///\\\\/////\
|
||||
${c3} _//////\\\\\\\////
|
||||
${c1} ///////${c3}\\\\\\\\\\//
|
||||
//////${c1}\\\\\/
|
||||
/////\\\\\/
|
||||
/////${c3}\\\\/
|
||||
/\\///\\\/
|
||||
/\\\/${c1}\\/
|
||||
/\\\\//
|
||||
//////
|
||||
/// ${c3}\\\\\\\\\\
|
||||
/// ${c3}\\\\\
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
.:-==++++++++++++++++++++++-.
|
||||
.:=+##############################+
|
||||
.=*###################################-
|
||||
:+######################################:
|
||||
:+######################################*-
|
||||
.+#############*+--:::::::::::::::::::::.
|
||||
:*##########*=:
|
||||
-###########=
|
||||
:##########+.
|
||||
*#########=
|
||||
=*********+ .::::::::::::::::.
|
||||
**********. -*###################+:
|
||||
:********** =#######################=
|
||||
-*********+ +************************
|
||||
:*********+ :***********************:
|
||||
.********** .=******************+-
|
||||
+*********-
|
||||
.**********.
|
||||
=**********:
|
||||
+**********=.
|
||||
=***********=:
|
||||
-*************+-.
|
||||
:+****************+++++++++++++++++++++==:
|
||||
:+**************************************+.
|
||||
-+************************************-
|
||||
.-+*********************************.
|
||||
:-==+*************************=.
|
||||
@@ -1348,6 +1348,15 @@ static const FFlogo E[] = {
|
||||
.colorKeys = FF_COLOR_FG_WHITE,
|
||||
.colorTitle = FF_COLOR_FG_WHITE,
|
||||
},
|
||||
// EshanizedOS
|
||||
{
|
||||
.names = {"EshanizedOS"},
|
||||
.lines = FASTFETCH_DATATEXT_LOGO_ESHANIZEDOS,
|
||||
.colors = {
|
||||
FF_COLOR_FG_RED,
|
||||
FF_COLOR_FG_WHITE,
|
||||
},
|
||||
},
|
||||
// EuroLinux
|
||||
{
|
||||
.names = {"EuroLinux"},
|
||||
|
||||
@@ -17,10 +17,13 @@ FFLogoImageResult ffLogoPrintImageIM6(FFLogoRequestData* requestData)
|
||||
FF_LIBRARY_LOAD(imageMagick, &instance.config.library.libImageMagick, FF_LOGO_IMAGE_RESULT_INIT_ERROR, "libMagickCore-6.Q16HDRI" FF_LIBRARY_EXTENSION, 8, "libMagickCore-6.Q16" FF_LIBRARY_EXTENSION, 8)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
|
||||
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||
.resizeFunc = logoResize,
|
||||
.library = imageMagick,
|
||||
});
|
||||
|
||||
imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -21,10 +21,13 @@ FFLogoImageResult ffLogoPrintImageIM7(FFLogoRequestData* requestData)
|
||||
)
|
||||
FF_LIBRARY_LOAD_SYMBOL_ADDRESS(imageMagick, ffResizeImage, ResizeImage, FF_LOGO_IMAGE_RESULT_INIT_ERROR);
|
||||
|
||||
return ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||
FFLogoImageResult result = ffLogoPrintImageImpl(requestData, &(FFIMData) {
|
||||
.resizeFunc = logoResize,
|
||||
.library = imageMagick,
|
||||
});
|
||||
|
||||
imageMagick = NULL; // leak imageMagick to prevent fastfetch from crashing #552
|
||||
return result;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_DISKIO_DISPLAY_NAME "Disk IO"
|
||||
#define FF_DISKIO_NUM_FORMAT_ARGS 11
|
||||
#define FF_DISKIO_NUM_FORMAT_ARGS 8
|
||||
|
||||
static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right)
|
||||
{
|
||||
@@ -17,10 +17,7 @@ static void formatKey(const FFDiskIOOptions* options, FFDiskIOResult* dev, uint3
|
||||
{
|
||||
if(options->moduleArgs.key.length == 0)
|
||||
{
|
||||
if(!dev->name.length)
|
||||
ffStrbufSetF(&dev->name, "unknown %u", (unsigned) index);
|
||||
|
||||
ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.chars);
|
||||
ffStrbufSetF(key, FF_DISKIO_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -74,34 +71,15 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
|
||||
ffParseSize(dev->bytesWritten, &buffer2);
|
||||
ffStrbufAppendS(&buffer2, "/s");
|
||||
|
||||
const char* physicalType;
|
||||
switch(dev->type)
|
||||
{
|
||||
case FF_DISKIO_PHYSICAL_TYPE_HDD:
|
||||
physicalType = "HDD";
|
||||
break;
|
||||
case FF_DISKIO_PHYSICAL_TYPE_SSD:
|
||||
physicalType = "SSD";
|
||||
break;
|
||||
default:
|
||||
physicalType = "Unknown";
|
||||
break;
|
||||
}
|
||||
FF_STRBUF_AUTO_DESTROY sizePretty = ffStrbufCreate();
|
||||
ffParseSize(dev->size, &sizePretty);
|
||||
|
||||
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_DISKIO_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer2},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesRead},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->bytesWritten},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->readCount},
|
||||
{FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &sizePretty},
|
||||
});
|
||||
}
|
||||
++index;
|
||||
@@ -110,7 +88,6 @@ void ffPrintDiskIO(FFDiskIOOptions* options)
|
||||
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
|
||||
{
|
||||
ffStrbufDestroy(&dev->name);
|
||||
ffStrbufDestroy(&dev->interconnect);
|
||||
ffStrbufDestroy(&dev->devPath);
|
||||
}
|
||||
}
|
||||
@@ -181,33 +158,16 @@ void ffGenerateDiskIOJsonResult(FFDiskIOOptions* options, yyjson_mut_doc* doc, y
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "interconnectType", &dev->interconnect);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
|
||||
|
||||
switch(dev->type)
|
||||
{
|
||||
case FF_DISKIO_PHYSICAL_TYPE_HDD:
|
||||
yyjson_mut_obj_add_str(doc, obj, "physicalType", "HDD");
|
||||
break;
|
||||
case FF_DISKIO_PHYSICAL_TYPE_SSD:
|
||||
yyjson_mut_obj_add_str(doc, obj, "physicalType", "SSD");
|
||||
break;
|
||||
default:
|
||||
yyjson_mut_obj_add_null(doc, obj, "physicalType");
|
||||
break;
|
||||
}
|
||||
|
||||
yyjson_mut_obj_add_uint(doc, obj, "bytesRead", dev->bytesRead);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "bytesWritten", dev->bytesWritten);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "readCount", dev->readCount);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "writeCount", dev->writeCount);
|
||||
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFDiskIOResult, dev, result)
|
||||
{
|
||||
ffStrbufDestroy(&dev->name);
|
||||
ffStrbufDestroy(&dev->interconnect);
|
||||
ffStrbufDestroy(&dev->devPath);
|
||||
}
|
||||
}
|
||||
@@ -218,14 +178,11 @@ void ffPrintDiskIOHelpFormat(void)
|
||||
"Size of data read per second (formatted)",
|
||||
"Size of data written per second (formatted)",
|
||||
"Device name",
|
||||
"Device interconnect type",
|
||||
"Device physical type (SSD / HDD)",
|
||||
"Device raw file path",
|
||||
"Size of data read per second (in bytes)",
|
||||
"Size of data written per second (in bytes)",
|
||||
"Number of reads",
|
||||
"Number of writes",
|
||||
"Device size (formatted)",
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "modules/opencl/opencl.h"
|
||||
#include "modules/os/os.h"
|
||||
#include "modules/packages/packages.h"
|
||||
#include "modules/physicaldisk/physicaldisk.h"
|
||||
#include "modules/player/player.h"
|
||||
#include "modules/poweradapter/poweradapter.h"
|
||||
#include "modules/processes/processes.h"
|
||||
|
||||
@@ -37,6 +37,7 @@
|
||||
#include "modules/opencl/option.h"
|
||||
#include "modules/os/option.h"
|
||||
#include "modules/packages/option.h"
|
||||
#include "modules/physicaldisk/option.h"
|
||||
#include "modules/player/option.h"
|
||||
#include "modules/poweradapter/option.h"
|
||||
#include "modules/processes/option.h"
|
||||
|
||||
@@ -0,0 +1,13 @@
|
||||
#pragma once
|
||||
|
||||
// This file will be included in "fastfetch.h", do NOT put unnecessary things here
|
||||
|
||||
#include "common/option.h"
|
||||
|
||||
typedef struct FFPhysicalDiskOptions
|
||||
{
|
||||
FFModuleBaseInfo moduleInfo;
|
||||
FFModuleArgs moduleArgs;
|
||||
|
||||
FFstrbuf namePrefix;
|
||||
} FFPhysicalDiskOptions;
|
||||
@@ -0,0 +1,241 @@
|
||||
#include "common/printing.h"
|
||||
#include "common/jsonconfig.h"
|
||||
#include "common/parsing.h"
|
||||
#include "detection/physicaldisk/physicaldisk.h"
|
||||
#include "modules/physicaldisk/physicaldisk.h"
|
||||
#include "util/stringUtils.h"
|
||||
|
||||
#define FF_PHYSICALDISK_DISPLAY_NAME "Physical Disk"
|
||||
#define FF_PHYSICALDISK_NUM_FORMAT_ARGS 7
|
||||
|
||||
static int sortDevices(const FFPhysicalDiskResult* left, const FFPhysicalDiskResult* right)
|
||||
{
|
||||
return ffStrbufComp(&left->name, &right->name);
|
||||
}
|
||||
|
||||
static void formatKey(const FFPhysicalDiskOptions* options, FFPhysicalDiskResult* dev, uint32_t index, FFstrbuf* key)
|
||||
{
|
||||
if(options->moduleArgs.key.length == 0)
|
||||
{
|
||||
ffStrbufSetF(key, FF_PHYSICALDISK_DISPLAY_NAME " (%s)", dev->name.length ? dev->name.chars : dev->devPath.chars);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffStrbufClear(key);
|
||||
ffParseFormatString(key, &options->moduleArgs.key, 2, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_UINT, &index},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options)
|
||||
{
|
||||
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
|
||||
const char* error = ffDetectPhysicalDisk(&result, options);
|
||||
|
||||
if(error)
|
||||
{
|
||||
ffPrintError(FF_PHYSICALDISK_DISPLAY_NAME, 0, &options->moduleArgs, "%s", error);
|
||||
return;
|
||||
}
|
||||
|
||||
ffListSort(&result, (const void*) sortDevices);
|
||||
|
||||
uint32_t index = 0;
|
||||
FF_STRBUF_AUTO_DESTROY key = ffStrbufCreate();
|
||||
FF_STRBUF_AUTO_DESTROY buffer = ffStrbufCreate();
|
||||
|
||||
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||
{
|
||||
formatKey(options, dev, result.length == 1 ? 0 : index + 1, &key);
|
||||
ffStrbufClear(&buffer);
|
||||
ffParseSize(dev->size, &buffer);
|
||||
|
||||
const char* physicalType = dev->type & FF_PHYSICALDISK_TYPE_HDD
|
||||
? "HDD"
|
||||
: dev->type & FF_PHYSICALDISK_TYPE_SSD
|
||||
? "SSD"
|
||||
: "";
|
||||
const char* removableType = dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE
|
||||
? "Removable"
|
||||
: dev->type & FF_PHYSICALDISK_TYPE_FIXED
|
||||
? "Fixed"
|
||||
: "";
|
||||
|
||||
if(options->moduleArgs.outputFormat.length == 0)
|
||||
{
|
||||
ffPrintLogoAndKey(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_DEFAULT);
|
||||
|
||||
if (physicalType[0] || removableType[0])
|
||||
{
|
||||
ffStrbufAppendS(&buffer, " [");
|
||||
if (physicalType[0])
|
||||
ffStrbufAppendS(&buffer, physicalType);
|
||||
if (removableType[0])
|
||||
{
|
||||
if (physicalType[0])
|
||||
ffStrbufAppendS(&buffer, ", ");
|
||||
ffStrbufAppendS(&buffer, removableType);
|
||||
}
|
||||
ffStrbufAppendC(&buffer, ']');
|
||||
}
|
||||
ffStrbufPutTo(&buffer, stdout);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffParseSize(dev->size, &buffer);
|
||||
ffPrintFormatString(key.chars, 0, &options->moduleArgs, FF_PRINT_TYPE_NO_CUSTOM_KEY, FF_PHYSICALDISK_NUM_FORMAT_ARGS, (FFformatarg[]){
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &buffer},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->name},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->interconnect},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, physicalType},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->devPath},
|
||||
{FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial},
|
||||
{FF_FORMAT_ARG_TYPE_STRING, removableType},
|
||||
});
|
||||
}
|
||||
++index;
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||
{
|
||||
ffStrbufDestroy(&dev->name);
|
||||
ffStrbufDestroy(&dev->interconnect);
|
||||
ffStrbufDestroy(&dev->devPath);
|
||||
ffStrbufDestroy(&dev->serial);
|
||||
}
|
||||
}
|
||||
|
||||
bool ffParsePhysicalDiskCommandOptions(FFPhysicalDiskOptions* options, const char* key, const char* value)
|
||||
{
|
||||
const char* subKey = ffOptionTestPrefix(key, FF_PHYSICALDISK_MODULE_NAME);
|
||||
if (!subKey) return false;
|
||||
if (ffOptionParseModuleArgs(key, subKey, value, &options->moduleArgs))
|
||||
return true;
|
||||
|
||||
if (ffStrEqualsIgnCase(subKey, "name-prefix"))
|
||||
{
|
||||
ffOptionParseString(key, value, &options->namePrefix);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
void ffParsePhysicalDiskJsonObject(FFPhysicalDiskOptions* options, yyjson_val* module)
|
||||
{
|
||||
yyjson_val *key_, *val;
|
||||
size_t idx, max;
|
||||
yyjson_obj_foreach(module, idx, max, key_, val)
|
||||
{
|
||||
const char* key = yyjson_get_str(key_);
|
||||
if(ffStrEqualsIgnCase(key, "type"))
|
||||
continue;
|
||||
|
||||
if (ffJsonConfigParseModuleArgs(key, val, &options->moduleArgs))
|
||||
continue;
|
||||
|
||||
if (ffStrEqualsIgnCase(key, "namePrefix"))
|
||||
{
|
||||
ffStrbufSetS(&options->namePrefix, yyjson_get_str(val));
|
||||
continue;
|
||||
}
|
||||
|
||||
ffPrintError(FF_PHYSICALDISK_MODULE_NAME, 0, &options->moduleArgs, "Unknown JSON key %s", key);
|
||||
}
|
||||
}
|
||||
|
||||
void ffGeneratePhysicalDiskJsonConfig(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
__attribute__((__cleanup__(ffDestroyPhysicalDiskOptions))) FFPhysicalDiskOptions defaultOptions;
|
||||
ffInitPhysicalDiskOptions(&defaultOptions);
|
||||
|
||||
ffJsonConfigGenerateModuleArgsConfig(doc, module, &defaultOptions.moduleArgs, &options->moduleArgs);
|
||||
|
||||
if (!ffStrbufEqual(&options->namePrefix, &defaultOptions.namePrefix))
|
||||
yyjson_mut_obj_add_strbuf(doc, module, "namePrefix", &options->namePrefix);
|
||||
}
|
||||
|
||||
void ffGeneratePhysicalDiskJsonResult(FFPhysicalDiskOptions* options, yyjson_mut_doc* doc, yyjson_mut_val* module)
|
||||
{
|
||||
FF_LIST_AUTO_DESTROY result = ffListCreate(sizeof(FFPhysicalDiskResult));
|
||||
const char* error = ffDetectPhysicalDisk(&result, options);
|
||||
|
||||
if(error)
|
||||
{
|
||||
yyjson_mut_obj_add_str(doc, module, "error", error);
|
||||
return;
|
||||
}
|
||||
|
||||
yyjson_mut_val* arr = yyjson_mut_obj_add_arr(doc, module, "result");
|
||||
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||
{
|
||||
yyjson_mut_val* obj = yyjson_mut_arr_add_obj(doc, arr);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "name", &dev->name);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "devPath", &dev->devPath);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "interconnect", &dev->interconnect);
|
||||
|
||||
if (dev->type & FF_PHYSICALDISK_TYPE_HDD)
|
||||
yyjson_mut_obj_add_str(doc, obj, "kind", "HDD");
|
||||
else if (dev->type & FF_PHYSICALDISK_TYPE_SSD)
|
||||
yyjson_mut_obj_add_str(doc, obj, "kind", "SSD");
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, obj, "kind");
|
||||
|
||||
yyjson_mut_obj_add_uint(doc, obj, "size", dev->size);
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial);
|
||||
|
||||
if (dev->type & FF_PHYSICALDISK_TYPE_REMOVABLE)
|
||||
yyjson_mut_obj_add_bool(doc, obj, "removable", true);
|
||||
else if (dev->type & FF_PHYSICALDISK_TYPE_FIXED)
|
||||
yyjson_mut_obj_add_bool(doc, obj, "removable", false);
|
||||
else
|
||||
yyjson_mut_obj_add_null(doc, obj, "removable");
|
||||
}
|
||||
|
||||
FF_LIST_FOR_EACH(FFPhysicalDiskResult, dev, result)
|
||||
{
|
||||
ffStrbufDestroy(&dev->name);
|
||||
ffStrbufDestroy(&dev->interconnect);
|
||||
ffStrbufDestroy(&dev->devPath);
|
||||
}
|
||||
}
|
||||
|
||||
void ffPrintPhysicalDiskHelpFormat(void)
|
||||
{
|
||||
ffPrintModuleFormatHelp(FF_PHYSICALDISK_MODULE_NAME, "{1}", FF_PHYSICALDISK_NUM_FORMAT_ARGS, (const char* []) {
|
||||
"Device size (formatted)",
|
||||
"Device name",
|
||||
"Device interconnect type",
|
||||
"Device raw file path",
|
||||
"Serial number",
|
||||
"Device kind (SSD or HDD)",
|
||||
"Device kind (Removable or Fixed)",
|
||||
});
|
||||
}
|
||||
|
||||
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options)
|
||||
{
|
||||
ffOptionInitModuleBaseInfo(
|
||||
&options->moduleInfo,
|
||||
FF_PHYSICALDISK_MODULE_NAME,
|
||||
"Print physical disk information",
|
||||
ffParsePhysicalDiskCommandOptions,
|
||||
ffParsePhysicalDiskJsonObject,
|
||||
ffPrintPhysicalDisk,
|
||||
ffGeneratePhysicalDiskJsonResult,
|
||||
ffPrintPhysicalDiskHelpFormat,
|
||||
ffGeneratePhysicalDiskJsonConfig
|
||||
);
|
||||
ffOptionInitModuleArg(&options->moduleArgs);
|
||||
|
||||
ffStrbufInit(&options->namePrefix);
|
||||
}
|
||||
|
||||
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options)
|
||||
{
|
||||
ffOptionDestroyModuleArg(&options->moduleArgs);
|
||||
ffStrbufDestroy(&options->namePrefix);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#pragma once
|
||||
|
||||
#include "fastfetch.h"
|
||||
|
||||
#define FF_PHYSICALDISK_MODULE_NAME "PhysicalDisk"
|
||||
|
||||
void ffPrintPhysicalDisk(FFPhysicalDiskOptions* options);
|
||||
void ffInitPhysicalDiskOptions(FFPhysicalDiskOptions* options);
|
||||
void ffDestroyPhysicalDiskOptions(FFPhysicalDiskOptions* options);
|
||||
+41
-4
@@ -30,7 +30,24 @@ const char* ffOptionsParseGeneralJsonConfig(FFOptionsGeneral* options, yyjson_va
|
||||
else if (ffStrEqualsIgnCase(key, "osFile"))
|
||||
ffStrbufSetS(&options->osFile, yyjson_get_str(val));
|
||||
else if (ffStrEqualsIgnCase(key, "dsForceDrm"))
|
||||
options->dsForceDrm = yyjson_get_bool(val);
|
||||
{
|
||||
if (yyjson_is_str(val))
|
||||
{
|
||||
int value;
|
||||
const char* error = ffJsonConfigParseEnum(val, &value, (FFKeyValuePair[]) {
|
||||
{ "sysfs-only", FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY },
|
||||
{ "false", FF_DS_FORCE_DRM_TYPE_FALSE },
|
||||
{ "true", FF_DS_FORCE_DRM_TYPE_TRUE },
|
||||
{},
|
||||
});
|
||||
if (error)
|
||||
return "Invalid enum value of `dsForceDrm`";
|
||||
else
|
||||
options->dsForceDrm = (FFDsForceDrmType) value;
|
||||
}
|
||||
else
|
||||
options->dsForceDrm = yyjson_get_bool(val) ? FF_DS_FORCE_DRM_TYPE_TRUE : FF_DS_FORCE_DRM_TYPE_FALSE;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
else if (ffStrEqualsIgnCase(key, "wmiTimeout"))
|
||||
options->wmiTimeout = (int32_t) yyjson_get_int(val);
|
||||
@@ -65,7 +82,14 @@ bool ffOptionsParseGeneralCommandLine(FFOptionsGeneral* options, const char* key
|
||||
else if (ffStrEqualsIgnCase(key, "--os-file"))
|
||||
ffOptionParseString(key, value, &options->osFile);
|
||||
else if(ffStrEqualsIgnCase(key, "--ds-force-drm"))
|
||||
options->dsForceDrm = ffOptionParseBoolean(value);
|
||||
{
|
||||
if (ffOptionParseBoolean(value))
|
||||
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_TRUE;
|
||||
else if (ffStrEqualsIgnCase(value, "sysfs-only"))
|
||||
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY;
|
||||
else
|
||||
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
|
||||
}
|
||||
#elif defined(_WIN32)
|
||||
else if (ffStrEqualsIgnCase(key, "--wmi-timeout"))
|
||||
options->wmiTimeout = ffOptionParseInt32(key, value);
|
||||
@@ -86,7 +110,7 @@ void ffOptionsInitGeneral(FFOptionsGeneral* options)
|
||||
options->escapeBedrock = true;
|
||||
ffStrbufInit(&options->playerName);
|
||||
ffStrbufInit(&options->osFile);
|
||||
options->dsForceDrm = false;
|
||||
options->dsForceDrm = FF_DS_FORCE_DRM_TYPE_FALSE;
|
||||
#elif defined(_WIN32)
|
||||
options->wmiTimeout = 5000;
|
||||
#endif
|
||||
@@ -125,7 +149,20 @@ void ffOptionsGenerateGeneralJsonConfig(FFOptionsGeneral* options, yyjson_mut_do
|
||||
yyjson_mut_obj_add_strbuf(doc, obj, "osFile", &options->osFile);
|
||||
|
||||
if (options->dsForceDrm != defaultOptions.dsForceDrm)
|
||||
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", options->dsForceDrm);
|
||||
{
|
||||
switch (options->dsForceDrm)
|
||||
{
|
||||
case FF_DS_FORCE_DRM_TYPE_FALSE:
|
||||
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", false);
|
||||
break;
|
||||
case FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY:
|
||||
yyjson_mut_obj_add_str(doc, obj, "dsForceDrm", "sysfs-only");
|
||||
break;
|
||||
case FF_DS_FORCE_DRM_TYPE_TRUE:
|
||||
yyjson_mut_obj_add_bool(doc, obj, "dsForceDrm", true);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(_WIN32)
|
||||
|
||||
|
||||
@@ -2,6 +2,13 @@
|
||||
|
||||
#include "util/FFstrbuf.h"
|
||||
|
||||
typedef enum FFDsForceDrmType
|
||||
{
|
||||
FF_DS_FORCE_DRM_TYPE_FALSE = 0, // Disable
|
||||
FF_DS_FORCE_DRM_TYPE_TRUE = 1, // Try `libdrm`, then `sysfs` if libdrm failed
|
||||
FF_DS_FORCE_DRM_TYPE_SYSFS_ONLY, // Use `/sys/class/drm` only
|
||||
} FFDsForceDrmType;
|
||||
|
||||
typedef struct FFOptionsGeneral
|
||||
{
|
||||
bool multithreading;
|
||||
@@ -12,7 +19,7 @@ typedef struct FFOptionsGeneral
|
||||
FFstrbuf playerName;
|
||||
FFstrbuf osFile;
|
||||
bool escapeBedrock;
|
||||
bool dsForceDrm;
|
||||
FFDsForceDrmType dsForceDrm;
|
||||
#elif defined(_WIN32)
|
||||
int32_t wmiTimeout;
|
||||
#endif
|
||||
|
||||
@@ -38,6 +38,7 @@ void ffOptionsInitModules(FFOptionsModules* options)
|
||||
ffInitOpenCLOptions(&options->openCL);
|
||||
ffInitOpenGLOptions(&options->openGL);
|
||||
ffInitPackagesOptions(&options->packages);
|
||||
ffInitPhysicalDiskOptions(&options->physicalDisk);
|
||||
ffInitPlayerOptions(&options->player);
|
||||
ffInitPowerAdapterOptions(&options->powerAdapter);
|
||||
ffInitProcessesOptions(&options->processes);
|
||||
@@ -98,6 +99,7 @@ void ffOptionsDestroyModules(FFOptionsModules* options)
|
||||
ffDestroyOSOptions(&options->os);
|
||||
ffDestroyOpenCLOptions(&options->openCL);
|
||||
ffDestroyOpenGLOptions(&options->openGL);
|
||||
ffDestroyPhysicalDiskOptions(&options->physicalDisk);
|
||||
ffDestroyPackagesOptions(&options->packages);
|
||||
ffDestroyPlayerOptions(&options->player);
|
||||
ffDestroyPowerAdapterOptions(&options->powerAdapter);
|
||||
|
||||
@@ -39,6 +39,7 @@ typedef struct FFOptionsModules
|
||||
FFOpenCLOptions openCL;
|
||||
FFOpenGLOptions openGL;
|
||||
FFPackagesOptions packages;
|
||||
FFPhysicalDiskOptions physicalDisk;
|
||||
FFPlayerOptions player;
|
||||
FFPowerAdapterOptions powerAdapter;
|
||||
FFProcessesOptions processes;
|
||||
|
||||
+5
-3
@@ -59,9 +59,9 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
|
||||
uint32_t oldFree = ffStrbufGetFree(strbuf);
|
||||
if (oldFree >= free && !(strbuf->allocated == 0 && strbuf->length > 0))
|
||||
return;
|
||||
|
||||
|
||||
uint32_t newCap = strbuf->allocated + (free - oldFree);
|
||||
|
||||
|
||||
if(strbuf->allocated == 0)
|
||||
{
|
||||
newCap += strbuf->length + 1; // +1 for the NUL
|
||||
@@ -74,7 +74,7 @@ void ffStrbufEnsureFixedLengthFree(FFstrbuf* strbuf, uint32_t free)
|
||||
}
|
||||
else
|
||||
strbuf->chars = realloc(strbuf->chars, sizeof(*strbuf->chars) * newCap);
|
||||
|
||||
|
||||
strbuf->allocated = newCap;
|
||||
}
|
||||
|
||||
@@ -99,6 +99,8 @@ void ffStrbufAppendC(FFstrbuf* strbuf, char c)
|
||||
|
||||
void ffStrbufAppendNC(FFstrbuf* strbuf, uint32_t num, char c)
|
||||
{
|
||||
if (num == 0) return;
|
||||
|
||||
ffStrbufEnsureFree(strbuf, num);
|
||||
memset(&strbuf->chars[strbuf->length], c, num);
|
||||
strbuf->length += num;
|
||||
|
||||
@@ -20,7 +20,7 @@ static void getExePath(FFPlatform* platform)
|
||||
FFstrbuf* const exePath = &platform->exePath;
|
||||
ffStrbufEnsureFree(exePath, PATH_MAX);
|
||||
#ifdef __linux__
|
||||
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated);
|
||||
ssize_t exePathLen = readlink("/proc/self/exe", exePath->chars, exePath->allocated - 1);
|
||||
#elif defined(__APPLE__)
|
||||
int exePathLen = proc_pidpath((int) getpid(), exePath->chars, exePath->allocated);
|
||||
#elif defined(__FreeBSD__)
|
||||
|
||||
@@ -18,6 +18,8 @@ bool ffIsSmbiosValueSet(FFstrbuf* value)
|
||||
!ffStrbufIgnCaseEqualS(value, "Undefined") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "Not Specified") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "Not Applicable") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "Not Defined") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "Not Available") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "INVALID") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "Type1ProductConfigId") &&
|
||||
!ffStrbufIgnCaseEqualS(value, "All Series") &&
|
||||
|
||||
Reference in New Issue
Block a user