packagefs: Add a .settings package symlink
It points to the settings directory appropriate for global settings. When a package is installed in ~/config, we cannot use the settings/ subdirectory for global settings, since then the files could clash with equally named user specific settings files (e.g. in case of ssh/known_hosts). So we use ~/config/settings/global for global settings instead.
This commit is contained in:
@@ -212,8 +212,11 @@ AddDirectoryToHaikuImage home mail draft ;
|
|||||||
AddDirectoryToHaikuImage home mail in ;
|
AddDirectoryToHaikuImage home mail in ;
|
||||||
AddDirectoryToHaikuImage home mail out ;
|
AddDirectoryToHaikuImage home mail out ;
|
||||||
|
|
||||||
AddSymlinkToHaikuImage home config settings : deskbar : be ;
|
# global settings when a package is installed in ~/config
|
||||||
|
AddDirectoryToHaikuImage home config settings global ;
|
||||||
|
|
||||||
# Deskbar Application links
|
# Deskbar Application links
|
||||||
|
AddSymlinkToHaikuImage home config settings : deskbar : be ;
|
||||||
AddDirectoryToHaikuImage home config settings deskbar Applications ;
|
AddDirectoryToHaikuImage home config settings deskbar Applications ;
|
||||||
DESKBAR_APPLICATIONS = ActivityMonitor CharacterMap CodyCam CDPlayer DeskCalc
|
DESKBAR_APPLICATIONS = ActivityMonitor CharacterMap CodyCam CDPlayer DeskCalc
|
||||||
Devices DiskProbe DriveSetup DiskUsage Expander Icon-O-Matic Installer
|
Devices DiskProbe DriveSetup DiskUsage Expander Icon-O-Matic Installer
|
||||||
|
|||||||
@@ -20,13 +20,15 @@
|
|||||||
|
|
||||||
|
|
||||||
static const char* const kSelfLinkName = ".self";
|
static const char* const kSelfLinkName = ".self";
|
||||||
|
static const char* const kSettingsLinkName = ".settings";
|
||||||
|
|
||||||
|
|
||||||
PackageLinkDirectory::PackageLinkDirectory()
|
PackageLinkDirectory::PackageLinkDirectory()
|
||||||
:
|
:
|
||||||
Directory(0),
|
Directory(0),
|
||||||
// the ID needs to be assigned later, when added to a volume
|
// the ID needs to be assigned later, when added to a volume
|
||||||
fSelfLink(NULL)
|
fSelfLink(NULL),
|
||||||
|
fSettingsLink(NULL)
|
||||||
{
|
{
|
||||||
get_real_time(fModifiedTime);
|
get_real_time(fModifiedTime);
|
||||||
}
|
}
|
||||||
@@ -36,6 +38,8 @@ PackageLinkDirectory::~PackageLinkDirectory()
|
|||||||
{
|
{
|
||||||
if (fSelfLink != NULL)
|
if (fSelfLink != NULL)
|
||||||
fSelfLink->ReleaseReference();
|
fSelfLink->ReleaseReference();
|
||||||
|
if (fSettingsLink != NULL)
|
||||||
|
fSettingsLink->ReleaseReference();
|
||||||
|
|
||||||
while (DependencyLink* link = fDependencyLinks.RemoveHead())
|
while (DependencyLink* link = fDependencyLinks.RemoveHead())
|
||||||
link->ReleaseReference();
|
link->ReleaseReference();
|
||||||
@@ -154,55 +158,32 @@ PackageLinkDirectory::_Update(PackageLinksListener* listener)
|
|||||||
{
|
{
|
||||||
// Always remove all dependency links -- if there's still a package, they
|
// Always remove all dependency links -- if there's still a package, they
|
||||||
// will be re-created below.
|
// will be re-created below.
|
||||||
while (DependencyLink* link = fDependencyLinks.RemoveHead()) {
|
while (DependencyLink* link = fDependencyLinks.RemoveHead())
|
||||||
NodeWriteLocker linkLocker(link);
|
_RemoveLink(link, listener);
|
||||||
if (listener != NULL)
|
|
||||||
listener->PackageLinkNodeRemoved(link);
|
|
||||||
|
|
||||||
RemoveChild(link);
|
|
||||||
linkLocker.Unlock();
|
|
||||||
link->ReleaseReference();
|
|
||||||
}
|
|
||||||
|
|
||||||
// check, if empty
|
// check, if empty
|
||||||
Package* package = fPackages.Head();
|
Package* package = fPackages.Head();
|
||||||
if (package == NULL) {
|
if (package == NULL) {
|
||||||
// remove self link, if any
|
// remove self and settings link
|
||||||
if (fSelfLink != NULL) {
|
_RemoveLink(fSelfLink, listener);
|
||||||
NodeWriteLocker selfLinkLocker(fSelfLink);
|
fSelfLink = NULL;
|
||||||
if (listener != NULL)
|
|
||||||
listener->PackageLinkNodeRemoved(fSelfLink);
|
|
||||||
|
|
||||||
RemoveChild(fSelfLink);
|
_RemoveLink(fSettingsLink, listener);
|
||||||
selfLinkLocker.Unlock();
|
fSettingsLink = NULL;
|
||||||
fSelfLink->ReleaseReference();
|
|
||||||
fSelfLink = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
// create/update self link
|
// create/update self and settings link
|
||||||
if (fSelfLink == NULL) {
|
status_t error = _CreateOrUpdateLink(fSelfLink, package,
|
||||||
fSelfLink = new(std::nothrow) Link(package);
|
Link::TYPE_INSTALLATION_LOCATION, kSelfLinkName, listener);
|
||||||
if (fSelfLink == NULL)
|
if (error != B_OK)
|
||||||
return B_NO_MEMORY;
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
status_t error = fSelfLink->Init(this, kSelfLinkName,
|
error = _CreateOrUpdateLink(fSettingsLink, package, Link::TYPE_SETTINGS,
|
||||||
NODE_FLAG_CONST_NAME);
|
kSettingsLinkName, listener);
|
||||||
if (error != B_OK)
|
if (error != B_OK)
|
||||||
RETURN_ERROR(error);
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
AddChild(fSelfLink);
|
|
||||||
|
|
||||||
if (listener != NULL) {
|
|
||||||
NodeWriteLocker selfLinkLocker(fSelfLink);
|
|
||||||
listener->PackageLinkNodeAdded(fSelfLink);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
NodeWriteLocker selfLinkLocker(fSelfLink);
|
|
||||||
fSelfLink->Update(package, listener);
|
|
||||||
}
|
|
||||||
|
|
||||||
// update the dependency links
|
// update the dependency links
|
||||||
return _UpdateDependencies(listener);
|
return _UpdateDependencies(listener);
|
||||||
@@ -256,3 +237,47 @@ PackageLinkDirectory::_UpdateDependencies(PackageLinksListener* listener)
|
|||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
PackageLinkDirectory::_RemoveLink(Link* link, PackageLinksListener* listener)
|
||||||
|
{
|
||||||
|
if (link != NULL) {
|
||||||
|
NodeWriteLocker linkLocker(link);
|
||||||
|
if (listener != NULL)
|
||||||
|
listener->PackageLinkNodeRemoved(link);
|
||||||
|
|
||||||
|
RemoveChild(link);
|
||||||
|
linkLocker.Unlock();
|
||||||
|
link->ReleaseReference();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
PackageLinkDirectory::_CreateOrUpdateLink(Link*& link, Package* package,
|
||||||
|
Link::Type type, const char* name, PackageLinksListener* listener)
|
||||||
|
{
|
||||||
|
if (link == NULL) {
|
||||||
|
link = new(std::nothrow) Link(package, type);
|
||||||
|
if (link == NULL)
|
||||||
|
return B_NO_MEMORY;
|
||||||
|
|
||||||
|
status_t error = link->Init(this, name, NODE_FLAG_CONST_NAME);
|
||||||
|
if (error != B_OK)
|
||||||
|
RETURN_ERROR(error);
|
||||||
|
|
||||||
|
AddChild(link);
|
||||||
|
|
||||||
|
if (listener != NULL) {
|
||||||
|
NodeWriteLocker lLinkLocker(link);
|
||||||
|
listener->PackageLinkNodeAdded(link);
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
NodeWriteLocker lLinkLocker(link);
|
||||||
|
link->Update(package, listener);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return B_OK;
|
||||||
|
}
|
||||||
|
|||||||
@@ -41,7 +41,7 @@ private:
|
|||||||
struct DependencyLink : public PackageLinkSymlink {
|
struct DependencyLink : public PackageLinkSymlink {
|
||||||
DependencyLink(Package* package)
|
DependencyLink(Package* package)
|
||||||
:
|
:
|
||||||
PackageLinkSymlink(package)
|
PackageLinkSymlink(package, TYPE_INSTALLATION_LOCATION)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,10 +58,18 @@ private:
|
|||||||
status_t _UpdateDependencies(
|
status_t _UpdateDependencies(
|
||||||
PackageLinksListener* listener);
|
PackageLinksListener* listener);
|
||||||
|
|
||||||
|
status_t _CreateOrUpdateLink(Link*& link,
|
||||||
|
Package* package, Link::Type type,
|
||||||
|
const char* name,
|
||||||
|
PackageLinksListener* listener);
|
||||||
|
void _RemoveLink(Link* link,
|
||||||
|
PackageLinksListener* listener);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
timespec fModifiedTime;
|
timespec fModifiedTime;
|
||||||
PackageList fPackages;
|
PackageList fPackages;
|
||||||
Link* fSelfLink;
|
Link* fSelfLink;
|
||||||
|
Link* fSettingsLink;
|
||||||
FamilyDependencyList fDependencyLinks;
|
FamilyDependencyList fDependencyLinks;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -17,27 +17,32 @@
|
|||||||
#include "Volume.h"
|
#include "Volume.h"
|
||||||
|
|
||||||
|
|
||||||
static const char* const kSystemLinkPath = "../..";
|
static const char* const kLinkPaths[PackageLinkSymlink::TYPE_ENUM_COUNT]
|
||||||
static const char* const kCommonLinkPath = "../../../common";
|
[PACKAGE_FS_MOUNT_TYPE_ENUM_COUNT] = {
|
||||||
static const char* const kHomeLinkPath = "../../../home/config";
|
{
|
||||||
|
"../..",
|
||||||
|
"../../../common",
|
||||||
|
"../../../home/config"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"../../../common/settings",
|
||||||
|
"../../../common/settings",
|
||||||
|
"../../../home/config/settings/global"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static const char* const kUnknownLinkTarget = "?";
|
static const char* const kUnknownLinkTarget = "?";
|
||||||
|
|
||||||
|
|
||||||
static const char*
|
static const char*
|
||||||
link_path_for_mount_type(MountType type)
|
link_path_for_mount_type(MountType mountType, PackageLinkSymlink::Type linkType)
|
||||||
{
|
{
|
||||||
switch (type) {
|
if (mountType < 0 || mountType >= PACKAGE_FS_MOUNT_TYPE_ENUM_COUNT
|
||||||
case PACKAGE_FS_MOUNT_TYPE_SYSTEM:
|
|| linkType < 0 || linkType >= PackageLinkSymlink::TYPE_ENUM_COUNT) {
|
||||||
return kSystemLinkPath;
|
return kUnknownLinkTarget;
|
||||||
case PACKAGE_FS_MOUNT_TYPE_COMMON:
|
|
||||||
return kCommonLinkPath;
|
|
||||||
case PACKAGE_FS_MOUNT_TYPE_HOME:
|
|
||||||
return kHomeLinkPath;
|
|
||||||
case PACKAGE_FS_MOUNT_TYPE_CUSTOM:
|
|
||||||
default:
|
|
||||||
return "?";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return kLinkPaths[linkType][mountType];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@@ -71,10 +76,11 @@ private:
|
|||||||
// #pragma mark - PackageLinkSymlink
|
// #pragma mark - PackageLinkSymlink
|
||||||
|
|
||||||
|
|
||||||
PackageLinkSymlink::PackageLinkSymlink(Package* package)
|
PackageLinkSymlink::PackageLinkSymlink(Package* package, Type type)
|
||||||
:
|
:
|
||||||
Node(0),
|
Node(0),
|
||||||
fLinkPath(kUnknownLinkTarget)
|
fLinkPath(kUnknownLinkTarget),
|
||||||
|
fType(type)
|
||||||
{
|
{
|
||||||
Update(package, NULL);
|
Update(package, NULL);
|
||||||
}
|
}
|
||||||
@@ -94,7 +100,7 @@ PackageLinkSymlink::Update(Package* package, PackageLinksListener* listener)
|
|||||||
fLinkPath = package->InstallPath();
|
fLinkPath = package->InstallPath();
|
||||||
if (fLinkPath == NULL) {
|
if (fLinkPath == NULL) {
|
||||||
fLinkPath = link_path_for_mount_type(
|
fLinkPath = link_path_for_mount_type(
|
||||||
package->Volume()->MountType());
|
package->Volume()->MountType(), fType);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
fLinkPath = kUnknownLinkTarget;
|
fLinkPath = kUnknownLinkTarget;
|
||||||
|
|||||||
@@ -15,7 +15,16 @@ class PackageLinksListener;
|
|||||||
|
|
||||||
class PackageLinkSymlink : public Node {
|
class PackageLinkSymlink : public Node {
|
||||||
public:
|
public:
|
||||||
PackageLinkSymlink(Package* package);
|
enum Type {
|
||||||
|
TYPE_INSTALLATION_LOCATION,
|
||||||
|
TYPE_SETTINGS,
|
||||||
|
|
||||||
|
TYPE_ENUM_COUNT
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
PackageLinkSymlink(Package* package,
|
||||||
|
Type type);
|
||||||
virtual ~PackageLinkSymlink();
|
virtual ~PackageLinkSymlink();
|
||||||
|
|
||||||
void Update(Package* package,
|
void Update(Package* package,
|
||||||
@@ -37,6 +46,7 @@ private:
|
|||||||
private:
|
private:
|
||||||
timespec fModifiedTime;
|
timespec fModifiedTime;
|
||||||
const char* fLinkPath;
|
const char* fLinkPath;
|
||||||
|
Type fType;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user