From 8c29f587282dbe71860169bfe1c9832c659f14c0 Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Sat, 16 Jul 2011 23:19:00 +0200 Subject: [PATCH] Add BPackageRoster::GetActivePackages() The implementation is temporary. Currently it reads through the packages in the respective packages directory and checks against the package links. Once package activation is tracked explicitly we'll use the activation file/directory. --- headers/build/os/package/PackageDefs.h | 2 + headers/os/package/PackageDefs.h | 24 ++++++ headers/os/package/PackageRoster.h | 9 ++- src/kits/package/PackageRoster.cpp | 101 +++++++++++++++++++++++++ 4 files changed, 135 insertions(+), 1 deletion(-) create mode 100644 headers/build/os/package/PackageDefs.h create mode 100644 headers/os/package/PackageDefs.h diff --git a/headers/build/os/package/PackageDefs.h b/headers/build/os/package/PackageDefs.h new file mode 100644 index 0000000000..7f036bc7ae --- /dev/null +++ b/headers/build/os/package/PackageDefs.h @@ -0,0 +1,2 @@ +#include <../os/package/PackageDefs.h> + diff --git a/headers/os/package/PackageDefs.h b/headers/os/package/PackageDefs.h new file mode 100644 index 0000000000..1f18345136 --- /dev/null +++ b/headers/os/package/PackageDefs.h @@ -0,0 +1,24 @@ +/* + * Copyright 2011, Haiku, Inc. + * Distributed under the terms of the MIT License. + */ +#ifndef _PACKAGE__PACKAGE_DEFS_H_ +#define _PACKAGE__PACKAGE_DEFS_H_ + + +namespace BPackageKit { + + +enum BPackageInstallationLocation { + B_PACKAGE_INSTALLATION_LOCATION_SYSTEM, + B_PACKAGE_INSTALLATION_LOCATION_COMMON, + B_PACKAGE_INSTALLATION_LOCATION_HOME, + + B_PACKAGE_INSTALLATION_LOCATION_ENUM_COUNT +}; + + +} // namespace BPackageKit + + +#endif // _PACKAGE__PACKAGE_DEFS_H_ diff --git a/headers/os/package/PackageRoster.h b/headers/os/package/PackageRoster.h index 9178b50cf9..d407da7e38 100644 --- a/headers/os/package/PackageRoster.h +++ b/headers/os/package/PackageRoster.h @@ -10,6 +10,8 @@ #include #include +#include + class BStringList; @@ -26,6 +28,7 @@ struct BRepositoryConfigVisitor { }; +class BPackageInfoSet; class BRepositoryCache; class BRepositoryConfig; @@ -56,12 +59,16 @@ public: BRepositoryCache* repositoryCache); status_t GetRepositoryConfig(const BString& name, BRepositoryConfig* repositoryConfig); + + status_t GetActivePackages( + BPackageInstallationLocation location, + BPackageInfoSet& packageInfos); + private: status_t _GetRepositoryPath(BPath* path, bool create, directory_which whichDir) const; status_t _VisitRepositoryConfigs(const BPath& path, BRepositoryConfigVisitor& visitor); - }; diff --git a/src/kits/package/PackageRoster.cpp b/src/kits/package/PackageRoster.cpp index 0fb31b535f..5ee0451718 100644 --- a/src/kits/package/PackageRoster.cpp +++ b/src/kits/package/PackageRoster.cpp @@ -18,13 +18,21 @@ #include #include +#include +#include +#include #include #include +#include + namespace BPackageKit { +using namespace BHPKG; + + BPackageRoster::BPackageRoster() { } @@ -175,6 +183,99 @@ BPackageRoster::GetRepositoryConfig(const BString& name, } +status_t +BPackageRoster::GetActivePackages(BPackageInstallationLocation location, + BPackageInfoSet& packageInfos) +{ +// This method makes sense only on an installed Haiku, but not for the build +// tools. +#if defined(__HAIKU__) && !defined(HAIKU_HOST_PLATFORM_HAIKU) + // check the given location + directory_which packagesDirectory; + switch (location) { + case B_PACKAGE_INSTALLATION_LOCATION_SYSTEM: + packagesDirectory = B_SYSTEM_PACKAGES_DIRECTORY; + break; + case B_PACKAGE_INSTALLATION_LOCATION_COMMON: + packagesDirectory = B_COMMON_PACKAGES_DIRECTORY; + break; + case B_PACKAGE_INSTALLATION_LOCATION_HOME: + packagesDirectory = B_USER_PACKAGES_DIRECTORY; + break; + default: + return B_BAD_VALUE; + } + + // find the package links directory + BPath packageLinksPath; + status_t error = find_directory(B_PACKAGE_LINKS_DIRECTORY, + &packageLinksPath); + if (error != B_OK) + return error; + + // find and open the packages directory + BPath packagesDirPath; + error = find_directory(packagesDirectory, &packagesDirPath); + if (error != B_OK) + return error; + + BDirectory directory; + error = directory.SetTo(packagesDirPath.Path()); + if (error != B_OK) + return error; + + // TODO: Implement that correctly be reading the activation files/directory! + + // iterate through the packages + char buffer[sizeof(dirent) + B_FILE_NAME_LENGTH]; + dirent* entry = (dirent*)&buffer; + while (directory.GetNextDirents(entry, sizeof(buffer), 1) == 1) { + if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) + continue; + + // get the full package file path + BPath packagePath; + error = packagePath.SetTo(packagesDirPath.Path(), entry->d_name); + if (error != B_OK) + continue; + + // read the package info from the file + BPackageReader packageReader(NULL); + error = packageReader.Init(packagePath.Path()); + if (error != B_OK) + continue; + + BPackageInfo info; + BPackageInfoContentHandler handler(info); + error = packageReader.ParseContent(&handler); + if (error != B_OK || info.InitCheck() != B_OK) + continue; + + // check whether the package is really active by verifying that a + // package link exists for it + BString packageLinkName(info.Name()); + packageLinkName << '-' << info.Version().ToString(); + BPath packageLinkPath; + struct stat st; + if (packageLinkPath.SetTo(packageLinksPath.Path(), packageLinkName) + != B_OK + || lstat(packageLinkPath.Path(), &st) != 0) { + continue; + } + + // add the info + error = packageInfos.AddInfo(info); + if (error != B_OK) + return error; + } + + return B_OK; +#else + return B_NOT_SUPPORTED; +#endif +} + + status_t BPackageRoster::_GetRepositoryPath(BPath* path, bool create, directory_which whichDir) const