1 /* 2 * Copyright 2013, Ingo Weinhold, ingo_weinhold@gmx.de. 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/.self", 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 } 94