|
| 1 | +/* |
| 2 | + * Copyright 2013, Ingo Weinhold, [email protected]. |
| 3 | + * Distributed under the terms of the MIT License. |
| 4 | + */ |
| 5 | + |
| 6 | + |
| 7 | +#include <PathFinder.h> |
| 8 | + |
| 9 | +#include <package/PackageResolvableExpression.h> |
| 10 | +#include <package/solver/SolverPackage.h> |
| 11 | + |
| 12 | +#include <directories.h> |
| 13 | +#include <package/manager/PackageManager.h> |
| 14 | + |
| 15 | + |
| 16 | +// NOTE: This is only the package kit specific part of BPathFinder. Everything |
| 17 | +// else is implemented in the storage kit. |
| 18 | + |
| 19 | + |
| 20 | +using namespace BPackageKit; |
| 21 | +using namespace BPackageKit::BPrivate; |
| 22 | +using namespace BPackageKit::BManager::BPrivate; |
| 23 | + |
| 24 | + |
| 25 | +static status_t |
| 26 | +find_package(const BPackageResolvableExpression& expression, |
| 27 | + BString& _versionedPackageName) |
| 28 | +{ |
| 29 | + if (expression.InitCheck() != B_OK) |
| 30 | + return B_BAD_VALUE; |
| 31 | + |
| 32 | + // create the package manager -- we only want to use its solver |
| 33 | + BPackageManager::ClientInstallationInterface installationInterface; |
| 34 | + BPackageManager::UserInteractionHandler userInteractionHandler; |
| 35 | + BPackageManager packageManager(B_PACKAGE_INSTALLATION_LOCATION_HOME, |
| 36 | + &installationInterface, &userInteractionHandler); |
| 37 | + packageManager.Init(BPackageManager::B_ADD_INSTALLED_REPOSITORIES); |
| 38 | + |
| 39 | + // search |
| 40 | + BObjectList<BSolverPackage> packages; |
| 41 | + status_t error = packageManager.Solver()->FindPackages(expression.Name(), |
| 42 | + BSolver::B_FIND_IN_NAME | BSolver::B_FIND_IN_PROVIDES, packages); |
| 43 | + if (error != B_OK) |
| 44 | + return B_ENTRY_NOT_FOUND; |
| 45 | + |
| 46 | + // find the newest matching package |
| 47 | + BSolverPackage* foundPackage = NULL; |
| 48 | + for (int32 i = 0; BSolverPackage* package = packages.ItemAt(i); i++) { |
| 49 | + if (package->Info().Matches(expression) |
| 50 | + && (foundPackage == NULL |
| 51 | + || package->Info().Version().Compare( |
| 52 | + foundPackage->Info().Version()) > 0)) { |
| 53 | + foundPackage = package; |
| 54 | + } |
| 55 | + } |
| 56 | + |
| 57 | + if (foundPackage == NULL) |
| 58 | + return B_ENTRY_NOT_FOUND; |
| 59 | + |
| 60 | + BString version = foundPackage->Info().Version().ToString(); |
| 61 | + _versionedPackageName = foundPackage->VersionedName(); |
| 62 | + return _versionedPackageName.IsEmpty() ? B_NO_MEMORY : B_OK; |
| 63 | +} |
| 64 | + |
| 65 | + |
| 66 | +BPathFinder::BPathFinder(const BResolvableExpression& expression, |
| 67 | + const char* dependency) |
| 68 | +{ |
| 69 | + SetTo(expression, dependency); |
| 70 | +} |
| 71 | + |
| 72 | + |
| 73 | +status_t |
| 74 | +BPathFinder::SetTo(const BResolvableExpression& expression, |
| 75 | + const char* dependency) |
| 76 | +{ |
| 77 | + BString versionedPackageName; |
| 78 | + fInitStatus = find_package(expression, versionedPackageName); |
| 79 | + if (fInitStatus != B_OK) |
| 80 | + return fInitStatus; |
| 81 | + |
| 82 | + BString packageLinksPath; |
| 83 | + packageLinksPath.SetToFormat(kSystemPackageLinksDirectory "/%s", |
| 84 | + versionedPackageName.String()); |
| 85 | + if (packageLinksPath.IsEmpty()) |
| 86 | + return fInitStatus = B_NO_MEMORY; |
| 87 | + |
| 88 | + struct stat st; |
| 89 | + if (lstat(packageLinksPath, &st) < 0) |
| 90 | + return fInitStatus = B_ENTRY_NOT_FOUND; |
| 91 | + |
| 92 | + return _SetTo(NULL, packageLinksPath, dependency); |
| 93 | +} |
0 commit comments