find_path*(): Improve B_FIND_PATH_IMAGE_PATH handling
* get_file_attribute(): Use O_NOTRAVERSE, so we correctly read the attribute from symlinks. * internal_path_for_path(): Shuffle things around a bit: The dependency is resolved before handling B_FIND_PATH_PACKAGE_PATH, now. This adds support for getting the package file for a dependency. The dependency was ignored in this case before. * Use kSystemPackageLinksDirectory instead of hard-coding "/packages".
This commit is contained in:
@@ -385,7 +385,8 @@ static status_t
|
|||||||
get_file_attribute(const char* path, const char* attribute, char* nameBuffer,
|
get_file_attribute(const char* path, const char* attribute, char* nameBuffer,
|
||||||
size_t bufferSize)
|
size_t bufferSize)
|
||||||
{
|
{
|
||||||
int fd = fs_open_attr(path, attribute, B_STRING_TYPE, O_RDONLY);
|
int fd = fs_open_attr(path, attribute, B_STRING_TYPE,
|
||||||
|
O_RDONLY | O_NOTRAVERSE);
|
||||||
if (fd < 0)
|
if (fd < 0)
|
||||||
return errno;
|
return errno;
|
||||||
|
|
||||||
@@ -489,47 +490,13 @@ internal_path_for_path(char* referencePath, size_t referencePathSize,
|
|||||||
if (strcmp(architecture, __get_primary_architecture()) == 0)
|
if (strcmp(architecture, __get_primary_architecture()) == 0)
|
||||||
architecture = NULL;
|
architecture = NULL;
|
||||||
|
|
||||||
// normalize
|
|
||||||
status_t error = normalize_path(referencePath, referencePath,
|
|
||||||
referencePathSize);
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
// handle B_FIND_PATH_IMAGE_PATH
|
|
||||||
if (baseDirectory == B_FIND_PATH_IMAGE_PATH)
|
|
||||||
return copy_path(referencePath, pathBuffer, bufferSize);
|
|
||||||
|
|
||||||
// get the installation location
|
|
||||||
InstallationLocations* installationLocations = InstallationLocations::Get();
|
|
||||||
MethodDeleter<InstallationLocations> installationLocationsDeleter(
|
|
||||||
installationLocations, &InstallationLocations::Put);
|
|
||||||
|
|
||||||
size_t installationLocationIndex;
|
|
||||||
const char* installationLocation = installationLocations->LocationFor(
|
|
||||||
referencePath, installationLocationIndex);
|
|
||||||
if (installationLocation == NULL)
|
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
|
|
||||||
// Handle B_FIND_PATH_PACKAGE_PATH: get the package file name and
|
|
||||||
// simply adjust our arguments to look the package file up in the packages
|
|
||||||
// directory.
|
|
||||||
char packageName[B_FILE_NAME_LENGTH];
|
|
||||||
if (baseDirectory == B_FIND_PATH_PACKAGE_PATH) {
|
|
||||||
error = get_file_attribute(referencePath, "SYS:PACKAGE_FILE",
|
|
||||||
packageName, sizeof(packageName));
|
|
||||||
if (error != B_OK)
|
|
||||||
return error;
|
|
||||||
|
|
||||||
dependency = NULL;
|
|
||||||
subPath = packageName;
|
|
||||||
baseDirectory = B_FIND_PATH_PACKAGES_DIRECTORY;
|
|
||||||
flags = B_FIND_PATH_EXISTING_ONLY;
|
|
||||||
}
|
|
||||||
|
|
||||||
// resolve dependency
|
// resolve dependency
|
||||||
|
char packageName[B_FILE_NAME_LENGTH];
|
||||||
|
// Temporarily used here, permanently used below where
|
||||||
|
// B_FIND_PATH_PACKAGE_PATH is handled.
|
||||||
if (dependency != NULL) {
|
if (dependency != NULL) {
|
||||||
// get the versioned package name
|
// get the versioned package name
|
||||||
error = get_file_attribute(referencePath, "SYS:PACKAGE",
|
status_t error = get_file_attribute(referencePath, "SYS:PACKAGE",
|
||||||
packageName, sizeof(packageName));
|
packageName, sizeof(packageName));
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
@@ -541,25 +508,52 @@ internal_path_for_path(char* referencePath, size_t referencePathSize,
|
|||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
// Compute the path of the dependency symlink and normalize it. This
|
// Compute the path of the dependency symlink. This will yield the
|
||||||
// should yield the installation location path.
|
// installation location path when normalized.
|
||||||
if (snprintf(referencePath, referencePathSize, "/packages/%s/%s",
|
if (snprintf(referencePath, referencePathSize,
|
||||||
packageName, normalizedDependency)
|
kSystemPackageLinksDirectory "/%s/%s", packageName,
|
||||||
|
normalizedDependency)
|
||||||
>= (ssize_t)referencePathSize) {
|
>= (ssize_t)referencePathSize) {
|
||||||
return B_BUFFER_OVERFLOW;
|
return B_BUFFER_OVERFLOW;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error = normalize_path(referencePath, referencePath, referencePathSize);
|
// handle B_FIND_PATH_IMAGE_PATH
|
||||||
|
if (baseDirectory == B_FIND_PATH_IMAGE_PATH)
|
||||||
|
return copy_path(referencePath, pathBuffer, bufferSize);
|
||||||
|
|
||||||
|
// Handle B_FIND_PATH_PACKAGE_PATH: get the package file name and
|
||||||
|
// simply adjust our arguments to look the package file up in the packages
|
||||||
|
// directory.
|
||||||
|
if (baseDirectory == B_FIND_PATH_PACKAGE_PATH) {
|
||||||
|
status_t error = get_file_attribute(referencePath, "SYS:PACKAGE_FILE",
|
||||||
|
packageName, sizeof(packageName));
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
return error;
|
return error;
|
||||||
|
|
||||||
// get the installation location
|
dependency = NULL;
|
||||||
installationLocation = installationLocations->LocationFor(referencePath,
|
subPath = packageName;
|
||||||
installationLocationIndex);
|
baseDirectory = B_FIND_PATH_PACKAGES_DIRECTORY;
|
||||||
if (installationLocation == NULL)
|
flags = B_FIND_PATH_EXISTING_ONLY;
|
||||||
return B_ENTRY_NOT_FOUND;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// normalize
|
||||||
|
status_t error = normalize_path(referencePath, referencePath,
|
||||||
|
referencePathSize);
|
||||||
|
if (error != B_OK)
|
||||||
|
return error;
|
||||||
|
|
||||||
|
// get the installation location
|
||||||
|
InstallationLocations* installationLocations = InstallationLocations::Get();
|
||||||
|
MethodDeleter<InstallationLocations> installationLocationsDeleter(
|
||||||
|
installationLocations, &InstallationLocations::Put);
|
||||||
|
|
||||||
|
size_t installationLocationIndex;
|
||||||
|
const char* installationLocation = installationLocations->LocationFor(
|
||||||
|
referencePath, installationLocationIndex);
|
||||||
|
if (installationLocation == NULL)
|
||||||
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
// get base dir and process the path
|
// get base dir and process the path
|
||||||
const char* relativePath = get_relative_directory_path(
|
const char* relativePath = get_relative_directory_path(
|
||||||
installationLocationIndex, baseDirectory);
|
installationLocationIndex, baseDirectory);
|
||||||
|
|||||||
Reference in New Issue
Block a user