diff --git a/completions/bash b/completions/bash index f06dc7b48..bc8bce7bc 100644 --- a/completions/bash +++ b/completions/bash @@ -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" diff --git a/src/common/init.c b/src/common/init.c index 5777a01fa..5d3b081de 100644 --- a/src/common/init.c +++ b/src/common/init.c @@ -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) diff --git a/src/common/io.c b/src/common/io.c index 75692e033..dd22bd3a2 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -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"); diff --git a/src/data/config.txt b/src/data/config.txt index f99eff661..81d2dc9d7 100644 --- a/src/data/config.txt +++ b/src/data/config.txt @@ -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. diff --git a/src/data/help.txt b/src/data/help.txt index 77fb85b29..5138a6f46 100644 --- a/src/data/help.txt +++ b/src/data/help.txt @@ -106,6 +106,7 @@ Library options: Set the path of a library to load Module specific options: --separator-string : Set the string printed by the separator module + --os-file : Set the path to the file containing OS informations --disk-folders : A colon separated list of folder paths for the disk output. Default is "/:/home" --battery-dir : The directory where the battery folders are. Standard: /sys/class/power_supply/ --localip-show-ipv4 : Show ipv4 addresses in local ip module. Default is true diff --git a/src/detection/os.c b/src/detection/os.c index 2e55ec9c9..fb8d2c45a 100644 --- a/src/detection/os.c +++ b/src/detection/os.c @@ -2,6 +2,32 @@ #include +#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"); diff --git a/src/fastfetch.c b/src/fastfetch.c index 018fa0b7a..ee4bb9f76 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -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) diff --git a/src/fastfetch.h b/src/fastfetch.h index 7c4f9e3fa..c8995aeac 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -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); diff --git a/src/flashfetch.c b/src/flashfetch.c index d41e53431..23e492cce 100644 --- a/src/flashfetch.c +++ b/src/flashfetch.c @@ -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 diff --git a/src/modules/os.c b/src/modules/os.c index 389008878..ae68ed126 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -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; }