From 1d47eb0c6069e9e0b81c45ddb703caa277fe9c0f Mon Sep 17 00:00:00 2001 From: Linus Dierheimer Date: Sun, 18 Apr 2021 15:19:21 +0200 Subject: [PATCH] shell version support --- CMakeLists.txt | 1 + src/common/io.c | 19 ++++++++------ src/common/processing.c | 33 ++++++++++++++++++++++++ src/fastfetch.c | 6 +++-- src/fastfetch.h | 4 +++ src/modules/shell.c | 56 +++++++++++++++++++++++++++++++++++------ src/util/FFstrbuf.c | 14 +++++++++++ src/util/FFstrbuf.h | 1 + 8 files changed, 117 insertions(+), 17 deletions(-) create mode 100644 src/common/processing.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 4ffe63831..7af267c13 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -60,6 +60,7 @@ set(SRCS src/common/init.c src/common/threading.c src/common/io.c + src/common/processing.c src/common/logo.c src/common/format.c src/common/parsing.c diff --git a/src/common/io.c b/src/common/io.c index 83ba2bc72..b898d54a5 100644 --- a/src/common/io.c +++ b/src/common/io.c @@ -134,7 +134,7 @@ static inline void getCacheFileSplit(FFinstance* instance, const char* moduleNam ffStrbufAppendS(cacheFilePath, ".ffcs"); } -bool printCachedValue(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat) +static bool printCachedValue(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat) { FFstrbuf cacheFilePath; ffStrbufInitA(&cacheFilePath, 64); @@ -168,7 +168,7 @@ bool printCachedValue(FFinstance* instance, const char* moduleName, const FFstrb return moduleCounter > 1; } -bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs) +static bool printCachedFormat(FFinstance* instance, const char* moduleName, const FFstrbuf* customKeyFormat, const FFstrbuf* formatString, uint32_t numArgs) { FFstrbuf cacheFilePath; ffStrbufInitA(&cacheFilePath, 64); @@ -358,12 +358,8 @@ void ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const c ffStrbufDestroy(&absolutePath); } -void ffAppendFileContent(const char* fileName, FFstrbuf* buffer) +void ffAppendFDContent(int fd, FFstrbuf* buffer) { - int fd = open(fileName, O_RDONLY); - if(fd == -1) - return; - ssize_t readed; while((readed = read(fd, buffer->chars + buffer->length, buffer->allocated - buffer->length)) == (buffer->allocated - buffer->length)) { @@ -376,6 +372,15 @@ void ffAppendFileContent(const char* fileName, FFstrbuf* buffer) ffStrbufTrimRight(buffer, '\n'); ffStrbufTrimRight(buffer, ' '); +} + +void ffAppendFileContent(const char* fileName, FFstrbuf* buffer) +{ + int fd = open(fileName, O_RDONLY); + if(fd == -1) + return; + + ffAppendFDContent(fd, buffer); close(fd); } diff --git a/src/common/processing.c b/src/common/processing.c new file mode 100644 index 000000000..c9641ca73 --- /dev/null +++ b/src/common/processing.c @@ -0,0 +1,33 @@ +#include "fastfetch.h" + +#include +#include +#include + +void ffProcessGetStdOut(FFstrbuf* buffer, char* const argv[]) +{ + int pipes[2]; + + if(pipe(pipes) == -1) + return; + + pid_t childPid = fork(); + if(childPid == -1) + return; + + if(childPid == 0) + { + dup2(pipes[1], STDOUT_FILENO); + close(pipes[0]); + close(pipes[1]); + execvp(argv[0], argv); + exit(901); + } + else + { + close(pipes[1]); + waitpid(childPid, NULL, 0); + ffAppendFDContent(pipes[0], buffer); + close(pipes[0]); + } +} diff --git a/src/fastfetch.c b/src/fastfetch.c index b35cb0909..6a7851a2a 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -272,9 +272,11 @@ static inline void printCommandHelp(const char* command) } else if(strcasecmp(command, "shell-format") == 0) { - constructAndPrintCommandHelpFormat("shell", "{2}", 2, + constructAndPrintCommandHelpFormat("shell", "{2} {4}", 4, "Shell path (without name)", - "Shell name" + "Shell name", + "Shell version raw", + "Shell version pretty" ); } else if(strcasecmp(command, "resolution-format") == 0) diff --git a/src/fastfetch.h b/src/fastfetch.h index 097f59ef3..712c1eafe 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -196,12 +196,16 @@ void ffCacheValidate(FFinstance* instance); void ffCacheOpenWrite(FFinstance* instance, const char* moduleName, FFcache* cache); void ffCacheClose(FFcache* cache); +void ffAppendFDContent(int fd, FFstrbuf* buffer); void ffAppendFileContent(const char* fileName, FFstrbuf* buffer); void ffGetFileContent(const char* fileName, FFstrbuf* buffer); void ffParsePropFile(const char* file, const char* regex, char* buffer); void ffParsePropFileHome(FFinstance* instance, const char* relativeFile, const char* regex, char* buffer); +//common/processing.c +void ffProcessGetStdOut(FFstrbuf* buffer, char* const argv[]); + //common/logo.c void ffLoadLogoSet(FFconfig* config, const char* logo); void ffLoadLogo(FFconfig* config); diff --git a/src/modules/shell.c b/src/modules/shell.c index c7be41960..a1b2627a7 100644 --- a/src/modules/shell.c +++ b/src/modules/shell.c @@ -1,9 +1,10 @@ #include "fastfetch.h" #include +#include #define FF_SHELL_MODULE_NAME "Shell" -#define FF_SHELL_NUM_FORMAT_ARGS 2 +#define FF_SHELL_NUM_FORMAT_ARGS 4 void ffPrintShell(FFinstance* instance) { @@ -17,28 +18,67 @@ void ffPrintShell(FFinstance* instance) return; } - char empty[1]; - empty[0] = '\0'; - char* shellName = strrchr(shellPath, '/'); + if(shellName != NULL) + ++shellName; + + FFstrbuf version; + ffStrbufInit(&version); + + FFstrbuf command; + ffStrbufInit(&command); + ffStrbufAppendS(&command, "printf %s \"$"); + ffStrbufAppendTransformS(&command, shellName != NULL ? shellName : shellPath, toupper); + ffStrbufAppendS(&command, "_VERSION\""); + + ffProcessGetStdOut(&version, (char* const[]){ + shellPath, + "-c", + command.chars, + NULL + }); + + ffStrbufDestroy(&command); + + FFstrbuf versionPretty; + ffStrbufInitCopy(&versionPretty, &version); + ffStrbufSubstrBeforeFirstC(&versionPretty, '('); + ffStrbufRemoveStrings(&versionPretty, 1, "-release"); + + char null = '\0'; + if(shellName == NULL) { shellName = shellPath; - shellPath = empty; + shellPath = &null; } else { - *shellName = '\0'; - ++shellName; + *(shellName - 1) = '\0'; } FF_STRBUF_CREATE(shell); ffStrbufSetS(&shell, shellName); + if(versionPretty.length > 0) + { + ffStrbufAppendC(&shell, ' '); + ffStrbufAppend(&shell, &versionPretty); + } + else if(version.length > 0) + { + ffStrbufAppendC(&shell, ' '); + ffStrbufAppend(&shell, &version); + } + ffPrintAndSaveToCache(instance, FF_SHELL_MODULE_NAME, &instance->config.shellKey, &shell, &instance->config.shellFormat, FF_SHELL_NUM_FORMAT_ARGS, (FFformatarg[]){ {FF_FORMAT_ARG_TYPE_STRING, shellPath}, - {FF_FORMAT_ARG_TYPE_STRING, shellName} + {FF_FORMAT_ARG_TYPE_STRING, shellName}, + {FF_FORMAT_ARG_TYPE_STRBUF, &version}, + {FF_FORMAT_ARG_TYPE_STRBUF, &versionPretty} }); ffStrbufDestroy(&shell); + ffStrbufDestroy(&versionPretty); + ffStrbufDestroy(&version); } diff --git a/src/util/FFstrbuf.c b/src/util/FFstrbuf.c index b22bddb8a..9ecb0f3c0 100644 --- a/src/util/FFstrbuf.c +++ b/src/util/FFstrbuf.c @@ -145,6 +145,20 @@ void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value) ffStrbufAppendNS(strbuf, value->length, value->chars); } +void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int)) +{ + if(value == NULL) + return; + + for(uint32_t i = 0; value[i] != '\0'; i++) + { + if(i % 16 == 0) + ffStrbufEnsureFree(strbuf, 16); + strbuf->chars[strbuf->length++] = transformFunc(value[i]); + } + strbuf->chars[strbuf->length] = '\0'; +} + void ffStrbufAppendS(FFstrbuf* strbuf, const char* value) { if(value == NULL) diff --git a/src/util/FFstrbuf.h b/src/util/FFstrbuf.h index 554d915ed..302be66fd 100644 --- a/src/util/FFstrbuf.h +++ b/src/util/FFstrbuf.h @@ -44,6 +44,7 @@ void ffStrbufSetF(FFstrbuf* strbuf, const char* format, ...); void ffStrbufSetVF(FFstrbuf* strbuf, const char* format, va_list arguments); void ffStrbufAppend(FFstrbuf* strbuf, const FFstrbuf* value); +void ffStrbufAppendTransformS(FFstrbuf* strbuf, const char* value, int(*transformFunc)(int)); void ffStrbufAppendS(FFstrbuf* strbuf, const char* value); void ffStrbufAppendNS(FFstrbuf* strbuf, uint32_t length, const char* value); void ffStrbufAppendC(FFstrbuf* strbuf, const char c);