* Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
* Distributed under the terms of the MIT License.
*/
#include <PathFinder.h>
#include <package/PackageResolvableExpression.h>
#include <package/solver/SolverPackage.h>
#include <directories.h>
#include <package/manager/PackageManager.h>
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;
BPackageManager::ClientInstallationInterface installationInterface;
BPackageManager::UserInteractionHandler userInteractionHandler;
BPackageManager packageManager(B_PACKAGE_INSTALLATION_LOCATION_HOME,
&installationInterface, &userInteractionHandler);
packageManager.Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES);
BObjectList<BSolverPackage> 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;
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/.self",
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);
}