From a1d8e3e598ec5081353c41d39bab05fb0e4a2dee Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Sun, 15 Jan 2023 15:57:26 +0100 Subject: [PATCH] Introduce FFPlatform --- CMakeLists.txt | 7 +- src/common/init.c | 188 +-------------- src/common/parsing.c | 11 - src/common/parsing.h | 1 - src/common/properties.c | 2 +- src/common/properties.h | 4 +- src/detection/gtk.c | 4 +- src/detection/os/os.h | 2 - src/detection/os/os_android.c | 4 - src/detection/os/os_apple.m | 4 - src/detection/os/os_linux.c | 5 - src/detection/os/os_windows.cpp | 5 - src/detection/packages/packages_linux.c | 2 +- src/detection/qt.c | 4 +- .../terminalfont/terminalfont_linux.c | 4 +- .../terminalshell/terminalshell_linux.c | 5 +- src/detection/title.c | 66 ----- src/detection/title.h | 17 -- src/detection/wmtheme/wmtheme_linux.c | 4 +- src/fastfetch.c | 14 +- src/fastfetch.h | 15 +- src/logo/image/image.c | 16 +- src/logo/logo.c | 6 +- src/modules/kernel.c | 20 +- src/modules/os.c | 24 +- src/modules/separator.c | 8 +- src/modules/title.c | 10 +- src/util/FFstrbuf.c | 11 + src/util/FFstrbuf.h | 2 + src/util/platform/FFPlatform.c | 118 +++++++++ src/util/platform/FFPlatform.h | 29 +++ src/util/platform/FFPlatform_private.h | 21 ++ src/util/platform/FFPlatform_unix.c | 138 +++++++++++ src/util/platform/FFPlatform_windows.c | 228 ++++++++++++++++++ src/util/windows/pwd.c | 22 -- src/util/windows/pwd.h | 22 -- src/util/windows/unicode.h | 4 +- src/util/windows/utsname.c | 116 --------- src/util/windows/utsname.h | 19 -- 39 files changed, 622 insertions(+), 560 deletions(-) delete mode 100644 src/detection/title.c delete mode 100644 src/detection/title.h create mode 100644 src/util/platform/FFPlatform.c create mode 100644 src/util/platform/FFPlatform.h create mode 100644 src/util/platform/FFPlatform_private.h create mode 100644 src/util/platform/FFPlatform_unix.c create mode 100644 src/util/platform/FFPlatform_windows.c delete mode 100644 src/util/windows/pwd.c delete mode 100644 src/util/windows/pwd.h delete mode 100644 src/util/windows/utsname.c delete mode 100644 src/util/windows/utsname.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 2b7ed8b72..87c9c6b7b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -245,7 +245,6 @@ set(LIBFASTFETCH_SRC src/detection/packages/packages.c src/detection/terminalfont/terminalfont.c src/detection/terminalshell/terminalshell.c - src/detection/title.c src/detection/vulkan.c src/logo/builtin.c src/logo/image/im6.c @@ -303,6 +302,7 @@ set(LIBFASTFETCH_SRC src/util/FFlist.c src/util/FFstrbuf.c src/util/FFvaluestore.c + src/util/platform/FFPlatform.c ) if(LINUX) @@ -344,6 +344,7 @@ if(LINUX) src/detection/users/users_linux.c src/detection/wifi/wifi_linux.c src/detection/wmtheme/wmtheme_linux.c + src/util/platform/FFPlatform_unix.c ) elseif(ANDROID) list(APPEND LIBFASTFETCH_SRC @@ -378,6 +379,7 @@ elseif(ANDROID) src/detection/users/users_linux.c src/detection/wifi/wifi_nosupport.c src/detection/wmtheme/wmtheme_nosupport.c + src/util/platform/FFPlatform_unix.c ) elseif(BSD) list(APPEND LIBFASTFETCH_SRC @@ -419,6 +421,7 @@ elseif(BSD) src/detection/users/users_linux.c src/detection/wifi/wifi_nosupport.c src/detection/wmtheme/wmtheme_linux.c + src/util/platform/FFPlatform_unix.c ) elseif(APPLE) list(APPEND LIBFASTFETCH_SRC @@ -457,6 +460,7 @@ elseif(APPLE) src/detection/wmtheme/wmtheme_apple.m src/util/apple/cf_helpers.c src/util/apple/osascript.m + src/util/platform/FFPlatform_unix.c ) elseif(WIN32) list(APPEND LIBFASTFETCH_SRC @@ -496,6 +500,7 @@ elseif(WIN32) src/util/windows/unicode.c src/util/windows/utsname.c src/util/windows/wmi.cpp + src/util/platform/FFPlatform_windows.c ) endif() diff --git a/src/common/init.c b/src/common/init.c index e2c32c3c0..d08cbaf09 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -18,186 +18,13 @@ #include #endif -#define FF_ENSURE_ONLY_ONCE_IN_LIST(list, element) \ - if(ffListFirstIndexComp(list, element, (bool(*)(const void*, const void*))ffStrbufEqual) < list->length - 1) \ - { \ - ffStrbufDestroy(ffListGet(list, list->length - 1)); \ - --list->length; \ - } - -static void pathsAddHome(FFlist* dirs, FFstate* state, const char* suffix) -{ - FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); - ffStrbufInitA(buffer, 64); - ffStrbufAppendS(buffer, state->passwd->pw_dir); - ffStrbufAppendS(buffer, suffix); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer); -} - -static void pathsAddAbsolute(FFlist* dirs, const char* path) -{ - FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); - ffStrbufInitA(buffer, 64); - ffStrbufAppendS(buffer, path); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer); -} - -static void pathsAddEnv(FFlist* dirs, const char* env) -{ - const char* envValue = getenv(env); - if(!ffStrSet(envValue)) - return; - - FFstrbuf value; - ffStrbufInitA(&value, 64); - ffStrbufAppendS(&value, envValue); - - uint32_t startIndex = 0; - while (startIndex < value.length) - { - uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':'); - value.chars[colonIndex] = '\0'; - - if(!ffStrSet(value.chars + startIndex)) - { - startIndex = colonIndex + 1; - continue; - } - - pathsAddAbsolute(dirs, value.chars + startIndex); - - startIndex = colonIndex + 1; - } - - ffStrbufDestroy(&value); -} - -#ifdef _WIN32 -static void pathsAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) -{ - PWSTR pPath; - if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath))) - { - FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); - ffStrbufInit(buffer); - ffStrbufSetWS(buffer, pPath); - ffStrbufReplaceAllC(buffer, '\\', '/'); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer); - } - CoTaskMemFree(pPath); -} - -static void pathsAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix) -{ - const char* value = getenv(env); - if(!ffStrSet(value)) - return; - - FFstrbuf* buffer = ffListAdd(dirs); - ffStrbufInitA(buffer, 64); - ffStrbufAppendS(buffer, value); - ffStrbufReplaceAllC(buffer, '\\', '/'); - ffStrbufEnsureEndsWithC(buffer, '/'); - ffStrbufAppendS(buffer, suffix); - ffStrbufEnsureEndsWithC(buffer, '/'); - FF_ENSURE_ONLY_ONCE_IN_LIST(dirs, buffer); -} -#endif - -static void initConfigDirs(FFstate* state) -{ - ffListInit(&state->configDirs, sizeof(FFstrbuf)); - - pathsAddEnv(&state->configDirs, "XDG_CONFIG_HOME"); // On systems where this is not set (Windows & Apple presumably), this wil do nothing - pathsAddHome(&state->configDirs, state, "/.config/"); - - #ifdef _WIN32 - pathsAddKnownFolder(&state->configDirs, &FOLDERID_RoamingAppData); - pathsAddKnownFolder(&state->configDirs, &FOLDERID_LocalAppData); - #elif defined(__APPLE__) - pathsAddHome(&state->configDirs, state, "/Library/Preferences/"); - #endif - - pathsAddHome(&state->configDirs, state, ""); - - #ifdef _WIN32 - if(getenv("MSYSTEM") && getenv("HOME")) - { - // We are in MSYS2 / Git Bash - pathsAddEnvSuffix(&state->configDirs, "HOME", ".config/"); - pathsAddEnvSuffix(&state->configDirs, "HOME", ""); - } - #endif - - pathsAddEnv(&state->configDirs, "XDG_CONFIG_DIRS"); - - #if !defined(_WIN32) && !defined(__APPLE__) - pathsAddAbsolute(&state->configDirs, FASTFETCH_TARGET_DIR_ETC"/xdg/"); - #endif - - #if !defined(_WIN32) - pathsAddAbsolute(&state->configDirs, FASTFETCH_TARGET_DIR_ETC"/"); - pathsAddAbsolute(&state->configDirs, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF"/"); - #endif -} - -static void initDataDirs(FFstate* state) -{ - ffListInit(&state->dataDirs, sizeof(FFstrbuf)); - - pathsAddEnv(&state->dataDirs, "XDG_DATA_HOME"); // On systems where this is not set (Windows & Apple presumably), this wil do nothing - pathsAddHome(&state->dataDirs, state, "/.local/share/"); - - #ifdef _WIN32 - pathsAddKnownFolder(&state->dataDirs, &FOLDERID_RoamingAppData); - pathsAddKnownFolder(&state->dataDirs, &FOLDERID_LocalAppData); - #elif defined(__APPLE__) - pathsAddHome(&state->dataDirs, state, "/Library/Application Support/"); - #endif - - pathsAddHome(&state->dataDirs, state, ""); - - #ifdef _WIN32 - if(getenv("MSYSTEM") && getenv("HOME")) - { - // We are in MSYS2 / Git Bash - pathsAddEnvSuffix(&state->dataDirs, "HOME", ".local/share/"); - pathsAddEnvSuffix(&state->dataDirs, "HOME", ""); - } - #endif - - pathsAddEnv(&state->dataDirs, "XDG_DATA_DIRS"); - - #if !defined(_WIN32) - pathsAddAbsolute(&state->dataDirs, FASTFETCH_TARGET_DIR_USR"/local/share/"); - pathsAddAbsolute(&state->dataDirs, FASTFETCH_TARGET_DIR_USR"/share/"); - #endif -} - static void initState(FFstate* state) { - #ifdef WIN32 - //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support - setlocale(LC_ALL, ".UTF8"); - #endif - state->logoWidth = 0; state->logoHeight = 0; state->keysHeight = 0; - #ifndef WIN32 - state->passwd = getpwuid(getuid()); - #else - state->passwd = ffGetPasswd(); - #endif - if(uname(&state->utsname) != 0) - memset(&state->utsname, 0, sizeof(struct utsname)); - - initConfigDirs(state); - initDataDirs(state); + ffPlatformInit(&state->platform); } static void initModuleArg(FFModuleArgs* args) @@ -366,6 +193,11 @@ static void defaultConfig(FFinstance* instance) void ffInitInstance(FFinstance* instance) { + #ifdef WIN32 + //https://learn.microsoft.com/en-us/cpp/c-runtime-library/reference/setlocale-wsetlocale?source=recommendations&view=msvc-170#utf-8-support + setlocale(LC_ALL, ".UTF8"); + #endif + initState(&instance->state); defaultConfig(instance); } @@ -588,13 +420,7 @@ static void destroyConfig(FFinstance* instance) static void destroyState(FFinstance* instance) { - FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.configDirs) - ffStrbufDestroy(configDir); - ffListDestroy(&instance->state.configDirs); - - FF_LIST_FOR_EACH(FFstrbuf, dataDir, instance->state.dataDirs) - ffStrbufDestroy(dataDir); - ffListDestroy(&instance->state.dataDirs); + ffPlatformDestroy(&instance->state.platform); } void ffDestroyInstance(FFinstance* instance) diff --git a/src/common/parsing.c b/src/common/parsing.c index 015235952..95bba4720 100644 --- a/src/common/parsing.c +++ b/src/common/parsing.c @@ -3,17 +3,6 @@ #include #include -bool ffStrSet(const char* str) -{ - if(str == NULL) - return false; - - while(isspace(*str)) - str++; - - return *str != '\0'; -} - void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch) { if(major->length > 0) diff --git a/src/common/parsing.h b/src/common/parsing.h index 239caa42f..613e20bb5 100644 --- a/src/common/parsing.h +++ b/src/common/parsing.h @@ -14,7 +14,6 @@ typedef struct FFVersion #define FF_VERSION_INIT ((FFVersion) {0}) -bool ffStrSet(const char* str); void ffParseSemver(FFstrbuf* buffer, const FFstrbuf* major, const FFstrbuf* minor, const FFstrbuf* patch); void ffParseGTK(FFstrbuf* buffer, const FFstrbuf* gtk2, const FFstrbuf* gtk3, const FFstrbuf* gtk4); diff --git a/src/common/properties.c b/src/common/properties.c index c2038be6b..2e3246517 100644 --- a/src/common/properties.c +++ b/src/common/properties.c @@ -148,7 +148,7 @@ bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeF { FFstrbuf absolutePath; ffStrbufInitA(&absolutePath, 64); - ffStrbufAppendS(&absolutePath, instance->state.passwd->pw_dir); + ffStrbufAppend(&absolutePath, &instance->state.platform.homeDir); ffStrbufAppendC(&absolutePath, '/'); ffStrbufAppendS(&absolutePath, relativeFile); diff --git a/src/common/properties.h b/src/common/properties.h index f10f7caaf..ea78ed903 100644 --- a/src/common/properties.h +++ b/src/common/properties.h @@ -34,7 +34,7 @@ static inline bool ffParsePropFileList(const FFlist* list, const char* relativeF static inline bool ffParsePropFileConfigValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { - return ffParsePropFileListValues(&instance->state.configDirs, relativeFile, numQueries, queries); + return ffParsePropFileListValues(&instance->state.platform.configDirs, relativeFile, numQueries, queries); } static inline bool ffParsePropFileConfig(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) @@ -44,7 +44,7 @@ static inline bool ffParsePropFileConfig(const FFinstance* instance, const char* static inline bool ffParsePropFileDataValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries) { - return ffParsePropFileListValues(&instance->state.dataDirs, relativeFile, numQueries, queries); + return ffParsePropFileListValues(&instance->state.platform.dataDirs, relativeFile, numQueries, queries); } static inline bool ffParsePropFileData(const FFinstance* instance, const char* relativeFile, const char* start, FFstrbuf* buffer) diff --git a/src/detection/gtk.c b/src/detection/gtk.c index 2e3c807d0..1db344edd 100644 --- a/src/detection/gtk.c +++ b/src/detection/gtk.c @@ -158,9 +158,9 @@ static void detectGTK(const FFinstance* instance, const char* version, FFGTKResu FFstrbuf baseDir; ffStrbufInitA(&baseDir, 64); - for(uint32_t i = 0; i < instance->state.configDirs.length; i++) + FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.platform.configDirs) { - ffStrbufSet(&baseDir, ffListGet(&instance->state.configDirs, i)); + ffStrbufSet(&baseDir, configDir); detectGTKFromConfigDir(&baseDir, version, result); if(allPropertiesSet(result)) break; diff --git a/src/detection/os/os.h b/src/detection/os/os.h index 688d6f63b..80fb6b2af 100644 --- a/src/detection/os/os.h +++ b/src/detection/os/os.h @@ -17,8 +17,6 @@ typedef struct FFOSResult FFstrbuf versionID; FFstrbuf codename; FFstrbuf buildID; - FFstrbuf systemName; - FFstrbuf architecture; } FFOSResult; const FFOSResult* ffDetectOS(const FFinstance* instance); diff --git a/src/detection/os/os_android.c b/src/detection/os/os_android.c index eb4bf97d5..890486ab7 100644 --- a/src/detection/os/os_android.c +++ b/src/detection/os/os_android.c @@ -23,10 +23,6 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->buildID); ffSettingsGetAndroidProperty("ro.build.id", &os->buildID); - ffStrbufInitS(&os->systemName, instance->state.utsname.sysname); - - ffStrbufInitS(&os->architecture, instance->state.utsname.machine); - ffStrbufInit(&os->idLike); ffStrbufInit(&os->variant); ffStrbufInit(&os->variantID); diff --git a/src/detection/os/os_apple.m b/src/detection/os/os_apple.m index d6a410506..8f8174387 100644 --- a/src/detection/os/os_apple.m +++ b/src/detection/os/os_apple.m @@ -61,8 +61,6 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->id); ffStrbufInit(&os->prettyName); ffStrbufInit(&os->versionID); - ffStrbufInit(&os->systemName); - ffStrbufInit(&os->architecture); ffStrbufInitA(&os->codename, 0); ffStrbufInitA(&os->idLike, 0); @@ -82,8 +80,6 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufAppend(&os->prettyName, &os->name); ffStrbufAppend(&os->versionID, &os->version); - ffSysctlGetString("kern.ostype", &os->systemName); - ffSysctlGetString("hw.machine", &os->architecture); parseOSXSoftwareLicense(os); } diff --git a/src/detection/os/os_linux.c b/src/detection/os/os_linux.c index 73c513922..45a0f5cec 100644 --- a/src/detection/os/os_linux.c +++ b/src/detection/os/os_linux.c @@ -138,11 +138,6 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->versionID); ffStrbufInit(&os->codename); ffStrbufInit(&os->buildID); - ffStrbufInit(&os->systemName); - ffStrbufInit(&os->architecture); - - ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); - ffStrbufSetS(&os->architecture, instance->state.utsname.machine); detectOS(os, instance); diff --git a/src/detection/os/os_windows.cpp b/src/detection/os/os_windows.cpp index fdda72c89..2dee095a0 100644 --- a/src/detection/os/os_windows.cpp +++ b/src/detection/os/os_windows.cpp @@ -56,8 +56,6 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) ffStrbufInit(&os->versionID); ffStrbufInit(&os->codename); ffStrbufInit(&os->buildID); - ffStrbufInit(&os->systemName); - ffStrbufInit(&os->architecture); if(getOsNameByWinbrand(&os->variant) && getOsNameByWmi(&os->variant)) return; @@ -106,7 +104,4 @@ void ffDetectOSImpl(FFOSResult* os, const FFinstance* instance) } ffStrbufAppendF(&os->id, "%*s %*s", os->prettyName.length, os->prettyName.chars, os->version.length, os->version.chars); - - ffStrbufSetS(&os->architecture, instance->state.utsname.machine); - ffStrbufSetS(&os->systemName, instance->state.utsname.sysname); } diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index a44d586f0..2c448f9a9 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -339,7 +339,7 @@ void ffDetectPackagesImpl(const FFinstance* instance, FFPackagesResult* result) result->rpm = getRpmFromLibrpm(instance); #endif - ffStrbufSetS(&baseDir, instance->state.passwd->pw_dir); + ffStrbufSet(&baseDir, &instance->state.platform.homeDir); result->nixUser = getNixPackages(&baseDir, "/.nix-profile"); ffStrbufDestroy(&baseDir); diff --git a/src/detection/qt.c b/src/detection/qt.c index 6a7794c8e..5ac1d943e 100644 --- a/src/detection/qt.c +++ b/src/detection/qt.c @@ -88,9 +88,9 @@ static void detectPlasma(const FFinstance* instance, FFQtResult* result) FFstrbuf baseDir; ffStrbufInitA(&baseDir, 64); - for(uint32_t i = 0; i < instance->state.configDirs.length; i++) + FF_LIST_FOR_EACH(FFstrbuf, configDir, instance->state.platform.configDirs) { - ffStrbufSet(&baseDir, ffListGet(&instance->state.configDirs, i)); + ffStrbufSet(&baseDir, configDir); ffStrbufAppendS(&baseDir, "kdeglobals"); if(detectPlasmaFromFile(baseDir.chars, result)) diff --git a/src/detection/terminalfont/terminalfont_linux.c b/src/detection/terminalfont/terminalfont_linux.c index 8eb90e7c5..1d06d09c1 100644 --- a/src/detection/terminalfont/terminalfont_linux.c +++ b/src/detection/terminalfont/terminalfont_linux.c @@ -149,7 +149,9 @@ static void detectDeepinTerminal(const FFinstance* instance, FFTerminalFontResul ffStrbufInit(&fontSize); FFstrbuf profile; - ffStrbufInitF(&profile, "%s/.config/deepin/deepin-terminal/config.conf", instance->state.passwd->pw_dir); + ffStrbufInit(&profile); + ffStrbufAppend(&profile, &instance->state.platform.homeDir); + ffStrbufAppendS(&profile, ".config/deepin/deepin-terminal/config.conf"); //TODO: Use config dirs FILE* file = fopen(profile.chars, "r"); if(file) diff --git a/src/detection/terminalshell/terminalshell_linux.c b/src/detection/terminalshell/terminalshell_linux.c index 07b902dac..1f30866c2 100644 --- a/src/detection/terminalshell/terminalshell_linux.c +++ b/src/detection/terminalshell/terminalshell_linux.c @@ -261,10 +261,7 @@ static void getTerminalFromEnv(FFTerminalShellResult* result) static void getUserShellFromEnv(const FFinstance* instance, FFTerminalShellResult* result) { - if(instance->state.passwd->pw_shell[0] != '\0') - ffStrbufAppendS(&result->userShellExe, instance->state.passwd->pw_shell); - else - ffStrbufAppendS(&result->userShellExe, getenv("SHELL")); + ffStrbufSet(&result->userShellExe, &instance->state.platform.userShell); if(result->userShellExe.length == 0) return; diff --git a/src/detection/title.c b/src/detection/title.c deleted file mode 100644 index df9367ba0..000000000 --- a/src/detection/title.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "fastfetch.h" -#include "detection/title.h" -#include "common/thread.h" - -#include -#include - -#ifndef HOST_NAME_MAX - #define HOST_NAME_MAX 64 -#endif - -#ifdef __linux__ -#include - -static void detectFQDN(FFTitleResult* title) -{ - struct addrinfo hints = {0}; - hints.ai_socktype = SOCK_STREAM; - hints.ai_flags = AI_CANONNAME; - - struct addrinfo* info = NULL; - - if(getaddrinfo(title->hostname.chars, "80", &hints, &info) == 0) - { - struct addrinfo* current = info; - while(title->fqdn.length == 0 && current != NULL) - { - ffStrbufAppendS(&title->fqdn, current->ai_canonname); - current = current->ai_next; - } - - freeaddrinfo(info); - } -} -#endif - -const FFTitleResult* ffDetectTitle(const FFinstance* instance) -{ - static FFTitleResult result; - - static FFThreadMutex mutex = FF_THREAD_MUTEX_INITIALIZER; - static bool init = false; - ffThreadMutexLock(&mutex); - if(init) - { - ffThreadMutexUnlock(&mutex); - return &result; - } - init = true; - - ffStrbufInit(&result.userName); - ffStrbufAppendS(&result.userName, instance->state.passwd->pw_name); - - ffStrbufInitA(&result.hostname, HOST_NAME_MAX); - ffStrbufAppendS(&result.hostname, instance->state.utsname.nodename); - - ffStrbufInitA(&result.fqdn, HOST_NAME_MAX); - #ifdef __linux__ - detectFQDN(&result); - #endif - if(result.fqdn.length == 0) - ffStrbufAppend(&result.fqdn, &result.hostname); - - ffThreadMutexUnlock(&mutex); - return &result; -} diff --git a/src/detection/title.h b/src/detection/title.h deleted file mode 100644 index 9dc31d312..000000000 --- a/src/detection/title.h +++ /dev/null @@ -1,17 +0,0 @@ -#pragma once - -#ifndef FF_INCLUDED_detection_title -#define FF_INCLUDED_detection_title - -#include "fastfetch.h" - -typedef struct FFTitleResult -{ - FFstrbuf userName; - FFstrbuf hostname; - FFstrbuf fqdn; //Fully qualified domain name -} FFTitleResult; - -const FFTitleResult* ffDetectTitle(const FFinstance* instance); - -#endif diff --git a/src/detection/wmtheme/wmtheme_linux.c b/src/detection/wmtheme/wmtheme_linux.c index 19765c79a..6efba12c5 100644 --- a/src/detection/wmtheme/wmtheme_linux.c +++ b/src/detection/wmtheme/wmtheme_linux.c @@ -131,9 +131,9 @@ static bool detectOpenbox(FFinstance* instance, const FFstrbuf* dePrettyName, FF { FFstrbuf absolutePath; ffStrbufInitA(&absolutePath, 64); - ffStrbufAppendS(&absolutePath, instance->state.passwd->pw_dir); - ffStrbufAppendC(&absolutePath, '/'); + ffStrbufAppend(&absolutePath, &instance->state.platform.homeDir); + //TODO: use config dirs if(ffStrbufIgnCaseCompS(dePrettyName, "LXQT") == 0) ffStrbufAppendS(&absolutePath, ".config/openbox/lxqt-rc.xml"); else if(ffStrbufIgnCaseCompS(dePrettyName, "LXDE") == 0) diff --git a/src/fastfetch.c b/src/fastfetch.c index e732422c3..8df75819f 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -527,7 +527,7 @@ static inline void listAvailablePresetsFromFolder(FFstrbuf* folder, uint8_t inde static inline void listAvailablePresets(FFinstance* instance) { - FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.platform.dataDirs) { ffStrbufAppendS(path, "fastfetch/presets/"); listAvailablePresetsFromFolder(path, 0, NULL); @@ -536,7 +536,7 @@ static inline void listAvailablePresets(FFinstance* instance) static void listConfigPaths(FFinstance* instance) { - FF_LIST_FOR_EACH(FFstrbuf, folder, instance->state.configDirs) + FF_LIST_FOR_EACH(FFstrbuf, folder, instance->state.platform.configDirs) { ffStrbufAppendS(folder, "fastfetch/config.conf"); printf("%s%s\n", folder->chars, ffFileExists(folder->chars, S_IFREG) ? " (*)" : ""); @@ -545,7 +545,7 @@ static void listConfigPaths(FFinstance* instance) static void listDataPaths(FFinstance* instance) { - FF_LIST_FOR_EACH(FFstrbuf, folder, instance->state.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, folder, instance->state.platform.dataDirs) { ffStrbufAppendS(folder, "fastfetch/"); puts(folder->chars); @@ -619,7 +619,7 @@ static bool parseConfigFile(FFinstance* instance, FFdata* data, const char* path static void generateConfigFile(FFinstance* instance, bool force) { - FFstrbuf* filename = (FFstrbuf*) ffListGet(&instance->state.configDirs, 0); + FFstrbuf* filename = (FFstrbuf*) ffListGet(&instance->state.platform.configDirs, 0); // Paths generated in `init.c/initConfigDirs` end with `/` ffStrbufAppendS(filename, "fastfetch/config.conf"); @@ -651,7 +651,7 @@ static void optionParseConfigFile(FFinstance* instance, FFdata* data, const char //Try to load as a relative path - FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, path, instance->state.platform.dataDirs) { uint32_t pathLength = path->length; @@ -1330,12 +1330,12 @@ error: static void parseConfigFiles(FFinstance* instance, FFdata* data) { - for(uint32_t i = instance->state.configDirs.length; i > 0; --i) + for(uint32_t i = instance->state.platform.configDirs.length; i > 0; --i) { if(!data->loadUserConfig) return; - FFstrbuf* dir = ffListGet(&instance->state.configDirs, i - 1); + FFstrbuf* dir = ffListGet(&instance->state.platform.configDirs, i - 1); uint32_t dirLength = dir->length; ffStrbufAppendS(dir, "fastfetch/config.conf"); diff --git a/src/fastfetch.h b/src/fastfetch.h index c793b3c0e..93be159df 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -8,16 +8,9 @@ #include #include -#ifndef _WIN32 - #include - #include -#else - #include "util/windows/pwd.h" - #include "util/windows/utsname.h" -#endif - #include "util/FFstrbuf.h" #include "util/FFlist.h" +#include "util/platform/FFPlatform.h" static inline void ffUnused(int dummy, ...) { (void) dummy; } #define FF_UNUSED(...) ffUnused(0, __VA_ARGS__); @@ -220,11 +213,7 @@ typedef struct FFstate uint32_t logoHeight; uint32_t keysHeight; - struct passwd* passwd; - struct utsname utsname; - - FFlist configDirs; // List of FFstrbuf, trailing slash included - FFlist dataDirs; // List of FFstrbuf, trailing slash included + FFPlatform platform; } FFstate; typedef struct FFinstance diff --git a/src/logo/image/image.c b/src/logo/image/image.c index 171809278..b2bfff6b5 100644 --- a/src/logo/image/image.c +++ b/src/logo/image/image.c @@ -691,20 +691,8 @@ static bool printImageIfExistsSlowPath(FFinstance* instance, FFLogoType type) requestData.logoPixelWidth = simpleCeil((double) instance->config.logo.width * requestData.characterPixelWidth); requestData.logoPixelHeight = simpleCeil((double) instance->config.logo.height * requestData.characterPixelHeight); - ffStrbufInitA(&requestData.cacheDir, PATH_MAX * 2); - - #if !(defined(_WIN32) || defined(__APPLE__) || defined(__ANDROID__)) - ffStrbufAppendS(&requestData.cacheDir, getenv("XDG_CACHE_HOME")); - #endif - - if(requestData.cacheDir.length == 0) - { - ffStrbufAppendS(&requestData.cacheDir, instance->state.passwd->pw_dir); - ffStrbufAppendS(&requestData.cacheDir, "/.cache/"); - } - else - ffStrbufEnsureEndsWithC(&requestData.cacheDir, '/'); - + ffStrbufInit(&requestData.cacheDir); + ffStrbufAppend(&requestData.cacheDir, &instance->state.platform.cacheDir); ffStrbufAppendS(&requestData.cacheDir, "fastfetch"); ffStrbufEnsureFree(&requestData.cacheDir, PATH_MAX); diff --git a/src/logo/logo.c b/src/logo/logo.c index dd9f7ddd5..60cbdf8bb 100644 --- a/src/logo/logo.c +++ b/src/logo/logo.c @@ -205,7 +205,7 @@ static const FFlogo* logoGetBuiltin(const char* name) return NULL; } -static const FFlogo* logoGetBuiltinDetected(FFinstance* instance) +static const FFlogo* logoGetBuiltinDetected(const FFinstance* instance) { const FFOSResult* os = ffDetectOS(instance); @@ -225,7 +225,7 @@ static const FFlogo* logoGetBuiltinDetected(FFinstance* instance) if(logo != NULL) return logo; - logo = logoGetBuiltin(os->systemName.chars); + logo = logoGetBuiltin(instance->state.platform.systemName.chars); if(logo != NULL) return logo; @@ -293,7 +293,7 @@ static bool loadLogoFile(const FFinstance* instance, FFstrbuf* buffer) FFstrbuf fullPath; ffStrbufInit(&fullPath); - FF_LIST_FOR_EACH(FFstrbuf, dataDir, instance->state.dataDirs) + FF_LIST_FOR_EACH(FFstrbuf, dataDir, instance->state.platform.dataDirs) { //We need to copy it, because multiple threads might be using dataDirs at the same time ffStrbufSet(&fullPath, dataDir); diff --git a/src/modules/kernel.c b/src/modules/kernel.c index 72096ce55..bc1139833 100644 --- a/src/modules/kernel.c +++ b/src/modules/kernel.c @@ -2,29 +2,29 @@ #include "common/printing.h" #define FF_KERNEL_MODULE_NAME "Kernel" -#define FF_KERNEL_NUM_FORMAT_ARGS 3 +#define FF_KERNEL_NUM_FORMAT_ARGS 4 void ffPrintKernel(FFinstance* instance) { if(instance->config.kernel.outputFormat.length == 0) { ffPrintLogoAndKey(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel.key); + ffStrbufWriteTo(&instance->state.platform.systemRelease, stdout); #ifdef _WIN32 - if(instance->state.utsname.version[0] != '\0') - printf("%s (%s)\n", instance->state.utsname.release, instance->state.utsname.version); - else - puts(instance->state.utsname.release); - #else - puts(instance->state.utsname.release); + if(instance->state.platform.systemVersion.length > 0) + printf(" (%s)", instance->state.platform.systemVersion.chars); #endif + + putchar('\n'); } else { ffPrintFormat(instance, FF_KERNEL_MODULE_NAME, 0, &instance->config.kernel, FF_KERNEL_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, - {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.release}, - {FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.version} + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemRelease}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemVersion}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemArchitecture} }); } } diff --git a/src/modules/os.c b/src/modules/os.c index 7d5a15842..140cfdbbe 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -7,7 +7,7 @@ #define FF_OS_MODULE_NAME "OS" #define FF_OS_NUM_FORMAT_ARGS 12 -static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result) +static void buildOutputDefault(const FFinstance* instance, const FFOSResult* os, FFstrbuf* result) { //Create the basic output if(os->name.length > 0) @@ -17,7 +17,7 @@ static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result) else if(os->id.length > 0) ffStrbufAppend(result, &os->id); else - ffStrbufAppend(result, &os->systemName); + ffStrbufAppend(result, &instance->state.platform.systemName); #ifdef __APPLE__ if(os->codename.length > 0) @@ -62,14 +62,14 @@ static void buildOutputDefault(const FFOSResult* os, FFstrbuf* result) } //Append architecture if it is missing - if(ffStrbufFirstIndex(result, &os->architecture) == result->length) + if(ffStrbufFirstIndex(result, &instance->state.platform.systemArchitecture) == result->length) { ffStrbufAppendC(result, ' '); - ffStrbufAppend(result, &os->architecture); + ffStrbufAppend(result, &instance->state.platform.systemArchitecture); } } -static void buildOutputNixOS(const FFOSResult* os, FFstrbuf* result) +static void buildOutputNixOS(const FFinstance* instance, const FFOSResult* os, FFstrbuf* result) { ffStrbufAppendS(result, "NixOS"); @@ -87,10 +87,10 @@ static void buildOutputNixOS(const FFOSResult* os, FFstrbuf* result) ffStrbufAppendC(result, ')'); } - if(os->architecture.length > 0) + if(instance->state.platform.systemArchitecture.length > 0) { ffStrbufAppendC(result, ' '); - ffStrbufAppend(result, &os->architecture); + ffStrbufAppend(result, &instance->state.platform.systemArchitecture); } } @@ -98,7 +98,7 @@ void ffPrintOS(FFinstance* instance) { const FFOSResult* os = ffDetectOS(instance); - if(os->name.length == 0 && os->prettyName.length == 0 && os->id.length == 0 && os->systemName.length == 0) + if(os->name.length == 0 && os->prettyName.length == 0 && os->id.length == 0) { ffPrintError(instance, FF_OS_MODULE_NAME, 0, &instance->config.os, "Could not detect OS"); return; @@ -110,9 +110,9 @@ void ffPrintOS(FFinstance* instance) ffStrbufInit(&result); if(ffStrbufIgnCaseCompS(&os->id, "nixos") == 0) - buildOutputNixOS(os, &result); + buildOutputNixOS(instance, os, &result); else - buildOutputDefault(os, &result); + buildOutputDefault(instance, os, &result); ffPrintLogoAndKey(instance, FF_OS_MODULE_NAME, 0, &instance->config.os.key); ffStrbufPutTo(&result, stdout); @@ -121,7 +121,7 @@ void ffPrintOS(FFinstance* instance) else { ffPrintFormat(instance, FF_OS_MODULE_NAME, 0, &instance->config.os, FF_OS_NUM_FORMAT_ARGS, (FFformatarg[]){ - {FF_FORMAT_ARG_TYPE_STRBUF, &os->systemName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemName}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->name}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->prettyName}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->id}, @@ -132,7 +132,7 @@ void ffPrintOS(FFinstance* instance) {FF_FORMAT_ARG_TYPE_STRBUF, &os->versionID}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->codename}, {FF_FORMAT_ARG_TYPE_STRBUF, &os->buildID}, - {FF_FORMAT_ARG_TYPE_STRBUF, &os->architecture} + {FF_FORMAT_ARG_TYPE_STRBUF, &instance->state.platform.systemArchitecture} }); } } diff --git a/src/modules/separator.c b/src/modules/separator.c index 7227f9ae4..879bc5bb8 100644 --- a/src/modules/separator.c +++ b/src/modules/separator.c @@ -1,12 +1,12 @@ #include "fastfetch.h" #include "common/printing.h" -#include "detection/title.h" void ffPrintSeparator(FFinstance* instance) { - const FFTitleResult* result = ffDetectTitle(instance); - uint32_t titleLength = result->userName.length + 1 + - (instance->config.titleFQDN ? result->fqdn.length : result->hostname.length); + uint32_t titleLength = instance->state.platform.userName.length + 1 + (instance->config.titleFQDN ? + instance->state.platform.domainName.length : + instance->state.platform.hostName.length + ); ffLogoPrintLine(instance); diff --git a/src/modules/title.c b/src/modules/title.c index cef00d146..4e509fbe5 100644 --- a/src/modules/title.c +++ b/src/modules/title.c @@ -1,6 +1,5 @@ #include "fastfetch.h" #include "common/printing.h" -#include "detection/title.h" #include "util/textModifier.h" static inline void printTitlePart(FFinstance* instance, const FFstrbuf* content) @@ -19,12 +18,13 @@ static inline void printTitlePart(FFinstance* instance, const FFstrbuf* content) void ffPrintTitle(FFinstance* instance) { - const FFTitleResult* result = ffDetectTitle(instance); - ffLogoPrintLine(instance); - printTitlePart(instance, &result->userName); + printTitlePart(instance, &instance->state.platform.userName); putchar('@'); - printTitlePart(instance, instance->config.titleFQDN ? &result->fqdn : &result->hostname); + printTitlePart(instance, instance->config.titleFQDN ? + &instance->state.platform.domainName : + &instance->state.platform.hostName + ); putchar('\n'); } diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index 94f436d51..375c53aaa 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -3,6 +3,17 @@ #include #include +bool ffStrSet(const char* str) +{ + if(str == NULL) + return false; + + while(isspace(*str)) + str++; + + return *str != '\0'; +} + static char* CHAR_NULL_PTR = ""; void ffStrbufInitA(FFstrbuf* strbuf, uint32_t allocate) diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 7755225a7..7342cb607 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -18,6 +18,8 @@ #define strcasestr StrStrIA #endif +bool ffStrSet(const char* str); + #define FASTFETCH_STRBUF_DEFAULT_ALLOC 32 typedef struct FFstrbuf diff --git a/src/util/platform/FFPlatform.c b/src/util/platform/FFPlatform.c new file mode 100644 index 000000000..9ea045736 --- /dev/null +++ b/src/util/platform/FFPlatform.c @@ -0,0 +1,118 @@ +#include "FFPlatform_private.h" + +void ffPlatformInit(FFPlatform* platform) +{ + ffStrbufInit(&platform->homeDir); + ffStrbufInit(&platform->cacheDir); + ffListInit(&platform->configDirs, sizeof(FFstrbuf)); + ffListInit(&platform->dataDirs, sizeof(FFstrbuf)); + + ffStrbufInit(&platform->userName); + ffStrbufInit(&platform->hostName); + ffStrbufInit(&platform->domainName); + ffStrbufInit(&platform->userShell); + + ffStrbufInit(&platform->systemName); + ffStrbufInit(&platform->systemRelease); + ffStrbufInit(&platform->systemVersion); + ffStrbufInit(&platform->systemArchitecture); + + ffPlatformInitÎmpl(platform); + + if(platform->domainName.length == 0) + ffStrbufAppend(&platform->domainName, &platform->hostName); + + if(platform->systemName.length == 0) + { + #if defined(__linux__) + ffStrbufAppendS(&platform->systemName, "Linux"); + #elif defined(__FreeBSD__) + ffStrbufAppendS(&platform->systemName, "FreeBSD"); + #elif defined(__APPLE__) + ffStrbufAppendS(&platform->systemName, "Darwin"); + #elif defined(__WIN32__) || defined(__WIN64__) + ffStrbufAppendS(&platform->systemName, "Windows_NT"); + #endif + } + + if(platform->systemArchitecture.length == 0) + { + #if defined(__x86_64__) || defined(__x86_64) || defined(__amd64__) || defined(__amd64) + ffStrbufAppendS(&platform->systemArchitecture, "x86_64"); + #elif defined(__i386__) || defined(__i386) || defined(__i486__) || defined(__i486) || defined(__i586__) || defined(__i586) || defined(__i686__) || defined(__i686) + ffStrbufAppendS(&platform->systemArchitecture, "i386"); + #elif defined(__aarch64__) + ffStrbufAppendS(&platform->systemArchitecture, "aarch64"); + #elif defined(__arm__) + ffStrbufAppendS(&platform->systemArchitecture, "arm"); + #endif + } +} + +void ffPlatformDestroy(FFPlatform* platform) +{ + ffStrbufDestroy(&platform->homeDir); + ffStrbufDestroy(&platform->cacheDir); + + FF_LIST_FOR_EACH(FFstrbuf, dir, platform->configDirs) + ffStrbufDestroy(dir); + ffListDestroy(&platform->configDirs); + + FF_LIST_FOR_EACH(FFstrbuf, dir, platform->dataDirs) + ffStrbufDestroy(dir); + ffListDestroy(&platform->dataDirs); + + ffStrbufDestroy(&platform->userName); + ffStrbufDestroy(&platform->hostName); + ffStrbufDestroy(&platform->domainName); + ffStrbufDestroy(&platform->userShell); +} + +void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path) +{ + FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); + ffStrbufInitA(buffer, 64); + ffStrbufAppendS(buffer, path); + ffStrbufEnsureEndsWithC(buffer, '/'); + FF_PLATFORM_PATH_UNIQUE(dirs, buffer); +} + +void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix) +{ + FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); + ffStrbufInitA(buffer, 64); + ffStrbufAppend(buffer, &platform->homeDir); + ffStrbufAppendS(buffer, suffix); + ffStrbufEnsureEndsWithC(buffer, '/'); + FF_PLATFORM_PATH_UNIQUE(dirs, buffer); +} + +void ffPlatformPathAddEnv(FFlist* dirs, const char* env) +{ + const char* envValue = getenv(env); + if(!ffStrSet(envValue)) + return; + + FFstrbuf value; + ffStrbufInitA(&value, 64); + ffStrbufAppendS(&value, envValue); + + uint32_t startIndex = 0; + while (startIndex < value.length) + { + uint32_t colonIndex = ffStrbufNextIndexC(&value, startIndex, ':'); + value.chars[colonIndex] = '\0'; + + if(!ffStrSet(value.chars + startIndex)) + { + startIndex = colonIndex + 1; + continue; + } + + ffPlatformPathAddAbsolute(dirs, value.chars + startIndex); + + startIndex = colonIndex + 1; + } + + ffStrbufDestroy(&value); +} diff --git a/src/util/platform/FFPlatform.h b/src/util/platform/FFPlatform.h new file mode 100644 index 000000000..caebc7c6f --- /dev/null +++ b/src/util/platform/FFPlatform.h @@ -0,0 +1,29 @@ +#pragma once + +#ifndef FF_INCLUDED_util_platform_FFPlatform +#define FF_INCLUDED_util_platform_FFPlatform + +#include "util/FFstrbuf.h" +#include "util/FFlist.h" + +typedef struct FFPlatform { + FFstrbuf homeDir; // Trailing slash included + FFstrbuf cacheDir; // Trailing slash included + FFlist configDirs; // List of FFstrbuf, trailing slash included + FFlist dataDirs; // List of FFstrbuf, trailing slash included + + FFstrbuf userName; + FFstrbuf hostName; + FFstrbuf domainName; + FFstrbuf userShell; + + FFstrbuf systemName; + FFstrbuf systemRelease; + FFstrbuf systemVersion; + FFstrbuf systemArchitecture; +} FFPlatform; + +void ffPlatformInit(FFPlatform* platform); +void ffPlatformDestroy(FFPlatform* platform); + +#endif diff --git a/src/util/platform/FFPlatform_private.h b/src/util/platform/FFPlatform_private.h new file mode 100644 index 000000000..c51d01d80 --- /dev/null +++ b/src/util/platform/FFPlatform_private.h @@ -0,0 +1,21 @@ +#pragma once + +#ifndef FF_INCLUDED_util_platform_FFPlatform_private +#define FF_INCLUDED_util_platform_FFPlatform_private + +#include "FFPlatform.h" + +void ffPlatformInitÎmpl(FFPlatform* platform); + +#define FF_PLATFORM_PATH_UNIQUE(list, element) \ + if(ffListFirstIndexComp(list, element, (bool(*)(const void*, const void*))ffStrbufEqual) < list->length - 1) \ + { \ + ffStrbufDestroy(ffListGet(list, list->length - 1)); \ + --list->length; \ + } + +void ffPlatformPathAddAbsolute(FFlist* dirs, const char* path); +void ffPlatformPathAddHome(FFlist* dirs, const FFPlatform* platform, const char* suffix); +void ffPlatformPathAddEnv(FFlist* dirs, const char* env); + +#endif diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c new file mode 100644 index 000000000..e5adaac95 --- /dev/null +++ b/src/util/platform/FFPlatform_unix.c @@ -0,0 +1,138 @@ +#include "FFPlatform_private.h" + +#include "fastfetch_config.h" + +#include +#include +#include +#include + +static void getHomeDir(FFPlatform* platform, const struct passwd* pwd) +{ + const char* home = getenv("HOME"); + if(!ffStrSet(home) && pwd) + home = pwd->pw_dir; + + ffStrbufAppendS(&platform->homeDir, home); + ffStrbufEnsureEndsWithC(&platform->homeDir, '/'); +} + +static void getCacheDir(FFPlatform* platform) +{ + const char* cache = getenv("XDG_CACHE_HOME"); + if(ffStrSet(cache)) + { + ffStrbufAppendS(&platform->cacheDir, cache); + ffStrbufEnsureEndsWithC(&platform->cacheDir, '/'); + } + else + { + ffStrbufAppend(&platform->cacheDir, &platform->homeDir); + ffStrbufAppendS(&platform->cacheDir, ".cache/"); + } + + ffStrbufAppendS(&platform->cacheDir, "fastfetch/"); +} + +static void getConfigDirs(FFPlatform* platform) +{ + ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME"); + ffPlatformPathAddHome(&platform->configDirs, platform, ".config/"); + + #if defined(__APPLE__) + pathsAddHome(&state->configDirs, state, "/Library/Preferences/"); + #endif + + ffPlatformPathAddHome(&platform->configDirs, platform, ""); + ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS"); + + #if !defined(__APPLE__) + ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC"/xdg/"); + #endif + + ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_ETC"/"); + ffPlatformPathAddAbsolute(&platform->configDirs, FASTFETCH_TARGET_DIR_INSTALL_SYSCONF"/"); +} + +static void getDataDirs(FFPlatform* platform) +{ + ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME"); + ffPlatformPathAddHome(&platform->dataDirs, platform, ".local/share/"); + ffPlatformPathAddHome(&platform->dataDirs, platform, ""); + ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS"); + ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR"/local/share/"); + ffPlatformPathAddAbsolute(&platform->dataDirs, FASTFETCH_TARGET_DIR_USR"/share/"); +} + +static void getUserName(FFPlatform* platform, const struct passwd* pwd) +{ + const char* user = getenv("USER"); + if(!ffStrSet(user) && pwd) + user = pwd->pw_name; + + ffStrbufAppendS(&platform->userName, user); +} + +static void getHostName(FFPlatform* platform, const struct utsname* uts) +{ + char hostname[256]; + if(gethostname(hostname, sizeof(hostname)) == 0) + ffStrbufAppendS(&platform->hostName, hostname); + + if(platform->hostName.length == 0) + ffStrbufAppendS(&platform->hostName, uts->nodename); +} + +static void getDomainName(FFPlatform* platform) +{ + struct addrinfo hints = {0}; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags = AI_CANONNAME; + + struct addrinfo* info = NULL; + + if(getaddrinfo(platform->hostName.chars, "80", &hints, &info) != 0) + return; + + struct addrinfo* current = info; + while(platform->domainName.length == 0 && current != NULL) + { + ffStrbufAppendS(&platform->domainName, current->ai_canonname); + current = current->ai_next; + } + + freeaddrinfo(info); +} + +static void getUserShell(FFPlatform* platform, const struct passwd* pwd) +{ + const char* shell = getenv("SHELL"); + if(!ffStrSet(shell) && pwd) + shell = pwd->pw_shell; + + ffStrbufAppendS(&platform->userShell, shell); +} + +void ffPlatformInitÎmpl(FFPlatform* platform) +{ + struct passwd* pwd = getpwuid(getuid()); + + struct utsname uts; + if(uname(&uts) != 0) + memset(&uts, 0, sizeof(uts)); + + getHomeDir(platform, pwd); + getCacheDir(platform); + getConfigDirs(platform); + getDataDirs(platform); + + getUserName(platform, pwd); + getHostName(platform, &uts); + getDomainName(platform); + getUserShell(platform, pwd); + + ffStrbufAppendS(&platform->systemName, uts.sysname); + ffStrbufAppendS(&platform->systemRelease, uts.release); + ffStrbufAppendS(&platform->systemVersion, uts.version); + ffStrbufAppendS(&platform->systemArchitecture, uts.machine); +} diff --git a/src/util/platform/FFPlatform_windows.c b/src/util/platform/FFPlatform_windows.c new file mode 100644 index 000000000..ade0087fc --- /dev/null +++ b/src/util/platform/FFPlatform_windows.c @@ -0,0 +1,228 @@ +#include "FFPlatform_private.h" + +#define WIN32_LEAN_AND_MEAN +#include +#include + +#include "util/windows/unicode.h" + +static void getHomeDir(FFPlatform* platform) +{ + PWSTR pPath; + if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath))) + { + ffStrbufSetWS(&platform->home_dir, pPath); + ffStrbufReplaceAllC(&platform->home_dir, '\\', '/'); + ffStrbufEnsureEndsWithC(&platform->home_dir, '/'); + } + CoTaskMemFree(pPath); +} + +static void getCacheDir(FFPlatform* platform) +{ + PWSTR pPath; + if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_LocalAppData, KF_FLAG_DEFAULT, NULL, &pPath))) + { + ffStrbufSetWS(&platform->cache_dir, pPath); + ffStrbufReplaceAllC(&platform->cache_dir, '\\', '/'); + ffStrbufEnsureEndsWithC(&platform->cache_dir, '/'); + } + else + { + ffStrbufAppend(&platform->cache_dir, &platform->home_dir); + ffStrbufAppendS(&platform->cache_dir, "AppData/Local/"); + } + CoTaskMemFree(pPath); + + ffStrbufAppendS(&platform->cache_dir, "fastfetch/"); +} + +static void platformPathAddKnownFolder(FFlist* dirs, REFKNOWNFOLDERID folderId) +{ + PWSTR pPath; + if(SUCCEEDED(SHGetKnownFolderPath(folderId, 0, NULL, &pPath))) + { + FFstrbuf* buffer = (FFstrbuf*) ffListAdd(dirs); + ffStrbufInit(buffer); + ffStrbufSetWS(buffer, pPath); + ffStrbufReplaceAllC(buffer, '\\', '/'); + ffStrbufEnsureEndsWithC(buffer, '/'); + FF_PLATFORM_PATH_UNIQUE(dirs, buffer); + } + CoTaskMemFree(pPath); +} + +static void platformPathAddEnvSuffix(FFlist* dirs, const char* env, const char* suffix) +{ + const char* value = getenv(env); + if(!ffStrSet(value)) + return; + + FFstrbuf* buffer = ffListAdd(dirs); + ffStrbufInitA(buffer, 64); + ffStrbufAppendS(buffer, value); + ffStrbufReplaceAllC(buffer, '\\', '/'); + ffStrbufEnsureEndsWithC(buffer, '/'); + ffStrbufAppendS(buffer, suffix); + ffStrbufEnsureEndsWithC(buffer, '/'); + FF_PLATFORM_PATH_UNIQUE(dirs, buffer); +} + +static void getConfigDirs(FFPlatform* platform) +{ + ffListInit(&platform->configDirs, sizeof(FFstrbuf)); + + ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME"); + ffPlatformPathAddHome(&platform->configDirs, platform, "/.config/"); + platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_RoamingAppData); + platformPathAddKnownFolder(&platform->configDirs, &FOLDERID_LocalAppData); + ffPlatformPathAddHome(&platform->configDirs, platform, ""); + + if(getenv("MSYSTEM") && getenv("HOME")) + { + // We are in MSYS2 / Git Bash + platformPathAddEnvSuffix(&platform->configDirs, "HOME", ".config/"); + platformPathAddEnvSuffix(&platform->configDirs, "HOME", ""); + } + + ffPlatformPathAddEnv(&platform->configDirs, "XDG_CONFIG_DIRS"); +} + +static void getConfigDirs(FFPlatform* platform) +{ + ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_HOME"); + ffPlatformPathAddHome(&platform->dataDirs, platform, "/.local/share/"); + platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_RoamingAppData); + platformPathAddKnownFolder(&platform->dataDirs, &FOLDERID_LocalAppData); + ffPlatformPathAddHome(&platform->dataDirs, platform, ""); + + if(getenv("MSYSTEM") && getenv("HOME")) + { + // We are in MSYS2 / Git Bash + platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ".local/share/"); + platformPathAddEnvSuffix(&platform->dataDirs, "HOME", ""); + } + + ffPlatformPathAddEnv(&platform->dataDirs, "XDG_DATA_DIRS"); +} + +static void getUserName(FFPlatform* platform) +{ + ffStrbufEnsureFree(&platform->userName, 64); + GetUserNameA(platform->userName.chars, (LPDWORD) ffStrbufGetFree(&platform->userName)); + ffStrbufRecalculateLength(&platform->userName); +} + +static void getHostName(FFPlatform* platform) +{ + ffStrbufEnsureFree(&platform->hostName, 64); + GetComputerNameA(platform->hostName.chars, (LPDWORD) ffStrbufGetFree(&platform->hostName)); + ffStrbufRecalculateLength(&platform->hostName); +} + +static void getDomainName(FFPlatform* platform) +{ + ffStrbufEnsureFree(&platform->domainName, 64); + GetComputerNameExA(ComputerNameDnsDomain, platform->domainName.chars, (LPDWORD) ffStrbufGetFree(&platform->domainName)); + ffStrbufRecalculateLength(&platform->domainName); +} + +static void getSystemName(FFPlatform* platform) +{ + ffStrbufAppendS(&platform->systemName, "Windows_NT"); +} + +static void getSystemReleaseAndVersion(FFPlatform* platform) +{ + HKEY hKey; + if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) + return; + + DWORD bufSize; + + char currentVersion[32]; + + { + DWORD currentMajorVersionNumber; + DWORD currentMinorVersionNumber; + bufSize = sizeof(currentMajorVersionNumber); + if(RegGetValueW(hKey, NULL, L"CurrentMajorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMajorVersionNumber, &bufSize) == ERROR_SUCCESS && + RegGetValueW(hKey, NULL, L"CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMinorVersionNumber, &bufSize) == ERROR_SUCCESS + ) + snprintf(currentVersion, sizeof(currentVersion), "%u.%u", (unsigned)currentMajorVersionNumber, (unsigned)currentMinorVersionNumber); + else + { + bufSize = sizeof(currentVersion); + if(RegGetValueA(hKey, NULL, "CurrentVersion", RRF_RT_REG_SZ, NULL, currentVersion, &bufSize) != ERROR_SUCCESS) + strcpy(currentVersion, "0.0"); + } + } + + char currentBuildNumber[32]; + bufSize = sizeof(currentBuildNumber); + if(RegGetValueA(hKey, NULL, "CurrentBuildNumber", RRF_RT_REG_SZ, NULL, currentBuildNumber, &bufSize) != ERROR_SUCCESS) + strcpy(currentBuildNumber, "0"); + + DWORD ubr; + bufSize = sizeof(ubr); + if(RegGetValueA(hKey, NULL, "UBR", RRF_RT_REG_DWORD, NULL, &ubr, &bufSize) != ERROR_SUCCESS || bufSize != sizeof(ubr)) + ubr = 0; + + ffStrbufAppendF(&platform->systemRelease, "%s.%s.%u", currentVersion, currentBuildNumber, (unsigned)ubr); + + ffStrbufEnsureFree(&platform->systemVersion, 256); + RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, platform->systemVersion.chars, (LPDWORD) ffStrbufGetFree(&platform->systemVersion)); + ffStrbufRecalculateLength(&platform->systemVersion); + + RegCloseKey(hKey); +} + +static void getSystemArchitecture(FFPlatform* platform) +{ + SYSTEM_INFO sysInfo = {0}; + GetNativeSystemInfo(&sysInfo); + + switch(sysInfo.wProcessorArchitecture) + { + case PROCESSOR_ARCHITECTURE_AMD64: + strcpy(name->machine, "x86_64"); + break; + case PROCESSOR_ARCHITECTURE_IA64: + strcpy(name->machine, "ia64"); + break; + case PROCESSOR_ARCHITECTURE_INTEL: + strcpy(name->machine, "x86"); + break; + case PROCESSOR_ARCHITECTURE_ARM64: + strcpy(name->machine, "aarch64"); + break; + case PROCESSOR_ARCHITECTURE_ARM: + strcpy(name->machine, "arm"); + break; + case PROCESSOR_ARCHITECTURE_PPC: + strcpy(name->machine, "ppc"); + break; + case PROCESSOR_ARCHITECTURE_MIPS: + strcpy(name->machine, "mips"); + break; + case PROCESSOR_ARCHITECTURE_UNKNOWN: + default: + break; + } +} + +void ffPlatformInitÎmpl(FFPlatform* platform) +{ + getHomeDir(platform); + getCacheDir(platform); + getConfigDirs(platform); + getDataDirs(platform); + + getUserName(platform); + getHostName(platform); + getDomainName(platform); + + getSystemName(platform); + getSystemReleaseAndVersion(platform); + getSystemArchitecture(platform); +} diff --git a/src/util/windows/pwd.c b/src/util/windows/pwd.c deleted file mode 100644 index ce37aabc7..000000000 --- a/src/util/windows/pwd.c +++ /dev/null @@ -1,22 +0,0 @@ -#include "pwd.h" - -#define WIN32_LEAN_AND_MEAN -#include -#include - -struct passwd* ffGetPasswd() -{ - static struct passwd res; - - DWORD len = sizeof(res.pw_name); - GetUserNameA(res.pw_name, &len); - - PWSTR pPath; - if(SUCCEEDED(SHGetKnownFolderPath(&FOLDERID_Profile, KF_FLAG_DEFAULT, NULL, &pPath))) - WideCharToMultiByte(CP_UTF8, 0, pPath, -1, res.pw_dir, sizeof(res.pw_dir), NULL, NULL); //res has been NULL inited - CoTaskMemFree(pPath); - for (char *current_pos = strchr(res.pw_dir, '\\'); current_pos; current_pos = strchr(current_pos + 1, '\\')) - *current_pos = '/'; - - return &res; -} diff --git a/src/util/windows/pwd.h b/src/util/windows/pwd.h deleted file mode 100644 index 29d4c883b..000000000 --- a/src/util/windows/pwd.h +++ /dev/null @@ -1,22 +0,0 @@ -#pragma once - -#ifndef FASTFETCH_INCLUDED_UTIL_PWD -#define FASTFETCH_INCLUDED_UTIL_PWD - -#include -#include - -struct passwd -{ - char pw_name[UNLEN + 1]; /* username */ - // char *pw_passwd[1]; /* user password */ - // int pw_uid; /* user ID */ - // int pw_gid; /* group ID */ - // char *pw_gecos; /* user information */ - char pw_dir[MAX_PATH]; /* home directory */ - // char *pw_shell; /* shell program */ -}; - -struct passwd* ffGetPasswd(); - -#endif diff --git a/src/util/windows/unicode.h b/src/util/windows/unicode.h index d70fbb22e..f01080b0a 100644 --- a/src/util/windows/unicode.h +++ b/src/util/windows/unicode.h @@ -3,16 +3,18 @@ #ifndef FASTFETCH_INCLUDED_UNICODE_H #define FASTFETCH_INCLUDED_UNICODE_H -#include "fastfetch.h" +#include "util/FFstrbuf.h" #include void ffStrbufSetNWS(FFstrbuf* result, uint32_t length, const wchar_t* source); + static inline void ffStrbufSetWS(FFstrbuf* result, const wchar_t* source) { return ffStrbufSetNWS(result, (uint32_t)wcslen(source), source); } FFstrbuf ffStrbufCreateNWS(uint32_t length, const wchar_t* source); + static inline FFstrbuf ffStrbufCreateWS(const wchar_t* source) { return ffStrbufCreateNWS((uint32_t)wcslen(source), source); diff --git a/src/util/windows/utsname.c b/src/util/windows/utsname.c deleted file mode 100644 index c21389f19..000000000 --- a/src/util/windows/utsname.c +++ /dev/null @@ -1,116 +0,0 @@ -#include "fastfetch.h" -#include "utsname.h" - -#define WIN32_LEAN_AND_MEAN 1 -#include - -static int detectSysname(struct utsname *name) -{ - strncpy(name->sysname, "Windows_NT", UTSNAME_MAXLENGTH); - return 0; -} - -static int detectNodename(struct utsname *name) -{ - DWORD bufSize = UTSNAME_MAXLENGTH - 1; - if(!GetComputerNameExA(ComputerNameDnsFullyQualified, name->nodename, &bufSize)) - return 1; - name->nodename[bufSize] = '\0'; - return 0; -} - -static int detectVersion(struct utsname *name) -{ - HKEY hKey; - if(RegOpenKeyExW(HKEY_LOCAL_MACHINE, L"SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion", 0, KEY_QUERY_VALUE, &hKey) != ERROR_SUCCESS) - return 1; - - DWORD bufSize; - - char currentVersion[32]; - - { - DWORD currentMajorVersionNumber; - DWORD currentMinorVersionNumber; - bufSize = sizeof(currentMajorVersionNumber); - if(RegGetValueW(hKey, NULL, L"CurrentMajorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMajorVersionNumber, &bufSize) == ERROR_SUCCESS && - RegGetValueW(hKey, NULL, L"CurrentMinorVersionNumber", RRF_RT_REG_DWORD, NULL, ¤tMinorVersionNumber, &bufSize) == ERROR_SUCCESS - ) - snprintf(currentVersion, sizeof(currentVersion), "%u.%u", (unsigned)currentMajorVersionNumber, (unsigned)currentMinorVersionNumber); - else - { - bufSize = sizeof(currentVersion); - if(RegGetValueA(hKey, NULL, "CurrentVersion", RRF_RT_REG_SZ, NULL, currentVersion, &bufSize) != ERROR_SUCCESS) - strcpy(currentVersion, "0.0"); - } - } - - char currentBuildNumber[32]; - bufSize = sizeof(currentBuildNumber); - if(RegGetValueA(hKey, NULL, "CurrentBuildNumber", RRF_RT_REG_SZ, NULL, currentBuildNumber, &bufSize) != ERROR_SUCCESS) - strcpy(currentBuildNumber, "0"); - - DWORD ubr; - bufSize = sizeof(ubr); - if(RegGetValueA(hKey, NULL, "UBR", RRF_RT_REG_DWORD, NULL, &ubr, &bufSize) != ERROR_SUCCESS || bufSize != sizeof(ubr)) - ubr = 0; - - snprintf(name->release, sizeof(name->release), "%s.%s.%u", currentVersion, currentBuildNumber, (unsigned)ubr); - - bufSize = sizeof(name->version); - RegGetValueA(hKey, NULL, "DisplayVersion", RRF_RT_REG_SZ, NULL, name->version, &bufSize); - - RegCloseKey(hKey); - return 0; -} - -static int detectMachine(struct utsname *name) -{ - // Get hardware info - SYSTEM_INFO sysInfo = {0}; - GetNativeSystemInfo(&sysInfo); - - // Set processor architecture - switch(sysInfo.wProcessorArchitecture) - { - case PROCESSOR_ARCHITECTURE_AMD64: - strcpy(name->machine, "x86_64"); - break; - case PROCESSOR_ARCHITECTURE_IA64: - strcpy(name->machine, "ia64"); - break; - case PROCESSOR_ARCHITECTURE_INTEL: - strcpy(name->machine, "x86"); - break; - case PROCESSOR_ARCHITECTURE_ARM64: - strcpy(name->machine, "aarch64"); - break; - case PROCESSOR_ARCHITECTURE_ARM: - strcpy(name->machine, "arm"); - break; - case PROCESSOR_ARCHITECTURE_PPC: - strcpy(name->machine, "ppc"); - break; - case PROCESSOR_ARCHITECTURE_MIPS: - strcpy(name->machine, "mips"); - break; - case PROCESSOR_ARCHITECTURE_UNKNOWN: - default: - strcpy(name->machine, "unknown"); - break; - } - - return 0; -} - -int uname(struct utsname *name) -{ - memset(name, 0, sizeof(*name)); - - int sysnameResult = detectSysname(name); - int nodenameResult = detectNodename(name); - int versionResult = detectVersion(name); - int machineResult = detectMachine(name); - - return sysnameResult || nodenameResult || versionResult || machineResult; -} diff --git a/src/util/windows/utsname.h b/src/util/windows/utsname.h deleted file mode 100644 index 96bc53adc..000000000 --- a/src/util/windows/utsname.h +++ /dev/null @@ -1,19 +0,0 @@ -#pragma once - -#ifndef FASTFETCH_INCLUDED_UTSNAME_H -#define FASTFETCH_INCLUDED_UTSNAME_H - -#define UTSNAME_MAXLENGTH 256 - -struct utsname -{ - char sysname[UTSNAME_MAXLENGTH]; // name of this implementation of the operating system - char nodename[UTSNAME_MAXLENGTH]; // name of this node within an implementation - dependent communications network - char release[UTSNAME_MAXLENGTH]; // current release level of this implementation - char version[UTSNAME_MAXLENGTH]; // current version level of this release - char machine[UTSNAME_MAXLENGTH]; // name of the hardware type on which the system is running -}; - -int uname(struct utsname *name); - -#endif