From ac07ae739b85122b76d71f33821c9ae79682f5bb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E9=80=9A=E6=B4=B2?= Date: Sat, 1 Jul 2023 14:20:34 +0800 Subject: [PATCH] LM (Linux): support version detection --- src/detection/lm/lm.h | 3 +- src/detection/lm/lm_linux.c | 92 +++++++++++++++++++++++++++++++++++++ src/modules/lm/lm.c | 7 ++- 3 files changed, 99 insertions(+), 3 deletions(-) diff --git a/src/detection/lm/lm.h b/src/detection/lm/lm.h index 5fd1919d5..e118419a5 100644 --- a/src/detection/lm/lm.h +++ b/src/detection/lm/lm.h @@ -9,8 +9,7 @@ typedef struct FFLMResult { FFstrbuf service; FFstrbuf type; - // bool isDisplay; - // bool remote; + FFstrbuf version; } FFLMResult; const char* ffDetectLM(FFLMResult* result); diff --git a/src/detection/lm/lm_linux.c b/src/detection/lm/lm_linux.c index dcc65c7c2..b698a2ae4 100644 --- a/src/detection/lm/lm_linux.c +++ b/src/detection/lm/lm_linux.c @@ -1,6 +1,7 @@ #include "lm.h" #include "common/properties.h" #include "common/dbus.h" +#include "common/processing.h" #include "detection/displayserver/displayserver.h" #include @@ -8,6 +9,90 @@ #define FF_SYSTEMD_SESSIONS_PATH "/var/run/systemd/sessions/" #define FF_SYSTEMD_USERS_PATH "/run/systemd/users/" +static const char* getGdmVersion(FFstrbuf* version) +{ + const char* error = ffProcessAppendStdOut(version, (char* const[]) { + "gdm", + "--version", + NULL + }); + if (error) + return error; + + // GDM 44.1 + ffStrbufSubstrAfterFirstC(version, ' '); + return NULL; +} + +#ifdef FF_HAVE_ZLIB +#include "common/library.h" +#include +#include + +static const char* getSddmVersion(FFstrbuf* version) +{ + FF_LIBRARY_LOAD(zlib, &instance.config.libZ, "dlopen libz failed", "libz" FF_LIBRARY_EXTENSION, 2) + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzopen); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzread); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzerror); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gztell); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzrewind); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(zlib, gzclose); + + gzFile file = ffgzopen("/usr/share/man/man1/sddm.1.gz", "rb"); + if (file == Z_NULL) + return "ffgzopen(\"/usr/share/man/man1/sddm.1.gz\", \"rb\") failed"; + + ffStrbufEnsureFree(version, 2047); + memset(version->chars, 0, version->allocated); + int size = ffgzread(file, version->chars, version->allocated - 1); + ffgzclose(file); + + if (size <= 0) + return "ffgzread(file, version->chars, version->length) failed"; + + version->length = (uint32_t) size; + uint32_t index = ffStrbufFirstIndexS(version, ".TH "); + if (index == version->length) + { + ffStrbufClear(version); + return ".TH is not found"; + } + + ffStrbufSubstrBefore(version, ffStrbufNextIndexC(version, index, '\n')); + ffStrbufSubstrAfter(version, index + strlen(".TH ")); + + // "SDDM" 1 "May 2014" "sddm 0.20.0" "sddm" + ffStrbufSubstrBeforeLastC(version, ' '); + ffStrbufTrimRight(version, '"'); + ffStrbufSubstrAfterLastC(version, ' '); + + return NULL; +} +#else +static const char* getSddmVersion(FF_MAYBE_UNUSED FFstrbuf* version) +{ + return "Fastfetch is built without libz support"; +} +#endif + +static const char* getXfwmVersion(FFstrbuf* version) +{ + const char* error = ffProcessAppendStdOut(version, (char* const[]) { + "xfwm4", + "--version", + NULL + }); + if (error) + return error; + + // This is xfwm4 version 4.18.0 (revision 7e7473c5b) for Xfce 4.18... + ffStrbufSubstrAfterFirstS(version, "version "); + ffStrbufSubstrBeforeFirstC(version, ' '); + + return NULL; +} + const char* ffDetectLM(FFLMResult* result) { FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); @@ -38,6 +123,13 @@ const char* ffDetectLM(FFLMResult* result) })) return "Failed to parse /run/systemd/sessions/$XDG_SESSION_ID"; + if (ffStrbufStartsWithS(&result->service, "gdm")) + getGdmVersion(&result->version); + else if (ffStrbufStartsWithS(&result->service, "sddm")) + getSddmVersion(&result->version); + else if (ffStrbufStartsWithS(&result->service, "xfwm")) + getXfwmVersion(&result->version); + // Correct char cases if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_WAYLAND)) ffStrbufSetS(&result->type, FF_WM_PROTOCOL_WAYLAND); diff --git a/src/modules/lm/lm.c b/src/modules/lm/lm.c index 34e28e6fa..adaf7d094 100644 --- a/src/modules/lm/lm.c +++ b/src/modules/lm/lm.c @@ -4,13 +4,14 @@ #include "modules/lm/lm.h" #include "util/stringUtils.h" -#define FF_LM_NUM_FORMAT_ARGS 2 +#define FF_LM_NUM_FORMAT_ARGS 3 void ffPrintLM(FFLMOptions* options) { FFLMResult result; ffStrbufInit(&result.service); ffStrbufInit(&result.type); + ffStrbufInit(&result.version); const char* error = ffDetectLM(&result); if(error) @@ -29,6 +30,8 @@ void ffPrintLM(FFLMOptions* options) { ffPrintLogoAndKey(FF_LM_MODULE_NAME, 0, &options->moduleArgs.key, &options->moduleArgs.keyColor); ffStrbufWriteTo(&result.service, stdout); + if(result.version.length) + printf(" %s", result.version.chars); if(result.type.length) printf(" (%s)", result.type.chars); putchar('\n'); @@ -38,10 +41,12 @@ void ffPrintLM(FFLMOptions* options) ffPrintFormat(FF_LM_MODULE_NAME, 0, &options->moduleArgs, FF_LM_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRBUF, &result.service}, {FF_FORMAT_ARG_TYPE_STRBUF, &result.type}, + {FF_FORMAT_ARG_TYPE_STRBUF, &result.version}, }); } ffStrbufDestroy(&result.service); ffStrbufDestroy(&result.type); + ffStrbufDestroy(&result.version); } void ffInitLMOptions(FFLMOptions* options)