Use sqlite to get rpm package count

This commit is contained in:
Linus Dierheimer 2022-05-23 19:30:02 +02:00
parent 3c648d84db
commit e4ecb9d069
No known key found for this signature in database
GPG Key ID: 74FA57726CDD7B61
13 changed files with 98 additions and 63 deletions

View File

@ -13,7 +13,7 @@ jobs:
uses: actions/checkout@v2
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev rpm librpm-dev libzstd-dev
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@v1

View File

@ -16,7 +16,7 @@ jobs:
uses: actions/checkout@v2
- name: install required packages
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev rpm librpm-dev libzstd-dev
run: sudo apt-get update && sudo apt-get install -y libpci-dev libvulkan-dev libwayland-dev libxrandr-dev libxcb-randr0-dev libdconf-dev libdbus-1-dev libmagickcore-dev libxfconf-0-dev libsqlite3-dev
- name: Initialize CodeQL
uses: github/codeql-action/init@v1

View File

@ -27,7 +27,7 @@ OPTION(ENABLE_GIO "Enable gio-2.0" ON)
OPTION(ENABLE_DCONF "Enable dconf" ON)
OPTION(ENABLE_DBUS "Enable dbus-1" ON)
OPTION(ENABLE_XFCONF "Enable libxfconf-0" ON)
OPTION(ENABLE_RPM "Enable rpm" ON)
OPTION(ENABLE_SQLITE3 "Enable sqlite3" ON)
OPTION(ENABLE_IMAGEMAGICK7 "Enable imagemagick 7" ON)
OPTION(ENABLE_IMAGEMAGICK6 "Enable imagemagick 6" ON)
OPTION(ENABLE_ZLIB "Enable zlib" ON)
@ -266,12 +266,12 @@ if(ENABLE_XFCONF)
endif()
endif()
if(ENABLE_RPM)
pkg_check_modules(RPM rpm)
if(RPM_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_RPM=1)
if(ENABLE_SQLITE3)
pkg_check_modules(SQLITE3 sqlite3)
if(SQLITE3_FOUND)
target_compile_definitions(libfastfetch PRIVATE FF_HAVE_SQLITE3=1)
else()
message(WARNING "Package librpm not found. Building without support.")
message(WARNING "Package sqlite3 not found. Building without support.")
endif()
endif()
@ -346,7 +346,7 @@ target_include_directories(libfastfetch
PRIVATE ${DCONF_INCLUDE_DIRS}
PRIVATE ${DBUS_INCLUDE_DIRS}
PRIVATE ${XFCONF_INCLUDE_DIRS}
PRIVATE ${RPM_INCLUDE_DIRS}
PRIVATE ${SQLITE3_INCLUDE_DIRS}
PRIVATE ${IMAGEMAGICK7_INCLUDE_DIRS}
PRIVATE ${IMAGEMAGICK6_INCLUDE_DIRS}
PRIVATE ${ZLIB_INCLUDE_DIRS}

View File

@ -33,7 +33,7 @@ The following libraries are used if present at runtime:
* [`libZ`](https://www.zlib.net/): Faster image output when using kitty graphics protocol.
* [`libDBus`](https://www.freedesktop.org/wiki/Software/dbus): Needed for detecting current media player and song.
* [`libXFConf`](https://gitlab.xfce.org/xfce/xfconf): Needed for XFWM theme and XFCE Terminal font.
* [`librpm`](http://rpm.org/): Needed for rpm package count.
* [`libsqlite3`](https://www.sqlite.org/index.html): Needed for rpm package count.
## Support status
All categories not listed here should work without needing a specific implementation.

View File

@ -231,7 +231,7 @@ __fastfetch_completion()
"--lib-DConf"
"--lib-DBus"
"--lib-XFConf"
"--lib-RPM"
"--lib-sqlite3"
"--lib-imagemagick"
"--lib-z"
"--lib-chafa"

View File

@ -199,7 +199,7 @@ static void defaultConfig(FFinstance* instance)
ffStrbufInitA(&instance->config.libDConf, 0);
ffStrbufInitA(&instance->config.libDBus, 0);
ffStrbufInitA(&instance->config.libXFConf, 0);
ffStrbufInitA(&instance->config.librpm, 0);
ffStrbufInitA(&instance->config.libSQLite3, 0);
ffStrbufInitA(&instance->config.libImageMagick, 0);
ffStrbufInitA(&instance->config.libZ, 0);
ffStrbufInitA(&instance->config.libChafa, 0);
@ -328,8 +328,8 @@ void ffListFeatures()
#ifdef FF_HAVE_XFCONF
"xfconf\n"
#endif
#ifdef FF_HAVE_RPM
"librpm\n"
#ifdef FF_HAVE_SQLITE3
"sqlite3\n"
#endif
""
, stdout);

View File

@ -1,6 +1,7 @@
#include "fastfetch.h"
#include <pthread.h>
#include <string.h>
#define FF_LIBRARY_DATA_LOAD_INIT(dataObject, userLibraryName, ...) \
static dataObject data; \
@ -267,6 +268,74 @@ FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, con
}
#endif //FF_HAVE_XFCONF
#ifdef FF_HAVE_SQLITE3
#include <sqlite3.h>
typedef struct SQLiteData
{
FF_LIBRARY_SYMBOL(sqlite3_open_v2)
FF_LIBRARY_SYMBOL(sqlite3_prepare_v2)
FF_LIBRARY_SYMBOL(sqlite3_step)
FF_LIBRARY_SYMBOL(sqlite3_data_count)
FF_LIBRARY_SYMBOL(sqlite3_column_int)
FF_LIBRARY_SYMBOL(sqlite3_finalize)
FF_LIBRARY_SYMBOL(sqlite3_close)
} SQLiteData;
static const SQLiteData* getSQLiteData(const FFinstance* instance)
{
FF_LIBRARY_DATA_LOAD_INIT(SQLiteData, instance->config.libSQLite3, "libsqlite3.so", 1);
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_open_v2)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_prepare_v2)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_step)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_data_count)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_column_int)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_finalize)
FF_LIBRARY_DATA_LOAD_SYMBOL(sqlite3_close)
FF_LIBRARY_DATA_LOAD_RETURN
}
int ffSettingsGetSQLite3Int(FFinstance* instance, const char* dbPath, const char* query)
{
const SQLiteData* data = getSQLiteData(instance);
if(data == NULL)
return 0;
sqlite3* db;
if(data->ffsqlite3_open_v2(dbPath, &db, SQLITE_OPEN_READONLY, NULL) != SQLITE_OK)
return 0;
sqlite3_stmt* stmt;
if(data->ffsqlite3_prepare_v2(db, query, (int) strlen(query), &stmt, NULL) != SQLITE_OK)
{
data->ffsqlite3_close(db);
return 0;
}
if(data->ffsqlite3_step(stmt) != SQLITE_ROW || data->ffsqlite3_data_count(stmt) < 1)
{
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return 0;
}
int result = data->ffsqlite3_column_int(stmt, 0);
data->ffsqlite3_finalize(stmt);
data->ffsqlite3_close(db);
return result;
}
#else //FF_HAVE_SQLITE3
int ffSettingsGetSQLite3Int(FFinstance* instance, const char* dbPath, const char* query)
{
FF_UNUSED(instance, dbPath, query)
return 0;
}
#endif //FF_HAVE_SQLITE3
#ifdef __ANDROID__
#include <sys/system_properties.h>
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result) {

View File

@ -233,7 +233,7 @@
#--lib-DConf /usr/lib/libdconf.so
#--lib-DBus /usr/lib/libdbus-1.so
#--lib-XFConf /usr/lib/libxfconf-0.so
#--lib-rpm /usr/lib/librpm.so
#--lib-sqlite3 /usr/lib/libsqlite3.so
#--lib-imagemagick /usr/lib/libMagickCore-7.Q16HDRI.so
#--lib-z /usr/lib/libz.so
#--lib-chafa /usr/lib/libchafa.so

View File

@ -122,7 +122,7 @@ Library options: Set the path of a library to load
--lib-DConf <path>
--lib-DBus <path>
--lib-XFConf <path>
--lib-RPM <path>
--lib-sqlite3 <path>
--lib-imagemagick <path>
--lib-z <path>
--lib-chafa <path>

View File

@ -991,8 +991,8 @@ static void parseOption(FFinstance* instance, FFdata* data, const char* key, con
optionParseString(key, value, &instance->config.libDBus);
else if(strcasecmp(key, "--lib-XFConf") == 0)
optionParseString(key, value, &instance->config.libXFConf);
else if(strcasecmp(key, "--lib-rpm") == 0)
optionParseString(key, value, &instance->config.librpm);
else if(strcasecmp(key, "--lib-sqlite") == 0 || strcasecmp(key, "--lib-sqlite3") == 0)
optionParseString(key, value, &instance->config.libSQLite3);
else if(strcasecmp(key, "--lib-imagemagick") == 0)
optionParseString(key, value, &instance->config.libImageMagick);
else if(strcasecmp(key, "--lib-z") == 0)

View File

@ -137,7 +137,7 @@ typedef struct FFconfig
FFstrbuf libDConf;
FFstrbuf libDBus;
FFstrbuf libXFConf;
FFstrbuf librpm;
FFstrbuf libSQLite3;
FFstrbuf libImageMagick;
FFstrbuf libZ;
FFstrbuf libChafa;
@ -466,6 +466,8 @@ FFvariant ffSettingsGetGSettings(FFinstance* instance, const char* schemaName, c
FFvariant ffSettingsGet(FFinstance* instance, const char* dconfKey, const char* gsettingsSchemaName, const char* gsettingsPath, const char* gsettingsKey, FFvarianttype type);
FFvariant ffSettingsGetXFConf(FFinstance* instance, const char* channelName, const char* propertyName, FFvarianttype type);
int ffSettingsGetSQLite3Int(FFinstance* instance, const char* dbPath, const char* query);
#ifdef __ANDROID__
bool ffSettingsGetAndroidProperty(const char* propName, FFstrbuf* result);
#endif

View File

@ -1513,7 +1513,7 @@ static const FFlogo* detectBuiltinLogoWithVersion(const FFstrbuf* versionString,
if(logoHasName(newLogo, name->chars)) \
{ \
long version = strtol(versionString->chars, NULL, 10); \
return (version == 0 || version == LONG_MAX || version == LONG_MIN || version > ver) ? newLogo : oldLogo; \
return (version == 0 || version == LONG_MAX || version == LONG_MIN || version >= ver) ? newLogo : oldLogo; \
}
FF_PRINT_LOGO_VERSIONED_IF_EXISTS(getLogoFedora(), getLogoFedoraOld(), 34)

View File

@ -6,44 +6,6 @@
#define FF_PACKAGES_MODULE_NAME "Packages"
#define FF_PACKAGES_NUM_FORMAT_ARGS 9
#ifdef FF_HAVE_RPM
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmlog.h>
static uint32_t getRpmPackageCount(FFinstance* instance)
{
FF_LIBRARY_LOAD(rpm, instance->config.librpm, 0, "librpm.so", 12)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmReadConfigFiles, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsCreate, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsInitIterator, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbGetIteratorCount, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmdbFreeIterator, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmtsFree, 0)
FF_LIBRARY_LOAD_SYMBOL(rpm, rpmlogSetMask, 0)
// Don't print any error messages
ffrpmlogSetMask(RPMLOG_MASK(RPMLOG_EMERG));
uint32_t count = 0;
rpmts ts = NULL;
rpmdbMatchIterator mi = NULL;
if (ffrpmReadConfigFiles(NULL, NULL)) goto exit;
if (!(ts = ffrpmtsCreate())) goto exit;
if (!(mi = ffrpmtsInitIterator(ts, RPMDBI_LABEL, NULL, 0))) goto exit;
count = (uint32_t) ffrpmdbGetIteratorCount(mi);
exit:
if (mi) ffrpmdbFreeIterator(mi);
if (ts) ffrpmtsFree(ts);
dlclose(rpm);
return count;
}
#endif
static uint32_t getNumElements(const char* dirname, unsigned char type)
{
DIR* dirp = opendir(dirname);
@ -183,11 +145,13 @@ void ffPrintPackages(FFinstance* instance)
uint32_t pacman = getNumElements(FASTFETCH_TARGET_DIR_ROOT"/var/lib/pacman/local", DT_DIR);
uint32_t dpkg = getNumStrings(FASTFETCH_TARGET_DIR_ROOT"/var/lib/dpkg/status", "Status: ");
#ifdef FF_HAVE_RPM
uint32_t rpm = getRpmPackageCount(instance);
#else
uint32_t rpm = 0;
#endif
// We do our own sql querys instead of using (lib)rpm, because:
// - simply faster
// - we get package count on SUSE platforms
// - we don't need to regulary increase librpm version, which increases rapidly without providing a major version symlink
uint32_t rpm = (uint32_t) ffSettingsGetSQLite3Int(instance, "/var/lib/rpm/rpmdb.sqlite", "SELECT count(blob) FROM Packages");
if(rpm == 0)
rpm = (uint32_t) ffSettingsGetSQLite3Int(instance, "/var/cache/dnf/packages.db", "SELECT count(pkg) FROM installed");
uint32_t emerge = countFilesIn(FASTFETCH_TARGET_DIR_ROOT"/var/db/pkg", "SIZE");
uint32_t xbps = getNumElements(FASTFETCH_TARGET_DIR_ROOT"/var/db/xbps", DT_REG);