diff --git a/src/cpu.c b/src/cpu.c index 44e410900..66437dde3 100644 --- a/src/cpu.c +++ b/src/cpu.c @@ -4,6 +4,9 @@ void ffPrintCPU(FFstate* state) { + if(ffPrintCachedValue(state, "CPU")) + return; + char name[256]; ffParsePropFile("/proc/cpuinfo", "model name%*s %[^\n]", name); if(name[0] == '\0') @@ -30,6 +33,10 @@ void ffPrintCPU(FFstate* state) frequency /= 1000; //to MHz double ghz = (double) frequency / 1000.0; //to GHz + char value[1024]; + sprintf(value, "%s (%i) @ %.9gGHz", name, get_nprocs(), ghz); + ffSaveCachedValue(state, "CPU", value); + ffPrintLogoAndKey(state, "CPU"); - printf("%s (%i) @ %.9gGHz\n", name, get_nprocs(), ghz); + puts(value); } \ No newline at end of file diff --git a/src/fastfetch.c b/src/fastfetch.c index 964374f4e..8184ab3aa 100644 --- a/src/fastfetch.c +++ b/src/fastfetch.c @@ -1,6 +1,10 @@ #include "fastfetch.h" #include +#include +#include +#include +#include void ffPrintKey(FFstate* state, const char* key) { @@ -99,6 +103,65 @@ void ffPrintError(FFstate* state, const char* key, const char* message) printf(FASTFETCH_TEXT_MODIFIER_ERROR"%s\n"FASTFETCH_TEXT_MODIFIER_RESET, message); } +static bool getCacheFileName(FFstate* state, const char* key, char* buffer) +{ + const char* xdgCache = getenv("XDG_CACHE_HOME"); + if(xdgCache == NULL) + { + strcpy(buffer, state->passwd->pw_dir); + strcat(buffer, "/.cache"); + } + else + { + strcpy(buffer, xdgCache); + } + + mkdir(buffer, S_IRWXU | S_IXGRP | S_IRGRP | S_IXOTH | S_IROTH); //I hope everybody has a cache folder but whow knews + + strcat(buffer, "/fastfetch/"); + mkdir(buffer, S_IRWXU | S_IRGRP | S_IROTH); + + strcat(buffer, key); +} + +bool ffPrintCachedValue(FFstate* state, const char* key) +{ + if(state->recache) + return false; + + char fileName[256]; + getCacheFileName(state, key, fileName); + + int fd = open(fileName, O_RDONLY); + if(fd == -1) + return false; + + char value[1024]; + if(read(fd, value, sizeof(value) - 1) < 1) + return false; + + value[1023] = '\n'; //Ensure that we end with a newline, even when we didn't fully read the file + + close(fd); + + ffPrintLogoAndKey(state, key); + puts(value); +} + +void ffSaveCachedValue(FFstate* state, const char* key, const char* value) +{ + char fileName[256]; + getCacheFileName(state, key, fileName); + + int fd = open(fileName, O_WRONLY | O_CREAT | O_TRUNC, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH); + if(fd == -1) + return; + + write(fd, value, strlen(value)); + + close(fd); +} + static void printHelp() { puts( @@ -109,6 +172,7 @@ static void printHelp() " -l , --logo : sets the shown logo. Also changes the main color accordingly\n" " -c , --color : sets the color of the keys. Must be a linux console color code\n" " -s , --seperator : sets the distance between logo and text\n" + " -r --recache: dont use cached values and generate new ones\n" " --show-errors: if an error occurs, show it instead of discarding the category\n" " --list-logos: lists the names of available logos and exits\n" " --print-logos: prints available logos and exits\n" @@ -148,6 +212,7 @@ static void initState(FFstate* state) state->logo_seperator = 4; state->titleLength = 20; // This is overwritten by ffPrintTitle state->showErrors = false; + state->recache = false; } static void parseArguments(int argc, char** argv, FFstate* state) @@ -218,6 +283,10 @@ static void parseArguments(int argc, char** argv, FFstate* state) } ++i; } + else if(strcmp(argv[i], "-r") == 0 || strcmp(argv[i], "--recache") == 0) + { + state->recache = true; + } else { printf("Error: unknown option: %s\n", argv[i]); diff --git a/src/fastfetch.h b/src/fastfetch.h index 9a65792ff..55e0bde30 100644 --- a/src/fastfetch.h +++ b/src/fastfetch.h @@ -30,19 +30,21 @@ typedef struct FFlogo typedef struct FFstate { + //Actual state stuff uint8_t current_row; + //Configuration stuff FFlogo logo; - uint16_t logo_seperator; char color[10]; - - bool showErrors; - uint8_t titleLength; + bool showErrors; + bool recache; + + //Common stuff struct passwd* passwd; struct utsname utsname; - struct sysinfo sysinfo; + struct sysinfo sysinfo; } FFstate; //Helper functions @@ -53,6 +55,8 @@ void ffParsePropFile(const char* file, const char* regex, char* buffer); void ffParsePropFileHome(FFstate* state, const char* relativeFile, const char* regex, char* buffer); void ffPrintGtkPretty(const char* gtk2, const char* gtk3, const char* gtk4); void ffPrintError(FFstate* state, const char* key, const char* message); +bool ffPrintCachedValue(FFstate* state, const char* key); +void ffSaveCachedValue(FFstate* state, const char* key, const char* value); void ffLoadLogoSet(FFstate* state, const char* logo); void ffLoadLogo(FFstate* state); diff --git a/src/gpu.c b/src/gpu.c index 12d2bc656..11466ff7c 100644 --- a/src/gpu.c +++ b/src/gpu.c @@ -7,20 +7,34 @@ static void handleGPU(FFstate* state, struct pci_access* pacc, struct pci_dev* d { char key[8]; sprintf(key, "GPU%hu", counter); - ffPrintLogoAndKey(state, key); - - char vendor[1048]; + + if(ffPrintCachedValue(state, key)) + return; + + char gpu[1024]; + + char vendor[512]; pci_lookup_name(pacc, vendor, sizeof(vendor), PCI_LOOKUP_VENDOR, dev->vendor_id, dev->device_id); - char name[1048]; + char name[512]; pci_lookup_name(pacc, name, sizeof(name), PCI_LOOKUP_DEVICE, dev->vendor_id, dev->device_id); if(strcmp(vendor, "Advanced Micro Devices, Inc. [AMD/ATI]") == 0) - printf("AMD ATI"); + { + strcpy(gpu, "AMD ATI "); + } else - printf(vendor); + { + strcpy(gpu, vendor); + strcat(gpu, " "); + } - printf(" %s\n", name); + strcat(gpu, name); + + ffSaveCachedValue(state, key, gpu); + + ffPrintLogoAndKey(state, key); + puts(gpu); } void ffPrintGPU(FFstate* state) diff --git a/src/host.c b/src/host.c index 3880cdd0f..df110d890 100644 --- a/src/host.c +++ b/src/host.c @@ -1,32 +1,38 @@ #include "fastfetch.h" +#include + void ffPrintHost(FFstate* state) { + if(ffPrintCachedValue(state, "Host")) + return; + + char host[1024]; + FILE* nameFile = fopen("/sys/devices/virtual/dmi/id/product_name", "r"); if(nameFile == NULL) { ffPrintError(state, "Host", "fopen(\"/sys/devices/virtual/dmi/id/product_name\", \"r\") == NULL"); return; } - char name[256]; - if(fscanf(nameFile, "%[^\n]", name) != 1) + if(fscanf(nameFile, "%[^\n]", host) != 1) { ffPrintError(state, "Host", "fscanf(nameFile, \"%[^\\n]\", name) != 1"); return; } fclose(nameFile); - ffPrintLogoAndKey(state, "Host"); - printf(name); - FILE* versionFile = fopen("/sys/devices/virtual/dmi/id/product_version", "r"); if(versionFile != NULL) { - char version[256]; - if(fscanf(versionFile, "%[^\n]", version) == 1) - printf(" %s", version); + ssize_t len = strlen(host); + host[len] = ' '; + fscanf(versionFile, "%[^\n]", host + len + 1); fclose(versionFile); } - - putchar('\n'); + + ffSaveCachedValue(state, "Host", host); + + ffPrintLogoAndKey(state, "Host"); + puts(host); } \ No newline at end of file diff --git a/src/locale.c b/src/locale.c index 057d411db..0f9639cb9 100644 --- a/src/locale.c +++ b/src/locale.c @@ -2,6 +2,9 @@ void ffPrintLocale(FFstate* state) { + if(ffPrintCachedValue(state, "Locale")) + return; + char locale[256]; ffParsePropFile("/etc/locale.conf", "LANG=%[^\n]", locale); if(locale[0] == '\0') @@ -10,6 +13,8 @@ void ffPrintLocale(FFstate* state) return; } + ffSaveCachedValue(state, "Locale", locale); + ffPrintLogoAndKey(state, "Locale"); puts(locale); } \ No newline at end of file diff --git a/src/os.c b/src/os.c index 56e6e8934..9713ead88 100644 --- a/src/os.c +++ b/src/os.c @@ -2,6 +2,9 @@ void ffPrintOS(FFstate* state) { + if(ffPrintCachedValue(state, "OS")) + return; + char name[256]; ffParsePropFile("/etc/os-release", "NAME=\"%[^\"]+", name); if(name[0] == '\0') @@ -10,6 +13,11 @@ void ffPrintOS(FFstate* state) return; } + char os[1024]; + sprintf(os, "%s %s", name, state->utsname.machine); + + ffSaveCachedValue(state, "OS", os); + ffPrintLogoAndKey(state, "OS"); - printf("%s %s\n", name, state->utsname.machine); + puts(os); } \ No newline at end of file diff --git a/src/resolution.c b/src/resolution.c index 60df7e376..d01313177 100644 --- a/src/resolution.c +++ b/src/resolution.c @@ -4,10 +4,17 @@ void ffPrintResolution(FFstate* state) { + if(ffPrintCachedValue(state, "Resolution")) + return; Display* display = XOpenDisplay(NULL); Screen* screen = DefaultScreenOfDisplay(display); + char resolution[1024]; + sprintf(resolution, "%ix%i", screen->width, screen->height); + + ffSaveCachedValue(state, "Resolution", resolution); + ffPrintLogoAndKey(state, "Resolution"); - printf("%ix%i\n", screen->width, screen->height); + puts(resolution); } \ No newline at end of file diff --git a/src/shell.c b/src/shell.c index 43308e71f..750eb901b 100644 --- a/src/shell.c +++ b/src/shell.c @@ -4,6 +4,9 @@ void ffPrintShell(FFstate* state) { + if(ffPrintCachedValue(state, "Shell")) + return; + char* shellPath = getenv("SHELL"); if(shellPath == NULL) { @@ -18,6 +21,8 @@ void ffPrintShell(FFstate* state) else if(shellName[0] == '/') ++shellName; + ffSaveCachedValue(state, "Shell", shellName); + ffPrintLogoAndKey(state, "Shell"); puts(shellName); } \ No newline at end of file