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