Create self package link

This commit is contained in:
Ingo Weinhold 2011-06-24 12:15:20 +02:00
parent 70c2780c73
commit 1d8edd93e2
2 changed files with 141 additions and 1 deletions

View File

@ -6,6 +6,9 @@
#include "PackageLinkDirectory.h"
#include <algorithm>
#include <new>
#include <AutoDeleter.h>
#include "EmptyAttributeDirectoryCookie.h"
@ -13,6 +16,126 @@
#include "PackageLinksListener.h"
#include "Utils.h"
#include "Version.h"
#include "Volume.h"
static const char* const kSelfLinkName = ".self";
static const char* const kSystemLinkPath = "../..";
static const char* const kCommonLinkPath = "../../../common";
static const char* const kHomeLinkPath = "../../../home/config";
static const char*
link_path_for_mount_type(MountType type)
{
switch (type) {
case MOUNT_TYPE_SYSTEM:
return kSystemLinkPath;
case MOUNT_TYPE_COMMON:
return kCommonLinkPath;
case MOUNT_TYPE_HOME:
return kHomeLinkPath;
case MOUNT_TYPE_CUSTOM:
default:
return "?";
}
}
// #pragma mark - SelfLink
class PackageLinkDirectory::SelfLink : public Node {
public:
SelfLink(Package* package)
:
Node(0),
fPackage(package),
fLinkPath(link_path_for_mount_type(
package->Domain()->Volume()->MountType()))
{
get_real_time(fModifiedTime);
}
virtual ~SelfLink()
{
}
virtual status_t Init(Directory* parent, const char* name)
{
return Node::Init(parent, name);
}
virtual mode_t Mode() const
{
return S_IFLNK | S_IRUSR | S_IXUSR | S_IRGRP | S_IXGRP | S_IROTH
| S_IXOTH;
}
virtual uid_t UserID() const
{
return 0;
}
virtual gid_t GroupID() const
{
return 0;
}
virtual timespec ModifiedTime() const
{
return fModifiedTime;
}
virtual off_t FileSize() const
{
return strlen(fLinkPath);
}
virtual status_t Read(off_t offset, void* buffer, size_t* bufferSize)
{
return B_BAD_VALUE;
}
virtual status_t Read(io_request* request)
{
return B_BAD_VALUE;
}
virtual status_t ReadSymlink(void* buffer, size_t* bufferSize)
{
size_t toCopy = std::min(strlen(fLinkPath), *bufferSize);
memcpy(buffer, fLinkPath, toCopy);
*bufferSize = toCopy;
return B_OK;
}
virtual status_t OpenAttributeDirectory(AttributeDirectoryCookie*& _cookie)
{
AttributeDirectoryCookie* cookie
= new(std::nothrow) EmptyAttributeDirectoryCookie;
if (cookie == NULL)
return B_NO_MEMORY;
_cookie = cookie;
return B_OK;
}
virtual status_t OpenAttribute(const char* name, int openMode,
AttributeCookie*& _cookie)
{
return B_ENTRY_NOT_FOUND;
}
private:
Package* fPackage;
timespec fModifiedTime;
const char* fLinkPath;
};
// #pragma mark - PackageLinkDirectory
PackageLinkDirectory::PackageLinkDirectory()
@ -26,12 +149,25 @@ PackageLinkDirectory::PackageLinkDirectory()
PackageLinkDirectory::~PackageLinkDirectory()
{
if (fSelfLink != NULL)
fSelfLink->ReleaseReference();
}
status_t
PackageLinkDirectory::Init(Directory* parent, Package* package)
{
// create the self link
fSelfLink = new(std::nothrow) SelfLink(package);
if (fSelfLink == NULL)
return B_NO_MEMORY;
status_t error = fSelfLink->Init(this, kSelfLinkName);
if (error != B_OK)
RETURN_ERROR(error);
AddChild(fSelfLink);
// compute the allocation size needed for the versioned name
size_t nameLength = strlen(package->Name());
size_t size = nameLength + 1;
@ -55,7 +191,7 @@ PackageLinkDirectory::Init(Directory* parent, Package* package)
}
// init the directory/node
status_t error = Init(parent, name);
error = Init(parent, name);
// TODO: This copies the name unnecessarily!
if (error != B_OK)
RETURN_ERROR(error);

View File

@ -40,9 +40,13 @@ public:
bool IsEmpty() const
{ return fPackages.IsEmpty(); }
private:
class SelfLink;
private:
timespec fModifiedTime;
PackageList fPackages;
SelfLink* fSelfLink;
};