mirror of
https://github.com/fastfetch-cli/fastfetch.git
synced 2026-09-13 02:42:09 +02:00
More flexible OS file detection
This commit is contained in:
@@ -27,6 +27,7 @@ __fastfetch_complete_help()
|
||||
"battery-format"
|
||||
"locale-format"
|
||||
"local-ip-format"
|
||||
"public-ip-format"
|
||||
)
|
||||
COMPREPLY=($(compgen -W "${__ff_helps[*]}" -- "$CURRENT_WORD"))
|
||||
}
|
||||
@@ -191,9 +192,12 @@ __fastfetch_completion()
|
||||
"--disk-key"
|
||||
"--local-ip-format"
|
||||
"--local-ip-key"
|
||||
"--public-ip-format"
|
||||
"--public-ip-key"
|
||||
)
|
||||
|
||||
local FF_OPTIONS_PATH=(
|
||||
"--os-file"
|
||||
"--lib-PCI"
|
||||
"--lib-vulkan"
|
||||
"--lib-wayland"
|
||||
|
||||
+2
-2
@@ -122,8 +122,6 @@ static void defaultConfig(FFinstance* instance)
|
||||
for(uint8_t i = 0; i < (uint8_t) FASTFETCH_LOGO_MAX_COLORS; ++i)
|
||||
ffStrbufInit(&instance->config.logoColors[i]);
|
||||
|
||||
ffLoadLogo(instance);
|
||||
|
||||
ffStrbufInitA(&instance->config.osFormat, 0);
|
||||
ffStrbufInitA(&instance->config.osKey, 0);
|
||||
ffStrbufInitA(&instance->config.hostFormat, 0);
|
||||
@@ -200,6 +198,8 @@ static void defaultConfig(FFinstance* instance)
|
||||
instance->config.localIpShowLoop = false;
|
||||
|
||||
instance->config.publicIpTimeout = 0;
|
||||
|
||||
ffStrbufInitA(&instance->config.osFile, 0);
|
||||
}
|
||||
|
||||
void ffInitInstance(FFinstance* instance)
|
||||
|
||||
+1
-1
@@ -302,7 +302,7 @@ bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquer
|
||||
if(allSet)
|
||||
{
|
||||
free(searchedValues);
|
||||
return access(filename, R_OK) == 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
FILE* file = fopen(filename, "r");
|
||||
|
||||
@@ -126,6 +126,13 @@
|
||||
# Default is 0 (disabled).
|
||||
#--public-ip-timeout 0
|
||||
|
||||
# OS file option
|
||||
# Sets the path to the file containing the operating system information.
|
||||
# Should be a valid path to an existing file.
|
||||
# Note that you might need to run fastfetch with --recache once for it to take affect.
|
||||
# Default is /etc/os-release.
|
||||
--os-file /etc/os-release
|
||||
|
||||
# Key options:
|
||||
# Sets the displayed key of a module
|
||||
# Can be any string. Some of theme take an argument like a format string. See "fastfetch --help format" for help.
|
||||
|
||||
@@ -106,6 +106,7 @@ Library options: Set the path of a library to load
|
||||
|
||||
Module specific options:
|
||||
--separator-string <str>: Set the string printed by the separator module
|
||||
--os-file <path>: Set the path to the file containing OS informations
|
||||
--disk-folders <folders>: A colon separated list of folder paths for the disk output. Default is "/:/home"
|
||||
--battery-dir <folder>: The directory where the battery folders are. Standard: /sys/class/power_supply/
|
||||
--localip-show-ipv4 <?value>: Show ipv4 addresses in local ip module. Default is true
|
||||
|
||||
+32
-48
@@ -2,6 +2,32 @@
|
||||
|
||||
#include <pthread.h>
|
||||
|
||||
#if !defined(__ANDROID__)
|
||||
|
||||
static void parseFile(const char* fileName, FFOSResult* result)
|
||||
{
|
||||
if(result->name.length > 0 && result->prettyName.length > 0)
|
||||
return;
|
||||
|
||||
ffParsePropFileValues(fileName, 13, (FFpropquery[]) {
|
||||
{"NAME =", &result->name},
|
||||
{"DISTRIB_DESCRIPTION =", &result->prettyName},
|
||||
{"PRETTY_NAME =", &result->prettyName},
|
||||
{"DISTRIB_ID =", &result->id},
|
||||
{"ID =", &result->id},
|
||||
{"ID_LIKE =", &result->idLike},
|
||||
{"VARIANT =", &result->variant},
|
||||
{"VARIANT_ID =", &result->variantID},
|
||||
{"DISTRIB_RELEASE =", &result->version},
|
||||
{"VERSION =", &result->version},
|
||||
{"VERSION_ID =", &result->versionID},
|
||||
{"VERSION_CODENAME =", &result->codename},
|
||||
{"BUILD_ID =", &result->buildID}
|
||||
});
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
const FFOSResult* ffDetectOS(FFinstance* instance)
|
||||
{
|
||||
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
|
||||
@@ -27,63 +53,21 @@ const FFOSResult* ffDetectOS(FFinstance* instance)
|
||||
ffStrbufInit(&result.codename);
|
||||
ffStrbufInit(&result.buildID);
|
||||
ffStrbufInit(&result.architecture);
|
||||
ffStrbufInit(&result.error);
|
||||
|
||||
ffStrbufSetS(&result.systemName, instance->state.utsname.sysname);
|
||||
ffStrbufSetS(&result.architecture, instance->state.utsname.machine);
|
||||
|
||||
#if !__ANDROID__
|
||||
bool isOsRelease = true;
|
||||
FILE* file = fopen("/etc/os-release", "r");
|
||||
|
||||
if(file == NULL)
|
||||
file = fopen("/usr/lib/os-release", "r");
|
||||
|
||||
if(file == NULL)
|
||||
if(instance->config.osFile.length > 0)
|
||||
{
|
||||
file = fopen("/etc/lsb-release", "r");
|
||||
isOsRelease = false;
|
||||
parseFile(instance->config.osFile.chars, &result);
|
||||
}
|
||||
|
||||
ffStrbufInitA(&result.error, 64);
|
||||
if(file == NULL)
|
||||
else
|
||||
{
|
||||
ffStrbufAppendS(&result.error, "couldn't read /etc/os-release nor /usr/lib/os-release nor /etc/lsb-release");
|
||||
return &result;
|
||||
parseFile("/etc/os-release", &result);
|
||||
parseFile("/usr/lib/os-release", &result);
|
||||
parseFile("/etc/lsb-release", &result);
|
||||
}
|
||||
|
||||
char* line = NULL;
|
||||
size_t len = 0;
|
||||
|
||||
// Documentation of the fields:
|
||||
// https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
while (getline(&line, &len, file) != -1)
|
||||
{
|
||||
if(isOsRelease)
|
||||
{
|
||||
ffGetPropValue(line, "NAME =", &result.name);
|
||||
ffGetPropValue(line, "PRETTY_NAME =", &result.prettyName);
|
||||
ffGetPropValue(line, "ID =", &result.id);
|
||||
ffGetPropValue(line, "ID_LIKE =", &result.idLike);
|
||||
ffGetPropValue(line, "VARIANT =", &result.variant);
|
||||
ffGetPropValue(line, "VARIANT_ID =", &result.variantID);
|
||||
ffGetPropValue(line, "VERSION =", &result.version);
|
||||
ffGetPropValue(line, "VERSION_ID =", &result.versionID);
|
||||
ffGetPropValue(line, "VERSION_CODENAME =", &result.codename);
|
||||
ffGetPropValue(line, "BUILD_ID =", &result.buildID);
|
||||
}
|
||||
else
|
||||
{
|
||||
ffGetPropValue(line, "DISTRIB_ID =", &result.id);
|
||||
ffGetPropValue(line, "DISTRIB_RELEASE =", &result.version);
|
||||
ffGetPropValue(line, "DISTRIB_DESCRIPTION =", &result.prettyName);
|
||||
}
|
||||
}
|
||||
|
||||
if(line != NULL)
|
||||
free(line);
|
||||
|
||||
fclose(file);
|
||||
#else
|
||||
ffStrbufSetS(&result.name, "Android");
|
||||
ffStrbufSetS(&result.id, "android");
|
||||
|
||||
@@ -878,6 +878,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
|
||||
instance->config.localIpShowIpV6 = optionParseBoolean(value);
|
||||
else if(strcasecmp(key, "--localip-show-loop") == 0)
|
||||
instance->config.localIpShowLoop = optionParseBoolean(value);
|
||||
else if(strcasecmp(key, "--os-file") == 0)
|
||||
optionParseString(key, value, &instance->config.osFile);
|
||||
else if(strcasecmp(key, "--public-ip-timeout") == 0)
|
||||
{
|
||||
if(value == NULL)
|
||||
@@ -1060,6 +1062,8 @@ int main(int argc, const char** argv)
|
||||
//Load custom logo if it exists
|
||||
if(data.logoName.length > 0)
|
||||
ffLoadLogoSet(&instance, data.logoName.chars);
|
||||
else
|
||||
ffLoadLogo(&instance);
|
||||
|
||||
//If we haven't set key color, use primary color of logo
|
||||
if(instance.config.color.length == 0)
|
||||
|
||||
+3
-1
@@ -132,6 +132,8 @@ typedef struct FFconfig
|
||||
|
||||
uint32_t publicIpTimeout;
|
||||
|
||||
FFstrbuf osFile;
|
||||
|
||||
} FFconfig;
|
||||
|
||||
typedef struct FFstate
|
||||
@@ -173,7 +175,6 @@ typedef struct FFOSResult
|
||||
FFstrbuf codename;
|
||||
FFstrbuf buildID;
|
||||
FFstrbuf architecture;
|
||||
FFstrbuf error;
|
||||
} FFOSResult;
|
||||
|
||||
typedef struct FFPlasmaResult
|
||||
@@ -365,6 +366,7 @@ void ffPrintColor(const FFstrbuf* colorValue);
|
||||
// They return true if the file was found, independently if start was found
|
||||
// Buffers which already contain content are not overwritten
|
||||
// The last occurence of start in the first file will be the one used
|
||||
// The *Values methods always return true, if all properties were already found before, without testing if the file exists
|
||||
bool ffParsePropFileValues(const char* filename, uint32_t numQueries, FFpropquery* queries);
|
||||
bool ffParsePropFile(const char* filename, const char* start, FFstrbuf* buffer);
|
||||
bool ffParsePropFileHomeValues(const FFinstance* instance, const char* relativeFile, uint32_t numQueries, FFpropquery* queries);
|
||||
|
||||
+3
-1
@@ -8,7 +8,9 @@ int main(int argc, char** argv)
|
||||
FFinstance instance;
|
||||
ffInitInstance(&instance); //This also applys default configuration to instance.config
|
||||
|
||||
//ffLoadLogoSet(&instance, "my custom logo");
|
||||
//Modify instance.config here
|
||||
|
||||
ffLoadLogo(&instance); //ffLoadLogoSet(&instance, "my custom logo");
|
||||
ffStrbufSet(&instance.config.color, &instance.config.logoColors[0]); //Use the primary color of the logo as key color
|
||||
|
||||
//Multithreading --> better performance
|
||||
|
||||
+2
-2
@@ -10,9 +10,9 @@ void ffPrintOS(FFinstance* instance)
|
||||
|
||||
const FFOSResult* result = ffDetectOS(instance);
|
||||
|
||||
if(result->error.length > 0)
|
||||
if(result->name.length == 0 && result->prettyName.length == 0)
|
||||
{
|
||||
ffPrintError(instance, FF_OS_MODULE_NAME, 0, &instance->config.osKey, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS, result->error.chars);
|
||||
ffPrintError(instance, FF_OS_MODULE_NAME, 0, &instance->config.osKey, &instance->config.osFormat, FF_OS_NUM_FORMAT_ARGS, "Could not detect OS");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user