From 62b164bd7174bb8cbb4f1617c91cd13b3b2a5ccb Mon Sep 17 00:00:00 2001 From: Ingo Weinhold Date: Thu, 21 Nov 2013 13:06:09 +0100 Subject: [PATCH] BPathFinder: Add BPackageResolvableExpression initialization Add a constructor and a SetTo() method with a BPackageResolvableExpression parameter instead of a path. The path of the package satisfying the expression is used. The new functionality lives in libpackage as it uses the package kit. --- headers/os/storage/PathFinder.h | 18 ++++++- src/kits/package/Jamfile | 2 + src/kits/package/PathFinder.cpp | 93 +++++++++++++++++++++++++++++++++ src/kits/storage/PathFinder.cpp | 4 ++ 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 src/kits/package/PathFinder.cpp diff --git a/headers/os/storage/PathFinder.h b/headers/os/storage/PathFinder.h index e203269374..0723c65403 100644 --- a/headers/os/storage/PathFinder.h +++ b/headers/os/storage/PathFinder.h @@ -15,7 +15,16 @@ class BStringList; struct entry_ref; +namespace BPackageKit { + class BPackageResolvableExpression; +} + + class BPathFinder { +public: + typedef BPackageKit::BPackageResolvableExpression + BResolvableExpression; + public: BPathFinder(const void* codePointer = NULL, const char* dependency = NULL); @@ -23,6 +32,10 @@ public: const char* dependency = NULL); BPathFinder(const entry_ref& ref, const char* dependency = NULL); + BPathFinder( + const BResolvableExpression& expression, + const char* dependency = NULL); + // requires libpackage status_t SetTo(const void* codePointer = NULL, const char* dependency = NULL); @@ -30,6 +43,9 @@ public: const char* dependency = NULL); status_t SetTo(const entry_ref& ref, const char* dependency = NULL); + status_t SetTo(const BResolvableExpression& expression, + const char* dependency = NULL); + // requires libpackage status_t FindPath(const char* architecture, path_base_directory baseDirectory, @@ -64,7 +80,7 @@ private: BString fPath; BString fDependency; status_t fInitStatus; - uint32 fReserved[4]; + addr_t fReserved[4]; }; diff --git a/src/kits/package/Jamfile b/src/kits/package/Jamfile index 1bfc7633d9..d63e86b0af 100644 --- a/src/kits/package/Jamfile +++ b/src/kits/package/Jamfile @@ -5,6 +5,7 @@ UsePrivateHeaders shared storage ; +UsePrivateSystemHeaders ; HPKG_SOURCES = AttributeDataReader.cpp @@ -103,6 +104,7 @@ for architectureObject in [ MultiArchSubDirSetup ] { PackageResolvableExpression.cpp PackageRoster.cpp PackageVersion.cpp + PathFinder.cpp RefreshRepositoryRequest.cpp RemoveRepositoryJob.cpp RepositoryCache.cpp diff --git a/src/kits/package/PathFinder.cpp b/src/kits/package/PathFinder.cpp new file mode 100644 index 0000000000..475f9b3f7d --- /dev/null +++ b/src/kits/package/PathFinder.cpp @@ -0,0 +1,93 @@ +/* + * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. + * Distributed under the terms of the MIT License. + */ + + +#include + +#include +#include + +#include +#include + + +// NOTE: This is only the package kit specific part of BPathFinder. Everything +// else is implemented in the storage kit. + + +using namespace BPackageKit; +using namespace BPackageKit::BPrivate; +using namespace BPackageKit::BManager::BPrivate; + + +static status_t +find_package(const BPackageResolvableExpression& expression, + BString& _versionedPackageName) +{ + if (expression.InitCheck() != B_OK) + return B_BAD_VALUE; + + // create the package manager -- we only want to use its solver + BPackageManager::ClientInstallationInterface installationInterface; + BPackageManager::UserInteractionHandler userInteractionHandler; + BPackageManager packageManager(B_PACKAGE_INSTALLATION_LOCATION_HOME, + &installationInterface, &userInteractionHandler); + packageManager.Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES); + + // search + BObjectList packages; + status_t error = packageManager.Solver()->FindPackages(expression.Name(), + BSolver::B_FIND_IN_NAME | BSolver::B_FIND_IN_PROVIDES, packages); + if (error != B_OK) + return B_ENTRY_NOT_FOUND; + + // find the newest matching package + BSolverPackage* foundPackage = NULL; + for (int32 i = 0; BSolverPackage* package = packages.ItemAt(i); i++) { + if (package->Info().Matches(expression) + && (foundPackage == NULL + || package->Info().Version().Compare( + foundPackage->Info().Version()) > 0)) { + foundPackage = package; + } + } + + if (foundPackage == NULL) + return B_ENTRY_NOT_FOUND; + + BString version = foundPackage->Info().Version().ToString(); + _versionedPackageName = foundPackage->VersionedName(); + return _versionedPackageName.IsEmpty() ? B_NO_MEMORY : B_OK; +} + + +BPathFinder::BPathFinder(const BResolvableExpression& expression, + const char* dependency) +{ + SetTo(expression, dependency); +} + + +status_t +BPathFinder::SetTo(const BResolvableExpression& expression, + const char* dependency) +{ + BString versionedPackageName; + fInitStatus = find_package(expression, versionedPackageName); + if (fInitStatus != B_OK) + return fInitStatus; + + BString packageLinksPath; + packageLinksPath.SetToFormat(kSystemPackageLinksDirectory "/%s", + versionedPackageName.String()); + if (packageLinksPath.IsEmpty()) + return fInitStatus = B_NO_MEMORY; + + struct stat st; + if (lstat(packageLinksPath, &st) < 0) + return fInitStatus = B_ENTRY_NOT_FOUND; + + return _SetTo(NULL, packageLinksPath, dependency); +} diff --git a/src/kits/storage/PathFinder.cpp b/src/kits/storage/PathFinder.cpp index 98fcab0e25..0666d39bf4 100644 --- a/src/kits/storage/PathFinder.cpp +++ b/src/kits/storage/PathFinder.cpp @@ -11,6 +11,10 @@ #include +// NOTE: The package kit specific part of BPathFinder (BResolvableExpression +// constructor and SetTo()) is implemented in the package kit. + + BPathFinder::BPathFinder(const void* codePointer, const char* dependency) { _SetTo(codePointer, NULL, dependency);