diff --git a/src/detection/packages/packages.h b/src/detection/packages/packages.h index 261c8acb0..24ce9748c 100644 --- a/src/detection/packages/packages.h +++ b/src/detection/packages/packages.h @@ -4,7 +4,8 @@ typedef struct FFPackagesResult { - uint32_t am; + uint32_t amSystem; + uint32_t amUser; uint32_t apk; uint32_t brew; uint32_t brewCask; diff --git a/src/detection/packages/packages_linux.c b/src/detection/packages/packages_linux.c index 6d5eff079..af20cbaa4 100644 --- a/src/detection/packages/packages_linux.c +++ b/src/detection/packages/packages_linux.c @@ -386,7 +386,29 @@ static uint32_t getRpmFromLibrpm(void) #endif //FF_HAVE_RPM -static uint32_t getAM(FFstrbuf* baseDir) +static uint32_t getAMPackages(FFstrbuf* baseDir) +{ + uint32_t baseLength = baseDir->length; + FF_AUTO_CLOSE_DIR DIR* dirp = opendir(baseDir->chars); + if (!dirp) return 0; + + uint32_t result = 0; + struct dirent *entry; + while ((entry = readdir(dirp)) != NULL) + { + if (entry->d_name[0] == '.') continue; + if (entry->d_type == DT_DIR) + { + ffStrbufAppendF(baseDir, "/%s/remove", entry->d_name); + if (ffPathExists(baseDir->chars, FF_PATHTYPE_FILE)) + ++result; + ffStrbufSubstrBefore(baseDir, baseLength); + } + } + return result; +} + +static uint32_t getAMSystem(FFstrbuf* baseDir) { // #771 uint32_t baseDirLength = baseDir->length; @@ -401,28 +423,26 @@ static uint32_t getAM(FFstrbuf* baseDir) { ++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); - } - } - } + result = getAMPackages(baseDir); } ffStrbufSubstrBefore(baseDir, baseDirLength); return result; } +static uint32_t getAMUser(void) +{ + // check if $XDG_CONFIG_HOME/appman/appman-config exists + FFstrbuf* baseDir = FF_LIST_GET(FFstrbuf, instance.state.platform.configDirs, 0); + uint32_t baseLen = baseDir->length; + ffStrbufAppendS(baseDir, "appman/appman-config"); + FF_STRBUF_AUTO_DESTROY packagesPath = ffStrbufCreate(); + ffReadFileBuffer(baseDir->chars, &packagesPath); + ffStrbufSubstrBefore(baseDir, baseLen); + + return packagesPath.length > 0 ? getAMPackages(&packagesPath) : 0; +} + static int compareHash(const void* a, const void* b) { return memcmp(a, b, 32); @@ -565,7 +585,7 @@ static void getPackageCounts(FFstrbuf* baseDir, FFPackagesResult* packageCounts, } 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:", "opkg"); // openwrt - if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->am = getAM(baseDir); + if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) packageCounts->amSystem = getAMSystem(baseDir); if (!(options->disabled & FF_PACKAGES_FLAG_SORCERY_BIT)) packageCounts->sorcery += getNumStrings(baseDir, "/var/state/sorcery/packages", ":installed:", "sorcery"); if (!(options->disabled & FF_PACKAGES_FLAG_GUIX_BIT)) { @@ -678,4 +698,8 @@ void ffDetectPackagesImpl(FFPackagesResult* result, FFPackagesOptions* options) if (!(options->disabled & FF_PACKAGES_FLAG_FLATPAK_BIT)) result->flatpakUser = getFlatpakPackages(&baseDir, "/.local/share"); + + if (!(options->disabled & FF_PACKAGES_FLAG_AM_BIT)) + result->amUser = getAMUser(); + } diff --git a/src/modules/packages/packages.c b/src/modules/packages/packages.c index 480bf193a..4c5e018af 100644 --- a/src/modules/packages/packages.c +++ b/src/modules/packages/packages.c @@ -62,7 +62,8 @@ void ffPrintPackages(FFPackagesOptions* options) FF_PRINT_PACKAGE(paludis) FF_PRINT_PACKAGE(winget) FF_PRINT_PACKAGE(opkg) - FF_PRINT_PACKAGE(am) + FF_PRINT_PACKAGE_NAME(amSystem, counts.amUser ? "am-system" : "am") + FF_PRINT_PACKAGE_NAME(amUser, "am-user") FF_PRINT_PACKAGE(sorcery) FF_PRINT_PACKAGE(lpkg) FF_PRINT_PACKAGE(lpkgbuild) @@ -108,7 +109,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.paludis, "paludis"), FF_FORMAT_ARG(counts.winget, "winget"), FF_FORMAT_ARG(counts.opkg, "opkg"), - FF_FORMAT_ARG(counts.am, "am"), + FF_FORMAT_ARG(counts.amSystem, "am-system"), FF_FORMAT_ARG(counts.sorcery, "sorcery"), FF_FORMAT_ARG(counts.lpkg, "lpkg"), FF_FORMAT_ARG(counts.lpkgbuild, "lpkgbuild"), @@ -119,6 +120,7 @@ void ffPrintPackages(FFPackagesOptions* options) FF_FORMAT_ARG(counts.pacstall, "pacstall"), FF_FORMAT_ARG(counts.mport, "mport"), FF_FORMAT_ARG(counts.qi, "qi"), + FF_FORMAT_ARG(counts.amUser, "am-user"), FF_FORMAT_ARG(nixAll, "nix-all"), FF_FORMAT_ARG(flatpakAll, "flatpak-all"), FF_FORMAT_ARG(brewAll, "brew-all"), @@ -400,7 +402,8 @@ void ffGeneratePackagesJsonResult(FF_MAYBE_UNUSED FFPackagesOptions* options, yy #define FF_APPEND_PACKAGE_COUNT(name) yyjson_mut_obj_add_uint(doc, obj, #name, counts.name); FF_APPEND_PACKAGE_COUNT(all) - FF_APPEND_PACKAGE_COUNT(am) + FF_APPEND_PACKAGE_COUNT(amSystem) + FF_APPEND_PACKAGE_COUNT(amUser) FF_APPEND_PACKAGE_COUNT(apk) FF_APPEND_PACKAGE_COUNT(brew) FF_APPEND_PACKAGE_COUNT(brewCask) diff --git a/src/util/platform/FFPlatform_unix.c b/src/util/platform/FFPlatform_unix.c index a6193c53d..c8b5c7c65 100644 --- a/src/util/platform/FFPlatform_unix.c +++ b/src/util/platform/FFPlatform_unix.c @@ -109,6 +109,7 @@ static void getCacheDir(FFPlatform* platform) static void getConfigDirs(FFPlatform* platform) { + // Always make sure `${XDG_CONFIG_HOME:-$HOME/.config}` is the first entry platformPathAddEnv(&platform->configDirs, "XDG_CONFIG_HOME"); ffPlatformPathAddHome(&platform->configDirs, platform, ".config/");