Boot loader BFS now has symbolic link support.

git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7516 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler
2004-05-11 12:16:26 +00:00
parent 450843b48f
commit ff76eb5cde
7 changed files with 152 additions and 7 deletions
@@ -1,16 +1,23 @@
/* /*
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved. ** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. ** Distributed under the terms of the OpenBeOS License.
*/ */
#include "Directory.h" #include "Directory.h"
#include "File.h" #include "File.h"
#include "Link.h"
#include <StorageDefs.h> #include <StorageDefs.h>
#include <KernelExport.h>
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
#include <string.h> #include <string.h>
#include <unistd.h>
// temp. private VFS API
extern Node *get_node_from(int fd);
namespace BFS { namespace BFS {
@@ -82,9 +89,25 @@ Directory::Lookup(const char *name, bool traverseLinks)
return NULL; return NULL;
Node *node = Stream::NodeFactory(fStream.GetVolume(), id); Node *node = Stream::NodeFactory(fStream.GetVolume(), id);
if (node->Type() == S_IFLNK) {
// ToDo: support links! if (S_ISLNK(node->Type())) {
// the node is a symbolic link, so we have to resolve the path
char linkPath[B_PATH_NAME_LENGTH];
((Link *)node)->ReadLink(linkPath, sizeof(linkPath));
delete node; delete node;
// we don't need this one anymore
int fd = open_from(this, linkPath, O_RDONLY);
if (fd >= 0) {
node = get_node_from(fd);
if (node != NULL)
node->Acquire();
close(fd);
return node;
}
return NULL; return NULL;
} }
@@ -1,5 +1,5 @@
/* /*
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved. ** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. ** Distributed under the terms of the OpenBeOS License.
*/ */
#ifndef FILE_H #ifndef FILE_H
@@ -30,7 +30,7 @@ class File : public Node {
virtual int32 Type() const; virtual int32 Type() const;
virtual off_t Size() const; virtual off_t Size() const;
private: protected:
Stream fStream; Stream fStream;
}; };
@@ -10,6 +10,7 @@ KernelStaticLibrary boot_bfs :
bfs.cpp bfs.cpp
Directory.cpp Directory.cpp
File.cpp File.cpp
Link.cpp
Stream.cpp Stream.cpp
BPlusTree.cpp BPlusTree.cpp
; ;
@@ -0,0 +1,66 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#include "Link.h"
#include <util/kernel_cpp.h>
namespace BFS {
Link::Link(Volume &volume, block_run run)
: File(volume, run)
{
}
Link::Link(Volume &volume, off_t id)
: File(volume, id)
{
}
Link::Link(const Stream &stream)
: File(stream)
{
}
status_t
Link::InitCheck()
{
return fStream.InitCheck();
}
status_t
Link::ReadLink(char *buffer, size_t bufferSize)
{
return fStream.ReadLink(buffer, bufferSize);
}
ssize_t
Link::ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize)
{
return B_NOT_ALLOWED;
}
ssize_t
Link::WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize)
{
return B_NOT_ALLOWED;
}
int32
Link::Type() const
{
return S_IFLNK;
}
} // namespace BFS
@@ -0,0 +1,33 @@
/*
** Copyright 2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License.
*/
#ifndef LINK_H
#define LINK_H
#include <boot/vfs.h>
#include "File.h"
namespace BFS {
class Link : public File {
public:
Link(Volume &volume, block_run run);
Link(Volume &volume, off_t id);
Link(const Stream &stream);
status_t InitCheck();
status_t ReadLink(char *buffer, size_t bufferSize);
virtual ssize_t ReadAt(void *cookie, off_t pos, void *buffer, size_t bufferSize);
virtual ssize_t WriteAt(void *cookie, off_t pos, const void *buffer, size_t bufferSize);
virtual int32 Type() const;
};
} // namespace BFS
#endif /* FILE_H */
@@ -1,6 +1,6 @@
/* Stream - inode stream access functions /* Stream - inode stream access functions
** **
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved. ** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. ** Distributed under the terms of the OpenBeOS License.
*/ */
@@ -8,6 +8,7 @@
#include "Stream.h" #include "Stream.h"
#include "Directory.h" #include "Directory.h"
#include "File.h" #include "File.h"
#include "Link.h"
#include <util/kernel_cpp.h> #include <util/kernel_cpp.h>
@@ -169,6 +170,21 @@ Stream::GetName(char *name, size_t size) const
} }
status_t
Stream::ReadLink(char *buffer, size_t bufferSize)
{
// link in the stream
if (Flags() & INODE_LONG_SYMLINK)
return ReadAt(0, (uint8 *)buffer, &bufferSize);
// link in the inode
strlcpy(buffer, short_symlink, bufferSize);
return B_OK;
}
status_t status_t
Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset) Stream::FindBlockRun(off_t pos, block_run &run, off_t &offset)
{ {
@@ -389,6 +405,9 @@ Stream::NodeFactory(Volume &volume, off_t id)
if (stream.IsContainer()) if (stream.IsContainer())
return new Directory(stream); return new Directory(stream);
if (stream.IsSymlink())
return new Link(stream);
return new File(stream); return new File(stream);
} }
@@ -1,6 +1,6 @@
/* Stream - inode stream access functions /* Stream - inode stream access functions
** **
** Copyright 2003, Axel Dörfler, [email protected]. All rights reserved. ** Copyright 2003-2004, Axel Dörfler, [email protected]. All rights reserved.
** Distributed under the terms of the OpenBeOS License. ** Distributed under the terms of the OpenBeOS License.
*/ */
#ifndef STREAM_H #ifndef STREAM_H
@@ -31,7 +31,10 @@ class Stream : public bfs_inode {
status_t GetName(char *name, size_t size) const; status_t GetName(char *name, size_t size) const;
off_t Size() const { return data.Size(); } off_t Size() const { return data.Size(); }
off_t ID() const { return fVolume.ToVnode(inode_num); } off_t ID() const { return fVolume.ToVnode(inode_num); }
status_t ReadLink(char *buffer, size_t bufferSize);
bool IsContainer() const { return Mode() & (S_IFDIR | S_INDEX_DIR | S_ATTR_DIR); } bool IsContainer() const { return Mode() & (S_IFDIR | S_INDEX_DIR | S_ATTR_DIR); }
bool IsSymlink() const { return S_ISLNK(Mode()); }
static Node *NodeFactory(Volume &volume, off_t id); static Node *NodeFactory(Volume &volume, off_t id);