162b164bdSIngo Weinhold /*
262b164bdSIngo Weinhold * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de.
362b164bdSIngo Weinhold * Distributed under the terms of the MIT License.
462b164bdSIngo Weinhold */
562b164bdSIngo Weinhold
662b164bdSIngo Weinhold
762b164bdSIngo Weinhold #include <PathFinder.h>
862b164bdSIngo Weinhold
962b164bdSIngo Weinhold #include <package/PackageResolvableExpression.h>
1062b164bdSIngo Weinhold #include <package/solver/SolverPackage.h>
1162b164bdSIngo Weinhold
1262b164bdSIngo Weinhold #include <directories.h>
1362b164bdSIngo Weinhold #include <package/manager/PackageManager.h>
1462b164bdSIngo Weinhold
1562b164bdSIngo Weinhold
1662b164bdSIngo Weinhold // NOTE: This is only the package kit specific part of BPathFinder. Everything
1762b164bdSIngo Weinhold // else is implemented in the storage kit.
1862b164bdSIngo Weinhold
1962b164bdSIngo Weinhold
2062b164bdSIngo Weinhold using namespace BPackageKit;
2162b164bdSIngo Weinhold using namespace BPackageKit::BPrivate;
2262b164bdSIngo Weinhold using namespace BPackageKit::BManager::BPrivate;
2362b164bdSIngo Weinhold
2462b164bdSIngo Weinhold
2562b164bdSIngo Weinhold static status_t
find_package(const BPackageResolvableExpression & expression,BString & _versionedPackageName)2662b164bdSIngo Weinhold find_package(const BPackageResolvableExpression& expression,
2762b164bdSIngo Weinhold BString& _versionedPackageName)
2862b164bdSIngo Weinhold {
2962b164bdSIngo Weinhold if (expression.InitCheck() != B_OK)
3062b164bdSIngo Weinhold return B_BAD_VALUE;
3162b164bdSIngo Weinhold
3262b164bdSIngo Weinhold // create the package manager -- we only want to use its solver
3362b164bdSIngo Weinhold BPackageManager::ClientInstallationInterface installationInterface;
3462b164bdSIngo Weinhold BPackageManager::UserInteractionHandler userInteractionHandler;
3562b164bdSIngo Weinhold BPackageManager packageManager(B_PACKAGE_INSTALLATION_LOCATION_HOME,
3662b164bdSIngo Weinhold &installationInterface, &userInteractionHandler);
3762b164bdSIngo Weinhold packageManager.Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES);
3862b164bdSIngo Weinhold
3962b164bdSIngo Weinhold // search
4062b164bdSIngo Weinhold BObjectList<BSolverPackage> packages;
4162b164bdSIngo Weinhold status_t error = packageManager.Solver()->FindPackages(expression.Name(),
4262b164bdSIngo Weinhold BSolver::B_FIND_IN_NAME | BSolver::B_FIND_IN_PROVIDES, packages);
4362b164bdSIngo Weinhold if (error != B_OK)
4462b164bdSIngo Weinhold return B_ENTRY_NOT_FOUND;
4562b164bdSIngo Weinhold
4662b164bdSIngo Weinhold // find the newest matching package
4762b164bdSIngo Weinhold BSolverPackage* foundPackage = NULL;
4862b164bdSIngo Weinhold for (int32 i = 0; BSolverPackage* package = packages.ItemAt(i); i++) {
4962b164bdSIngo Weinhold if (package->Info().Matches(expression)
5062b164bdSIngo Weinhold && (foundPackage == NULL
5162b164bdSIngo Weinhold || package->Info().Version().Compare(
5262b164bdSIngo Weinhold foundPackage->Info().Version()) > 0)) {
5362b164bdSIngo Weinhold foundPackage = package;
5462b164bdSIngo Weinhold }
5562b164bdSIngo Weinhold }
5662b164bdSIngo Weinhold
5762b164bdSIngo Weinhold if (foundPackage == NULL)
5862b164bdSIngo Weinhold return B_ENTRY_NOT_FOUND;
5962b164bdSIngo Weinhold
6062b164bdSIngo Weinhold BString version = foundPackage->Info().Version().ToString();
6162b164bdSIngo Weinhold _versionedPackageName = foundPackage->VersionedName();
6262b164bdSIngo Weinhold return _versionedPackageName.IsEmpty() ? B_NO_MEMORY : B_OK;
6362b164bdSIngo Weinhold }
6462b164bdSIngo Weinhold
6562b164bdSIngo Weinhold
BPathFinder(const BResolvableExpression & expression,const char * dependency)6662b164bdSIngo Weinhold BPathFinder::BPathFinder(const BResolvableExpression& expression,
6762b164bdSIngo Weinhold const char* dependency)
6862b164bdSIngo Weinhold {
6962b164bdSIngo Weinhold SetTo(expression, dependency);
7062b164bdSIngo Weinhold }
7162b164bdSIngo Weinhold
7262b164bdSIngo Weinhold
7362b164bdSIngo Weinhold status_t
SetTo(const BResolvableExpression & expression,const char * dependency)7462b164bdSIngo Weinhold BPathFinder::SetTo(const BResolvableExpression& expression,
7562b164bdSIngo Weinhold const char* dependency)
7662b164bdSIngo Weinhold {
7762b164bdSIngo Weinhold BString versionedPackageName;
7862b164bdSIngo Weinhold fInitStatus = find_package(expression, versionedPackageName);
7962b164bdSIngo Weinhold if (fInitStatus != B_OK)
8062b164bdSIngo Weinhold return fInitStatus;
8162b164bdSIngo Weinhold
8262b164bdSIngo Weinhold BString packageLinksPath;
83*676481a5SIngo Weinhold packageLinksPath.SetToFormat(kSystemPackageLinksDirectory "/%s/.self",
8462b164bdSIngo Weinhold versionedPackageName.String());
8562b164bdSIngo Weinhold if (packageLinksPath.IsEmpty())
8662b164bdSIngo Weinhold return fInitStatus = B_NO_MEMORY;
8762b164bdSIngo Weinhold
8862b164bdSIngo Weinhold struct stat st;
8962b164bdSIngo Weinhold if (lstat(packageLinksPath, &st) < 0)
9062b164bdSIngo Weinhold return fInitStatus = B_ENTRY_NOT_FOUND;
9162b164bdSIngo Weinhold
9262b164bdSIngo Weinhold return _SetTo(NULL, packageLinksPath, dependency);
9362b164bdSIngo Weinhold }
94