2022-10-13 21:43:31 +02:00
#include "packages.h"
2023-01-28 12:40:12 +01:00
#include "common/io/io.h"
2022-10-13 22:02:58 +02:00
#include "common/parsing.h"
#include "common/processing.h"
2022-10-08 17:41:25 +08:00
#include "common/properties.h"
#include "common/settings.h"
#include "detection/os/os.h"
2023-06-19 15:38:37 +08:00
#include "util/stringUtils.h"
2022-10-08 17:41:25 +08:00
#include <dirent.h>
2022-10-13 21:43:31 +02:00
static uint32_t getNumElementsImpl ( const char * dirname , unsigned char type )
2022-10-08 17:41:25 +08:00
{
2023-12-08 09:30:17 +08:00
FF_AUTO_CLOSE_DIR DIR * dirp = opendir ( dirname );
2022-10-08 17:41:25 +08:00
if ( dirp == NULL )
return 0 ;
uint32_t num_elements = 0 ;
struct dirent * entry ;
while (( entry = readdir ( dirp )) != NULL ) {
if ( entry -> d_type == type )
++ num_elements ;
}
2022-10-13 21:43:31 +02:00
if ( type == DT_DIR && num_elements >= 2 )
2022-10-08 17:41:25 +08:00
num_elements -= 2 ; // accounting for . and ..
return num_elements ;
}
2022-10-13 21:43:31 +02:00
static uint32_t getNumElements ( FFstrbuf * baseDir , const char * dirname , unsigned char type )
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , dirname );
uint32_t num_elements = getNumElementsImpl ( baseDir -> chars , type );
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return num_elements ;
}
2022-10-08 17:41:25 +08:00
2022-10-13 21:43:31 +02:00
static uint32_t getNumStringsImpl ( const char * filename , const char * needle )
2022-10-08 17:41:25 +08:00
{
2023-12-06 19:06:44 +09:00
FF_STRBUF_AUTO_DESTROY content = ffStrbufCreate ();
if ( ! ffReadFileBuffer ( filename , & content ))
2022-10-08 17:41:25 +08:00
return 0 ;
uint32_t count = 0 ;
2023-12-06 19:06:44 +09:00
char * iter = content . chars ;
size_t needleLength = strlen ( needle );
while (( iter = memmem ( iter , content . length - ( size_t )( iter - content . chars ), needle , needleLength )) != NULL )
2022-10-08 17:41:25 +08:00
{
2023-12-06 19:06:44 +09:00
++ count ;
iter += needleLength ;
2022-10-08 17:41:25 +08:00
}
return count ;
}
2022-10-13 21:43:31 +02:00
static uint32_t getNumStrings ( FFstrbuf * baseDir , const char * filename , const char * needle )
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , filename );
uint32_t num_elements = getNumStringsImpl ( baseDir -> chars , needle );
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return num_elements ;
}
2023-06-24 10:59:53 +08:00
static uint32_t getSQLite3Int ( FFstrbuf * baseDir , const char * dbPath , const char * query )
2022-10-13 21:43:31 +02:00
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , dbPath );
2023-06-24 10:59:53 +08:00
uint32_t num_elements = ( uint32_t ) ffSettingsGetSQLite3Int ( baseDir -> chars , query );
2022-10-13 21:43:31 +02:00
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return num_elements ;
}
2022-10-08 17:41:25 +08:00
2022-10-13 21:43:31 +02:00
static uint32_t countFilesRecursiveImpl ( FFstrbuf * baseDirPath , const char * filename )
2022-10-08 17:41:25 +08:00
{
uint32_t baseDirPathLength = baseDirPath -> length ;
ffStrbufAppendC ( baseDirPath , '/' );
ffStrbufAppendS ( baseDirPath , filename );
2023-01-28 11:52:23 +01:00
bool exists = ffPathExists ( baseDirPath -> chars , FF_PATHTYPE_FILE );
2022-10-08 17:41:25 +08:00
ffStrbufSubstrBefore ( baseDirPath , baseDirPathLength );
if ( exists )
return 1 ;
DIR * dirp = opendir ( baseDirPath -> chars );
if ( dirp == NULL )
return 0 ;
ffStrbufAppendC ( baseDirPath , '/' );
baseDirPathLength = baseDirPath -> length ;
uint32_t sum = 0 ;
struct dirent * entry ;
while (( entry = readdir ( dirp )) != NULL ) {
// According to the PMS, neither category nor package name can begin with '.', so no need to check for . or .. specifically
if ( entry -> d_type != DT_DIR || entry -> d_name [ 0 ] == '.' )
continue ;
ffStrbufAppendS ( baseDirPath , entry -> d_name );
2022-10-13 21:43:31 +02:00
sum += countFilesRecursiveImpl ( baseDirPath , filename );
2022-10-08 17:41:25 +08:00
ffStrbufSubstrBefore ( baseDirPath , baseDirPathLength );
}
closedir ( dirp );
return sum ;
}
2022-10-13 21:43:31 +02:00
static uint32_t countFilesRecursive ( FFstrbuf * baseDir , const char * dirname , const char * filename )
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , dirname );
uint32_t sum = countFilesRecursiveImpl ( baseDir , filename );
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return sum ;
}
2024-04-28 20:59:05 -05:00
static bool isValidNixPkg ( FFstrbuf * pkg )
{
if ( ! ffPathExists ( pkg -> chars , FF_PATHTYPE_DIRECTORY ))
return false ;
ffStrbufSubstrAfterLastC ( pkg , '/' );
if (
ffStrbufStartsWithS ( pkg , "nixos-system-nixos-" ) ||
ffStrbufEndsWithS ( pkg , "-doc" ) ||
ffStrbufEndsWithS ( pkg , "-man" ) ||
ffStrbufEndsWithS ( pkg , "-info" ) ||
ffStrbufEndsWithS ( pkg , "-dev" ) ||
ffStrbufEndsWithS ( pkg , "-bin" )
) return false ;
enum { START , DIGIT , DOT , MATCH } state = START ;
for ( uint32_t i = 0 ; i < pkg -> length ; i ++ )
{
char c = pkg -> chars [ i ];
switch ( state )
{
case START :
if ( c >= '0' && c <= '9' )
state = DIGIT ;
break ;
case DIGIT :
if ( c >= '0' && c <= '9' )
continue ;
if ( c == '.' )
state = DOT ;
else
state = START ;
break ;
case DOT :
if ( c >= '0' && c <= '9' )
state = MATCH ;
else
state = START ;
break ;
case MATCH :
break ;
}
}
return state == MATCH ;
}
static bool checkNixCache ( FFstrbuf * cacheDir , FFstrbuf * hash , uint32_t * count )
{
if ( ! ffPathExists ( cacheDir -> chars , FF_PATHTYPE_FILE ))
return false ;
2024-04-29 10:04:20 +08:00
FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreate ();
2024-04-28 20:59:05 -05:00
if ( ! ffReadFileBuffer ( cacheDir -> chars , & cacheContent ))
return false ;
// Format: <hash>\n<count>
uint32_t split = ffStrbufFirstIndexC ( & cacheContent , '\n' );
if ( split == cacheContent . length )
return false ;
ffStrbufSetNS ( hash , split , cacheContent . chars );
* count = ( uint32_t ) atoi ( cacheContent . chars + split + 1 );
return true ;
}
static bool writeNixCache ( FFstrbuf * cacheDir , FFstrbuf * hash , uint32_t count )
{
2024-04-29 10:04:20 +08:00
FF_STRBUF_AUTO_DESTROY cacheContent = ffStrbufCreateCopy ( hash );
ffStrbufAppendF ( & cacheContent , " \n %u" , count );
2024-04-28 20:59:05 -05:00
return ffWriteFileBuffer ( cacheDir -> chars , & cacheContent );
}
2022-10-13 21:43:31 +02:00
static uint32_t getNixPackagesImpl ( char * path )
2022-10-08 17:41:25 +08:00
{
//Nix detection is kinda slow, so we only do it if the dir exists
2023-01-28 11:52:23 +01:00
if ( ! ffPathExists ( path , FF_PATHTYPE_DIRECTORY ))
2022-10-08 17:41:25 +08:00
return 0 ;
2024-04-29 10:04:20 +08:00
FF_STRBUF_AUTO_DESTROY cacheDir = ffStrbufCreateCopy ( & instance . state . platform . cacheDir );
2024-04-28 20:59:05 -05:00
ffStrbufEnsureEndsWithC ( & cacheDir , '/' );
ffStrbufAppendS ( & cacheDir , "fastfetch/packages/nix" );
ffStrbufAppendS ( & cacheDir , path );
//Check the hash first to determine if we need to recompute the count
FF_STRBUF_AUTO_DESTROY hash = ffStrbufCreateA ( 64 );
FF_STRBUF_AUTO_DESTROY cacheHash = ffStrbufCreateA ( 64 );
uint32_t count = 0 ;
ffProcessAppendStdOut ( & hash , ( char * const []) {
"nix-store" ,
"--query" ,
"--hash" ,
path ,
NULL
});
2022-10-08 17:41:25 +08:00
2024-04-28 20:59:05 -05:00
if ( checkNixCache ( & cacheDir , & cacheHash , & count ) && ffStrbufEqual ( & hash , & cacheHash ))
return count ;
//Cache is invalid, recompute the count
count = 0 ;
//Implementation based on bash script from here:
2023-06-12 17:26:37 +02:00
//https://github.com/fastfetch-cli/fastfetch/issues/195#issuecomment-1191748222
2024-04-29 10:04:20 +08:00
2024-04-28 20:59:05 -05:00
FF_STRBUF_AUTO_DESTROY output = ffStrbufCreateA ( 1024 );
2022-10-08 17:41:25 +08:00
ffProcessAppendStdOut ( & output , ( char * const []) {
2024-04-28 20:59:05 -05:00
"nix-store" ,
"--query" ,
"--requisites" ,
path ,
2022-10-08 17:41:25 +08:00
NULL
});
2024-04-28 20:59:05 -05:00
uint32_t lineLength = 0 ;
for ( uint32_t i = 0 ; i < output . length ; i ++ )
{
if ( output . chars [ i ] != '\n' )
{
lineLength ++ ;
continue ;
}
output . chars [ i ] = '\0' ;
FFstrbuf line = {
. allocated = 0 ,
. length = lineLength ,
. chars = output . chars + i - lineLength
};
if ( isValidNixPkg ( & line ))
count ++ ;
lineLength = 0 ;
}
2024-04-29 10:04:20 +08:00
2024-04-28 20:59:05 -05:00
writeNixCache ( & cacheDir , & hash , count );
return count ;
2022-10-08 17:41:25 +08:00
}
2022-10-13 21:43:31 +02:00
static uint32_t getNixPackages ( FFstrbuf * baseDir , const char * dirname )
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , dirname );
uint32_t num_elements = getNixPackagesImpl ( baseDir -> chars );
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return num_elements ;
}
static uint32_t getXBPSImpl ( FFstrbuf * baseDir )
2022-10-08 17:41:25 +08:00
{
DIR * dir = opendir ( baseDir -> chars );
if ( dir == NULL )
return 0 ;
uint32_t result = 0 ;
struct dirent * entry ;
while (( entry = readdir ( dir )) != NULL )
{
2023-06-19 15:38:37 +08:00
if ( entry -> d_type != DT_REG || ! ffStrStartsWithIgnCase ( entry -> d_name , "pkgdb-" ))
2022-10-08 17:41:25 +08:00
continue ;
ffStrbufAppendC ( baseDir , '/' );
ffStrbufAppendS ( baseDir , entry -> d_name );
2022-10-13 21:43:31 +02:00
result = getNumStringsImpl ( baseDir -> chars , "<string>installed</string>" );
2022-10-08 17:41:25 +08:00
break ;
}
closedir ( dir );
return result ;
}
2022-10-13 21:43:31 +02:00
static uint32_t getXBPS ( FFstrbuf * baseDir , const char * dirname )
2022-10-08 17:41:25 +08:00
{
uint32_t baseDirLength = baseDir -> length ;
2022-10-13 21:43:31 +02:00
ffStrbufAppendS ( baseDir , dirname );
uint32_t result = getXBPSImpl ( baseDir );
2022-10-08 17:41:25 +08:00
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return result ;
}
2022-10-13 21:43:31 +02:00
static uint32_t getSnap ( FFstrbuf * baseDir )
2022-10-08 17:41:25 +08:00
{
2022-10-13 21:43:31 +02:00
uint32_t result = getNumElements ( baseDir , "/snap" , DT_DIR );
2022-10-08 17:41:25 +08:00
2023-09-20 16:00:09 +08:00
if ( result == 0 )
result = getNumElements ( baseDir , "/var/lib/snapd/snap" , DT_DIR );
2022-10-13 21:43:31 +02:00
//Accounting for the /snap/bin folder
return result > 0 ? result - 1 : 0 ;
2022-10-08 17:41:25 +08:00
}
2023-04-06 11:11:31 +02:00
static uint32_t getFlatpak ( FFstrbuf * baseDir , const char * dirname )
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , dirname );
uint32_t result =
getNumElements ( baseDir , "/app" , DT_DIR ) +
getNumElements ( baseDir , "/runtime" , DT_DIR );
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return result ;
}
2022-10-08 17:41:25 +08:00
#ifdef FF_HAVE_RPM
#include "common/library.h"
#include <rpm/rpmlib.h>
#include <rpm/rpmts.h>
#include <rpm/rpmdb.h>
#include <rpm/rpmlog.h>
2023-06-24 10:59:53 +08:00
static uint32_t getRpmFromLibrpm ( void )
2022-10-08 17:41:25 +08:00
{
2023-10-25 16:24:24 +08:00
FF_LIBRARY_LOAD ( rpm , & instance . config . library . librpm , 0 , "librpm" FF_LIBRARY_EXTENSION , 12 )
2022-10-08 17:41:25 +08:00
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 ));
if ( ffrpmReadConfigFiles ( NULL , NULL ) != 0 )
return 0 ;
rpmts ts = ffrpmtsCreate ();
if ( ts == NULL )
return 0 ;
rpmdbMatchIterator mi = ffrpmtsInitIterator ( ts , RPMDBI_LABEL , NULL , 0 );
if ( mi == NULL )
{
ffrpmtsFree ( ts );
return 0 ;
}
int count = ffrpmdbGetIteratorCount ( mi );
ffrpmdbFreeIterator ( mi );
ffrpmtsFree ( ts );
return count > 0 ? ( uint32_t ) count : 0 ;
}
#endif //FF_HAVE_RPM
2024-04-03 21:08:33 +08:00
static uint32_t getAM ( FFstrbuf * baseDir )
{
// #771
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , "/opt" );
uint32_t optDirLength = baseDir -> length ;
uint32_t result = 0 ;
ffStrbufAppendS ( baseDir , "/am/APP-MANAGER" );
if ( ffPathExists ( baseDir -> chars , FF_PATHTYPE_FILE ))
{
++ result ; // `am` itself is counted as a package too
ffStrbufSubstrBefore ( baseDir , optDirLength );
FF_AUTO_CLOSE_DIR DIR * dirp = opendir ( baseDir -> chars );
if ( dirp )
{
struct dirent * entry ;
while (( entry = readdir ( dirp )) != NULL )
{
if ( entry -> d_name [ 0 ] == '.' ) continue ;
if ( entry -> d_type == DT_DIR )
{
ffStrbufAppendF ( baseDir , "/%s/AM-updater" , entry -> d_name );
if ( ffPathExists ( baseDir -> chars , FF_PATHTYPE_FILE ))
++ result ;
ffStrbufSubstrBefore ( baseDir , optDirLength );
}
}
}
}
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return result ;
}
2024-02-21 15:56:52 +08:00
static void getPackageCounts ( FFstrbuf * baseDir , FFPackagesResult * packageCounts , FFPackagesOptions * options )
2022-10-08 17:41:25 +08:00
{
2024-02-21 15:56:52 +08:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_APK_BIT )) packageCounts -> apk += getNumStrings ( baseDir , "/lib/apk/db/installed" , "C:Q" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_DPKG_BIT )) packageCounts -> dpkg += getNumStrings ( baseDir , "/var/lib/dpkg/status" , "Status: install ok installed" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_EMERGE_BIT )) packageCounts -> emerge += countFilesRecursive ( baseDir , "/var/db/pkg" , "SIZE" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_EOPKG_BIT )) packageCounts -> eopkg += getNumElements ( baseDir , "/var/lib/eopkg/package" , DT_DIR );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_FLATPAK_BIT )) packageCounts -> flatpakSystem += getFlatpak ( baseDir , "/var/lib/flatpak" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_NIX_BIT ))
{
packageCounts -> nixDefault += getNixPackages ( baseDir , "/nix/var/nix/profiles/default" );
packageCounts -> nixSystem += getNixPackages ( baseDir , "/run/current-system" );
}
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_PACMAN_BIT )) packageCounts -> pacman += getNumElements ( baseDir , "/var/lib/pacman/local" , DT_DIR );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_PKGTOOL_BIT )) packageCounts -> pkgtool += getNumElements ( baseDir , "/var/log/packages" , DT_REG );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_RPM_BIT )) packageCounts -> rpm += getSQLite3Int ( baseDir , "/var/lib/rpm/rpmdb.sqlite" , "SELECT count(*) FROM Packages" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_SNAP_BIT )) packageCounts -> snap += getSnap ( baseDir );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_XBPS_BIT )) packageCounts -> xbps += getXBPS ( baseDir , "/var/db/xbps" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_BREW_BIT ))
{
packageCounts -> brewCask += getNumElements ( baseDir , "/home/linuxbrew/.linuxbrew/Caskroom" , DT_DIR );
packageCounts -> brew += getNumElements ( baseDir , "/home/linuxbrew/.linuxbrew/Cellar" , DT_DIR );
}
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_PALUDIS_BIT )) packageCounts -> paludis += countFilesRecursive ( baseDir , "/var/db/paludis/repositories" , "environment.bz2" );
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_OPKG_BIT )) packageCounts -> opkg += getNumStrings ( baseDir , "/usr/lib/opkg/status" , "Package:" ); // openwrt
2024-04-03 21:08:33 +08:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_AM_BIT )) packageCounts -> am = getAM ( baseDir );
2024-04-30 20:25:04 -07:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_SORCERY_BIT )) packageCounts -> sorcery += getNumStrings ( baseDir , "/var/state/sorcery/packages" , ":installed:" );
2022-10-13 21:43:31 +02:00
}
2022-10-08 17:41:25 +08:00
2024-02-21 15:56:52 +08:00
static void getPackageCountsRegular ( FFstrbuf * baseDir , FFPackagesResult * packageCounts , FFPackagesOptions * options )
2022-10-13 21:43:31 +02:00
{
2024-02-21 15:56:52 +08:00
getPackageCounts ( baseDir , packageCounts , options );
2022-10-08 17:41:25 +08:00
2024-02-21 15:56:52 +08:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_PACMAN_BIT ))
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , FASTFETCH_TARGET_DIR_ETC "/pacman-mirrors.conf" );
if ( ffParsePropFile ( baseDir -> chars , "Branch =" , & packageCounts -> pacmanBranch ) && packageCounts -> pacmanBranch . length == 0 )
ffStrbufAppendS ( & packageCounts -> pacmanBranch , "stable" );
ffStrbufSubstrBefore ( baseDir , baseDirLength );
}
2022-10-08 17:41:25 +08:00
}
2024-02-21 15:56:52 +08:00
static void getPackageCountsBedrock ( FFstrbuf * baseDir , FFPackagesResult * packageCounts , FFPackagesOptions * options )
2022-10-08 17:41:25 +08:00
{
uint32_t baseDirLength = baseDir -> length ;
ffStrbufAppendS ( baseDir , "/bedrock/strata" );
2024-02-21 15:40:04 +08:00
FF_AUTO_CLOSE_DIR DIR * dir = opendir ( baseDir -> chars );
2022-10-08 17:41:25 +08:00
if ( dir == NULL )
{
ffStrbufSubstrBefore ( baseDir , baseDirLength );
return ;
}
ffStrbufAppendC ( baseDir , '/' );
2022-10-13 21:43:31 +02:00
uint32_t baseDirLength2 = baseDir -> length ;
2022-10-08 17:41:25 +08:00
struct dirent * entry ;
while (( entry = readdir ( dir )) != NULL )
{
if ( entry -> d_type != DT_DIR )
continue ;
2023-06-19 16:07:23 +08:00
if ( ffStrEquals ( entry -> d_name , "." ) || ffStrEquals ( entry -> d_name , ".." ))
2023-01-09 10:45:51 +08:00
continue ;
2022-10-08 17:41:25 +08:00
ffStrbufAppendS ( baseDir , entry -> d_name );
2024-02-21 15:56:52 +08:00
getPackageCounts ( baseDir , packageCounts , options );
2022-10-13 21:43:31 +02:00
ffStrbufSubstrBefore ( baseDir , baseDirLength2 );
2022-10-08 17:41:25 +08:00
}
2022-10-13 21:43:31 +02:00
ffStrbufSubstrBefore ( baseDir , baseDirLength );
2022-10-08 17:41:25 +08:00
}
2024-02-21 15:56:52 +08:00
void ffDetectPackagesImpl ( FFPackagesResult * result , FFPackagesOptions * options )
2022-10-08 17:41:25 +08:00
{
2023-04-15 15:29:54 +08:00
FF_STRBUF_AUTO_DESTROY baseDir = ffStrbufCreateA ( 512 );
2022-10-08 17:41:25 +08:00
ffStrbufAppendS ( & baseDir , FASTFETCH_TARGET_DIR_ROOT );
2023-06-24 10:59:53 +08:00
if ( ffStrbufIgnCaseEqualS ( & ffDetectOS () -> id , "bedrock" ))
2024-02-21 15:56:52 +08:00
getPackageCountsBedrock ( & baseDir , result , options );
2022-10-08 17:41:25 +08:00
else
2024-02-21 15:56:52 +08:00
getPackageCountsRegular ( & baseDir , result , options );
2022-10-08 17:41:25 +08:00
// If SQL failed, we can still try with librpm.
// This is needed on openSUSE, which seems to use a proprietary database file
// This method doesn't work on bedrock, so we do it here.
#ifdef FF_HAVE_RPM
2024-02-21 15:56:52 +08:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_RPM_BIT ) && result -> rpm == 0 )
2023-06-24 10:59:53 +08:00
result -> rpm = getRpmFromLibrpm ();
2022-10-08 17:41:25 +08:00
#endif
2023-06-24 10:59:53 +08:00
ffStrbufSet ( & baseDir , & instance . state . platform . homeDir );
2024-02-21 15:56:52 +08:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_NIX_BIT ))
2024-05-02 09:55:50 -05:00
{
// check if ~/.nix-profile exists
FF_STRBUF_AUTO_DESTROY profilePath = ffStrbufCreateCopy ( & baseDir );
ffStrbufAppendS ( & profilePath , ".nix-profile" );
if ( ffPathExists ( profilePath . chars , FF_PATHTYPE_DIRECTORY ))
{
result -> nixUser = getNixPackages ( & baseDir , ".nix-profile" );
}
// check if $XDG_STATE_HOME/nix/profile exists
else
{
FF_STRBUF_AUTO_DESTROY stateDir = ffStrbufCreate ();
const char * stateHome = getenv ( "XDG_STATE_HOME" );
if ( ffStrSet ( stateHome ))
{
ffStrbufSetS ( & stateDir , stateHome );
ffStrbufEnsureEndsWithC ( & stateDir , '/' );
}
else
{
ffStrbufSet ( & stateDir , & instance . state . platform . homeDir );
ffStrbufAppendS ( & stateDir , ".local/state/" );
}
ffStrbufSet ( & profilePath , & stateDir );
ffStrbufAppendS ( & profilePath , "nix/profile" );
result -> nixUser = getNixPackages ( & stateDir , "nix/profile" );
}
}
2024-02-21 15:56:52 +08:00
if ( ! ( options -> disabled & FF_PACKAGES_FLAG_FLATPAK_BIT ))
result -> flatpakUser = getFlatpak ( & baseDir , "/.local/share/flatpak" );
2022-10-08 17:41:25 +08:00
}