From 40aa4a60d6cd8cccc979cb1d117c45b6425e5600 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 8 Dec 2023 09:30:17 +0800 Subject: [PATCH 01/53] Packages: improve performance of pkg and rpm detection --- CMakeLists.txt | 2 +- src/detection/packages/packages_bsd.c | 8 ++++++++ src/detection/packages/packages_linux.c | 9 +++------ 3 files changed, 12 insertions(+), 7 deletions(-) create mode 100644 src/detection/packages/packages_bsd.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 12807993e..16810ecee 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -529,7 +529,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 diff --git a/src/detection/packages/packages_bsd.c b/src/detection/packages/packages_bsd.c new file mode 100644 index 000000000..cb9091457 --- /dev/null +++ b/src/detection/packages/packages_bsd.c @@ -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"); +} diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index ef5d1162d..0b608497c 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -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; } @@ -265,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); @@ -281,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); From a19888bb33e38b11881dead8c055da08420ea08b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 8 Dec 2023 10:16:10 +0800 Subject: [PATCH 02/53] CI: don't run cpuusage in FreeBSD, which seems to have issues when running in VM --- presets/ci.jsonc | 1 - 1 file changed, 1 deletion(-) diff --git a/presets/ci.jsonc b/presets/ci.jsonc index 766a08bb5..44b390368 100644 --- a/presets/ci.jsonc +++ b/presets/ci.jsonc @@ -35,7 +35,6 @@ "terminalfont", "terminalsize", "cpu", - "cpuusage", "gpu", "memory", "swap", From 77cc0c61d70a601d3d83f94578b2a4278c232fa7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 8 Dec 2023 10:16:18 +0800 Subject: [PATCH 03/53] Doc: update changelog --- CHANGELOG.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff02b1cac..318ab09d3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,8 @@ +# 2.3.5 + +Features: +* Improve performance of detecting rpm and pkg package count (Packages, Linux / FreeBSD) + # 2.3.4 Bugfixes: From 4925222dabebcdbe6b948a5d948434870a8fec22 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 8 Dec 2023 10:58:11 +0800 Subject: [PATCH 04/53] CI: run basic modules only in FreeBSD --- .github/workflows/ci.yml | 4 ++-- presets/ci.jsonc | 1 + 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index f15eae60f..563936012 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -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 diff --git a/presets/ci.jsonc b/presets/ci.jsonc index 44b390368..766a08bb5 100644 --- a/presets/ci.jsonc +++ b/presets/ci.jsonc @@ -35,6 +35,7 @@ "terminalfont", "terminalsize", "cpu", + "cpuusage", "gpu", "memory", "swap", From f20b6d438714943f77c787857b719bf4b504ff8b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 8 Dec 2023 15:59:58 +0800 Subject: [PATCH 05/53] Temps (macOS): support Apple M3 --- CHANGELOG.md | 1 + src/detection/cpu/cpu_apple.c | 14 ++++++++---- src/detection/gpu/gpu_apple.c | 22 ++++++++++++------- src/detection/temps/temps_apple.c | 36 ++++++++++++++++++++++++++++++- src/detection/temps/temps_apple.h | 2 ++ 5 files changed, 62 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 318ab09d3..8f3160625 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ Features: * Improve performance of detecting rpm and pkg package count (Packages, Linux / FreeBSD) +* Support Apple M3X temperature detection (CPU / GPU, macOS) # 2.3.4 diff --git a/src/detection/cpu/cpu_apple.c b/src/detection/cpu/cpu_apple.c index 418ab2165..e75dbc1c8 100644 --- a/src/detection/cpu/cpu_apple.c +++ b/src/detection/cpu/cpu_apple.c @@ -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); diff --git a/src/detection/gpu/gpu_apple.c b/src/detection/gpu/gpu_apple.c index 616a62cc9..bb734596d 100644 --- a/src/detection/gpu/gpu_apple.c +++ b/src/detection/gpu/gpu_apple.c @@ -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; diff --git a/src/detection/temps/temps_apple.c b/src/detection/temps/temps_apple.c index 7054a3ed3..b274c49e0 100644 --- a/src/detection/temps/temps_apple.c +++ b/src/detection/temps/temps_apple.c @@ -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; } diff --git a/src/detection/temps/temps_apple.h b/src/detection/temps/temps_apple.h index 7d340ba22..ccf914311 100644 --- a/src/detection/temps/temps_apple.h +++ b/src/detection/temps/temps_apple.h @@ -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, From a28dc8a9bfc646ecfbb249794ac7f0eac1799ba6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 11 Dec 2023 13:25:58 +0800 Subject: [PATCH 06/53] DisplayServer (Linux): support `--ds-force-drm sysfs-only` --- CHANGELOG.md | 1 + doc/json_schema.json | 21 +++++++-- src/data/help.json | 9 +++- .../displayserver/linux/displayserver_linux.c | 2 +- src/detection/displayserver/linux/drm.c | 7 ++- src/options/general.c | 45 +++++++++++++++++-- src/options/general.h | 9 +++- 7 files changed, 81 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8f3160625..b4a84c112 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ 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` # 2.3.4 diff --git a/doc/json_schema.json b/doc/json_schema.json index 091770f46..99b908c63 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -251,9 +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", - "default": false + "description": "Force display detection to use DRM. Linux only", + "oneOf": [ + { + "type": "bool", + "const": false, + "description": "Try `libdrm` first, then `sysfs` if libdrm failed" + }, + { + "type": "string", + "description": "Use `/sys/class/drm` only.", + "const": "sysfs-only" + }, + { + "type": "bool", + "const": true, + "description": "Don't force using DRM" + } + ] }, "wmiTimeout": { "type": "integer", diff --git a/src/data/help.json b/src/data/help.json index f72a94a2d..8dcd3c03a 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -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": "Don't force using DRM" + } } } ], diff --git a/src/detection/displayserver/linux/displayserver_linux.c b/src/detection/displayserver/linux/displayserver_linux.c index d6eb3da99..e75e311b0 100644 --- a/src/detection/displayserver/linux/displayserver_linux.c +++ b/src/detection/displayserver/linux/displayserver_linux.c @@ -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 diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c index baf4e4bdf..4adffe6be 100644 --- a/src/detection/displayserver/linux/drm.c +++ b/src/detection/displayserver/linux/drm.c @@ -285,8 +285,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); diff --git a/src/options/general.c b/src/options/general.c index 6357e04b8..7cec888f7 100644 --- a/src/options/general.c +++ b/src/options/general.c @@ -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) diff --git a/src/options/general.h b/src/options/general.h index 156991028..98667c2f8 100644 --- a/src/options/general.h +++ b/src/options/general.h @@ -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 From 165c213ed022edc543588ba22e8d8c692fcc3fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 11 Dec 2023 14:00:50 +0800 Subject: [PATCH 07/53] FFstrbuf: don't crash with `ffStrbufAppendNC(&str, 0, 'c')` --- CHANGELOG.md | 3 +++ src/util/FFstrbuf.c | 8 +++++--- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index b4a84c112..81ef5bfcc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,9 @@ Features: * Support Apple M3X temperature detection (CPU / GPU, macOS) * `--ds-force-drm` support a new option `sysfs-only` +Bugfixes: +* Fix crashes sometimes when `--logo-padding-top` is not set (Logo) + # 2.3.4 Bugfixes: diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 574324f7a..6dfe59589 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -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; From 663d568927430f7e956149e886ad89c9e367be41 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 11 Dec 2023 16:36:12 +0800 Subject: [PATCH 08/53] DE (Linux): fix xfce4 version detection --- src/detection/de/de_linux.c | 33 +++++++++++++-------------------- 1 file changed, 13 insertions(+), 20 deletions(-) diff --git a/src/detection/de/de_linux.c b/src/detection/de/de_linux.c index 1e800bc8f..90326c226 100644 --- a/src/detection/de/de_linux.c +++ b/src/detection/de/de_linux.c @@ -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", "

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, ' '); } } From 0555fb97e89ccd7a0daa45c82ccd0fab0df802cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 12 Dec 2023 09:50:36 +0800 Subject: [PATCH 09/53] TerminalShell (Linux): tidy --- .../terminalshell/terminalshell_linux.c | 32 +++++++++---------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 7fa216f16..a974ecc1b 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -68,8 +68,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 +84,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 +104,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) From 453f4757ed9284c2c9c0e2a27bf361796f9c3586 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 12 Dec 2023 10:06:01 +0800 Subject: [PATCH 10/53] DE (FreeBSD): support detection with processes --- .gitignore | 1 + src/detection/displayserver/linux/wmde.c | 59 +++++++++++++++++++----- 2 files changed, 48 insertions(+), 12 deletions(-) diff --git a/.gitignore b/.gitignore index 94a0919c6..6a7a19529 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,4 @@ cscope.* tags fastfetch.kdev4 +*.user diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index 740050b46..5eaeab15a 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -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 #include #include #include -#include + +#ifdef __FreeBSD__ + #include + #include + #include +#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; } @@ -244,23 +252,49 @@ static void getWMProtocolNameFromEnv(FFDisplayServerResult* result) } } -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 +306,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 +331,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 +373,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( From a565dcfb9edf86f30d5ecba4e5fd2595b9060b75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Tue, 12 Dec 2023 10:12:12 +0800 Subject: [PATCH 11/53] Doc: update changelog Fix: #655 --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 81ef5bfcc..c07d14ec3 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,8 @@ 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 +* Improve detection (WM / DE, FreeBSD) Bugfixes: * Fix crashes sometimes when `--logo-padding-top` is not set (Logo) From b63e6a30530ccdb1fd5a86b9d519f47a09723ad1 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 12 Dec 2023 18:20:02 +0800 Subject: [PATCH 12/53] DE (Linux): add support for CDE Fix #658 --- src/detection/displayserver/displayserver.h | 2 ++ src/detection/displayserver/linux/wmde.c | 9 +++++++++ 2 files changed, 11 insertions(+) diff --git a/src/detection/displayserver/displayserver.h b/src/detection/displayserver/displayserver.h index 7a5ebb8f8..b5655a84f 100644 --- a/src/detection/displayserver/displayserver.h +++ b/src/detection/displayserver/displayserver.h @@ -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" diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index 5eaeab15a..5f421ff0e 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -114,6 +114,8 @@ static void applyPrettyNameIfWM(FFDisplayServerResult* result, const char* name) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_HERBSTLUFTWM); else if(strcasecmp(name, "icewm") == 0) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_ICEWM); + else if(strcasecmp(name, "dtwm") == 0) + ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM); } static void applyNameIfWM(FFDisplayServerResult* result, const char* processName) @@ -217,6 +219,13 @@ static void applyPrettyNameIfDE(FFDisplayServerResult* result, const char* name) ffStrbufSetS(&result->deProcessName, "budgie-desktop"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_BUDGIE); } + + else if( + strcasecmp(name, "dtsession") == 0 + ) { + ffStrbufSetS(&result->deProcessName, "dtsession"); + ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CDE); + } } static void getWMProtocolNameFromEnv(FFDisplayServerResult* result) From 25a792743b7fcb7503c0a8a8278510e834d733ba Mon Sep 17 00:00:00 2001 From: Carter Li Date: Tue, 12 Dec 2023 18:22:20 +0800 Subject: [PATCH 13/53] WMDE: tidy --- src/detection/displayserver/linux/wmde.c | 114 +++++++++++------------ 1 file changed, 57 insertions(+), 57 deletions(-) diff --git a/src/detection/displayserver/linux/wmde.c b/src/detection/displayserver/linux/wmde.c index 5f421ff0e..971b14d29 100644 --- a/src/detection/displayserver/linux/wmde.c +++ b/src/detection/displayserver/linux/wmde.c @@ -68,53 +68,53 @@ 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(strcasecmp(name, "dtwm") == 0) + else if(ffStrEqualsIgnCase(name, "dtwm")) ffStrbufSetS(&result->wmPrettyName, FF_WM_PRETTY_DTWM); } @@ -146,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); @@ -157,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"); @@ -171,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); @@ -211,17 +211,17 @@ 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( - strcasecmp(name, "dtsession") == 0 + ffStrEqualsIgnCase(name, "dtsession") ) { ffStrbufSetS(&result->deProcessName, "dtsession"); ffStrbufSetS(&result->dePrettyName, FF_DE_PRETTY_CDE); @@ -236,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); @@ -254,7 +254,7 @@ 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; From f62cdff92433942a24dbe240cf7090e49c5f4315 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Wed, 13 Dec 2023 02:56:13 -0600 Subject: [PATCH 14/53] README: add start history --- README.md | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/README.md b/README.md index a606dc872..254b4cff9 100644 --- a/README.md +++ b/README.md @@ -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! + + + + + + Star History Chart + + From 8ed5d30b3e4bfea6c29e05ce52265dba14eff527 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Wed, 13 Dec 2023 19:32:28 +0800 Subject: [PATCH 15/53] Wifi (Windows): use less magic numbers --- src/detection/wifi/wifi_windows.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/src/detection/wifi/wifi_windows.c b/src/detection/wifi/wifi_windows.c index 3b7ac5a1c..18638c046 100644 --- a/src/detection/wifi/wifi_windows.c +++ b/src/detection/wifi/wifi_windows.c @@ -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 */: From 833727f333a462075e257f5407f5cac6148b4e1c Mon Sep 17 00:00:00 2001 From: "Horst G. Burkhardt" Date: Thu, 14 Dec 2023 06:56:09 +0000 Subject: [PATCH 16/53] remove unnecessary escaping for Adelie logo --- src/logo/ascii/adelie.txt | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/src/logo/ascii/adelie.txt b/src/logo/ascii/adelie.txt index df46e57a0..417b5eb04 100644 --- a/src/logo/ascii/adelie.txt +++ b/src/logo/ascii/adelie.txt @@ -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}\\\\\ From 8048101eca4eb492e55f8b9a4db470fdf7818aee Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Dec 2023 15:49:43 +0800 Subject: [PATCH 17/53] Doc: fix documentation of `--ds-force-drm` --- doc/json_schema.json | 7 ++++--- src/data/help.json | 2 +- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index 99b908c63..9e9fa4914 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -256,7 +256,7 @@ { "type": "bool", "const": false, - "description": "Try `libdrm` first, then `sysfs` if libdrm failed" + "description": "Try `wayland`, then `x11`, then `drm`" }, { "type": "string", @@ -266,9 +266,10 @@ { "type": "bool", "const": true, - "description": "Don't force using DRM" + "description": "Try `libdrm` first, then `sysfs` if libdrm failed" } - ] + ], + "default": false }, "wmiTimeout": { "type": "integer", diff --git a/src/data/help.json b/src/data/help.json index 8dcd3c03a..232598eda 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -130,7 +130,7 @@ "enum": { "true": "Try `libdrm` first, then `sysfs` if libdrm failed", "sysfs-only": "Use `/sys/class/drm` only", - "false": "Don't force using DRM" + "false": "Try `wayland`, then `x11`, then `drm`" } } } From e804dfc49e6a51c90b272ad57bd88d04ad135b01 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Thu, 14 Dec 2023 16:12:19 +0800 Subject: [PATCH 18/53] Memory (macOS): align algo of memory usage counting to `stats` Which seems to print the same result of neofetch --- CHANGELOG.md | 1 + src/detection/memory/memory_apple.c | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index c07d14ec3..e40e54deb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ Features: Bugfixes: * Fix crashes sometimes when `--logo-padding-top` is not set (Logo) +* Fix memory usage counting algorithm (Memory, macOS) # 2.3.4 diff --git a/src/detection/memory/memory_apple.c b/src/detection/memory/memory_apple.c index b3a50a1eb..19e67f1a4 100644 --- a/src/detection/memory/memory_apple.c +++ b/src/detection/memory/memory_apple.c @@ -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; } From 224a6a9881473fbf89bfa3de90dd2ec40977ebf7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Fri, 15 Dec 2023 14:29:51 +0800 Subject: [PATCH 19/53] TerminalShell: code cleanup --- src/detection/terminalshell/terminalshell.c | 26 +++++++++++++++- .../terminalshell/terminalshell_linux.c | 30 ++----------------- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/detection/terminalshell/terminalshell.c b/src/detection/terminalshell/terminalshell.c index d54e1cc61..68b963e07 100644 --- a/src/detection/terminalshell/terminalshell.c +++ b/src/detection/terminalshell/terminalshell.c @@ -4,6 +4,8 @@ #include "common/properties.h" #include "util/stringUtils.h" +#include + #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 } diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index a974ecc1b..3fde133c4 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -5,7 +5,6 @@ #include "common/thread.h" #include "util/stringUtils.h" -#include #include #include #include @@ -284,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() @@ -348,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"); From 10e1753c036b6bafc71b741e69504ec1d1b723c5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 00:41:59 +0800 Subject: [PATCH 20/53] DisplayServer (Linux): better handling abnormal situations Try fix #660 --- src/detection/displayserver/linux/drm.c | 166 ++++++++++++++++++------ 1 file changed, 123 insertions(+), 43 deletions(-) diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c index 4adffe6be..1f5730128 100644 --- a/src/detection/displayserver/linux/drm.c +++ b/src/detection/displayserver/linux/drm.c @@ -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,16 +301,29 @@ 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); @@ -237,42 +332,27 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) ffStrbufSetF(&name, "%s-%d", connectorTypeName, iConn); } - 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); From 8fa073b1e45b3846f24c026653fb99f9399dc9d4 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 17 Dec 2023 01:00:21 +0800 Subject: [PATCH 21/53] DisplayServer (Linux): test for `status` instead of `enabled` --- src/detection/displayserver/linux/drm.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/detection/displayserver/linux/drm.c b/src/detection/displayserver/linux/drm.c index 1f5730128..cf6bf3cde 100644 --- a/src/detection/displayserver/linux/drm.c +++ b/src/detection/displayserver/linux/drm.c @@ -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; @@ -329,7 +329,7 @@ static const char* drmConnectLibdrm(FFDisplayServerResult* result) 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); } ffdsAppendDisplay(result, From 335022e034cb168e46b2a95cb96d3be05e8a636d Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 17 Dec 2023 09:10:11 +0800 Subject: [PATCH 22/53] SMBIOS: ignore more meaningless values --- src/util/smbiosHelper.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/util/smbiosHelper.c b/src/util/smbiosHelper.c index 1033ec880..88249f6d8 100644 --- a/src/util/smbiosHelper.c +++ b/src/util/smbiosHelper.c @@ -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") && From f91a8aea4dada6fd8e1b5c892d5ffb097c2ad7d0 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 17 Dec 2023 10:38:16 +0800 Subject: [PATCH 23/53] DiskIO (Linux): improve detection 1. Ignore `dm-*` 2. Add devices that don't have disk ids 3. Fix device size detection --- src/detection/diskio/diskio_linux.c | 157 ++++++++++++++++------------ 1 file changed, 89 insertions(+), 68 deletions(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index 3737789be..9f8e0c98c 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -7,80 +7,81 @@ 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")])) + if (ffStrStartsWith(devName, "dm-")) // LVM logical partitions 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); - FF_AUTO_CLOSE_FILE FILE* sysBlockStat = fopen(pathSysBlock, "r"); - if (!sysBlockStat) continue; + char blockId[256] = ""; + { + FF_AUTO_CLOSE_DIR DIR* devDiskDirp = opendir("/dev/disk/by-id"); + if (devDiskDirp) + { + struct dirent* devDiskEntry; + while ((devDiskEntry = readdir(devDiskDirp)) != NULL) + { + if (devDiskEntry->d_name[0] == '.') + continue; - // 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) - continue; + char pathDevDisk[PATH_MAX]; + snprintf(pathDevDisk, PATH_MAX, "/dev/disk/by-id/%s", devDiskEntry->d_name); + + char pathDev[PATH_MAX]; + ssize_t pathLen = readlink(pathDevDisk, pathDev, sizeof(pathDev) - 1); + if (pathLen > 0) + { + pathDev[pathLen] = '\0'; + if (!ffStrEquals(basename(pathDev), devName)) + continue; + + if (ffStrStartsWith(devDiskEntry->d_name, "nvme-eui.")) // NVMe drive identifier + continue; + + strcpy(blockId, devDiskEntry->d_name); + break; + } + } + } + } FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); - char* slash = strchr(entry->d_name, '-'); - if (slash) + + if (blockId[0]) { - char* slash2 = strchr(slash + 1, '-'); - if (slash2) - ffStrbufInitNS(&device->name, (uint32_t) (slash2 - slash - 1), slash + 1); + char* slash = strchr(blockId, '-'); + 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 - blockId), blockId); + } else - ffStrbufInitS(&device->name, slash + 1); - ffStrbufInitNS(&device->interconnect, (uint32_t) (slash - entry->d_name), entry->d_name); + { + ffStrbufInitS(&device->name, blockId); + ffStrbufInit(&device->interconnect); + } + ffStrbufReplaceAllC(&device->name, '_', ' '); } else { - ffStrbufInitS(&device->name, entry->d_name); + ffStrbufInitS(&device->name, devName); ffStrbufInit(&device->interconnect); } - ffStrbufReplaceAllC(&device->name, '_', ' '); if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) { @@ -90,24 +91,44 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) 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/queue/rotational", devName); + char isRotationalChar = '1'; + if (ffReadFileData(pathSysBlock, 1, &isRotationalChar)) + device->type = isRotationalChar = '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; + { + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/size", devName); + ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blockId) - 1, blockId); + if (fileSize > 0) + { + blockId[fileSize] = 0; + device->size = (uint64_t) strtoul(blockId, NULL, 10) * 512; + } + else + device->size = 0; + } } return NULL; From b3484088e963982a0d17451c5cfcad69697c26db Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 11:46:28 +0800 Subject: [PATCH 24/53] FFPlatform (Linux): tidy --- src/util/platform/FFPlatform_unix.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index 04687f0be..f224c84eb 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -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__) From d32125e98845b7484d14eb6e4adf35eb0139851a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 11:47:05 +0800 Subject: [PATCH 25/53] DiskIO (Linux): improve device name detection --- src/detection/diskio/diskio_linux.c | 99 ++++++++++++----------------- 1 file changed, 40 insertions(+), 59 deletions(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index 9f8e0c98c..b02eb7867 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -24,71 +24,51 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) char pathSysBlock[PATH_MAX]; - char blockId[256] = ""; - { - FF_AUTO_CLOSE_DIR DIR* devDiskDirp = opendir("/dev/disk/by-id"); - if (devDiskDirp) - { - struct dirent* devDiskEntry; - while ((devDiskEntry = readdir(devDiskDirp)) != NULL) - { - if (devDiskEntry->d_name[0] == '.') - continue; - - char pathDevDisk[PATH_MAX]; - snprintf(pathDevDisk, PATH_MAX, "/dev/disk/by-id/%s", devDiskEntry->d_name); - - char pathDev[PATH_MAX]; - ssize_t pathLen = readlink(pathDevDisk, pathDev, sizeof(pathDev) - 1); - if (pathLen > 0) - { - pathDev[pathLen] = '\0'; - if (!ffStrEquals(basename(pathDev), devName)) - continue; - - if (ffStrStartsWith(devDiskEntry->d_name, "nvme-eui.")) // NVMe drive identifier - continue; - - strcpy(blockId, devDiskEntry->d_name); - break; - } - } - } - } + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName); + if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY)) + continue; FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); + ffStrbufInit(&device->name); - if (blockId[0]) { - char* slash = strchr(blockId, '-'); - if (slash) + 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)) { - 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 - blockId), blockId); + ffStrbufDestroy(&device->name); + result->length--; + continue; } - else - { - ffStrbufInitS(&device->name, blockId); - ffStrbufInit(&device->interconnect); - } - ffStrbufReplaceAllC(&device->name, '_', ' '); } - else + { - ffStrbufInitS(&device->name, devName); ffStrbufInit(&device->interconnect); - } + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); + char pathSysDevices[PATH_MAX]; + ssize_t resultLength = readlink(pathSysBlock, pathSysDevices, sizeof(pathSysDevices) - 1); + if (resultLength > 0) + { + pathSysDevices[resultLength] = '\0'; + if (strstr(pathSysDevices, "/usb") != NULL) + ffStrbufSetS(&device->interconnect, "usb"); + } - if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) - { - ffStrbufDestroy(&device->name); - ffStrbufDestroy(&device->interconnect); - result->length--; - continue; + if (device->interconnect.length == 0) + { + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName); + ffAppendFileBuffer(pathSysBlock, &device->interconnect); + } } // I/Os merges sectors ticks ... @@ -113,18 +93,19 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName); char isRotationalChar = '1'; if (ffReadFileData(pathSysBlock, 1, &isRotationalChar)) - device->type = isRotationalChar = '1' ? FF_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD; + device->type = isRotationalChar == '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); - ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blockId) - 1, blockId); + char blkSize[32]; + ssize_t fileSize = ffReadFileData(pathSysBlock, sizeof(blkSize) - 1, blkSize); if (fileSize > 0) { - blockId[fileSize] = 0; - device->size = (uint64_t) strtoul(blockId, NULL, 10) * 512; + blkSize[fileSize] = 0; + device->size = (uint64_t) strtoul(blkSize, NULL, 10) * 512; } else device->size = 0; From 3400e40e4740843d05d86b8d4ec9f6ce7c6d0e74 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 11:48:59 +0800 Subject: [PATCH 26/53] DiskIO (Linux): detect device serial number --- src/detection/diskio/diskio.h | 1 + src/detection/diskio/diskio_linux.c | 6 ++++++ 2 files changed, 7 insertions(+) diff --git a/src/detection/diskio/diskio.h b/src/detection/diskio/diskio.h index 0f8b39f56..11c8918a5 100644 --- a/src/detection/diskio/diskio.h +++ b/src/detection/diskio/diskio.h @@ -13,6 +13,7 @@ typedef struct FFDiskIOResult { FFstrbuf name; FFstrbuf interconnect; + FFstrbuf serial; FFDiskIOPhysicalType type; uint64_t size; FFstrbuf devPath; diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index b02eb7867..8a83c4fc5 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -110,6 +110,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) else device->size = 0; } + + { + ffStrbufInit(&device->serial); + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/serial", devName); + ffReadFileBuffer(pathSysBlock, &device->serial); + } } return NULL; From e071a1eeb26a79e97676c3ac162e9360b70fd831 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 12:13:28 +0800 Subject: [PATCH 27/53] Disk (Linux): improve removable type detection --- src/detection/disk/disk_linux.c | 26 ++++++-------------------- 1 file changed, 6 insertions(+), 20 deletions(-) diff --git a/src/detection/disk/disk_linux.c b/src/detection/disk/disk_linux.c index 0cef2d64b..ae94117c2 100644 --- a/src/detection/disk/disk_linux.c +++ b/src/detection/disk/disk_linux.c @@ -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; } From 529f94c64ad4fd6323b52aa4f03f98736ec3afc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 12:21:12 +0800 Subject: [PATCH 28/53] DiskIO (Linux): better handling virtual devices --- src/detection/diskio/diskio_linux.c | 23 ++++++++++------------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index 8a83c4fc5..f904f672d 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -19,10 +19,15 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) if (devName[0] == '.') continue; - if (ffStrStartsWith(devName, "dm-")) // LVM logical partitions - continue; char pathSysBlock[PATH_MAX]; + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); + + char pathSysDeviceReal[PATH_MAX] = ""; + readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1); + + if (strstr(pathSysDeviceReal, "/virtual/")) // virtual device + continue; snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device", devName); if (!ffPathExists(pathSysBlock, FF_PATHTYPE_DIRECTORY)) @@ -54,17 +59,9 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { ffStrbufInit(&device->interconnect); - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); - char pathSysDevices[PATH_MAX]; - ssize_t resultLength = readlink(pathSysBlock, pathSysDevices, sizeof(pathSysDevices) - 1); - if (resultLength > 0) - { - pathSysDevices[resultLength] = '\0'; - if (strstr(pathSysDevices, "/usb") != NULL) - ffStrbufSetS(&device->interconnect, "usb"); - } - - if (device->interconnect.length == 0) + if (strstr(pathSysDeviceReal, "/usb") != NULL) + ffStrbufSetS(&device->interconnect, "usb"); + else { snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName); ffAppendFileBuffer(pathSysBlock, &device->interconnect); From b692b759c778145f3cc32ea0b4a9ff2753f68831 Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 17 Dec 2023 12:52:34 +0800 Subject: [PATCH 29/53] DiskIO (Linux): detect interconnect more aggressively --- src/detection/diskio/diskio_linux.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index f904f672d..5f2763303 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -1,5 +1,6 @@ #include "diskio.h" #include "common/io/io.h" +#include "common/properties.h" #include "util/stringUtils.h" #include @@ -64,7 +65,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) else { snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/transport", devName); - ffAppendFileBuffer(pathSysBlock, &device->interconnect); + if (!ffAppendFileBuffer(pathSysBlock, &device->interconnect)) + { + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/uevent", devName); + if (ffParsePropFile(pathSysBlock, "DEVTYPE=", &device->interconnect)) + ffStrbufSubstrBeforeLastC(&device->interconnect, '_'); + } } } From 9339a0fb4e734ca31cf64fdcc7ea0244f0d87fa6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 13:43:52 +0800 Subject: [PATCH 30/53] DiskIO (Windows): detect serial number --- src/detection/diskio/diskio_windows.c | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index 0fe06faf7..853c74266 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -64,8 +64,29 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) device->bytesWritten = (uint64_t) diskPerformance.BytesWritten.QuadPart; device->writeCount = (uint64_t) diskPerformance.WriteCount; - DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {}; DWORD retSize = 0; + + 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) + { + STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer; + if (sdd->SerialNumberOffset != 0) + ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset); + } + + DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {}; if(DeviceIoControl( hDevice, IOCTL_STORAGE_QUERY_PROPERTY, From e7c787159abc4ea5ab8bfbbf8cc64f5c155f1d6c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 13:51:17 +0800 Subject: [PATCH 31/53] DiskIO: print serial number in json format Always init serial property --- src/detection/diskio/diskio_apple.c | 1 + src/detection/diskio/diskio_bsd.c | 1 + src/detection/diskio/diskio_windows.c | 4 ++++ src/modules/diskio/diskio.c | 5 ++++- 4 files changed, 10 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c index b733cbfc9..dd87d3851 100644 --- a/src/detection/diskio/diskio_apple.c +++ b/src/detection/diskio/diskio_apple.c @@ -46,6 +46,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); + ffStrbufInit(&device->serial); ffStrbufInitS(&device->name, deviceName); ffStrbufInit(&device->devPath); device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c index a4a911b93..8e3b3bc8a 100644 --- a/src/detection/diskio/diskio_bsd.c +++ b/src/detection/diskio/diskio_bsd.c @@ -47,6 +47,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name); + ffStrbufInit(&device->serial); ffStrbufInit(&device->interconnect); switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK) { diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index 853c74266..380ba14ba 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -66,6 +66,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) DWORD retSize = 0; + ffStrbufInit(&device->serial); char sddBuffer[4096]; if(DeviceIoControl( hDevice, @@ -83,7 +84,10 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer; if (sdd->SerialNumberOffset != 0) + { ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset); + ffStrbufTrim(&device->serial, ' '); + } } DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {}; diff --git a/src/modules/diskio/diskio.c b/src/modules/diskio/diskio.c index ef15cef11..143e56340 100644 --- a/src/modules/diskio/diskio.c +++ b/src/modules/diskio/diskio.c @@ -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 12 static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right) { @@ -102,6 +102,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options) {FF_FORMAT_ARG_TYPE_UINT64, &dev->readCount}, {FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount}, {FF_FORMAT_ARG_TYPE_STRBUF, &sizePretty}, + {FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial}, }); } ++index; @@ -202,6 +203,7 @@ void ffGenerateDiskIOJsonResult(FFDiskIOOptions* options, yyjson_mut_doc* doc, y 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); + yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial); } FF_LIST_FOR_EACH(FFDiskIOResult, dev, result) @@ -226,6 +228,7 @@ void ffPrintDiskIOHelpFormat(void) "Number of reads", "Number of writes", "Device size (formatted)", + "Serial number", }); } From 1dbd8474c29776ec681a9bfa994f4c62f3aac66d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 17:27:38 +0800 Subject: [PATCH 32/53] DiskIO (Linux): fix serial number detection --- src/detection/diskio/diskio_linux.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index 5f2763303..8343357bb 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -116,7 +116,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { ffStrbufInit(&device->serial); - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/serial", devName); + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName); ffReadFileBuffer(pathSysBlock, &device->serial); } } From 70f39e641cba3bcf0911ec46b28c0031a0e20b39 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 18:24:01 +0800 Subject: [PATCH 33/53] DiskIO (Windows): improve device name detection --- src/detection/diskio/diskio_windows.c | 212 ++++++++++++++------------ 1 file changed, 115 insertions(+), 97 deletions(-) diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index 380ba14ba..ae01712fa 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -17,111 +17,129 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) 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 <= nDevices; ++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) continue; - DISK_PERFORMANCE diskPerformance; - DWORD ioctrlSize = sizeof(diskPerformance); - DWORD dwSize; - if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &diskPerformance, ioctrlSize, &dwSize, NULL)) + 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; + + FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); + ffStrbufInit(&device->name); + + STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer; + 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); - - if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) - { - ffStrbufDestroy(&device->name); - ffStrbufDestroy(&device->interconnect); - result->length--; - continue; - } - - 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; - - DWORD retSize = 0; - - ffStrbufInit(&device->serial); - 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) - { - STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer; - if (sdd->SerialNumberOffset != 0) - { - ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset); - ffStrbufTrim(&device->serial, ' '); - } - } - - 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_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD; - else - device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; - - 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; + 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, ' '); + } + + ffStrbufInit(&device->serial); + if (sdd->SerialNumberOffset != 0) + { + ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset); + ffStrbufTrim(&device->serial, ' '); + } + + if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) + { + ffStrbufDestroy(&device->name); + result->length--; + continue; + } + + 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; + } + + 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; + } + + 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_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD; + else + device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; + + 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; From fb8c7d6e4a56c71265b67450a59d256746348fdd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 18:34:42 +0800 Subject: [PATCH 34/53] DiskIO: add property `removable` --- src/detection/diskio/diskio.h | 1 + src/detection/diskio/diskio_apple.c | 1 + src/detection/diskio/diskio_bsd.c | 1 + src/detection/diskio/diskio_linux.c | 6 ++++++ src/detection/diskio/diskio_windows.c | 2 ++ src/modules/diskio/diskio.c | 5 ++++- 6 files changed, 15 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio.h b/src/detection/diskio/diskio.h index 11c8918a5..1c8c7664f 100644 --- a/src/detection/diskio/diskio.h +++ b/src/detection/diskio/diskio.h @@ -16,6 +16,7 @@ typedef struct FFDiskIOResult FFstrbuf serial; FFDiskIOPhysicalType type; uint64_t size; + bool removable; FFstrbuf devPath; uint64_t bytesRead; uint64_t readCount; diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c index dd87d3851..60de386a9 100644 --- a/src/detection/diskio/diskio_apple.c +++ b/src/detection/diskio/diskio_apple.c @@ -49,6 +49,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) ffStrbufInit(&device->serial); ffStrbufInitS(&device->name, deviceName); ffStrbufInit(&device->devPath); + device->removable = false; device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; device->size = 0; diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c index 8e3b3bc8a..cac500b3b 100644 --- a/src/detection/diskio/diskio_bsd.c +++ b/src/detection/diskio/diskio_bsd.c @@ -49,6 +49,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name); ffStrbufInit(&device->serial); ffStrbufInit(&device->interconnect); + device->removable = false; switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK) { case DEVSTAT_TYPE_IF_SCSI: ffStrbufAppendS(&device->interconnect, "SCSI"); break; diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index 8343357bb..d941c0e40 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -114,6 +114,12 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) device->size = 0; } + { + char removableChar = '0'; + snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/removable", devName); + device->removable = removableChar == '1'; + } + { ffStrbufInit(&device->serial); snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName); diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index ae01712fa..9acf739a3 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -74,6 +74,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; } + device->removable = !!sdd->RemovableMedia; + ffStrbufInit(&device->interconnect); switch (sdd->BusType) { diff --git a/src/modules/diskio/diskio.c b/src/modules/diskio/diskio.c index 143e56340..f6f7cfe40 100644 --- a/src/modules/diskio/diskio.c +++ b/src/modules/diskio/diskio.c @@ -6,7 +6,7 @@ #include "util/stringUtils.h" #define FF_DISKIO_DISPLAY_NAME "Disk IO" -#define FF_DISKIO_NUM_FORMAT_ARGS 12 +#define FF_DISKIO_NUM_FORMAT_ARGS 13 static int sortDevices(const FFDiskIOResult* left, const FFDiskIOResult* right) { @@ -103,6 +103,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options) {FF_FORMAT_ARG_TYPE_UINT64, &dev->writeCount}, {FF_FORMAT_ARG_TYPE_STRBUF, &sizePretty}, {FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial}, + {FF_FORMAT_ARG_TYPE_BOOL, &dev->removable}, }); } ++index; @@ -204,6 +205,7 @@ void ffGenerateDiskIOJsonResult(FFDiskIOOptions* options, yyjson_mut_doc* doc, y yyjson_mut_obj_add_uint(doc, obj, "writeCount", dev->writeCount); yyjson_mut_obj_add_uint(doc, obj, "size", dev->size); yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial); + yyjson_mut_obj_add_bool(doc, obj, "removable", dev->removable); } FF_LIST_FOR_EACH(FFDiskIOResult, dev, result) @@ -229,6 +231,7 @@ void ffPrintDiskIOHelpFormat(void) "Number of writes", "Device size (formatted)", "Serial number", + "Removable", }); } From ce9f9ed7edfa582cfeb762b6bfe743eab98ed5e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 19:04:26 +0800 Subject: [PATCH 35/53] Windows: try fixing `--no-buffer` --- src/common/init.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/common/init.c b/src/common/init.c index 41a79b5ac..12724aa2d 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -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; From c3a28064f6c2e5d418d791ff57e6f8d1e632b43e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 19:29:45 +0800 Subject: [PATCH 36/53] DiskIO: tidy --- src/detection/diskio/diskio.c | 2 +- src/detection/diskio/diskio_windows.c | 42 +++++++++++++++------------ 2 files changed, 25 insertions(+), 19 deletions(-) diff --git a/src/detection/diskio/diskio.c b/src/detection/diskio/diskio.c index cb452743e..7dc4e548b 100644 --- a/src/detection/diskio/diskio.c +++ b/src/detection/diskio/diskio.c @@ -48,7 +48,7 @@ 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"; + return "Physical disk name 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)) diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index 9acf739a3..0c2ed7b72 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -43,9 +43,9 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); - ffStrbufInit(&device->name); - STORAGE_DEVICE_DESCRIPTOR* sdd = (STORAGE_DEVICE_DESCRIPTOR*) sddBuffer; + + ffStrbufInit(&device->name); if (sdd->VendorIdOffset != 0) { ffStrbufSetS(&device->name, (const char*) sddBuffer + sdd->VendorIdOffset); @@ -60,13 +60,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) ffStrbufTrimRight(&device->name, ' '); } - ffStrbufInit(&device->serial); - if (sdd->SerialNumberOffset != 0) - { - ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset); - ffStrbufTrim(&device->serial, ' '); - } - if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) { ffStrbufDestroy(&device->name); @@ -74,6 +67,28 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; } + 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; + } + + ffStrbufInit(&device->serial); + if (sdd->SerialNumberOffset != 0) + { + ffStrbufSetS(&device->serial, (const char*) sddBuffer + sdd->SerialNumberOffset); + ffStrbufTrim(&device->serial, ' '); + } + device->removable = !!sdd->RemovableMedia; ffStrbufInit(&device->interconnect); @@ -102,15 +117,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) default: ffStrbufSetF(&device->interconnect, "Unknown (%d)", (int) sdd->BusType); break; } - 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; - } - DEVICE_SEEK_PENALTY_DESCRIPTOR dspd = {}; if(DeviceIoControl( hDevice, From 4e4246a46a062ffa73d4f4bbeecf46b33cfca2d0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 19:40:24 +0800 Subject: [PATCH 37/53] DiskIO (Windows): fix segfault and memleak --- src/detection/diskio/diskio.h | 2 +- src/detection/diskio/diskio_windows.c | 1 + src/modules/diskio/diskio.c | 1 + 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio.h b/src/detection/diskio/diskio.h index 1c8c7664f..39e0a1d4a 100644 --- a/src/detection/diskio/diskio.h +++ b/src/detection/diskio/diskio.h @@ -14,10 +14,10 @@ typedef struct FFDiskIOResult FFstrbuf name; FFstrbuf interconnect; FFstrbuf serial; + FFstrbuf devPath; FFDiskIOPhysicalType type; uint64_t size; bool removable; - FFstrbuf devPath; uint64_t bytesRead; uint64_t readCount; uint64_t bytesWritten; diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index 0c2ed7b72..99149e948 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -82,6 +82,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; } + ffStrbufInitWS(&device->devPath, szDevice); ffStrbufInit(&device->serial); if (sdd->SerialNumberOffset != 0) { diff --git a/src/modules/diskio/diskio.c b/src/modules/diskio/diskio.c index f6f7cfe40..8387d0217 100644 --- a/src/modules/diskio/diskio.c +++ b/src/modules/diskio/diskio.c @@ -114,6 +114,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options) ffStrbufDestroy(&dev->name); ffStrbufDestroy(&dev->interconnect); ffStrbufDestroy(&dev->devPath); + ffStrbufDestroy(&dev->serial); } } From 04a41cbd6bc7694b198867fb5f8e4e226394014c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sun, 17 Dec 2023 21:49:54 +0800 Subject: [PATCH 38/53] DiskIO (Windows): don't use registry --- src/detection/diskio/diskio_windows.c | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index 99149e948..a0c18ffad 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -7,23 +7,15 @@ 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) - continue; + break; DWORD retSize; char sddBuffer[4096]; From 569883a1a1418e2ff8219d47caea856c55f1c44e Mon Sep 17 00:00:00 2001 From: Carter Li Date: Sun, 17 Dec 2023 15:36:34 +0000 Subject: [PATCH 39/53] DiskIO (FreeBSD): detect disk serial number --- src/detection/diskio/diskio_bsd.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c index cac500b3b..2fb969eb6 100644 --- a/src/detection/diskio/diskio_bsd.c +++ b/src/detection/diskio/diskio_bsd.c @@ -33,6 +33,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; FF_STRBUF_AUTO_DESTROY name = ffStrbufCreateS(provider->lg_name); + FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate(); FFDiskIOPhysicalType type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; for (struct gconfig* ptr = provider->lg_config.lh_first; ptr; ptr = ptr->lg_config.le_next) { @@ -40,6 +41,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) 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; + else if (ffStrEquals(ptr->lg_name, "ident")) + ffStrbufSetS(&identifier, ptr->lg_val); } if (options->namePrefix.length && !ffStrbufStartsWith(&name, &options->namePrefix)) @@ -47,7 +50,7 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); ffStrbufInitF(&device->devPath, "/dev/%s", provider->lg_name); - ffStrbufInit(&device->serial); + ffStrbufInitMove(&device->serial, &identifier); ffStrbufInit(&device->interconnect); device->removable = false; switch (snapIter->device_type & DEVSTAT_TYPE_IF_MASK) From 0f497a53ad49b749860428ec4f8a2113ab71de95 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 09:57:19 +0800 Subject: [PATCH 40/53] DiskIO (macOS): detect serial number and removable --- src/detection/diskio/diskio_apple.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c index 60de386a9..ca1dd5248 100644 --- a/src/detection/diskio/diskio_apple.c +++ b/src/detection/diskio/diskio_apple.c @@ -53,6 +53,9 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; device->size = 0; + FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions); + device->removable = !!CFBooleanGetValue(removable); + ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead); ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten); ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsReadsKey), (int64_t*) &device->readCount); @@ -77,11 +80,13 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) { FF_CFTYPE_AUTO_RELEASE CFDictionaryRef protocolCharacteristics = IORegistryEntryCreateCFProperty(entryPhysical, CFSTR(kIOPropertyProtocolCharacteristicsKey), kCFAllocatorDefault, kNilOptions); if (protocolCharacteristics) - ffCfDictGetString(protocolCharacteristics, CFSTR("Physical Interconnect"), &device->interconnect); + 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) { From 3cd81ec3ad966ce9def96a2a40cb08d0d11b3ce1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 10:43:20 +0800 Subject: [PATCH 41/53] PhysicalDisk: add new module --- CMakeLists.txt | 6 + src/common/modules.c | 1 + src/detection/physicaldisk/physicaldisk.h | 25 ++ .../physicaldisk/physicaldisk_apple.c | 93 +++++++ src/detection/physicaldisk/physicaldisk_bsd.c | 70 +++++ .../physicaldisk/physicaldisk_linux.c | 114 +++++++++ .../physicaldisk/physicaldisk_windows.c | 131 ++++++++++ src/modules/modules.h | 1 + src/modules/options.h | 1 + src/modules/physicaldisk/option.h | 13 + src/modules/physicaldisk/physicaldisk.c | 241 ++++++++++++++++++ src/modules/physicaldisk/physicaldisk.h | 9 + src/options/modules.c | 2 + src/options/modules.h | 1 + 14 files changed, 708 insertions(+) create mode 100644 src/detection/physicaldisk/physicaldisk.h create mode 100644 src/detection/physicaldisk/physicaldisk_apple.c create mode 100644 src/detection/physicaldisk/physicaldisk_bsd.c create mode 100644 src/detection/physicaldisk/physicaldisk_linux.c create mode 100644 src/detection/physicaldisk/physicaldisk_windows.c create mode 100644 src/modules/physicaldisk/option.h create mode 100644 src/modules/physicaldisk/physicaldisk.c create mode 100644 src/modules/physicaldisk/physicaldisk.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 16810ecee..710f980b2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -340,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 @@ -394,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 @@ -453,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 @@ -506,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 @@ -566,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 @@ -619,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 diff --git a/src/common/modules.c b/src/common/modules.c index a065bc625..580e946f6 100644 --- a/src/common/modules.c +++ b/src/common/modules.c @@ -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, diff --git a/src/detection/physicaldisk/physicaldisk.h b/src/detection/physicaldisk/physicaldisk.h new file mode 100644 index 000000000..eea569d2a --- /dev/null +++ b/src/detection/physicaldisk/physicaldisk.h @@ -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); diff --git a/src/detection/physicaldisk/physicaldisk_apple.c b/src/detection/physicaldisk/physicaldisk_apple.c new file mode 100644 index 000000000..bd186fab1 --- /dev/null +++ b/src/detection/physicaldisk/physicaldisk_apple.c @@ -0,0 +1,93 @@ +#include "physicaldisk.h" +#include "util/apple/cf_helpers.h" + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/src/detection/physicaldisk/physicaldisk_bsd.c b/src/detection/physicaldisk/physicaldisk_bsd.c new file mode 100644 index 000000000..c23b08aea --- /dev/null +++ b/src/detection/physicaldisk/physicaldisk_bsd.c @@ -0,0 +1,70 @@ +#include "physicaldisk.h" +#include "util/stringUtils.h" + +#include +#include +#include +#include +#include +#include + +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; +} diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c new file mode 100644 index 000000000..ac4311e5a --- /dev/null +++ b/src/detection/physicaldisk/physicaldisk_linux.c @@ -0,0 +1,114 @@ +#include "physicaldisk.h" +#include "common/io/io.h" +#include "common/properties.h" +#include "util/stringUtils.h" + +#include +#include + +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] = ""; + readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1); + + 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; +} diff --git a/src/detection/physicaldisk/physicaldisk_windows.c b/src/detection/physicaldisk/physicaldisk_windows.c new file mode 100644 index 000000000..1ad1a5779 --- /dev/null +++ b/src/detection/physicaldisk/physicaldisk_windows.c @@ -0,0 +1,131 @@ +#include "physicaldisk.h" +#include "common/io/io.h" +#include "util/windows/unicode.h" + +#include +#include + +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; +} diff --git a/src/modules/modules.h b/src/modules/modules.h index 57632fb7d..35d6523c4 100644 --- a/src/modules/modules.h +++ b/src/modules/modules.h @@ -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" diff --git a/src/modules/options.h b/src/modules/options.h index 191767c77..aa124c24a 100644 --- a/src/modules/options.h +++ b/src/modules/options.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" diff --git a/src/modules/physicaldisk/option.h b/src/modules/physicaldisk/option.h new file mode 100644 index 000000000..243a98a6a --- /dev/null +++ b/src/modules/physicaldisk/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; diff --git a/src/modules/physicaldisk/physicaldisk.c b/src/modules/physicaldisk/physicaldisk.c new file mode 100644 index 000000000..05911eb64 --- /dev/null +++ b/src/modules/physicaldisk/physicaldisk.c @@ -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); +} diff --git a/src/modules/physicaldisk/physicaldisk.h b/src/modules/physicaldisk/physicaldisk.h new file mode 100644 index 000000000..d8216c140 --- /dev/null +++ b/src/modules/physicaldisk/physicaldisk.h @@ -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); diff --git a/src/options/modules.c b/src/options/modules.c index 2047abdde..68b835d82 100644 --- a/src/options/modules.c +++ b/src/options/modules.c @@ -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); diff --git a/src/options/modules.h b/src/options/modules.h index 66b4203c6..e9836e140 100644 --- a/src/options/modules.h +++ b/src/options/modules.h @@ -39,6 +39,7 @@ typedef struct FFOptionsModules FFOpenCLOptions openCL; FFOpenGLOptions openGL; FFPackagesOptions packages; + FFPhysicalDiskOptions physicalDisk; FFPlayerOptions player; FFPowerAdapterOptions powerAdapter; FFProcessesOptions processes; From 89bc7eb015590e898f80818eebb2ce0e4f5e3ebd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 15:06:20 +0800 Subject: [PATCH 42/53] DiskIO: move device info detected in `PhysicalDisk` module --- src/detection/diskio/diskio.c | 4 +- src/detection/diskio/diskio.h | 12 ----- src/detection/diskio/diskio_apple.c | 37 ------------- src/detection/diskio/diskio_bsd.c | 21 ++------ src/detection/diskio/diskio_linux.c | 51 ------------------ src/detection/diskio/diskio_windows.c | 75 +++------------------------ src/modules/diskio/diskio.c | 54 +------------------ 7 files changed, 13 insertions(+), 241 deletions(-) diff --git a/src/detection/diskio/diskio.c b/src/detection/diskio/diskio.c index 7dc4e548b..efac624b9 100644 --- a/src/detection/diskio/diskio.c +++ b/src/detection/diskio/diskio.c @@ -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 "Physical disk 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)) diff --git a/src/detection/diskio/diskio.h b/src/detection/diskio/diskio.h index 39e0a1d4a..0082b18b7 100644 --- a/src/detection/diskio/diskio.h +++ b/src/detection/diskio/diskio.h @@ -2,22 +2,10 @@ #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; - FFstrbuf serial; FFstrbuf devPath; - FFDiskIOPhysicalType type; - uint64_t size; - bool removable; uint64_t bytesRead; uint64_t readCount; uint64_t bytesWritten; diff --git a/src/detection/diskio/diskio_apple.c b/src/detection/diskio/diskio_apple.c index ca1dd5248..bc5d57f25 100644 --- a/src/detection/diskio/diskio_apple.c +++ b/src/detection/diskio/diskio_apple.c @@ -46,15 +46,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; FFDiskIOResult* device = (FFDiskIOResult*) ffListAdd(result); - ffStrbufInit(&device->serial); ffStrbufInitS(&device->name, deviceName); ffStrbufInit(&device->devPath); - device->removable = false; - device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; - device->size = 0; - - FF_CFTYPE_AUTO_RELEASE CFBooleanRef removable = IORegistryEntryCreateCFProperty(entryPartition, CFSTR(kIOMediaRemovableKey), kCFAllocatorDefault, kNilOptions); - device->removable = !!CFBooleanGetValue(removable); ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesReadKey), (int64_t*) &device->bytesRead); ffCfDictGetInt64(statistics, CFSTR(kIOBlockStorageDriverStatisticsBytesWrittenKey), (int64_t*) &device->bytesWritten); @@ -67,36 +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(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_DISKIO_PHYSICAL_TYPE_SSD; - else if (CFStringCompare(mediumType, CFSTR(kIOPropertyMediumTypeRotationalKey), 0) == 0) - device->type = FF_DISKIO_PHYSICAL_TYPE_HDD; - } - } - } } return NULL; diff --git a/src/detection/diskio/diskio_bsd.c b/src/detection/diskio/diskio_bsd.c index 2fb969eb6..08ecb47cf 100644 --- a/src/detection/diskio/diskio_bsd.c +++ b/src/detection/diskio/diskio_bsd.c @@ -32,40 +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); - FF_STRBUF_AUTO_DESTROY identifier = ffStrbufCreate(); - 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; - else if (ffStrEquals(ptr->lg_name, "ident")) - ffStrbufSetS(&identifier, ptr->lg_val); } + 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); - ffStrbufInitMove(&device->serial, &identifier); - ffStrbufInit(&device->interconnect); - device->removable = false; - 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); diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index d941c0e40..fc9ffe043 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -20,7 +20,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) if (devName[0] == '.') continue; - char pathSysBlock[PATH_MAX]; snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); @@ -58,22 +57,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) } } - { - 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, '_'); - } - } - } - // I/Os merges sectors ticks ... uint64_t nRead, sectorRead, nWritten, sectorWritten; { @@ -91,40 +74,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) device->bytesWritten = sectorWritten * 512; device->readCount = nRead; device->writeCount = nWritten; - - { - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/queue/rotational", devName); - char isRotationalChar = '1'; - if (ffReadFileData(pathSysBlock, 1, &isRotationalChar)) - device->type = isRotationalChar == '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); - 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); - device->removable = removableChar == '1'; - } - - { - ffStrbufInit(&device->serial); - snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s/device/serial", devName); - ffReadFileBuffer(pathSysBlock, &device->serial); - } } return NULL; diff --git a/src/detection/diskio/diskio_windows.c b/src/detection/diskio/diskio_windows.c index a0c18ffad..de7ef5c1c 100644 --- a/src/detection/diskio/diskio_windows.c +++ b/src/detection/diskio/diskio_windows.c @@ -1,8 +1,8 @@ #include "diskio.h" #include "common/io/io.h" -#include "util/windows/registry.h" #include "util/windows/unicode.h" +#include #include const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) @@ -52,6 +52,9 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) ffStrbufTrimRight(&device->name, ' '); } + if (!device->name.length) + ffStrbufAppendF(&device->name, "PhysicalDrive%u", (unsigned) idev); + if (options->namePrefix.length && !ffStrbufStartsWith(&device->name, &options->namePrefix)) { ffStrbufDestroy(&device->name); @@ -59,6 +62,8 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) continue; } + ffStrbufInitWS(&device->devPath, szDevice); + DISK_PERFORMANCE dp = {}; if (DeviceIoControl(hDevice, IOCTL_DISK_PERFORMANCE, NULL, 0, &dp, sizeof(dp), &retSize, NULL)) { @@ -73,74 +78,6 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) 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->removable = !!sdd->RemovableMedia; - - 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_DISKIO_PHYSICAL_TYPE_HDD : FF_DISKIO_PHYSICAL_TYPE_SSD; - else - device->type = FF_DISKIO_PHYSICAL_TYPE_UNKNOWN; - - 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; diff --git a/src/modules/diskio/diskio.c b/src/modules/diskio/diskio.c index 8387d0217..d92c21609 100644 --- a/src/modules/diskio/diskio.c +++ b/src/modules/diskio/diskio.c @@ -6,7 +6,7 @@ #include "util/stringUtils.h" #define FF_DISKIO_DISPLAY_NAME "Disk IO" -#define FF_DISKIO_NUM_FORMAT_ARGS 13 +#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,36 +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}, - {FF_FORMAT_ARG_TYPE_STRBUF, &dev->serial}, - {FF_FORMAT_ARG_TYPE_BOOL, &dev->removable}, }); } ++index; @@ -112,9 +88,7 @@ void ffPrintDiskIO(FFDiskIOOptions* options) FF_LIST_FOR_EACH(FFDiskIOResult, dev, result) { ffStrbufDestroy(&dev->name); - ffStrbufDestroy(&dev->interconnect); ffStrbufDestroy(&dev->devPath); - ffStrbufDestroy(&dev->serial); } } @@ -184,35 +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); - yyjson_mut_obj_add_strbuf(doc, obj, "serial", &dev->serial); - yyjson_mut_obj_add_bool(doc, obj, "removable", dev->removable); } FF_LIST_FOR_EACH(FFDiskIOResult, dev, result) { ffStrbufDestroy(&dev->name); - ffStrbufDestroy(&dev->interconnect); ffStrbufDestroy(&dev->devPath); } } @@ -223,16 +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)", - "Serial number", - "Removable", }); } From e8326306f8ed60f80fe53703d27dac656f519c58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 15:53:15 +0800 Subject: [PATCH 43/53] Doc: add module physical disk --- doc/json_schema.json | 27 +++++++++++++++++++++++++++ presets/all | 2 +- presets/all.jsonc | 1 + presets/ci.jsonc | 1 + src/data/help.json | 7 +++++++ 5 files changed, 37 insertions(+), 1 deletion(-) diff --git a/doc/json_schema.json b/doc/json_schema.json index 9e9fa4914..7b5516411 100644 --- a/doc/json_schema.json +++ b/doc/json_schema.json @@ -600,6 +600,7 @@ "opengl", "os", "packages", + "physicaldisk", "player", "poweradapter", "processes", @@ -1369,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": { diff --git a/presets/all b/presets/all index 20442e13f..79fa56291 100644 --- a/presets/all +++ b/presets/all @@ -1 +1 @@ ---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 +--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:PhysicalDisk:Version:Break:Colors diff --git a/presets/all.jsonc b/presets/all.jsonc index f26925af6..53b553aea 100644 --- a/presets/all.jsonc +++ b/presets/all.jsonc @@ -53,6 +53,7 @@ "weather", "netio", "diskio", + "physicaldisk", "version", "break", "colors" diff --git a/presets/ci.jsonc b/presets/ci.jsonc index 766a08bb5..0283d9ec2 100644 --- a/presets/ci.jsonc +++ b/presets/ci.jsonc @@ -62,6 +62,7 @@ }, "netio", "diskio", + "physicaldisk", "version", "break", "colors" diff --git a/src/data/help.json b/src/data/help.json index 232598eda..32f6ba73e 100644 --- a/src/data/help.json +++ b/src/data/help.json @@ -947,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", From 9937eeab1d978f323dc856cb2fff0db59b149868 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 15:57:35 +0800 Subject: [PATCH 44/53] Logo (Builtin): add EshanizedOS --- src/logo/ascii/eshanizedos.txt | 27 +++++++++++++++++++++++++++ src/logo/builtin.c | 9 +++++++++ 2 files changed, 36 insertions(+) create mode 100644 src/logo/ascii/eshanizedos.txt diff --git a/src/logo/ascii/eshanizedos.txt b/src/logo/ascii/eshanizedos.txt new file mode 100644 index 000000000..26ec7422a --- /dev/null +++ b/src/logo/ascii/eshanizedos.txt @@ -0,0 +1,27 @@ + .:-==++++++++++++++++++++++-. + .:=+##############################+ + .=*###################################- + :+######################################: + :+######################################*- + .+#############*+--:::::::::::::::::::::. + :*##########*=: + -###########= + :##########+. + *#########= + =*********+ .::::::::::::::::. + **********. -*###################+: +:********** =#######################= +-*********+ +************************ +:*********+ :***********************: +.********** .=******************+- + +*********- + .**********. + =**********: + +**********=. + =***********=: + -*************+-. + :+****************+++++++++++++++++++++==: + :+**************************************+. + -+************************************- + .-+*********************************. + :-==+*************************=. diff --git a/src/logo/builtin.c b/src/logo/builtin.c index 9e80422f3..62d141fd1 100644 --- a/src/logo/builtin.c +++ b/src/logo/builtin.c @@ -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"}, From 064d7d3c3abad0d1371168e0c96fd7c5a22deaed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 15:58:01 +0800 Subject: [PATCH 45/53] Doc: update changelog --- CHANGELOG.md | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e40e54deb..a0266c58c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,11 +5,18 @@ Features: * Support Apple M3X temperature detection (CPU / GPU, macOS) * `--ds-force-drm` support a new option `sysfs-only` * Improve xfce4 version detection -* Improve detection (WM / DE, FreeBSD) +* 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) + +Logo: +* Remove unnecessary escaping for Adelie logo +* Add EshanizedOS # 2.3.4 From c076f5ae988974996139ed053ca52b626d5697c1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 16:04:56 +0800 Subject: [PATCH 46/53] Github: update issue templates --- .github/ISSUE_TEMPLATE/bug_report.md | 7 ++----- .github/ISSUE_TEMPLATE/feature_request.md | 4 +++- .github/ISSUE_TEMPLATE/logo_request.md | 6 +++--- 3 files changed, 8 insertions(+), 9 deletions(-) diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index 3a9df9a7c..7b3260a5e 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -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`: ``` diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index 6a2a7bde0..febdba836 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,12 +1,14 @@ --- name: Feature request about: Suggest an idea for this project -title: '' +title: '[FEAT] ' labels: enhancement assignees: '' --- + + # Current state: # Wanted state: diff --git a/.github/ISSUE_TEMPLATE/logo_request.md b/.github/ISSUE_TEMPLATE/logo_request.md index 4c49dc893..223b86f0f 100644 --- a/.github/ISSUE_TEMPLATE/logo_request.md +++ b/.github/ISSUE_TEMPLATE/logo_request.md @@ -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. ``` From 4f3cd46f96649ff988d2131ed27e70f3d36e1ab5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 16:09:24 +0800 Subject: [PATCH 47/53] Presets: rename all flag based files to `*.conf` --- presets/{all => all.conf} | 2 ++ presets/{btw => btw.conf} | 2 ++ presets/examples/1 | 1 - presets/examples/{2 => 2.conf} | 2 +- presets/examples/{3 => 3.conf} | 2 +- presets/examples/{4 => 4.conf} | 2 +- presets/examples/{5 => 5.conf} | 2 +- presets/{hardware => hardware.conf} | 2 ++ presets/{neofetch => neofetch.conf} | 2 ++ presets/{paleofetch => paleofetch.conf} | 2 ++ presets/{software => software.conf} | 2 ++ 11 files changed, 16 insertions(+), 5 deletions(-) rename presets/{all => all.conf} (89%) rename presets/{btw => btw.conf} (60%) delete mode 100644 presets/examples/1 rename presets/examples/{2 => 2.conf} (95%) rename presets/examples/{3 => 3.conf} (76%) rename presets/examples/{4 => 4.conf} (70%) rename presets/examples/{5 => 5.conf} (77%) rename presets/{hardware => hardware.conf} (74%) rename presets/{neofetch => neofetch.conf} (88%) rename presets/{paleofetch => paleofetch.conf} (81%) rename presets/{software => software.conf} (61%) diff --git a/presets/all b/presets/all.conf similarity index 89% rename from presets/all rename to presets/all.conf index 79fa56291..7a424b8f8 100644 --- a/presets/all +++ b/presets/all.conf @@ -1 +1,3 @@ +# This file is deprecated, use all.jsonc instead + --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:PhysicalDisk:Version:Break:Colors diff --git a/presets/btw b/presets/btw.conf similarity index 60% rename from presets/btw rename to presets/btw.conf index 47a557979..0868810f4 100644 --- a/presets/btw +++ b/presets/btw.conf @@ -1,3 +1,5 @@ +# This file is deprecated, use btw.jsonc instead + --logo arch --os-format "Arch Linux ({12})" --packages-format "{} (pacman)" diff --git a/presets/examples/1 b/presets/examples/1 deleted file mode 100644 index 99a981ad3..000000000 --- a/presets/examples/1 +++ /dev/null @@ -1 +0,0 @@ -# Load with --load-config examples/1 diff --git a/presets/examples/2 b/presets/examples/2.conf similarity index 95% rename from presets/examples/2 rename to presets/examples/2.conf index 6bd5a0ce3..e9638835b 100644 --- a/presets/examples/2 +++ b/presets/examples/2.conf @@ -1,4 +1,4 @@ -# Load with --load-config examples/2 +# This file is deprecated, use 2.jsonc instead # Note that you must replace the image path to an existing image to display it. --kitty /home/linus/Bilder/Gentoo.png diff --git a/presets/examples/3 b/presets/examples/3.conf similarity index 76% rename from presets/examples/3 rename to presets/examples/3.conf index bd89f592f..bd3014b2d 100644 --- a/presets/examples/3 +++ b/presets/examples/3.conf @@ -1,4 +1,4 @@ -# Load with --load-config example/3 +# This file is deprecated, use 3.jsonc instead --logo debian_small --structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP diff --git a/presets/examples/4 b/presets/examples/4.conf similarity index 70% rename from presets/examples/4 rename to presets/examples/4.conf index f41e25a73..49a8f194e 100644 --- a/presets/examples/4 +++ b/presets/examples/4.conf @@ -1,4 +1,4 @@ -# Load with --load-config examples/4 +# This file is deprecated, use 4.jsonc instead --color blue --logo arch_small diff --git a/presets/examples/5 b/presets/examples/5.conf similarity index 77% rename from presets/examples/5 rename to presets/examples/5.conf index 27180ca9c..c070a697d 100644 --- a/presets/examples/5 +++ b/presets/examples/5.conf @@ -1,4 +1,4 @@ -# Load with --load-config examples/5 +# This file is deprecated, use 5.jsonc instead --logo none --color reset_magenta diff --git a/presets/hardware b/presets/hardware.conf similarity index 74% rename from presets/hardware rename to presets/hardware.conf index f93873197..19ee61e6f 100644 --- a/presets/hardware +++ b/presets/hardware.conf @@ -1,3 +1,5 @@ +# This file is deprecated, use hardware.jsonc instead + --structure Host:Display:CPU:GPU:Memory:Disk:Battery --memory-format "{?2}{2}{?}" --disk-format "{?2}{2}{?}" diff --git a/presets/neofetch b/presets/neofetch.conf similarity index 88% rename from presets/neofetch rename to presets/neofetch.conf index 925f4705b..14b6ed9c8 100644 --- a/presets/neofetch +++ b/presets/neofetch.conf @@ -1,3 +1,5 @@ +# This file is deprecated, use neofetch.jsonc instead + --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}" diff --git a/presets/paleofetch b/presets/paleofetch.conf similarity index 81% rename from presets/paleofetch rename to presets/paleofetch.conf index 66913e3dc..1f5dcf6c9 100644 --- a/presets/paleofetch +++ b/presets/paleofetch.conf @@ -1,3 +1,5 @@ +# This file is deprecated, use paleofetch.jsonc instead + --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}]{?}" diff --git a/presets/software b/presets/software.conf similarity index 61% rename from presets/software rename to presets/software.conf index dd78f7451..cd1e3e3f7 100644 --- a/presets/software +++ b/presets/software.conf @@ -1 +1,3 @@ +# This file is deprecated, use software.jsonc instead + --structure OS:Kernel:Shell:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont From e89d475a3ba8a0053c2cf3f5a5b01b3458a3c2e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 16:13:45 +0800 Subject: [PATCH 48/53] Presets: remove flag based config files --- CHANGELOG.md | 7 ++++++- presets/all.conf | 3 --- presets/btw.conf | 5 ----- presets/examples/2.conf | 24 ------------------------ presets/examples/3.conf | 7 ------- presets/examples/4.conf | 7 ------- presets/examples/5.conf | 11 ----------- presets/hardware.conf | 6 ------ presets/neofetch.conf | 11 ----------- presets/paleofetch.conf | 7 ------- presets/software.conf | 3 --- 11 files changed, 6 insertions(+), 85 deletions(-) delete mode 100644 presets/all.conf delete mode 100644 presets/btw.conf delete mode 100644 presets/examples/2.conf delete mode 100644 presets/examples/3.conf delete mode 100644 presets/examples/4.conf delete mode 100644 presets/examples/5.conf delete mode 100644 presets/hardware.conf delete mode 100644 presets/neofetch.conf delete mode 100644 presets/paleofetch.conf delete mode 100644 presets/software.conf diff --git a/CHANGELOG.md b/CHANGELOG.md index a0266c58c..f01bd52a1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,9 @@ -# 2.3.5 +# 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) diff --git a/presets/all.conf b/presets/all.conf deleted file mode 100644 index 7a424b8f8..000000000 --- a/presets/all.conf +++ /dev/null @@ -1,3 +0,0 @@ -# This file is deprecated, use all.jsonc instead - ---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:PhysicalDisk:Version:Break:Colors diff --git a/presets/btw.conf b/presets/btw.conf deleted file mode 100644 index 0868810f4..000000000 --- a/presets/btw.conf +++ /dev/null @@ -1,5 +0,0 @@ -# This file is deprecated, use btw.jsonc instead - ---logo arch ---os-format "Arch Linux ({12})" ---packages-format "{} (pacman)" diff --git a/presets/examples/2.conf b/presets/examples/2.conf deleted file mode 100644 index e9638835b..000000000 --- a/presets/examples/2.conf +++ /dev/null @@ -1,24 +0,0 @@ -# This file is deprecated, use 2.jsonc instead -# 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 " " diff --git a/presets/examples/3.conf b/presets/examples/3.conf deleted file mode 100644 index bd3014b2d..000000000 --- a/presets/examples/3.conf +++ /dev/null @@ -1,7 +0,0 @@ -# This file is deprecated, use 3.jsonc instead - ---logo debian_small ---structure Vulkan:OpenGL:OpenCL:Memory:Disk:LocalIP ---binary-prefix si ---localip-show-loop false ---disk-folders /:/home:/boot:/efi diff --git a/presets/examples/4.conf b/presets/examples/4.conf deleted file mode 100644 index 49a8f194e..000000000 --- a/presets/examples/4.conf +++ /dev/null @@ -1,7 +0,0 @@ -# This file is deprecated, use 4.jsonc instead - ---color blue ---logo arch_small ---logo-padding-right 1 ---separator "  " ---structure DateTime:Break:Player:Media diff --git a/presets/examples/5.conf b/presets/examples/5.conf deleted file mode 100644 index c070a697d..000000000 --- a/presets/examples/5.conf +++ /dev/null @@ -1,11 +0,0 @@ -# This file is deprecated, use 5.jsonc instead - ---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 diff --git a/presets/hardware.conf b/presets/hardware.conf deleted file mode 100644 index 19ee61e6f..000000000 --- a/presets/hardware.conf +++ /dev/null @@ -1,6 +0,0 @@ -# This file is deprecated, use hardware.jsonc instead - ---structure Host:Display:CPU:GPU:Memory:Disk:Battery ---memory-format "{?2}{2}{?}" ---disk-format "{?2}{2}{?}" ---battery-format "{?1}{1} {?}{?2}{2} {?}{?3}({3}){?}" diff --git a/presets/neofetch.conf b/presets/neofetch.conf deleted file mode 100644 index 14b6ed9c8..000000000 --- a/presets/neofetch.conf +++ /dev/null @@ -1,11 +0,0 @@ -# This file is deprecated, use neofetch.jsonc instead - ---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}{-}{/}{} / {}" diff --git a/presets/paleofetch.conf b/presets/paleofetch.conf deleted file mode 100644 index 1f5dcf6c9..000000000 --- a/presets/paleofetch.conf +++ /dev/null @@ -1,7 +0,0 @@ -# This file is deprecated, use paleofetch.jsonc instead - ---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" diff --git a/presets/software.conf b/presets/software.conf deleted file mode 100644 index cd1e3e3f7..000000000 --- a/presets/software.conf +++ /dev/null @@ -1,3 +0,0 @@ -# This file is deprecated, use software.jsonc instead - ---structure OS:Kernel:Shell:DE:WM:WMTheme:Theme:Icons:Font:Cursor:Terminal:TerminalFont From 4ae0c43c6f72173719322ae9e9ac093417a583ef Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 20:36:05 +0800 Subject: [PATCH 49/53] IO: remove support of `FF_PATHTYPE_LINK` --- src/common/io/io.h | 42 ++++++++++++++++++++++++++++++++------ src/common/io/io_unix.c | 20 ------------------ src/common/io/io_windows.c | 20 +----------------- 3 files changed, 37 insertions(+), 45 deletions(-) diff --git a/src/common/io/io.h b/src/common/io/io.h index c311feb76..f499d1332 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -75,15 +75,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 diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index e4b9e62e1..fcfe05718 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -103,26 +103,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; diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index f4a3747aa..3a520f098 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -37,7 +37,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 +87,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); From 11b1b975677e034857c867d250bd70744c3c81cf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 21:00:19 +0800 Subject: [PATCH 50/53] IO: only retry when open() error is ENOENT / ERROR_PATH_NOT_FOUND Close: #663 --- src/common/io/io.h | 1 + src/common/io/io_unix.c | 13 +++++++++---- src/common/io/io_windows.c | 13 +++++++++---- 3 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/common/io/io.h b/src/common/io/io.h index f499d1332..257e9ce83 100644 --- a/src/common/io/io.h +++ b/src/common/io/io.h @@ -10,6 +10,7 @@ #else #include #include + #include 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 diff --git a/src/common/io/io_unix.c b/src/common/io/io_unix.c index fcfe05718..546231198 100644 --- a/src/common/io/io_unix.c +++ b/src/common/io/io_unix.c @@ -3,10 +3,10 @@ #include "util/unused.h" #include -#include #include #include #include +#include #if __has_include() #include @@ -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; } diff --git a/src/common/io/io_windows.c b/src/common/io/io_windows.c index 3a520f098..e53a1cee6 100644 --- a/src/common/io/io_windows.c +++ b/src/common/io/io_windows.c @@ -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; } From 600f6c7f24276aace7daf830f2b62437f66722f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 21:25:15 +0800 Subject: [PATCH 51/53] Image: don't `dlclose(imageMagick)` Fix: #552 --- CHANGELOG.md | 1 + src/logo/image/im6.c | 5 ++++- src/logo/image/im7.c | 5 ++++- 3 files changed, 9 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index f01bd52a1..7d24f1742 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -18,6 +18,7 @@ Bugfixes: * 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 diff --git a/src/logo/image/im6.c b/src/logo/image/im6.c index a8820f53b..9694a797b 100644 --- a/src/logo/image/im6.c +++ b/src/logo/image/im6.c @@ -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 diff --git a/src/logo/image/im7.c b/src/logo/image/im7.c index 03229aacb..b0eeed2dc 100644 --- a/src/logo/image/im7.c +++ b/src/logo/image/im7.c @@ -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 From 70160d324fe92b5ae97f97fa43d14199a26b646b Mon Sep 17 00:00:00 2001 From: apocelipes Date: Mon, 18 Dec 2023 17:04:26 +0900 Subject: [PATCH 52/53] fix(DiskIO, PhysicalDisk): fix readlink --- src/detection/diskio/diskio_linux.c | 7 +++++-- src/detection/physicaldisk/physicaldisk_linux.c | 7 +++++-- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/src/detection/diskio/diskio_linux.c b/src/detection/diskio/diskio_linux.c index fc9ffe043..e865581c2 100644 --- a/src/detection/diskio/diskio_linux.c +++ b/src/detection/diskio/diskio_linux.c @@ -23,8 +23,11 @@ const char* ffDiskIOGetIoCounters(FFlist* result, FFDiskIOOptions* options) char pathSysBlock[PATH_MAX]; snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); - char pathSysDeviceReal[PATH_MAX] = ""; - readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1); + 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; diff --git a/src/detection/physicaldisk/physicaldisk_linux.c b/src/detection/physicaldisk/physicaldisk_linux.c index ac4311e5a..b94667731 100644 --- a/src/detection/physicaldisk/physicaldisk_linux.c +++ b/src/detection/physicaldisk/physicaldisk_linux.c @@ -23,8 +23,11 @@ const char* ffDetectPhysicalDisk(FFlist* result, FFPhysicalDiskOptions* options) char pathSysBlock[PATH_MAX]; snprintf(pathSysBlock, PATH_MAX, "/sys/block/%s", devName); - char pathSysDeviceReal[PATH_MAX] = ""; - readlink(pathSysBlock, pathSysDeviceReal, sizeof(pathSysDeviceReal) - 1); + 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; From d84ae91f59592848df230e247976cd2474378119 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Mon, 18 Dec 2023 23:55:11 +0800 Subject: [PATCH 53/53] Release: v2.4.0 --- CMakeLists.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 710f980b2..b9072d5d6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1,7 +1,7 @@ cmake_minimum_required(VERSION 3.12.0) # target_link_libraries with OBJECT libs & project homepage url project(fastfetch - VERSION 2.3.4 + VERSION 2.4.0 LANGUAGES C DESCRIPTION "Fast neofetch-like system information tool" HOMEPAGE_URL "https://github.com/fastfetch-cli/fastfetch"