Files
fastfetch/src/detection/lm/lm_linux.c
T

169 lines
5.9 KiB
C
Raw Normal View History

2023-06-20 23:01:18 +08:00
#include "lm.h"
2026-01-06 09:48:38 +08:00
#include "common/properties.h"
#include "common/dbus.h"
#include "common/processing.h"
#include "detection/displayserver/displayserver.h"
#include <unistd.h>
2023-06-20 23:01:18 +08:00
2024-06-21 20:27:22 +08:00
#define FF_SYSTEMD_SESSIONS_PATH "/run/systemd/sessions/"
#define FF_SYSTEMD_USERS_PATH "/run/systemd/users/"
2023-06-20 23:01:18 +08:00
2026-03-29 09:28:49 +08:00
static const char* getGdmVersion(FFstrbuf* version) {
2026-07-10 18:08:04 +08:00
const char* error = ffProcessAppendStdOut(version, (char* const[]) { "gdm", "--version", nullptr });
2026-03-29 09:28:49 +08:00
if (error || version->length == 0) {
2026-07-10 18:08:04 +08:00
error = ffProcessAppendStdOut(version, (char* const[]) { "gdm3", "--version", nullptr });
2026-03-29 09:28:49 +08:00
if (error || version->length == 0) {
return "Failed to get GDM version";
}
}
2023-07-01 14:20:34 +08:00
// GDM 44.1
ffStrbufSubstrAfterFirstC(version, ' ');
2026-07-10 18:08:04 +08:00
return nullptr;
2023-07-01 14:20:34 +08:00
}
2026-03-29 09:28:49 +08:00
static const char* getSshdVersion(FFstrbuf* version) {
2026-07-10 18:08:04 +08:00
const char* error = ffProcessAppendStdErr(version, (char* const[]) { "sshd", "-V", nullptr });
2026-03-29 09:28:49 +08:00
if (error) {
2023-07-10 16:13:10 +08:00
return error;
2026-03-29 09:28:49 +08:00
}
2023-07-10 16:13:10 +08:00
// OpenSSH_9.0p1, OpenSSL 3.0.9 30 May 2023...
ffStrbufSubstrBeforeFirstC(version, ',');
ffStrbufSubstrAfterFirstC(version, '_');
2026-07-10 18:08:04 +08:00
return nullptr;
2023-07-10 16:13:10 +08:00
}
2023-07-01 14:20:34 +08:00
#ifdef FF_HAVE_ZLIB
#include "common/library.h"
#include <stdlib.h>
#include <zlib.h>
2023-07-01 14:20:34 +08:00
2026-03-29 09:28:49 +08:00
static const char* getSddmVersion(FFstrbuf* version) {
FF_LIBRARY_LOAD_MESSAGE(zlib, "libz" FF_LIBRARY_EXTENSION, 2)
2023-10-26 23:27:40 +08:00
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)
2023-07-01 14:20:34 +08:00
gzFile file = ffgzopen(FASTFETCH_TARGET_DIR_USR "/share/man/man1/sddm.1.gz", "rb");
2026-03-29 09:28:49 +08:00
if (file == Z_NULL) {
2023-07-01 14:20:34 +08:00
return "ffgzopen(\"/usr/share/man/man1/sddm.1.gz\", \"rb\") failed";
2026-03-29 09:28:49 +08:00
}
2023-07-01 14:20:34 +08:00
ffStrbufEnsureFree(version, 2047);
memset(version->chars, 0, version->allocated);
int size = ffgzread(file, version->chars, version->allocated - 1);
ffgzclose(file);
2026-03-29 09:28:49 +08:00
if (size <= 0) {
2023-07-01 14:20:34 +08:00
return "ffgzread(file, version->chars, version->length) failed";
2026-03-29 09:28:49 +08:00
}
2023-07-01 14:20:34 +08:00
version->length = (uint32_t) size;
uint32_t index = ffStrbufFirstIndexS(version, ".TH ");
2026-03-29 09:28:49 +08:00
if (index == version->length) {
2023-07-01 14:20:34 +08:00
ffStrbufClear(version);
return ".TH is not found";
}
ffStrbufSubstrBefore(version, ffStrbufNextIndexC(version, index, '\n'));
2023-07-09 00:36:29 +08:00
ffStrbufSubstrAfter(version, index + (uint32_t) strlen(".TH "));
2023-07-01 14:20:34 +08:00
// "SDDM" 1 "May 2014" "sddm 0.20.0" "sddm"
ffStrbufSubstrBeforeLastC(version, ' ');
ffStrbufTrimRight(version, '"');
ffStrbufSubstrAfterLastC(version, ' ');
2026-07-10 18:08:04 +08:00
return nullptr;
2023-07-01 14:20:34 +08:00
}
#else
2026-04-09 16:20:59 +08:00
static const char* getSddmVersion(FF_A_UNUSED FFstrbuf* version) {
2023-07-01 14:20:34 +08:00
return "Fastfetch is built without libz support";
}
#endif
2026-03-29 09:28:49 +08:00
static const char* getXfwmVersion(FFstrbuf* version) {
2026-07-10 18:08:04 +08:00
const char* error = ffProcessAppendStdOut(version, (char* const[]) { "xfwm4", "--version", nullptr });
2026-03-29 09:28:49 +08:00
if (error) {
2023-07-01 14:20:34 +08:00
return error;
2026-03-29 09:28:49 +08:00
}
2023-07-01 14:20:34 +08:00
2026-03-29 09:28:49 +08:00
// This is xfwm4 version 4.18.0 (revision 7e7473c5b) for Xfce 4.18...
2023-07-01 14:20:34 +08:00
ffStrbufSubstrAfterFirstS(version, "version ");
ffStrbufSubstrBeforeFirstC(version, ' ');
2026-07-10 18:08:04 +08:00
return nullptr;
2023-07-01 14:20:34 +08:00
}
2026-03-29 09:28:49 +08:00
static const char* getLightdmVersion(FFstrbuf* version) {
2026-07-10 18:08:04 +08:00
const char* error = ffProcessAppendStdErr(version, (char* const[]) { "lightdm", "--version", nullptr });
2026-03-29 09:28:49 +08:00
if (error) {
2023-07-08 09:16:13 +08:00
return error;
2026-03-29 09:28:49 +08:00
}
2023-07-08 09:16:13 +08:00
// lightdm 1.30.0
ffStrbufSubstrAfterFirstC(version, ' ');
2023-07-13 11:19:23 +08:00
ffStrbufTrimRight(version, '\n');
2023-07-08 09:16:13 +08:00
2026-07-10 18:08:04 +08:00
return nullptr;
2023-07-08 09:16:13 +08:00
}
2026-03-29 09:28:49 +08:00
const char* ffDetectLM(FFLMResult* result) {
FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate();
FF_STRBUF_AUTO_DESTROY sessionId = ffStrbufCreateS(getenv("XDG_SESSION_ID"));
2026-03-29 09:28:49 +08:00
if (sessionId.length == 0) {
// On some incorrectly configured systems, $XDG_SESSION_ID is not set. Try finding it ourself
// WARNING: This is private data. Do not parse
2026-02-10 20:25:50 +08:00
ffStrbufSetF(&path, FF_SYSTEMD_USERS_PATH "%d", instance.state.platform.uid);
2023-06-20 23:01:18 +08:00
// This is actually buggy, and assumes current user is using DE
// `sd_pid_get_session` can be a better option, but we need to find a pid to use
if (!ffParsePropFileValues(path.chars, 1, (FFpropquery[]) {
2026-03-30 10:27:23 +08:00
{ "DISPLAY=", &sessionId },
2026-03-29 09:28:49 +08:00
})) {
return "Failed to get $XDG_SESSION_ID";
2026-03-29 09:28:49 +08:00
}
}
2023-06-20 23:01:18 +08:00
2024-06-21 20:27:22 +08:00
ffStrbufSetS(&path, FF_SYSTEMD_SESSIONS_PATH);
ffStrbufAppend(&path, &sessionId);
// WARNING: This is private data. Do not parse
if (!ffParsePropFileValues(path.chars, 2, (FFpropquery[]) {
2026-03-30 10:27:23 +08:00
{ "SERVICE=", &result->service },
{ "TYPE=", &result->type },
2026-03-29 09:28:49 +08:00
})) {
2024-06-21 20:27:22 +08:00
return "Failed to parse " FF_SYSTEMD_SESSIONS_PATH "$XDG_SESSION_ID";
2026-03-29 09:28:49 +08:00
}
2023-06-20 23:01:18 +08:00
2026-03-29 09:28:49 +08:00
if (instance.config.general.detectVersion) {
if (ffStrbufStartsWithS(&result->service, "gdm")) {
getGdmVersion(&result->version);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->service, "sddm")) {
getSddmVersion(&result->version);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->service, "xfwm")) {
getXfwmVersion(&result->version);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->service, "lightdm")) {
getLightdmVersion(&result->version);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufStartsWithS(&result->service, "sshd")) {
getSshdVersion(&result->version);
2026-03-29 09:28:49 +08:00
}
}
2023-07-01 14:20:34 +08:00
// Correct char cases
2026-03-29 09:28:49 +08:00
if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_WAYLAND)) {
ffStrbufSetS(&result->type, FF_WM_PROTOCOL_WAYLAND);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_X11)) {
ffStrbufSetS(&result->type, FF_WM_PROTOCOL_X11);
2026-03-29 09:28:49 +08:00
} else if (ffStrbufIgnCaseEqualS(&result->type, FF_WM_PROTOCOL_TTY)) {
ffStrbufSetS(&result->type, FF_WM_PROTOCOL_TTY);
2026-03-29 09:28:49 +08:00
}
2026-07-10 18:08:04 +08:00
return nullptr;
2023-06-20 23:01:18 +08:00
}