find_path*(): Support user specific home directory
No longer hard-code the home directory path. Instead ask find_directory(), so we get the correct one for the current user.
This commit is contained in:
@@ -43,6 +43,7 @@
|
|||||||
#define kSystemTempDirectory "/boot/system/cache/tmp"
|
#define kSystemTempDirectory "/boot/system/cache/tmp"
|
||||||
#define kSystemVarDirectory "/boot/system/var"
|
#define kSystemVarDirectory "/boot/system/var"
|
||||||
#define kSystemLogDirectory "/boot/system/var/log"
|
#define kSystemLogDirectory "/boot/system/var/log"
|
||||||
|
#define kSystemNonpackagedDirectory "/boot/system/non-packaged"
|
||||||
#define kSystemNonpackagedAddonsDirectory "/boot/system/non-packaged/add-ons"
|
#define kSystemNonpackagedAddonsDirectory "/boot/system/non-packaged/add-ons"
|
||||||
#define kSystemNonpackagedBinDirectory "/boot/system/non-packaged/bin"
|
#define kSystemNonpackagedBinDirectory "/boot/system/non-packaged/bin"
|
||||||
#define kSystemNonpackagedLibDirectory "/boot/system/non-packaged/lib"
|
#define kSystemNonpackagedLibDirectory "/boot/system/non-packaged/lib"
|
||||||
@@ -54,6 +55,7 @@
|
|||||||
#define kUserLibDirectory "/boot/home/config/lib"
|
#define kUserLibDirectory "/boot/home/config/lib"
|
||||||
#define kUserPackagesDirectory "/boot/home/config/packages"
|
#define kUserPackagesDirectory "/boot/home/config/packages"
|
||||||
#define kUserSettingsDirectory "/boot/home/config/settings"
|
#define kUserSettingsDirectory "/boot/home/config/settings"
|
||||||
|
#define kUserNonpackagedDirectory "/boot/home/config/non-packaged"
|
||||||
#define kUserNonpackagedAddonsDirectory "/boot/home/config/non-packaged/add-ons"
|
#define kUserNonpackagedAddonsDirectory "/boot/home/config/non-packaged/add-ons"
|
||||||
#define kUserNonpackagedBinDirectory "/boot/home/config/non-packaged/bin"
|
#define kUserNonpackagedBinDirectory "/boot/home/config/non-packaged/bin"
|
||||||
#define kUserNonpackagedLibDirectory "/boot/home/config/non-packaged/lib"
|
#define kUserNonpackagedLibDirectory "/boot/home/config/non-packaged/lib"
|
||||||
|
|||||||
@@ -17,21 +17,13 @@
|
|||||||
|
|
||||||
#include <architecture_private.h>
|
#include <architecture_private.h>
|
||||||
#include <AutoDeleter.h>
|
#include <AutoDeleter.h>
|
||||||
|
#include <directories.h>
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
|
|
||||||
#include "PathBuffer.h"
|
#include "PathBuffer.h"
|
||||||
|
|
||||||
|
|
||||||
static const char* const kInstallationLocations[] = {
|
|
||||||
"/boot/home/config/non-packaged",
|
|
||||||
"/boot/home/config",
|
|
||||||
"/boot/system/non-packaged",
|
|
||||||
"/boot/system",
|
|
||||||
};
|
|
||||||
|
|
||||||
static size_t kHomeInstallationLocationIndex = 1;
|
static size_t kHomeInstallationLocationIndex = 1;
|
||||||
static size_t kInstallationLocationCount
|
|
||||||
= sizeof(kInstallationLocations) / sizeof(kInstallationLocations[0]);
|
|
||||||
|
|
||||||
static const path_base_directory kArchitectureSpecificBaseDirectories[] = {
|
static const path_base_directory kArchitectureSpecificBaseDirectories[] = {
|
||||||
B_FIND_PATH_ADD_ONS_DIRECTORY,
|
B_FIND_PATH_ADD_ONS_DIRECTORY,
|
||||||
@@ -45,6 +37,124 @@ static size_t kArchitectureSpecificBaseDirectoryCount =
|
|||||||
/ sizeof(kArchitectureSpecificBaseDirectories[0]);
|
/ sizeof(kArchitectureSpecificBaseDirectories[0]);
|
||||||
|
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
|
||||||
|
|
||||||
|
struct InstallationLocations {
|
||||||
|
public:
|
||||||
|
static const size_t kCount = 4;
|
||||||
|
|
||||||
|
public:
|
||||||
|
InstallationLocations()
|
||||||
|
:
|
||||||
|
fReferenceCount(1)
|
||||||
|
{
|
||||||
|
fLocations[0] = kUserNonpackagedDirectory;
|
||||||
|
fLocations[1] = kUserConfigDirectory;
|
||||||
|
fLocations[2] = kSystemNonpackagedDirectory;
|
||||||
|
fLocations[3] = kSystemDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
InstallationLocations(const char* home)
|
||||||
|
:
|
||||||
|
fReferenceCount(1)
|
||||||
|
{
|
||||||
|
static const char* const kNonPackagedSuffix = "/non-packaged";
|
||||||
|
char* homeNonPackaged
|
||||||
|
= (char*)malloc(strlen(home) + strlen(kNonPackagedSuffix) + 1);
|
||||||
|
fLocations[0] = homeNonPackaged;
|
||||||
|
if (homeNonPackaged != NULL) {
|
||||||
|
strcpy(homeNonPackaged, home);
|
||||||
|
strcat(homeNonPackaged, kNonPackagedSuffix);
|
||||||
|
}
|
||||||
|
|
||||||
|
fLocations[1] = strdup(home);
|
||||||
|
|
||||||
|
fLocations[2] = kSystemNonpackagedDirectory;
|
||||||
|
fLocations[3] = kSystemDirectory;
|
||||||
|
}
|
||||||
|
|
||||||
|
~InstallationLocations()
|
||||||
|
{
|
||||||
|
free(const_cast<char*>(fLocations[0]));
|
||||||
|
free(const_cast<char*>(fLocations[1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
bool IsValid() const
|
||||||
|
{
|
||||||
|
return fLocations[0] != NULL && fLocations[1] != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static InstallationLocations* Default()
|
||||||
|
{
|
||||||
|
char sBuffer[sizeof(InstallationLocations)];
|
||||||
|
InstallationLocations* sDefaultLocations
|
||||||
|
= new(&sBuffer) InstallationLocations;
|
||||||
|
return sDefaultLocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
static InstallationLocations* Get()
|
||||||
|
{
|
||||||
|
InstallationLocations* defaultLocations = Default();
|
||||||
|
|
||||||
|
// Get the home config installation location and create a new object,
|
||||||
|
// if it differs from the default.
|
||||||
|
char homeInstallationLocation[B_PATH_NAME_LENGTH];
|
||||||
|
if (__find_directory(B_USER_CONFIG_DIRECTORY, -1, false,
|
||||||
|
homeInstallationLocation, sizeof(homeInstallationLocation))
|
||||||
|
== B_OK) {
|
||||||
|
_kern_normalize_path(homeInstallationLocation, true,
|
||||||
|
homeInstallationLocation);
|
||||||
|
// failure is OK
|
||||||
|
if (strcmp(homeInstallationLocation,
|
||||||
|
defaultLocations->At(kHomeInstallationLocationIndex))
|
||||||
|
!= 0) {
|
||||||
|
InstallationLocations* locations
|
||||||
|
= new(std::nothrow) InstallationLocations(
|
||||||
|
homeInstallationLocation);
|
||||||
|
if (locations != NULL && locations->IsValid())
|
||||||
|
return locations;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
atomic_add(&defaultLocations->fReferenceCount, 1);
|
||||||
|
return defaultLocations;
|
||||||
|
}
|
||||||
|
|
||||||
|
void Put()
|
||||||
|
{
|
||||||
|
if (atomic_add(&fReferenceCount, -1) == 1)
|
||||||
|
delete this;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* At(size_t index) const
|
||||||
|
{
|
||||||
|
return fLocations[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
const char* LocationFor(const char* path, size_t& _index)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < kCount; i++) {
|
||||||
|
size_t length = strlen(fLocations[i]);
|
||||||
|
if (strncmp(path, fLocations[i], length) == 0
|
||||||
|
&& (path[length] == '/' || path[length] == '\0')) {
|
||||||
|
_index = i;
|
||||||
|
return fLocations[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
int32 fReferenceCount;
|
||||||
|
const char* fLocations[kCount];
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // unnamed namespace
|
||||||
|
|
||||||
|
|
||||||
/*! Returns the installation location relative path for the given base directory
|
/*! Returns the installation location relative path for the given base directory
|
||||||
constant and installation location index. A '%' in the returned path must be
|
constant and installation location index. A '%' in the returned path must be
|
||||||
replaced by "" for the primary architecture and by "/<arch>" for a secondary
|
replaced by "" for the primary architecture and by "/<arch>" for a secondary
|
||||||
@@ -271,22 +381,6 @@ normalize_longest_existing_path_prefix(const char* path, char* buffer,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static const char*
|
|
||||||
get_installation_location(const char* path, size_t& _index)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < kInstallationLocationCount; i++) {
|
|
||||||
size_t length = strlen(kInstallationLocations[i]);
|
|
||||||
if (strncmp(path, kInstallationLocations[i], length) == 0
|
|
||||||
&& (path[length] == '/' || path[length] == '\0')) {
|
|
||||||
_index = i;
|
|
||||||
return kInstallationLocations[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
static status_t
|
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)
|
||||||
@@ -406,9 +500,13 @@ internal_path_for_path(char* referencePath, size_t referencePathSize,
|
|||||||
return copy_path(referencePath, pathBuffer, bufferSize);
|
return copy_path(referencePath, pathBuffer, bufferSize);
|
||||||
|
|
||||||
// get the installation location
|
// get the installation location
|
||||||
|
InstallationLocations* installationLocations = InstallationLocations::Get();
|
||||||
|
MethodDeleter<InstallationLocations> installationLocationsDeleter(
|
||||||
|
installationLocations, &InstallationLocations::Put);
|
||||||
|
|
||||||
size_t installationLocationIndex;
|
size_t installationLocationIndex;
|
||||||
const char* installationLocation = get_installation_location(referencePath,
|
const char* installationLocation = installationLocations->LocationFor(
|
||||||
installationLocationIndex);
|
referencePath, installationLocationIndex);
|
||||||
if (installationLocation == NULL)
|
if (installationLocation == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
|
|
||||||
@@ -456,7 +554,7 @@ internal_path_for_path(char* referencePath, size_t referencePathSize,
|
|||||||
return error;
|
return error;
|
||||||
|
|
||||||
// get the installation location
|
// get the installation location
|
||||||
installationLocation = get_installation_location(referencePath,
|
installationLocation = installationLocations->LocationFor(referencePath,
|
||||||
installationLocationIndex);
|
installationLocationIndex);
|
||||||
if (installationLocation == NULL)
|
if (installationLocation == NULL)
|
||||||
return B_ENTRY_NOT_FOUND;
|
return B_ENTRY_NOT_FOUND;
|
||||||
@@ -569,23 +667,28 @@ __find_paths_etc(const char* architecture, path_base_directory baseDirectory,
|
|||||||
|
|
||||||
size_t subPathLength = subPath != NULL ? strlen(subPath) + 1 : 0;
|
size_t subPathLength = subPath != NULL ? strlen(subPath) + 1 : 0;
|
||||||
|
|
||||||
|
// get the installation locations
|
||||||
|
InstallationLocations* installationLocations = InstallationLocations::Get();
|
||||||
|
MethodDeleter<InstallationLocations> installationLocationsDeleter(
|
||||||
|
installationLocations, &InstallationLocations::Put);
|
||||||
|
|
||||||
// Get the relative paths and compute the total size to allocate.
|
// Get the relative paths and compute the total size to allocate.
|
||||||
const char* relativePaths[kInstallationLocationCount];
|
const char* relativePaths[InstallationLocations::kCount];
|
||||||
size_t totalSize = 0;
|
size_t totalSize = 0;
|
||||||
|
|
||||||
for (size_t i = 0; i < kInstallationLocationCount; i++) {
|
for (size_t i = 0; i < InstallationLocations::kCount; i++) {
|
||||||
relativePaths[i] = get_relative_directory_path(i, baseDirectory);
|
relativePaths[i] = get_relative_directory_path(i, baseDirectory);
|
||||||
if (relativePaths[i] == NULL)
|
if (relativePaths[i] == NULL)
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
|
|
||||||
totalSize += strlen(kInstallationLocations[i])
|
totalSize += strlen(installationLocations->At(i))
|
||||||
+ strlen(relativePaths[i]) + subPathLength + 1;
|
+ strlen(relativePaths[i]) + subPathLength + 1;
|
||||||
if (strchr(relativePaths[i], '%') != NULL)
|
if (strchr(relativePaths[i], '%') != NULL)
|
||||||
totalSize += architectureSize - 1;
|
totalSize += architectureSize - 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
// allocate storage
|
// allocate storage
|
||||||
char** paths = (char**)malloc(sizeof(char*) * kInstallationLocationCount
|
char** paths = (char**)malloc(sizeof(char*) * InstallationLocations::kCount
|
||||||
+ totalSize);
|
+ totalSize);
|
||||||
if (paths == NULL)
|
if (paths == NULL)
|
||||||
return B_NO_MEMORY;
|
return B_NO_MEMORY;
|
||||||
@@ -593,10 +696,10 @@ __find_paths_etc(const char* architecture, path_base_directory baseDirectory,
|
|||||||
|
|
||||||
// construct and process the paths
|
// construct and process the paths
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
char* pathBuffer = (char*)(paths + kInstallationLocationCount);
|
char* pathBuffer = (char*)(paths + InstallationLocations::kCount);
|
||||||
const char* pathBufferEnd = pathBuffer + totalSize;
|
const char* pathBufferEnd = pathBuffer + totalSize;
|
||||||
for (size_t i = 0; i < kInstallationLocationCount; i++) {
|
for (size_t i = 0; i < InstallationLocations::kCount; i++) {
|
||||||
ssize_t pathSize = process_path(kInstallationLocations[i],
|
ssize_t pathSize = process_path(installationLocations->At(i),
|
||||||
architecture, relativePaths[i], subPath, flags, pathBuffer,
|
architecture, relativePaths[i], subPath, flags, pathBuffer,
|
||||||
pathBufferEnd - pathBuffer);
|
pathBufferEnd - pathBuffer);
|
||||||
if (pathSize < 0)
|
if (pathSize < 0)
|
||||||
@@ -631,9 +734,13 @@ __guess_secondary_architecture_from_path(const char* path,
|
|||||||
}
|
}
|
||||||
|
|
||||||
// get an installation location relative path
|
// get an installation location relative path
|
||||||
|
InstallationLocations* installationLocations = InstallationLocations::Get();
|
||||||
|
MethodDeleter<InstallationLocations> installationLocationsDeleter(
|
||||||
|
installationLocations, &InstallationLocations::Put);
|
||||||
|
|
||||||
size_t installationLocationIndex;
|
size_t installationLocationIndex;
|
||||||
const char* installationLocation = get_installation_location(prefix,
|
const char* installationLocation = installationLocations->LocationFor(
|
||||||
installationLocationIndex);
|
prefix, installationLocationIndex);
|
||||||
if (installationLocation == NULL)
|
if (installationLocation == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user