From 1785f2a2d765840c16bee97118ef3b243c77d5c1 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:07:39 -0500 Subject: [PATCH 01/15] Delete src/detection/media/media_linux.c removed to add patch file --- src/detection/media/media_linux.c | 290 ------------------------------ 1 file changed, 290 deletions(-) delete mode 100644 src/detection/media/media_linux.c diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c deleted file mode 100644 index 37b19048ea..0000000000 --- a/src/detection/media/media_linux.c +++ /dev/null @@ -1,290 +0,0 @@ -#include "common/io/io.h" -#include "fastfetch.h" -#include "detection/media/media.h" -#include "util/stringUtils.h" -#include "util/unused.h" - -#include - -#define FF_DBUS_MPRIS_PREFIX "org.mpris.MediaPlayer2." - -#ifdef FF_HAVE_DBUS -#include "common/dbus.h" - -#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \ - { \ - if(!(dbus)->lib->ffdbus_message_iter_next(iterator)) \ - break; \ - continue; \ - } - -static bool parseMprisMetadata(FFDBusData* data, DBusMessageIter* rootIterator, FFMediaResult* result) -{ - DBusMessageIter arrayIterator; - - if (data->lib->ffdbus_message_iter_get_arg_type(rootIterator) == DBUS_TYPE_VARIANT) - { - DBusMessageIter variantIterator; - data->lib->ffdbus_message_iter_recurse(rootIterator, &variantIterator); - if(data->lib->ffdbus_message_iter_get_arg_type(&variantIterator) != DBUS_TYPE_ARRAY) - return false; - data->lib->ffdbus_message_iter_recurse(&variantIterator, &arrayIterator); - } - else - { - data->lib->ffdbus_message_iter_recurse(rootIterator, &arrayIterator); - } - - while(true) - { - if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY) - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - - DBusMessageIter dictIterator; - data->lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator); - - if(data->lib->ffdbus_message_iter_get_arg_type(&dictIterator) != DBUS_TYPE_STRING) - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - - if(!data->lib->ffdbus_message_iter_has_next(&dictIterator)) - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - - const char* key; - data->lib->ffdbus_message_iter_get_basic(&dictIterator, &key); - - data->lib->ffdbus_message_iter_next(&dictIterator); - - if(ffStrStartsWith(key, "xesam:")) - { - const char* xesam = key + strlen("xesam:"); - if(ffStrEquals(xesam, "title")) - ffDBusGetString(data, &dictIterator, &result->song); - else if(ffStrEquals(xesam, "album")) - ffDBusGetString(data, &dictIterator, &result->album); - else if(ffStrEquals(xesam, "artist")) - ffDBusGetString(data, &dictIterator, &result->artist); - else if(ffStrEquals(xesam, "url")) - ffDBusGetString(data, &dictIterator, &result->url); - - if(result->song.length > 0 && result->artist.length > 0 && result->album.length > 0 && result->url.length > 0) - break; - } - else if (ffStrStartsWith(key, "mpris:")) - { - const char* xesam = key + strlen("mpris:"); - if(ffStrEquals(xesam, "artUrl")) - { - FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); - ffDBusGetString(data, &dictIterator, &path); - if (ffStrbufStartsWithS(&path, "file:///")) - { - ffStrbufEnsureFree(&result->cover, path.length - (uint32_t) strlen("file://")); - for (uint32_t i = (uint32_t) strlen("file://"); i < path.length; ++i) - { - if (path.chars[i] == '%') - { - if (i + 2 >= path.length) - break; - char str[] = { path.chars[i + 1], path.chars[i + 2], 0 }; - char* end = NULL; - const char decodedChar = (char) strtoul(str, &end, 16); - if (end == &str[2]) - { - i += 2; - ffStrbufAppendC(&result->cover, decodedChar); - } - else - ffStrbufAppendC(&result->cover, '%'); - } - else - { - ffStrbufAppendC(&result->cover, path.chars[i]); - } - } - } - } - } - - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - } - - return true; -} - -static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResult* result) -{ - // Get all properties at once to reduce the number of IPCs - DBusMessage* reply = ffDBusGetAllProperties(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player"); - if(reply == NULL) - return false; - - DBusMessageIter rootIterator; - if(!data->lib->ffdbus_message_iter_init(reply, &rootIterator) && - data->lib->ffdbus_message_iter_get_arg_type(&rootIterator) != DBUS_TYPE_ARRAY) - { - data->lib->ffdbus_message_unref(reply); - return false; - } - - DBusMessageIter arrayIterator; - data->lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator); - - while(true) - { - if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY) - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - - DBusMessageIter dictIterator; - data->lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator); - - const char* key; - data->lib->ffdbus_message_iter_get_basic(&dictIterator, &key); - - data->lib->ffdbus_message_iter_next(&dictIterator); - - if(ffStrEquals(key, "Metadata")) - parseMprisMetadata(data, &dictIterator, result); - else if(ffStrEquals(key, "PlaybackStatus")) - ffDBusGetString(data, &dictIterator, &result->status); - - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - } - - if(result->song.length == 0) - { - if(result->url.length) - { - const char* fileName = memrchr(result->url.chars, '/', result->url.length); - assert(fileName); - ++fileName; - ffStrbufEnsureFixedLengthFree(&result->song, result->url.length - (uint32_t) (fileName - result->url.chars)); - for(; *fileName && *fileName != '?'; ++fileName) - { - if (*fileName != '%') - { - ffStrbufAppendC(&result->song, *fileName); - } - else - { - if (fileName[1] == 0 || fileName[2] == 0) - break; - char str[] = { fileName[1], fileName[2], 0 }; - ffStrbufAppendC(&result->song, (char) strtoul(str, NULL, 16)); - fileName += 2; - } - } - } - else - { - ffStrbufClear(&result->artist); - ffStrbufClear(&result->album); - ffStrbufClear(&result->url); - ffStrbufClear(&result->status); - return false; - } - } - - //Set short bus name - ffStrbufAppendS(&result->playerId, busName + sizeof(FF_DBUS_MPRIS_PREFIX) - 1); - - //We found a song, get the player name - if (ffStrbufStartsWithS(&result->playerId, "musikcube.instance")) - { - // dbus calls are EXTREMELY slow on musikcube, so we set the player name manually - ffStrbufSetStatic(&result->player, "musikcube"); - } - else - { - ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Identity", &result->player); - if(result->player.length == 0) - ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "DesktopEntry", &result->player); - if(result->player.length == 0) - ffStrbufAppend(&result->player, &result->playerId); - } - - data->lib->ffdbus_message_unref(reply); - - return true; -} - -static void getCustomBus(FFDBusData* data, const FFstrbuf* playerName, FFMediaResult* result) -{ - if(ffStrbufStartsWithS(playerName, FF_DBUS_MPRIS_PREFIX)) - { - getBusProperties(data, playerName->chars, result); - return; - } - - FF_STRBUF_AUTO_DESTROY busName = ffStrbufCreateS(FF_DBUS_MPRIS_PREFIX); - ffStrbufAppend(&busName, playerName); - getBusProperties(data, busName.chars, result); -} - -static void getBestBus(FFDBusData* data, FFMediaResult* result) -{ - if( - getBusProperties(data, FF_DBUS_MPRIS_PREFIX "spotify", result) || - getBusProperties(data, FF_DBUS_MPRIS_PREFIX "vlc", result) || - getBusProperties(data, FF_DBUS_MPRIS_PREFIX "plasma-browser-integration", result) - ) return; - - DBusMessage* reply = ffDBusGetMethodReply(data, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", NULL, NULL); - if(reply == NULL) - return; - - DBusMessageIter rootIterator; - if(!data->lib->ffdbus_message_iter_init(reply, &rootIterator) || data->lib->ffdbus_message_iter_get_arg_type(&rootIterator) != DBUS_TYPE_ARRAY) - return; - - DBusMessageIter arrayIterator; - data->lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator); - - while(true) - { - if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_STRING) - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - - const char* busName; - data->lib->ffdbus_message_iter_get_basic(&arrayIterator, &busName); - - if(!ffStrStartsWith(busName, FF_DBUS_MPRIS_PREFIX)) - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - - if(getBusProperties(data, busName, result)) - break; - - FF_DBUS_ITER_CONTINUE(data, &arrayIterator) - } - - data->lib->ffdbus_message_unref(reply); -} - -static const char* getMedia(FFMediaResult* result) -{ - FFDBusData data; - const char* error = ffDBusLoadData(DBUS_BUS_SESSION, &data); - if(error != NULL) - return error; - - // FIXME: This is shared for both player and media module. - // However it uses an option in one specific module - if(instance.config.general.playerName.length > 0) - getCustomBus(&data, &instance.config.general.playerName, result); - else - getBestBus(&data, result); - - return NULL; -} - -#endif - -void ffDetectMediaImpl(FFMediaResult* media, bool saveCover) -{ - FF_UNUSED(saveCover); // We don't save the cover to a file for Mpris implementation - #ifdef FF_HAVE_DBUS - const char* error = getMedia(media); - ffStrbufAppendS(&media->error, error); - #else - ffStrbufAppendS(&media->error, "Fastfetch was compiled without DBus support"); - #endif -} From bf6bd5bf8eec777fce2658986d99d7435292c730 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:08:12 -0500 Subject: [PATCH 02/15] Add files via upload --- src/detection/media/media_linux.c | 290 ++++++++++++++++++++++++++++++ 1 file changed, 290 insertions(+) create mode 100644 src/detection/media/media_linux.c diff --git a/src/detection/media/media_linux.c b/src/detection/media/media_linux.c new file mode 100644 index 0000000000..40d37af746 --- /dev/null +++ b/src/detection/media/media_linux.c @@ -0,0 +1,290 @@ +#include "common/io/io.h" +#include "fastfetch.h" +#include "detection/media/media.h" +#include "util/stringUtils.h" +#include "util/unused.h" + +#include + +#define FF_DBUS_MPRIS_PREFIX "org.mpris.MediaPlayer2." + +#ifdef FF_HAVE_DBUS +#include "common/dbus.h" + +#define FF_DBUS_ITER_CONTINUE(dbus, iterator) \ + { \ + if(!(dbus)->lib->ffdbus_message_iter_next(iterator)) \ + break; \ + continue; \ + } + +static bool parseMprisMetadata(FFDBusData* data, DBusMessageIter* rootIterator, FFMediaResult* result) +{ + DBusMessageIter arrayIterator; + + if (data->lib->ffdbus_message_iter_get_arg_type(rootIterator) == DBUS_TYPE_VARIANT) + { + DBusMessageIter variantIterator; + data->lib->ffdbus_message_iter_recurse(rootIterator, &variantIterator); + if(data->lib->ffdbus_message_iter_get_arg_type(&variantIterator) != DBUS_TYPE_ARRAY) + return false; + data->lib->ffdbus_message_iter_recurse(&variantIterator, &arrayIterator); + } + else + { + data->lib->ffdbus_message_iter_recurse(rootIterator, &arrayIterator); + } + + while(true) + { + if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY) + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + + DBusMessageIter dictIterator; + data->lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator); + + if(data->lib->ffdbus_message_iter_get_arg_type(&dictIterator) != DBUS_TYPE_STRING) + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + + if(!data->lib->ffdbus_message_iter_has_next(&dictIterator)) + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + + const char* key; + data->lib->ffdbus_message_iter_get_basic(&dictIterator, &key); + + data->lib->ffdbus_message_iter_next(&dictIterator); + + if(ffStrStartsWith(key, "xesam:")) + { + const char* xesam = key + strlen("xesam:"); + if(ffStrEquals(xesam, "title")) + ffDBusGetString(data, &dictIterator, &result->song); + else if(ffStrEquals(xesam, "album")) + ffDBusGetString(data, &dictIterator, &result->album); + else if(ffStrEquals(xesam, "artist")) + ffDBusGetString(data, &dictIterator, &result->artist); + else if(ffStrEquals(xesam, "url")) + ffDBusGetString(data, &dictIterator, &result->url); + + if(result->song.length > 0 && result->artist.length > 0 && result->album.length > 0 && result->url.length > 0) + break; + } + else if (ffStrStartsWith(key, "mpris:")) + { + const char* xesam = key + strlen("mpris:"); + if(ffStrEquals(xesam, "artUrl")) + { + FF_STRBUF_AUTO_DESTROY path = ffStrbufCreate(); + ffDBusGetString(data, &dictIterator, &path); + if (ffStrbufStartsWithS(&path, "file:///")) + { + ffStrbufEnsureFree(&result->cover, path.length - (uint32_t) strlen("file://")); + for (uint32_t i = (uint32_t) strlen("file://"); i < path.length; ++i) + { + if (path.chars[i] == '%') + { + if (i + 2 >= path.length) + break; + char str[] = { path.chars[i + 1], path.chars[i + 2], 0 }; + char* end = NULL; + const char decodedChar = (char) strtoul(str, &end, 16); + if (end == &str[2]) + { + i += 2; + ffStrbufAppendC(&result->cover, decodedChar); + } + else + ffStrbufAppendC(&result->cover, '%'); + } + else + { + ffStrbufAppendC(&result->cover, path.chars[i]); + } + } + } + } + } + + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + } + + return true; +} + +static bool getBusProperties(FFDBusData* data, const char* busName, FFMediaResult* result) +{ + // Get all properties at once to reduce the number of IPCs + DBusMessage* reply = ffDBusGetAllProperties(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2.Player"); + if(reply == NULL) + return false; + + DBusMessageIter rootIterator; + if(!data->lib->ffdbus_message_iter_init(reply, &rootIterator) && + data->lib->ffdbus_message_iter_get_arg_type(&rootIterator) != DBUS_TYPE_ARRAY) + { + data->lib->ffdbus_message_unref(reply); + return false; + } + + DBusMessageIter arrayIterator; + data->lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator); + + while(true) + { + if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_DICT_ENTRY) + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + + DBusMessageIter dictIterator; + data->lib->ffdbus_message_iter_recurse(&arrayIterator, &dictIterator); + + const char* key; + data->lib->ffdbus_message_iter_get_basic(&dictIterator, &key); + + data->lib->ffdbus_message_iter_next(&dictIterator); + + if(ffStrEquals(key, "Metadata")) + parseMprisMetadata(data, &dictIterator, result); + else if(ffStrEquals(key, "PlaybackStatus")) + ffDBusGetString(data, &dictIterator, &result->status); + + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + } + + if(result->song.length == 0) + { + if(result->url.length) + { + const char* fileName = memchr(result->url.chars, '/', result->url.length); + assert(fileName); + ++fileName; + ffStrbufEnsureFixedLengthFree(&result->song, result->url.length - (uint32_t) (fileName - result->url.chars)); + for(; *fileName && *fileName != '?'; ++fileName) + { + if (*fileName != '%') + { + ffStrbufAppendC(&result->song, *fileName); + } + else + { + if (fileName[1] == 0 || fileName[2] == 0) + break; + char str[] = { fileName[1], fileName[2], 0 }; + ffStrbufAppendC(&result->song, (char) strtoul(str, NULL, 16)); + fileName += 2; + } + } + } + else + { + ffStrbufClear(&result->artist); + ffStrbufClear(&result->album); + ffStrbufClear(&result->url); + ffStrbufClear(&result->status); + return false; + } + } + + //Set short bus name + ffStrbufAppendS(&result->playerId, busName + sizeof(FF_DBUS_MPRIS_PREFIX) - 1); + + //We found a song, get the player name + if (ffStrbufStartsWithS(&result->playerId, "musikcube.instance")) + { + // dbus calls are EXTREMELY slow on musikcube, so we set the player name manually + ffStrbufSetStatic(&result->player, "musikcube"); + } + else + { + ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "Identity", &result->player); + if(result->player.length == 0) + ffDBusGetPropertyString(data, busName, "/org/mpris/MediaPlayer2", "org.mpris.MediaPlayer2", "DesktopEntry", &result->player); + if(result->player.length == 0) + ffStrbufAppend(&result->player, &result->playerId); + } + + data->lib->ffdbus_message_unref(reply); + + return true; +} + +static void getCustomBus(FFDBusData* data, const FFstrbuf* playerName, FFMediaResult* result) +{ + if(ffStrbufStartsWithS(playerName, FF_DBUS_MPRIS_PREFIX)) + { + getBusProperties(data, playerName->chars, result); + return; + } + + FF_STRBUF_AUTO_DESTROY busName = ffStrbufCreateS(FF_DBUS_MPRIS_PREFIX); + ffStrbufAppend(&busName, playerName); + getBusProperties(data, busName.chars, result); +} + +static void getBestBus(FFDBusData* data, FFMediaResult* result) +{ + if( + getBusProperties(data, FF_DBUS_MPRIS_PREFIX "spotify", result) || + getBusProperties(data, FF_DBUS_MPRIS_PREFIX "vlc", result) || + getBusProperties(data, FF_DBUS_MPRIS_PREFIX "plasma-browser-integration", result) + ) return; + + DBusMessage* reply = ffDBusGetMethodReply(data, "org.freedesktop.DBus", "/org/freedesktop/DBus", "org.freedesktop.DBus", "ListNames", NULL, NULL); + if(reply == NULL) + return; + + DBusMessageIter rootIterator; + if(!data->lib->ffdbus_message_iter_init(reply, &rootIterator) || data->lib->ffdbus_message_iter_get_arg_type(&rootIterator) != DBUS_TYPE_ARRAY) + return; + + DBusMessageIter arrayIterator; + data->lib->ffdbus_message_iter_recurse(&rootIterator, &arrayIterator); + + while(true) + { + if(data->lib->ffdbus_message_iter_get_arg_type(&arrayIterator) != DBUS_TYPE_STRING) + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + + const char* busName; + data->lib->ffdbus_message_iter_get_basic(&arrayIterator, &busName); + + if(!ffStrStartsWith(busName, FF_DBUS_MPRIS_PREFIX)) + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + + if(getBusProperties(data, busName, result)) + break; + + FF_DBUS_ITER_CONTINUE(data, &arrayIterator) + } + + data->lib->ffdbus_message_unref(reply); +} + +static const char* getMedia(FFMediaResult* result) +{ + FFDBusData data; + const char* error = ffDBusLoadData(DBUS_BUS_SESSION, &data); + if(error != NULL) + return error; + + // FIXME: This is shared for both player and media module. + // However it uses an option in one specific module + if(instance.config.general.playerName.length > 0) + getCustomBus(&data, &instance.config.general.playerName, result); + else + getBestBus(&data, result); + + return NULL; +} + +#endif + +void ffDetectMediaImpl(FFMediaResult* media, bool saveCover) +{ + FF_UNUSED(saveCover); // We don't save the cover to a file for Mpris implementation + #ifdef FF_HAVE_DBUS + const char* error = getMedia(media); + ffStrbufAppendS(&media->error, error); + #else + ffStrbufAppendS(&media->error, "Fastfetch was compiled without DBus support"); + #endif +} From 096e6426fde480cf66a5cea607c0af0cf525d539 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:08:51 -0500 Subject: [PATCH 03/15] Delete src/detection/gpu/gpu_pci.c removed to add patch file --- src/detection/gpu/gpu_pci.c | 239 ------------------------------------ 1 file changed, 239 deletions(-) delete mode 100644 src/detection/gpu/gpu_pci.c diff --git a/src/detection/gpu/gpu_pci.c b/src/detection/gpu/gpu_pci.c deleted file mode 100644 index cce1deb45d..0000000000 --- a/src/detection/gpu/gpu_pci.c +++ /dev/null @@ -1,239 +0,0 @@ -#include "gpu.h" -#include "common/io/io.h" -#include "common/properties.h" - -#include -#ifdef __FreeBSD__ - #include - #ifndef _PATH_LOCALBASE - #define _PATH_LOCALBASE "/usr/local" - #endif -#elif __OpenBSD__ - #define _PATH_LOCALBASE "/usr/local" -#elif __NetBSD__ - #define _PATH_LOCALBASE "/usr/pkg" -#endif - -#if FF_HAVE_EMBEDDED_PCIIDS -#include "fastfetch_pciids.c.inc" -#endif -#if FF_HAVE_EMBEDDED_AMDGPUIDS -#include "fastfetch_amdgpuids.c.inc" -#endif - -#define FF_STR_INDIR(x) #x -#define FF_STR(x) FF_STR_INDIR(x) - -static const FFstrbuf* loadPciIds() -{ - static FFstrbuf pciids; - - if (pciids.chars) return &pciids; - ffStrbufInit(&pciids); - - #ifdef FF_CUSTOM_PCI_IDS_PATH - - ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), &pciids); - - #else // FF_CUSTOM_PCI_IDS_PATH - - #if __linux__ - ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", &pciids); - if (pciids.length == 0) - { - ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/misc/pci.ids", &pciids); // debian? - if (pciids.length == 0) - ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", &pciids); - } - #elif __OpenBSD__ || __FreeBSD__ || __NetBSD__ - ffReadFileBuffer(_PATH_LOCALBASE "/share/hwdata/pci.ids", &pciids); - if (pciids.length == 0) - ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", &pciids); - #elif __sun - ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids); - #elif __HAIKU__ - ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/system/data/hwdata/pci.ids", &pciids); - #endif - - #endif // FF_CUSTOM_PCI_IDS_PATH - - return &pciids; -} - -static void parsePciIdsFile(const FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu) -{ - if (content->length) - { - char buffer[32]; - - // Search for vendor - uint32_t len = (uint32_t) snprintf(buffer, ARRAY_SIZE(buffer), "\n%04x ", vendor); - char* start = (char*) memmem(content->chars, content->length, buffer, len); - char* end = content->chars + content->length; - if (start) - { - start += len; - end = memchr(start, '\n', (uint32_t) (end - start)); - if (!end) - end = content->chars + content->length; - if (!gpu->vendor.length) - ffStrbufSetNS(&gpu->vendor, (uint32_t) (end - start), start); - - start = end; // point to '\n' of vendor - end = start + 1; // point to start of devices - // find the start of next vendor - while (end[0] == '\t' || end[0] == '#') - { - end = strchr(end, '\n'); - if (!end) - { - end = content->chars + content->length; - break; - } - else - end++; - } - - // Search for device - len = (uint32_t) snprintf(buffer, ARRAY_SIZE(buffer), "\n\t%04x ", device); - start = memmem(start, (size_t) (end - start), buffer, len); - if (start) - { - start += len; - end = memchr(start, '\n', (uint32_t) (end - start)); - if (!end) - end = content->chars + content->length; - - char* closingBracket = end - 1; - if (*closingBracket == ']') - { - char* openingBracket = memrchr(start, '[', (size_t) (closingBracket - start)); - if (openingBracket) - { - openingBracket++; - ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket); - } - } - if (!gpu->name.length) - ffStrbufSetNS(&gpu->name, (uint32_t) (end - start), start); - } - } - } - - if (!gpu->name.length) - { - const char* subclassStr; - switch (subclass) - { - case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break; - case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break; - case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break; - default: subclassStr = ""; break; - } - - ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr); - } -} - -#if FF_HAVE_EMBEDDED_PCIIDS -static inline int pciDeviceCmp(const uint16_t* key, const FFPciDevice* element) -{ - return (int) *key - (int) element->id; -} - -static bool loadPciidsInc(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu) -{ - for (const FFPciVendor* pvendor = ffPciVendors; pvendor->name; pvendor++) - { - if (pvendor->id != vendor) continue; - - if (!gpu->vendor.length) - ffStrbufSetS(&gpu->vendor, pvendor->name); - - const FFPciDevice* pdevice = (const FFPciDevice*) bsearch(&device, pvendor->devices, pvendor->nDevices, sizeof(*pdevice), (void*) pciDeviceCmp); - - if (pdevice) - { - uint32_t nameLen = (uint32_t) strlen(pdevice->name); - const char* closingBracket = pdevice->name + nameLen - 1; - if (*closingBracket == ']') - { - const char* openingBracket = memrchr(pdevice->name, '[', nameLen - 1); - if (openingBracket) - { - openingBracket++; - ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket); - } - } - if (!gpu->name.length) - ffStrbufSetNS(&gpu->name, nameLen, pdevice->name); - return true; - } - - if (!gpu->name.length) - { - const char* subclassStr; - switch (subclass) - { - case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break; - case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break; - case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break; - default: subclassStr = ""; break; - } - - ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr); - } - return true; - } - return false; -} -#endif - -void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu) -{ - #if FF_HAVE_EMBEDDED_PCIIDS - bool ok = loadPciidsInc(subclass, vendor, device, gpu); - if (ok) return; - #endif - return parsePciIdsFile(loadPciIds(), subclass, vendor, device, gpu); -} - -#if FF_HAVE_EMBEDDED_AMDGPUIDS -static inline int amdGpuCmp(const uint32_t* key, const FFArmGpuProduct* element) -{ - // Maximum value of *key is 0x00FFFFFF. `(int) *key` should never overflow - return (int) *key - (int) element->id; -} - -static bool loadAmdGpuIdsInc(uint16_t deviceId, uint8_t revision, FFGPUResult* gpu) -{ - uint32_t key = (deviceId << 8u) | revision; - FFArmGpuProduct* product = bsearch(&key, ffAmdGpuProducts, ARRAY_SIZE(ffAmdGpuProducts), sizeof(*ffAmdGpuProducts), (void*) amdGpuCmp); - if (product) - { - ffStrbufSetS(&gpu->name, product->name); - return true; - } - return false; -} -#endif - -static void parseAmdGpuIdsFile(uint16_t deviceId, uint8_t revision, FFGPUResult* gpu) -{ - char query[32]; - snprintf(query, ARRAY_SIZE(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision); - #ifdef FF_CUSTOM_AMDGPU_IDS_PATH - ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name); - #else - ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name); - #endif -} - -void ffGPUQueryAmdGpuName(uint16_t deviceId, uint8_t revisionId, FFGPUResult* gpu) -{ - #if FF_HAVE_EMBEDDED_AMDGPUIDS - bool ok = loadAmdGpuIdsInc(deviceId, revisionId, gpu); - if (ok) return; - #endif - return parseAmdGpuIdsFile(deviceId, revisionId, gpu); -} From 1a6552d542e1fe83f7da7bc2cfac45d624a25d0a Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:09:31 -0500 Subject: [PATCH 04/15] Add files via upload --- src/detection/gpu/gpu_pci.c | 239 ++++++++++++++++++++++++++++++++++++ 1 file changed, 239 insertions(+) create mode 100644 src/detection/gpu/gpu_pci.c diff --git a/src/detection/gpu/gpu_pci.c b/src/detection/gpu/gpu_pci.c new file mode 100644 index 0000000000..3e308278be --- /dev/null +++ b/src/detection/gpu/gpu_pci.c @@ -0,0 +1,239 @@ +#include "gpu.h" +#include "common/io/io.h" +#include "common/properties.h" + +#include +#ifdef __FreeBSD__ + #include + #ifndef _PATH_LOCALBASE + #define _PATH_LOCALBASE "/usr/local" + #endif +#elif __OpenBSD__ + #define _PATH_LOCALBASE "/usr/local" +#elif __NetBSD__ + #define _PATH_LOCALBASE "/usr/pkg" +#endif + +#if FF_HAVE_EMBEDDED_PCIIDS +#include "fastfetch_pciids.c.inc" +#endif +#if FF_HAVE_EMBEDDED_AMDGPUIDS +#include "fastfetch_amdgpuids.c.inc" +#endif + +#define FF_STR_INDIR(x) #x +#define FF_STR(x) FF_STR_INDIR(x) + +static const FFstrbuf* loadPciIds() +{ + static FFstrbuf pciids; + + if (pciids.chars) return &pciids; + ffStrbufInit(&pciids); + + #ifdef FF_CUSTOM_PCI_IDS_PATH + + ffReadFileBuffer(FF_STR(FF_CUSTOM_PCI_IDS_PATH), &pciids); + + #else // FF_CUSTOM_PCI_IDS_PATH + + #if __linux__ + ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/hwdata/pci.ids", &pciids); + if (pciids.length == 0) + { + ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/share/misc/pci.ids", &pciids); // debian? + if (pciids.length == 0) + ffReadFileBuffer(FASTFETCH_TARGET_DIR_USR "/local/share/hwdata/pci.ids", &pciids); + } + #elif __OpenBSD__ || __FreeBSD__ || __NetBSD__ + ffReadFileBuffer(_PATH_LOCALBASE "/share/hwdata/pci.ids", &pciids); + if (pciids.length == 0) + ffReadFileBuffer(_PATH_LOCALBASE "/share/pciids/pci.ids", &pciids); + #elif __sun + ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/usr/share/hwdata/pci.ids", &pciids); + #elif __HAIKU__ + ffReadFileBuffer(FASTFETCH_TARGET_DIR_ROOT "/system/data/hwdata/pci.ids", &pciids); + #endif + + #endif // FF_CUSTOM_PCI_IDS_PATH + + return &pciids; +} + +static void parsePciIdsFile(const FFstrbuf* content, uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu) +{ + if (content->length) + { + char buffer[32]; + + // Search for vendor + uint32_t len = (uint32_t) snprintf(buffer, ARRAY_SIZE(buffer), "\n%04x ", vendor); + char* start = (char*) memmem(content->chars, content->length, buffer, len); + char* end = content->chars + content->length; + if (start) + { + start += len; + end = memchr(start, '\n', (uint32_t) (end - start)); + if (!end) + end = content->chars + content->length; + if (!gpu->vendor.length) + ffStrbufSetNS(&gpu->vendor, (uint32_t) (end - start), start); + + start = end; // point to '\n' of vendor + end = start + 1; // point to start of devices + // find the start of next vendor + while (end[0] == '\t' || end[0] == '#') + { + end = strchr(end, '\n'); + if (!end) + { + end = content->chars + content->length; + break; + } + else + end++; + } + + // Search for device + len = (uint32_t) snprintf(buffer, ARRAY_SIZE(buffer), "\n\t%04x ", device); + start = memmem(start, (size_t) (end - start), buffer, len); + if (start) + { + start += len; + end = memchr(start, '\n', (uint32_t) (end - start)); + if (!end) + end = content->chars + content->length; + + char* closingBracket = end - 1; + if (*closingBracket == ']') + { + char* openingBracket = memchr(start, '[', (size_t) (closingBracket - start)); + if (openingBracket) + { + openingBracket++; + ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket); + } + } + if (!gpu->name.length) + ffStrbufSetNS(&gpu->name, (uint32_t) (end - start), start); + } + } + } + + if (!gpu->name.length) + { + const char* subclassStr; + switch (subclass) + { + case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break; + case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break; + case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break; + default: subclassStr = ""; break; + } + + ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr); + } +} + +#if FF_HAVE_EMBEDDED_PCIIDS +static inline int pciDeviceCmp(const uint16_t* key, const FFPciDevice* element) +{ + return (int) *key - (int) element->id; +} + +static bool loadPciidsInc(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu) +{ + for (const FFPciVendor* pvendor = ffPciVendors; pvendor->name; pvendor++) + { + if (pvendor->id != vendor) continue; + + if (!gpu->vendor.length) + ffStrbufSetS(&gpu->vendor, pvendor->name); + + const FFPciDevice* pdevice = (const FFPciDevice*) bsearch(&device, pvendor->devices, pvendor->nDevices, sizeof(*pdevice), (void*) pciDeviceCmp); + + if (pdevice) + { + uint32_t nameLen = (uint32_t) strlen(pdevice->name); + const char* closingBracket = pdevice->name + nameLen - 1; + if (*closingBracket == ']') + { + const char* openingBracket = memchr(pdevice->name, '[', nameLen - 1); + if (openingBracket) + { + openingBracket++; + ffStrbufSetNS(&gpu->name, (uint32_t) (closingBracket - openingBracket), openingBracket); + } + } + if (!gpu->name.length) + ffStrbufSetNS(&gpu->name, nameLen, pdevice->name); + return true; + } + + if (!gpu->name.length) + { + const char* subclassStr; + switch (subclass) + { + case 0 /*PCI_CLASS_DISPLAY_VGA*/: subclassStr = " (VGA compatible)"; break; + case 1 /*PCI_CLASS_DISPLAY_XGA*/: subclassStr = " (XGA compatible)"; break; + case 2 /*PCI_CLASS_DISPLAY_3D*/: subclassStr = " (3D)"; break; + default: subclassStr = ""; break; + } + + ffStrbufSetF(&gpu->name, "%s Device %04X%s", gpu->vendor.length ? gpu->vendor.chars : "Unknown", device, subclassStr); + } + return true; + } + return false; +} +#endif + +void ffGPUFillVendorAndName(uint8_t subclass, uint16_t vendor, uint16_t device, FFGPUResult* gpu) +{ + #if FF_HAVE_EMBEDDED_PCIIDS + bool ok = loadPciidsInc(subclass, vendor, device, gpu); + if (ok) return; + #endif + return parsePciIdsFile(loadPciIds(), subclass, vendor, device, gpu); +} + +#if FF_HAVE_EMBEDDED_AMDGPUIDS +static inline int amdGpuCmp(const uint32_t* key, const FFArmGpuProduct* element) +{ + // Maximum value of *key is 0x00FFFFFF. `(int) *key` should never overflow + return (int) *key - (int) element->id; +} + +static bool loadAmdGpuIdsInc(uint16_t deviceId, uint8_t revision, FFGPUResult* gpu) +{ + uint32_t key = (deviceId << 8u) | revision; + FFArmGpuProduct* product = bsearch(&key, ffAmdGpuProducts, ARRAY_SIZE(ffAmdGpuProducts), sizeof(*ffAmdGpuProducts), (void*) amdGpuCmp); + if (product) + { + ffStrbufSetS(&gpu->name, product->name); + return true; + } + return false; +} +#endif + +static void parseAmdGpuIdsFile(uint16_t deviceId, uint8_t revision, FFGPUResult* gpu) +{ + char query[32]; + snprintf(query, ARRAY_SIZE(query), "%X,\t%X,", (unsigned) deviceId, (unsigned) revision); + #ifdef FF_CUSTOM_AMDGPU_IDS_PATH + ffParsePropFile(FF_STR(FF_CUSTOM_AMDGPU_IDS_PATH), query, &gpu->name); + #else + ffParsePropFileData("libdrm/amdgpu.ids", query, &gpu->name); + #endif +} + +void ffGPUQueryAmdGpuName(uint16_t deviceId, uint8_t revisionId, FFGPUResult* gpu) +{ + #if FF_HAVE_EMBEDDED_AMDGPUIDS + bool ok = loadAmdGpuIdsInc(deviceId, revisionId, gpu); + if (ok) return; + #endif + return parseAmdGpuIdsFile(deviceId, revisionId, gpu); +} From 186cb9b9d5d2b46554a2c70e8fa88f50bd556839 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:10:07 -0500 Subject: [PATCH 05/15] Delete src/detection/zpool/zpool.c removed to add patch files --- src/detection/zpool/zpool.c | 126 ------------------------------------ 1 file changed, 126 deletions(-) delete mode 100644 src/detection/zpool/zpool.c diff --git a/src/detection/zpool/zpool.c b/src/detection/zpool/zpool.c deleted file mode 100644 index 67e121b859..0000000000 --- a/src/detection/zpool/zpool.c +++ /dev/null @@ -1,126 +0,0 @@ -#include "zpool.h" - -#if FF_HAVE_LIBZFS - -#include "util/kmod.h" - -#ifdef __sun -#include -#else -#include "libzfs_simplified.h" -#endif - -#include "common/library.h" - -typedef struct FFZfsData -{ - FF_LIBRARY_SYMBOL(libzfs_fini) - FF_LIBRARY_SYMBOL(zpool_get_prop_int) - FF_LIBRARY_SYMBOL(zpool_get_prop) - FF_LIBRARY_SYMBOL(zpool_close) - - // The fields in this struct store property IDs returned by `zpool_name_to_prop`, - // not the property values themselves. - struct { - int name; - int health; - int guid; - int size; - int free; - int allocated; - int fragmentation; - int readonly; - } props; - - libzfs_handle_t* handle; - FFlist* result; -} FFZfsData; - -static inline void cleanLibzfs(FFZfsData* data) -{ - if (data->fflibzfs_fini && data->handle) - { - data->fflibzfs_fini(data->handle); - data->handle = NULL; - } -} - -static int enumZpoolCallback(zpool_handle_t* zpool, void* param) -{ - FFZfsData* data = (FFZfsData*) param; - zprop_source_t source; - FFZpoolResult* item = ffListAdd(data->result); - char buf[1024]; - if (data->ffzpool_get_prop(zpool, data->props.name, buf, ARRAY_SIZE(buf), &source, false) == 0) - ffStrbufInitS(&item->name, buf); - else - ffStrbufInitStatic(&item->name, "unknown"); - if (data->ffzpool_get_prop(zpool, data->props.health, buf, ARRAY_SIZE(buf), &source, false) == 0) - ffStrbufInitS(&item->state, buf); - else - ffStrbufInitStatic(&item->state, "unknown"); - item->guid = data->ffzpool_get_prop_int(zpool, data->props.guid, &source); - item->total = data->ffzpool_get_prop_int(zpool, data->props.size, &source); - item->used = item->total - data->ffzpool_get_prop_int(zpool, data->props.free, &source); - item->allocated = data->ffzpool_get_prop_int(zpool, data->props.allocated, &source); - uint64_t fragmentation = data->ffzpool_get_prop_int(zpool, data->props.fragmentation, &source); - item->fragmentation = fragmentation == UINT64_MAX ? -DBL_MAX : (double) fragmentation; - item->readOnly = (bool) data->ffzpool_get_prop_int(zpool, data->props.readonly, &source); - data->ffzpool_close(zpool); - return 0; -} - -const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */) -{ - FF_LIBRARY_LOAD(libzfs, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 6); - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init); - - libzfs_handle_t* handle = fflibzfs_init(); - if (!handle) - { - if (!ffKmodLoaded("zfs")) return "`zfs` kernel module is not loaded"; - return "libzfs_init() failed"; - } - - __attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = { - .handle = handle, - .result = result, - }; - - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_name_to_prop); - - #define FF_QUERY_ZPOOL_PROP_FROM_NAME(prop_name) do { \ - data.props.prop_name = ffzpool_name_to_prop(#prop_name); \ - if (data.props.prop_name < 0) \ - return "Failed to query prop: " #prop_name; \ - } while (false) - FF_QUERY_ZPOOL_PROP_FROM_NAME(name); - FF_QUERY_ZPOOL_PROP_FROM_NAME(health); - FF_QUERY_ZPOOL_PROP_FROM_NAME(guid); - FF_QUERY_ZPOOL_PROP_FROM_NAME(size); - FF_QUERY_ZPOOL_PROP_FROM_NAME(free); - FF_QUERY_ZPOOL_PROP_FROM_NAME(allocated); - FF_QUERY_ZPOOL_PROP_FROM_NAME(fragmentation); - FF_QUERY_ZPOOL_PROP_FROM_NAME(readonly); - #undef FF_QUERY_ZPOOL_PROP_FROM_NAME - - FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop); - FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_close); - - if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0) - return "zpool_iter() failed"; - - return NULL; -} - -#else - -const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result) -{ - return "fastfetch was compiled without libzfs support"; -} - -#endif From 975e4263803aecf49dece9f9305f3fb8f67319a3 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:10:31 -0500 Subject: [PATCH 06/15] Add files via upload --- src/detection/zpool/zpool.c | 139 ++++++++++++++++++++++++++++ src/detection/zpool/zpool_linux.c | 149 ++++++++++++++++++++++++++++++ 2 files changed, 288 insertions(+) create mode 100644 src/detection/zpool/zpool.c create mode 100644 src/detection/zpool/zpool_linux.c diff --git a/src/detection/zpool/zpool.c b/src/detection/zpool/zpool.c new file mode 100644 index 0000000000..2d76789c97 --- /dev/null +++ b/src/detection/zpool/zpool.c @@ -0,0 +1,139 @@ +#include "zpool.h" + +#if FF_HAVE_LIBZFS + +#include "util/kmod.h" +#ifdef __sun +#include +#else +#include "libzfs_simplified.h" +#endif + +#include "common/library.h" + +typedef struct FFZfsData +{ + FF_LIBRARY_SYMBOL(libzfs_fini) + FF_LIBRARY_SYMBOL(zpool_get_prop_int) + FF_LIBRARY_SYMBOL(zpool_get_prop) + FF_LIBRARY_SYMBOL(zpool_close) + + // The fields in this struct store property IDs returned by `zpool_name_to_prop`, + // not the property values themselves. + struct { + int name; + int health; + int guid; + int size; + int free; + int allocated; + int fragmentation; + int readonly; + } props; + + libzfs_handle_t* handle; + FFlist* result; +} FFZfsData; + +static inline void cleanLibzfs(FFZfsData* data) +{ + if (data->fflibzfs_fini && data->handle) + { + data->fflibzfs_fini(data->handle); + data->handle = NULL; + } +} + +/* Portable wrapper for zpool_get_prop */ +#ifdef __sun +#define FF_ZPOOL_GET_PROP(zpool, prop, buf, len, src) \ + data->ffzpool_get_prop(zpool, prop, buf, len, src) +#else +#define FF_ZPOOL_GET_PROP(zpool, prop, buf, len, src) \ + data->ffzpool_get_prop(zpool, prop, buf, len, src, false) +#endif + +static int enumZpoolCallback(zpool_handle_t* zpool, void* param) +{ + FFZfsData* data = (FFZfsData*) param; + zprop_source_t source; + FFZpoolResult* item = ffListAdd(data->result); + char buf[1024]; + + if (FF_ZPOOL_GET_PROP(zpool, data->props.name, buf, ARRAY_SIZE(buf), &source) == 0) + ffStrbufInitS(&item->name, buf); + else + ffStrbufInitStatic(&item->name, "unknown"); + + if (FF_ZPOOL_GET_PROP(zpool, data->props.health, buf, ARRAY_SIZE(buf), &source) == 0) + ffStrbufInitS(&item->state, buf); + else + ffStrbufInitStatic(&item->state, "unknown"); + + item->guid = data->ffzpool_get_prop_int(zpool, data->props.guid, &source); + item->total = data->ffzpool_get_prop_int(zpool, data->props.size, &source); + item->used = item->total - data->ffzpool_get_prop_int(zpool, data->props.free, &source); + item->allocated = data->ffzpool_get_prop_int(zpool, data->props.allocated, &source); + uint64_t fragmentation = data->ffzpool_get_prop_int(zpool, data->props.fragmentation, &source); + item->fragmentation = fragmentation == UINT64_MAX ? -DBL_MAX : (double) fragmentation; + item->readOnly = (bool) data->ffzpool_get_prop_int(zpool, data->props.readonly, &source); + + data->ffzpool_close(zpool); + return 0; +} + +const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */) +{ + FF_LIBRARY_LOAD(libzfs, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 6); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init); + + libzfs_handle_t* handle = fflibzfs_init(); + if (!handle) + { + if (!ffKmodLoaded("zfs")) return "`zfs` kernel module is not loaded"; + return "libzfs_init() failed"; + } + + __attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = { + .handle = handle, + .result = result, + }; + + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_name_to_prop); + + #define FF_QUERY_ZPOOL_PROP_FROM_NAME(prop_name) do { \ + data.props.prop_name = ffzpool_name_to_prop(#prop_name); \ + if (data.props.prop_name < 0) \ + return "Failed to query prop: " #prop_name; \ + } while (false) + + FF_QUERY_ZPOOL_PROP_FROM_NAME(name); + FF_QUERY_ZPOOL_PROP_FROM_NAME(health); + FF_QUERY_ZPOOL_PROP_FROM_NAME(guid); + FF_QUERY_ZPOOL_PROP_FROM_NAME(size); + FF_QUERY_ZPOOL_PROP_FROM_NAME(free); + FF_QUERY_ZPOOL_PROP_FROM_NAME(allocated); + FF_QUERY_ZPOOL_PROP_FROM_NAME(fragmentation); + FF_QUERY_ZPOOL_PROP_FROM_NAME(readonly); + #undef FF_QUERY_ZPOOL_PROP_FROM_NAME + + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_close); + + if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0) + return "zpool_iter() failed"; + + return NULL; +} + +#else + +const char* ffDetectZpool(FF_MAYBE_UNUSED FFlist* result) +{ + return "fastfetch was compiled without libzfs support"; +} + +#endif diff --git a/src/detection/zpool/zpool_linux.c b/src/detection/zpool/zpool_linux.c new file mode 100644 index 0000000000..b6c74197ce --- /dev/null +++ b/src/detection/zpool/zpool_linux.c @@ -0,0 +1,149 @@ +#include "zpool.h" + +#ifdef FF_HAVE_LIBZFS +#include "util/kmod.h" + +#ifdef __sun +#define FF_DISABLE_DLOPEN +#include + +// Solaris 11.4 compatible implementation +const char* zpool_get_state_str(zpool_handle_t* zpool) +{ + if (zpool_get_state(zpool) == POOL_STATE_UNAVAIL) + return "FAULTED"; + + const char *str; + zpool_status_t status = zpool_get_status(zpool, (char**)&str); + if (status == ZPOOL_STATUS_IO_FAILURE_WAIT || + status == ZPOOL_STATUS_IO_FAILURE_CONTINUE) + return "SUSPENDED"; + + nvlist_t *nvroot; + if (nvlist_lookup_nvlist(zpool_get_config(zpool, NULL), + ZPOOL_CONFIG_VDEV_TREE, + &nvroot) != 0) + return "UNKNOWN"; + + uint_t vsc; + vdev_stat_t *vs; +#ifdef __x86_64__ + if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, + (uint64_t**)&vs, &vsc) != 0) +#else + if (nvlist_lookup_uint32_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, + (uint32_t**)&vs, &vsc) != 0) +#endif + return "UNKNOWN"; + + return zpool_state_to_name(vs->vs_state, vs->vs_aux); +} + +#else // non-Solaris (Linux/OpenZFS) +#include + +const char* zpool_get_state_str(zpool_handle_t* zpool) +{ + if (zpool_get_state(zpool) == POOL_STATE_UNAVAIL) + return "FAULTED"; + else + { + const char *str; + zpool_errata_t errata; + zpool_status_t status = zpool_get_status(zpool, (char**) &str, &errata); + if (status == ZPOOL_STATUS_IO_FAILURE_WAIT || + status == ZPOOL_STATUS_IO_FAILURE_CONTINUE || + status == ZPOOL_STATUS_IO_FAILURE_WAIT) + return "SUSPENDED"; + else + { + nvlist_t *nvroot = nvlist_lookup_nvlist(zpool_get_config(zpool, NULL), ZPOOL_CONFIG_VDEV_TREE); + uint_t vsc; + vdev_stat_t *vs; +#ifdef __x86_64__ + if (nvlist_lookup_uint64_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint64_t**) &vs, &vsc) != 0) +#else + if (nvlist_lookup_uint32_array(nvroot, ZPOOL_CONFIG_VDEV_STATS, (uint32_t**) &vs, &vsc) != 0) +#endif + return "UNKNOWN"; + else + return zpool_state_to_name(vs->vs_state, vs->vs_aux); + } + } +} +#endif // __sun + +#else +#include "libzfs_simplified.h" +#endif + +#include "common/library.h" + +typedef struct FFZfsData +{ + FF_LIBRARY_SYMBOL(libzfs_fini) + FF_LIBRARY_SYMBOL(zpool_iter) + FF_LIBRARY_SYMBOL(zpool_get_prop_int) + FF_LIBRARY_SYMBOL(zpool_get_name) + FF_LIBRARY_SYMBOL(zpool_get_state_str) + + libzfs_handle_t* handle; + FFlist* result; +} FFZfsData; + +static inline void cleanLibzfs(FFZfsData* data) +{ + if (data->fflibzfs_fini && data->handle) + { + data->fflibzfs_fini(data->handle); + data->handle = NULL; + } +} + +static int enumZpoolCallback(zpool_handle_t* zpool, void* param) +{ + FFZfsData* data = (FFZfsData*) param; + zprop_source_t source; + FFZpoolResult* item = ffListAdd(data->result); + ffStrbufInitS(&item->name, data->ffzpool_get_name(zpool)); + ffStrbufInitS(&item->state, data->ffzpool_get_state_str(zpool)); + item->version = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_VERSION, &source); + item->total = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_SIZE, &source); + item->used = item->total - data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_FREE, &source); + uint64_t fragmentation = data->ffzpool_get_prop_int(zpool, ZPOOL_PROP_DELEGATION, &source); + item->fragmentation = fragmentation == UINT64_MAX ? -DBL_MAX : (double) fragmentation; + return 0; +} + +const char* ffDetectZpool(FFlist* result /* list of FFZpoolResult */) +{ +#ifdef FF_HAVE_LIBZFS + FF_LIBRARY_LOAD(libzfs, "dlopen libzfs" FF_LIBRARY_EXTENSION " failed", "libzfs" FF_LIBRARY_EXTENSION, 6); + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, libzfs_init); + + libzfs_handle_t* handle = fflibzfs_init(); + if (!handle) + { + if (!ffKmodLoaded("zfs")) return "`zfs` kernel module is not loaded"; + return "libzfs_init() failed"; + } + + __attribute__((__cleanup__(cleanLibzfs))) FFZfsData data = { + .handle = handle, + .result = result, + }; + + FF_LIBRARY_LOAD_SYMBOL_MESSAGE(libzfs, zpool_iter); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, libzfs_fini); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_prop_int); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_name); + FF_LIBRARY_LOAD_SYMBOL_VAR_MESSAGE(libzfs, data, zpool_get_state_str); + + if (ffzpool_iter(handle, enumZpoolCallback, &data) < 0) + return "zpool_iter() failed"; + + return NULL; +#else + return "Fastfetch was compiled without libzfs support"; +#endif +} From 3781fd18a6a4dccacaeb77f239af8f3c4c67f511 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:22:49 -0500 Subject: [PATCH 07/15] Update README.md --- README.md | 342 +----------------------------------------------------- 1 file changed, 2 insertions(+), 340 deletions(-) diff --git a/README.md b/README.md index a087b5e0df..0929ad459b 100644 --- a/README.md +++ b/README.md @@ -1,341 +1,3 @@ -# Fastfetch +Quite simply a port for fastfetch on Oracle Solaris 11.4 systems. -[![GitHub Workflow Status (with event)](https://img.shields.io/github/actions/workflow/status/fastfetch-cli/fastfetch/ci.yml)](https://github.com/fastfetch-cli/fastfetch/actions) -[![GitHub license](https://img.shields.io/github/license/fastfetch-cli/fastfetch)](https://github.com/fastfetch-cli/fastfetch/blob/dev/LICENSE) -[![GitHub contributors](https://img.shields.io/github/contributors/fastfetch-cli/fastfetch)](https://github.com/fastfetch-cli/fastfetch/graphs/contributors) -[![GitHub top language](https://img.shields.io/github/languages/top/fastfetch-cli/fastfetch?logo=c&label=)](https://github.com/fastfetch-cli/fastfetch/blob/dev/CMakeLists.txt#L5) -[![GitHub commit activity (branch)](https://img.shields.io/github/commit-activity/m/fastfetch-cli/fastfetch)](https://github.com/fastfetch-cli/fastfetch/commits) -[![homebrew downloads](https://img.shields.io/homebrew/installs/dm/fastfetch?logo=homebrew)](https://formulae.brew.sh/formula/fastfetch#default) -[![GitHub all releases](https://img.shields.io/github/downloads/fastfetch-cli/fastfetch/total?logo=github)](https://github.com/fastfetch-cli/fastfetch/releases) -[![GitHub release (with filter)](https://img.shields.io/github/v/release/fastfetch-cli/fastfetch?logo=github)](https://github.com/fastfetch-cli/fastfetch/releases) -[![latest packaged version(s)](https://repology.org/badge/latest-versions/fastfetch.svg)](https://repology.org/project/fastfetch/versions) -[![Packaging status](https://repology.org/badge/tiny-repos/fastfetch.svg)](https://repology.org/project/fastfetch/versions) -[![Ask DeepWiki](https://deepwiki.com/badge.svg)](https://deepwiki.com/fastfetch-cli/fastfetch) -[![中文README](https://img.shields.io/badge/%E4%B8%AD%E6%96%87-README-red)](README-cn.md) - -Fastfetch is a [neofetch](https://github.com/dylanaraps/neofetch)-like tool for fetching system information and displaying it in a visually appealing way. It is written mainly in C, with a focus on performance and customizability. Currently, it supports Linux, macOS, Windows 7+, Android, FreeBSD, OpenBSD, NetBSD, DragonFly, Haiku, and SunOS. - - - - - - - - - -According configuration files for examples are located [here](https://github.com/fastfetch-cli/fastfetch/tree/dev/presets/examples). - -There are [screenshots on different platforms](https://github.com/fastfetch-cli/fastfetch/wiki). - -## Installation - -### Linux - -Some distributions package outdated versions of fastfetch. Older versions receive no support, so please always try to use the latest version. - - - Packaging status - - -* Ubuntu: [`ppa:zhangsongcui3371/fastfetch`](https://launchpad.net/~zhangsongcui3371/+archive/ubuntu/fastfetch) (Ubuntu 22.04 or newer; latest version) -* Debian / Ubuntu: `apt install fastfetch` (Debian 13 or newer; Ubuntu 25.04 or newer) -* Debian / Ubuntu: Download `fastfetch-linux-.deb` from [Github release page](https://github.com/fastfetch-cli/fastfetch/releases/latest) and double-click it (for Ubuntu 20.04 or newer and Debian 11 or newer). -* Arch Linux: `pacman -S fastfetch` -* Fedora: `dnf install fastfetch` -* Gentoo: `emerge --ask app-misc/fastfetch` -* Alpine: `apk add --upgrade fastfetch` -* NixOS: `nix-shell -p fastfetch` -* openSUSE: `zypper install fastfetch` -* ALT Linux: `apt-get install fastfetch` -* Exherbo: `cave resolve --execute app-misc/fastfetch` -* Solus: `eopkg install fastfetch` -* Slackware: `sbopkg -i fastfetch` -* Void Linux: `xbps-install fastfetch` -* Venom Linux: `scratch install fastfetch` - -You may need `sudo`, `doas`, or `sup` to run these commands. - -If fastfetch is not packaged for your distribution or an outdated version is packaged, [linuxbrew](https://brew.sh/) is a good alternative: `brew install fastfetch` - -### macOS - -* [Homebrew](https://formulae.brew.sh/formula/fastfetch#default): `brew install fastfetch` -* [MacPorts](https://ports.macports.org/port/fastfetch/): `sudo port install fastfetch` - -### Windows - -* [scoop](https://scoop.sh/#/apps?q=fastfetch): `scoop install fastfetch` -* [Chocolatey](https://community.chocolatey.org/packages/fastfetch): `choco install fastfetch` -* [winget](https://github.com/microsoft/winget-pkgs/tree/master/manifests/f/Fastfetch-cli/Fastfetch): `winget install fastfetch` -* [MSYS2 MinGW](https://packages.msys2.org/base/mingw-w64-fastfetch): `pacman -S mingw-w64---fastfetch` - -You may also download the program directly from [the GitHub releases page](https://github.com/fastfetch-cli/fastfetch/releases/latest) in the form of an archive file. - -### BSD systems - -* FreeBSD: `pkg install fastfetch` -* NetBSD: `pkgin in fastfetch` -* OpenBSD: `pkg_add fastfetch` (Snapshots only) -* DragonFly BSD: `pkg install fastfetch` (Snapshots only) - -### Android (Termux) - -* `pkg install fastfetch` - -### Nightly - - - -## Build from source - -See the Wiki: https://github.com/fastfetch-cli/fastfetch/wiki/Building - -## Usage - -* Run with default configuration: `fastfetch` -* Run with [all supported modules](https://github.com/fastfetch-cli/fastfetch/wiki/Support+Status#available-modules) to find what interests you: `fastfetch -c all.jsonc` -* View all data that fastfetch detects: `fastfetch -s [:][:] --format json` -* Display help messages: `fastfetch --help` -* Generate a minimal config file: `fastfetch [-s [:]] --gen-config []` - * Use: `--gen-config-full` to generate a full config file with all optional options - -## Customization - -Fastfetch uses JSONC (JSON with comments) for configuration. [See the Wiki for details](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). There are some premade config files in the [`presets`](presets) directory, including those used for the screenshots above. You can load them using `-c `. These files can serve as examples of the configuration syntax. - -Logos can also be heavily customized; see the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for more information. - -### WARNING - -Fastfetch supports a `Command` module that can run arbitrary shell commands. If you copy-paste a config file from an untrusted source, it may contain malicious commands that can harm your system or compromise your privacy. Please always review the config file before using it. - -## FAQ - -### Q: Neofetch is good enough. Why do I need fastfetch? - -1. Fastfetch is actively maintained. -2. Fastfetch is faster, as the name suggests. -3. Fastfetch has a greater number of features, though by default it only has a few modules enabled; use `fastfetch -c all` to discover what you want. -4. Fastfetch is more configurable. You can find more information in the Wiki: . -5. Fastfetch is more polished. For example, neofetch prints `555 MiB` in the Memory module and `23 G` in the Disk module, whereas fastfetch prints `555.00 MiB` and `22.97 GiB` respectively. -6. Fastfetch is more accurate. For example, [neofetch never actually supports the Wayland protocol](https://github.com/dylanaraps/neofetch/pull/2395). - -### Q: Fastfetch shows my local IP address. Does it leak my privacy? - -A local IP address (10.x.x.x, 172.x.x.x, 192.168.x.x) has nothing to do with privacy. It only has meaning if you are on the same network, for example, if you connect to the same Wi-Fi network. - -Actually, the `Local IP` module is the most useful module for me personally. I (@CarterLi) have several VMs installed to test fastfetch and often need to SSH into them. With fastfetch running on shell startup, I never need to type `ip addr` manually. - -If you really don't like it, you can disable the `Local IP` module in `config.jsonc`. - -### Q: Where is the config file? I can't find it. - -Fastfetch does not generate a config file automatically. You can use `fastfetch --gen-config` to generate one. The config file will be saved in `~/.config/fastfetch/config.jsonc` by default. See the [Wiki for details](https://github.com/fastfetch-cli/fastfetch/wiki/Configuration). - -### Q: The configuration is so complex. Where is the documentation? - -Fastfetch uses JSON (with comments) for configuration. I suggest using an IDE with JSON schema support (like VSCode) to edit it. - -Alternatively, you can refer to the presets in the [`presets` directory](https://github.com/fastfetch-cli/fastfetch/tree/dev/presets). - -The **correct** way to edit the configuration: - -This is an example that [changes size prefix from MiB / GiB to MB / GB](https://github.com/fastfetch-cli/fastfetch/discussions/1014). Editor used: [helix](https://github.com/helix-editor/helix) - -[![asciicast](https://asciinema.org/a/1uF6sTPGKrHKI1MVaFcikINSQ.svg)](https://asciinema.org/a/1uF6sTPGKrHKI1MVaFcikINSQ) - -### Q: I WANT THE DOCUMENTATION! - -[Here is the documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Json-Schema). It is generated from the [JSON schema](https://github.com/fastfetch-cli/fastfetch/blob/dev/doc/json_schema.json), but you might not find it very user-friendly. - -### Q: How can I customize the module output? - -Fastfetch uses `format` to generate output. For example, to make the `GPU` module show only the GPU name (leaving other information undisplayed), you can use: - -```jsonc -{ - "modules": [ - { - "type": "gpu", - "format": "{name}" // See `fastfetch -h gpu-format` for details - } - ] -} -``` - -...which is equivalent to `fastfetch -s gpu --gpu-format '{name}'` - -See `fastfetch -h format` for information on basic usage. For module-specific formatting, see `fastfetch -h -format` - -### Q: I have my own ASCII art / image file. How can I show it with fastfetch? - -Try `fastfetch -l /path/to/logo`. See the [logo documentation](https://github.com/fastfetch-cli/fastfetch/wiki/Logo-options) for details. - -If you just want to display the distro name in [FIGlet text](https://github.com/pwaller/pyfiglet): - -```bash -# install pyfiglet and jq first -pyfiglet -s -f small_slant $(fastfetch -s os --format json | jq -r '.[0].result.name') && fastfetch -l none -``` - -![image](https://github.com/fastfetch-cli/fastfetch/assets/6134068/6466524e-ab8c-484f-848d-eec7ddeb7df2) - -### Q: My image logo behaves strangely. How can I fix it? - -See the troubleshooting section: - -### Q: Fastfetch runs in black and white on shell startup. Why? - -This issue usually occurs when using fastfetch with `p10k`. There are known incompatibilities between fastfetch and p10k instant prompt. -The p10k documentation clearly states that you should NOT print anything to stdout after `p10k-instant-prompt` is initialized. You should put `fastfetch` before the initialization of `p10k-instant-prompt` (recommended). - -You can always use `fastfetch --pipe false` to force fastfetch to run in colorful mode. - -### Q: Why do fastfetch and neofetch show different memory usage results? - -See [#1096](https://github.com/fastfetch-cli/fastfetch/issues/1096). - -### Q: Fastfetch shows fewer dpkg packages than neofetch. Is it a bug? - -Neofetch incorrectly counts `rc` packages (packages that have been removed but still have configuration files remaining). See bug: https://github.com/dylanaraps/neofetch/issues/2278 - -### Q: I use Debian / Ubuntu / Debian-derived distro. My GPU is detected as `XXXX Device XXXX (VGA compatible)`. Is this a bug? - -Try upgrading `pci.ids`: Download and overwrite the file `/usr/share/hwdata/pci.ids`. For AMD GPUs, you should also upgrade `amdgpu.ids`: Download and overwrite the file `/usr/share/libdrm/amdgpu.ids` - -Alternatively, you may try using `fastfetch --gpu-driver-specific`, which will make fastfetch attempt to ask the driver for the GPU name if supported. - -### Q: I get the error `Authorization required, but no authorization protocol specified` when running fastfetch as root - -Try `export XAUTHORITY=$HOME/.Xauthority` - -### Q: Fastfetch cannot detect my awesome 3rd-party macOS window manager! - -Try `fastfetch --wm-detect-plugin`. See also [#984](https://github.com/fastfetch-cli/fastfetch/issues/984) - -### Q: How can I change the colors of my ASCII logo? - -Try `fastfetch --logo-color-[1-9] `, where `[1-9]` is the index of color placeholders. - -For example: `fastfetch --logo-color-1 red --logo-color-2 green`. - -In JSONC, you can use: - -```jsonc -{ - "logo": { - "color": { - "1": "red", - "2": "green" - } - } -} -``` - -### Q: How do I hide a key? - -Set the key to a white space. - -```jsonc -{ - "key": " " -} -``` - -### Q: How can I display images on Windows? - -As of April 2025: - -#### mintty and Wezterm - -mintty (used by Bash on Windows and MSYS2) and Wezterm (nightly build only) support the iTerm image protocol on Windows. - -In `config.jsonc`: -```json -{ - "logo": { - "type": "iterm", - "source": "C:/path/to/image.png", - "width": - } -} -``` - -#### Windows Terminal - -Windows Terminal supports the sixel image protocol only. - -* If you installed fastfetch through MSYS2: - 1. Install imagemagick: `pacman -S mingw-w64--x86_64-imagemagick` - 2. In `config.jsonc`: -```jsonc -{ - "logo": { - "type": "sixel", // DO NOT USE "auto" - "source": "C:/path/to/image.png", // Do NOT use `~` as fastfetch is a native Windows program and doesn't apply cygwin path conversion - "width": , // Optional - "height": // Optional - } -} -``` -* If you installed fastfetch via scoop or downloaded the binary directly from the GitHub Releases page: - 1. Convert your image manually to sixel format using [any online image conversion service](https://www.google.com/search?q=convert+image+to+sixel) - 2. In `config.jsonc`: -```jsonc -{ - "logo": { - "type": "raw", // DO NOT USE "auto" - "source": "C:/path/to/image.sixel", - "width": , // Required - "height": // Required - } -} -``` - -### Q: I want feature A / B / C. Will fastfetch support it? - -Fastfetch is a system information tool. We only accept hardware or system-level software feature requests. For most personal uses, I recommend using the `Command` module to implement custom functionality, which can be used to grab output from a custom shell script: - -```jsonc -// This module shows the default editor -{ - "modules": [ - { - "type": "command", - "text": "$EDITOR --version | head -1", - "key": "Editor" - } - ] -} -``` - -Otherwise, please open a feature request in [GitHub Issues](https://github.com/fastfetch-cli/fastfetch/issues). - -### Q: I have questions. Where can I get help? - -* For usage questions, please start a discussion in [GitHub Discussions](https://github.com/fastfetch-cli/fastfetch/discussions). -* For possible bugs, please open an issue in [GitHub Issues](https://github.com/fastfetch-cli/fastfetch/issues). Be sure to fill out the bug report template carefully to help developers investigate. - -## Donate - -If you find Fastfetch useful, please consider donating. - -* Current maintainer: [@CarterLi](https://paypal.me/zhangsongcui) -* Original author: [@LinusDierheimer](https://github.com/sponsors/LinusDierheimer) - -## Code signing - -* Free code signing provided by [SignPath.io](https://about.signpath.io/), certificate by [SignPath Foundation](https://signpath.org/) -* This program will not transfer any information to other networked systems unless specifically requested by the user or the person installing or operating it - -## Star History - -Give us a star to show your support! - - - - - - Star History Chart - - +To build, I added a file called "build.reference" with all the details From 1223e55b8bbea7a8451266c10111a3d1ffeb5f67 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:24:01 -0500 Subject: [PATCH 08/15] Add files via upload --- build.reference | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 build.reference diff --git a/build.reference b/build.reference new file mode 100644 index 0000000000..39e9b92384 --- /dev/null +++ b/build.reference @@ -0,0 +1,29 @@ + +- Started new Solaris 11.4 VM + +- pkg update --accept + +- pkg install cmake gcc pkg-config + +- mkdir fastfetch + +- wget https://github.com/fastfetch-cli/fastfetch/archive/refs/tags/2.55.1.tar.gz + +- tar -xvf 2.55.1.tar.gz + +- cd fastfetch-2.55.1 + +- export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig + +- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/gpu/gpu_pci.c with patched gpu_pci.c + +- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/media/media_linux.c with patched media_linux.c + +- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/zpool/zpool_linux.c with patched zpool_linux.c + +- mkdir build && cd build + +- cmake .. + +- cmake --build . --target fastfetch +Success From cb1fc29ced995ea5a0a91afe6a6546d2101d935d Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:28:01 -0500 Subject: [PATCH 09/15] Delete build.reference updated build instructions --- build.reference | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 build.reference diff --git a/build.reference b/build.reference deleted file mode 100644 index 39e9b92384..0000000000 --- a/build.reference +++ /dev/null @@ -1,29 +0,0 @@ - -- Started new Solaris 11.4 VM - -- pkg update --accept - -- pkg install cmake gcc pkg-config - -- mkdir fastfetch - -- wget https://github.com/fastfetch-cli/fastfetch/archive/refs/tags/2.55.1.tar.gz - -- tar -xvf 2.55.1.tar.gz - -- cd fastfetch-2.55.1 - -- export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig - -- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/gpu/gpu_pci.c with patched gpu_pci.c - -- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/media/media_linux.c with patched media_linux.c - -- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/zpool/zpool_linux.c with patched zpool_linux.c - -- mkdir build && cd build - -- cmake .. - -- cmake --build . --target fastfetch -Success From f6bec39ef3f2ef7465bb81d08bc801ffc52b6c16 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:28:20 -0500 Subject: [PATCH 10/15] Add files via upload --- build.reference | 29 +++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 build.reference diff --git a/build.reference b/build.reference new file mode 100644 index 0000000000..6e2c5c1707 --- /dev/null +++ b/build.reference @@ -0,0 +1,29 @@ + +- Started new Solaris 11.4 VM + +- pkg update --accept + +- pkg install cmake gcc pkg-config + +- mkdir fastfetch + +- wget https://github.com/ThatSmittyDude/fastfetch/archive/refs/tags/2.56.0.tar.gz + +- tar -xvf 2.55.1.tar.gz + +- cd fastfetch-2.55.1 + +- export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig + +- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/gpu/gpu_pci.c with patched gpu_pci.c + +- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/media/media_linux.c with patched media_linux.c + +- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/zpool/zpool_linux.c with patched zpool_linux.c + +- mkdir build && cd build + +- cmake .. + +- cmake --build . --target fastfetch +Success From 347567845b29063ec240cf79485fd3868e50df57 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:29:54 -0500 Subject: [PATCH 11/15] Delete build.reference updated build instructions --- build.reference | 29 ----------------------------- 1 file changed, 29 deletions(-) delete mode 100644 build.reference diff --git a/build.reference b/build.reference deleted file mode 100644 index 6e2c5c1707..0000000000 --- a/build.reference +++ /dev/null @@ -1,29 +0,0 @@ - -- Started new Solaris 11.4 VM - -- pkg update --accept - -- pkg install cmake gcc pkg-config - -- mkdir fastfetch - -- wget https://github.com/ThatSmittyDude/fastfetch/archive/refs/tags/2.56.0.tar.gz - -- tar -xvf 2.55.1.tar.gz - -- cd fastfetch-2.55.1 - -- export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig - -- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/gpu/gpu_pci.c with patched gpu_pci.c - -- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/media/media_linux.c with patched media_linux.c - -- replaced ~/fastfetch/fastfetch-2.55.1/src/detection/zpool/zpool_linux.c with patched zpool_linux.c - -- mkdir build && cd build - -- cmake .. - -- cmake --build . --target fastfetch -Success From 990581b7057739eee16c2bc13a22ef884634b3a1 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:30:15 -0500 Subject: [PATCH 12/15] Add files via upload --- build.reference | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) create mode 100644 build.reference diff --git a/build.reference b/build.reference new file mode 100644 index 0000000000..bcc7183541 --- /dev/null +++ b/build.reference @@ -0,0 +1,23 @@ + +- Started new Solaris 11.4 VM + +- pkg update --accept + +- pkg install cmake gcc pkg-config + +- mkdir fastfetch + +- wget https://github.com/ThatSmittyDude/fastfetch/archive/refs/tags/2.56.0.tar.gz + +- tar -xvf 2.55.1.tar.gz + +- cd fastfetch-2.55.1 + +- export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig + +- mkdir build && cd build + +- cmake .. + +- cmake --build . --target fastfetch + From 012f6565d1f31a5ec78a2e7e2771363a64db8951 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:30:57 -0500 Subject: [PATCH 13/15] Update build.reference --- build.reference | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/build.reference b/build.reference index bcc7183541..1f60b50c81 100644 --- a/build.reference +++ b/build.reference @@ -9,9 +9,9 @@ - wget https://github.com/ThatSmittyDude/fastfetch/archive/refs/tags/2.56.0.tar.gz -- tar -xvf 2.55.1.tar.gz +- tar -xvf 2.56.0.tar.gz -- cd fastfetch-2.55.1 +- cd fastfetch-2.56.0 - export PKG_CONFIG_PATH=/usr/lib/64/pkgconfig From 354cb0c2ed6e7abb5c7327d69814f5eab53da1c8 Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:31:50 -0500 Subject: [PATCH 14/15] Update build.reference --- build.reference | 2 -- 1 file changed, 2 deletions(-) diff --git a/build.reference b/build.reference index 1f60b50c81..9572c64431 100644 --- a/build.reference +++ b/build.reference @@ -1,6 +1,4 @@ -- Started new Solaris 11.4 VM - - pkg update --accept - pkg install cmake gcc pkg-config From 22cce4f246cf184b43f2073deeb2188c9bcf758a Mon Sep 17 00:00:00 2001 From: that_smitty_dude Date: Sat, 6 Dec 2025 11:35:52 -0500 Subject: [PATCH 15/15] Update README.md --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 0929ad459b..3726beaa7d 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,3 @@ -Quite simply a port for fastfetch on Oracle Solaris 11.4 systems. +Quite simply a port for fastfetch on Oracle Solaris 11.4 systems with amd64 processor To build, I added a file called "build.reference" with all the details