From 76424950e373d3b04ac3dd13019151bfba3e8423 Mon Sep 17 00:00:00 2001 From: sumuel Date: Mon, 17 Aug 2026 20:44:55 +0000 Subject: Add the files --- src/detection/packages/packages.c | 119 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 119 insertions(+) create mode 100644 src/detection/packages/packages.c (limited to 'src/detection/packages/packages.c') diff --git a/src/detection/packages/packages.c b/src/detection/packages/packages.c new file mode 100644 index 0000000..25f59b3 --- /dev/null +++ b/src/detection/packages/packages.c @@ -0,0 +1,119 @@ +#include "packages.h" +#include "common/io.h" +#include "common/time.h" + +#include +#include + +#ifdef __APPLE__ + #define st_mtim st_mtimespec +#endif + +void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options); + +const char* ffDetectPackages(FFPackagesResult* result, FFPackagesOptions* options) { + ffDetectPackagesImpl(result, options); + + for (uint32_t i = 0; i < offsetof(FFPackagesResult, all) / sizeof(uint32_t); ++i) { + result->all += ((uint32_t*) result)[i]; + } + + return NULL; +} + +bool ffPackagesReadCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, const char* filePath, const char* packageId, uint32_t* result) { +#ifndef _WIN32 + struct stat st; + if (stat(filePath, &st) < 0) // file doesn't exist or isn't accessible + { + *result = 0; + return true; + } + + if (__builtin_expect(st.st_mtim.tv_sec <= 0, false)) { + return false; + } + + uint64_t mtime_current = (uint64_t) st.st_mtim.tv_sec * 1000ull + (uint64_t) st.st_mtim.tv_nsec / 1000000ull; +#else + FF_AUTO_CLOSE_FD HANDLE handle = CreateFileA(filePath, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL); + + if (handle == INVALID_HANDLE_VALUE) // file doesn't exist or isn't accessible + { + *result = 0; + return true; + } + + uint64_t mtime_current; + FILE_BASIC_INFORMATION fileInfo; + IO_STATUS_BLOCK iosb; + if (!NT_SUCCESS(NtQueryInformationFile(handle, &iosb, &fileInfo, sizeof(fileInfo), FileBasicInformation))) { + return false; + } + + mtime_current = ffFileTimeToUnixMs((uint64_t) fileInfo.LastWriteTime.QuadPart); +#endif + + ffStrbufSet(cacheDir, &instance.state.platform.cacheDir); + ffStrbufEnsureEndsWithC(cacheDir, '/'); + ffStrbufAppendF(cacheDir, "fastfetch/packages/%s.txt", packageId); + + if (ffReadFileBuffer(cacheDir->chars, cacheContent)) { + uint64_t mtime_cached; + uint32_t num_cached; + if (sscanf(cacheContent->chars, "%" SCNu64 " %" SCNu32, &mtime_cached, &num_cached) == 2 && + mtime_cached == mtime_current && num_cached > 0) { + *result = num_cached; + return true; + } + } + + ffStrbufSetF(cacheContent, "%" PRIu64 " ", mtime_current); + + return false; +} + +bool ffPackagesWriteCache(FFstrbuf* cacheDir, FFstrbuf* cacheContent, uint32_t num_elements) { + if (__builtin_expect(cacheContent->length == 0, false)) { + return false; + } + + ffStrbufAppendF(cacheContent, "%" PRIu32, num_elements); + return ffWriteFileBuffer(cacheDir->chars, cacheContent); +} + +#ifndef _WIN32 +uint32_t ffPackagesGetNumElements(const char* dirname, bool isdir) { + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(dirname); + if (dirp == NULL) { + return 0; + } + + uint32_t num_elements = 0; + + struct dirent* entry; + while ((entry = readdir(dirp)) != NULL) { + bool ok = false; + + if (entry->d_name[0] != '.') { + #if !defined(__sun) && !defined(__HAIKU__) + if (entry->d_type != DT_UNKNOWN && entry->d_type != DT_LNK) { + ok = entry->d_type == (isdir ? DT_DIR : DT_REG); + } else + #endif + { + struct stat stbuf; + if (fstatat(dirfd(dirp), entry->d_name, &stbuf, 0) == 0) { + ok = isdir ? S_ISDIR(stbuf.st_mode) : S_ISREG(stbuf.st_mode); + } + } + } + + if (ok) { + ++num_elements; + } + } + + return num_elements; +} +#endif -- cgit v1.2.3