diff --git a/src/common.c b/src/common.c index 6f6d53122..ccfa0a0f8 100644 --- a/src/common.c +++ b/src/common.c @@ -128,7 +128,8 @@ void ffParsePropFile(const char* fileName, const char* regex, char* buffer) } fclose(file); - free(line); + if(line != NULL) + free(line); } void ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer) diff --git a/src/fastfetch.c b/src/fastfetch.c index 19fd32e29..c6b60be11 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -155,7 +155,22 @@ static inline void printCommandHelp(const char* command) else if(strcasecmp(command, "format") == 0) printCommandHelpFormat(); else if(strcasecmp(command, "os-format") == 0) - constructAndPrintCommandHelpFormat("os", "{} {}", 2, "Name of the OS", "Architecture of the OS"); + { + constructAndPrintCommandHelpFormat("os", "{3} {12}", 12, + "System name, typically just Linux", + "Name of the OS", + "Pretty name of the OS", + "ID of the OS", + "ID like of the OS", + "Variant of the OS", + "Variant ID of the OS", + "Version of the OS", + "Version ID of the OS", + "Version codename of the OS", + "Build ID of the OS", + "Architecture of the OS" + ); + } else if(strcasecmp(command, "host-format") == 0) constructAndPrintCommandHelpFormat("host", "{} {} {}", 3, "Host family", "Host name", "Host version"); else if(strcasecmp(command, "kernel-format") == 0) diff --git a/src/modules/os.c b/src/modules/os.c index f16f97493..a726bd1a7 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -5,24 +5,121 @@ void ffPrintOS(FFinstance* instance) if(ffPrintCachedValue(instance, "OS")) return; - char name[256]; - ffParsePropFile("/etc/os-release", "NAME=\"%[^\"]+", name); + // Documentation of the fields: + // https://www.freedesktop.org/software/systemd/man/os-release.html + + char name[128]; name[0] = '\0'; + char prettyName[128]; prettyName[0] = '\0'; + char id[128]; id[0] = '\0'; + char idLike[128]; idLike[0] = '\0'; + char variant[128]; variant[0] = '\0'; + char variantId[128]; variantId[0] = '\0'; + char version[128]; version[0] = '\0'; + char versionId[128]; versionId[0] = '\0'; + char versionCodename[128]; versionCodename[0] = '\0'; + char buildId[128]; buildId[0] = '\0'; + + FILE* osRelease = fopen("/etc/os-release", "r"); + + if(osRelease == NULL) + osRelease = fopen("/usr/lib/os-release", "r"); + + char* line = NULL; + size_t len; + + while (getline(&line, &len, osRelease) != -1) + { + sscanf(line, "NAME=\"%[^\"]+", name); + sscanf(line, "NAME=%[^\n]", name); + sscanf(line, "PRETTY_NAME=\"%[^\"]+", prettyName); + sscanf(line, "PRETTY_NAME=%[^\n]", prettyName); + sscanf(line, "ID=\"%[^\"]+", id); + sscanf(line, "ID=%[^\n]", id); + sscanf(line, "ID_LIKE=\"%[^\"]+", idLike); + sscanf(line, "ID_LIKE=%[^\n]", idLike); + sscanf(line, "VARIANT=\"%[^\"]+", variant); + sscanf(line, "VARIANT=%[^\n]", variant); + sscanf(line, "VARIANT_ID=\"%[^\"]+", variantId); + sscanf(line, "VARIANT_ID=%[^\n]", variantId); + sscanf(line, "VERSION=\"%[^\"]+", version); + sscanf(line, "VERSION=%[^\n]", version); + sscanf(line, "VERSION_ID=\"%[^\"]+", versionId); + sscanf(line, "VERSION_ID=%[^\n]", versionId); + sscanf(line, "VERSION_CODENAME=\"%[^\"]+", versionCodename); + sscanf(line, "VERSION_CODENAME=%[^\n]", versionCodename); + sscanf(line, "BUILD_ID=\"%[^\"]+", buildId); + sscanf(line, "BUILD_ID=%[^\n]", buildId); + } + + fclose(osRelease); + + if(line != NULL) + free(line); + FF_STRBUF_CREATE(os); if(instance->config.osFormat.length == 0) { - if(name[0] == '\0') + if(prettyName[0] != '\0') { - ffPrintError(instance, "OS", "\"NAME=\\\"%[^\\\"]+\" not found in \"/etc/os-release\""); - return; + ffStrbufAppendS(&os, prettyName); + } + else if(name[0] == '\0' && id[0] == '\0') + { + ffStrbufAppendS(&os, instance->state.utsname.sysname); + } + else + { + if(name[0] != '\0') + ffStrbufAppendS(&os, name); + else + ffStrbufAppendS(&os, id); + + if(version[0] != '\0') + { + ffStrbufAppendC(&os, ' '); + ffStrbufAppendS(&os, version); + } + else + { + if(versionId[0] != '\0') + { + ffStrbufAppendC(&os, ' '); + ffStrbufAppendS(&os, versionId); + } + + if(variant[0] != '\0') + { + ffStrbufAppendS(&os, " ("); + ffStrbufAppendS(&os, variant); + ffStrbufAppendC(&os, ')'); + } + else if(variantId[0] != '\0') + { + ffStrbufAppendS(&os, " ("); + ffStrbufAppendS(&os, variantId); + ffStrbufAppendC(&os, ')'); + } + } } - ffStrbufSetF(&os, "%s %s", name, instance->state.utsname.machine); + ffStrbufAppendC(&os, ' '); + ffStrbufAppendS(&os, instance->state.utsname.machine); } else { - ffParseFormatString(&os, &instance->config.osFormat, 2, + ffParseFormatString(&os, &instance->config.osFormat, 12, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.sysname}, (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, name}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, prettyName}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, id}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, idLike}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, variant}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, variantId}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, version}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, versionId}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, versionCodename}, + (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, buildId}, (FFformatarg){FF_FORMAT_ARG_TYPE_STRING, instance->state.utsname.machine} ); }