More flexible OS file detection

This commit is contained in:
Linus Dierheimer
2022-01-18 18:56:37 +01:00
parent a0f5432903
commit f2663a65cc
10 changed files with 59 additions and 55 deletions
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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");
+7
View File
@@ -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.
+1
View File
@@ -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
View File
@@ -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");
+4
View File
@@ -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
View File
@@ -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
View File
@@ -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
View File
@@ -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;
}