From ff76eb5cdeb9f4448961ed0367826862ea388f78 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Axel=20D=C3=B6rfler?= Date: Tue, 11 May 2004 12:16:26 +0000 Subject: [PATCH] Boot loader BFS now has symbolic link support. git-svn-id: file:///srv/svn/repos/haiku/trunk/current@7516 a95241bf-73f2-0310-859d-f6bbb57e9c96 --- .../loader/file_systems/bfs/Directory.cpp | 29 +++++++- .../boot/loader/file_systems/bfs/File.h | 4 +- .../boot/loader/file_systems/bfs/Jamfile | 1 + .../boot/loader/file_systems/bfs/Link.cpp | 66 +++++++++++++++++++ .../boot/loader/file_systems/bfs/Link.h | 33 ++++++++++ .../boot/loader/file_systems/bfs/Stream.cpp | 21 +++++- .../boot/loader/file_systems/bfs/Stream.h | 5 +- 7 files changed, 152 insertions(+), 7 deletions(-) create mode 100644 src/kernel/boot/loader/file_systems/bfs/Link.cpp create mode 100644 src/kernel/boot/loader/file_systems/bfs/Link.h diff --git a/src/kernel/boot/loader/file_systems/bfs/Directory.cpp b/src/kernel/boot/loader/file_systems/bfs/Directory.cpp index 81037ca2c0..69e2ac5358 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Directory.cpp +++ b/src/kernel/boot/loader/file_systems/bfs/Directory.cpp @@ -1,16 +1,23 @@ /* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ #include "Directory.h" #include "File.h" +#include "Link.h" #include +#include #include #include +#include + + +// temp. private VFS API +extern Node *get_node_from(int fd); namespace BFS { @@ -82,9 +89,25 @@ Directory::Lookup(const char *name, bool traverseLinks) return NULL; 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; + // 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; } diff --git a/src/kernel/boot/loader/file_systems/bfs/File.h b/src/kernel/boot/loader/file_systems/bfs/File.h index 55b34ee4a1..8cf0ab26cb 100644 --- a/src/kernel/boot/loader/file_systems/bfs/File.h +++ b/src/kernel/boot/loader/file_systems/bfs/File.h @@ -1,5 +1,5 @@ /* -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ #ifndef FILE_H @@ -30,7 +30,7 @@ class File : public Node { virtual int32 Type() const; virtual off_t Size() const; - private: + protected: Stream fStream; }; diff --git a/src/kernel/boot/loader/file_systems/bfs/Jamfile b/src/kernel/boot/loader/file_systems/bfs/Jamfile index 3011d7c0c0..f2b20e5d65 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Jamfile +++ b/src/kernel/boot/loader/file_systems/bfs/Jamfile @@ -10,6 +10,7 @@ KernelStaticLibrary boot_bfs : bfs.cpp Directory.cpp File.cpp + Link.cpp Stream.cpp BPlusTree.cpp ; diff --git a/src/kernel/boot/loader/file_systems/bfs/Link.cpp b/src/kernel/boot/loader/file_systems/bfs/Link.cpp new file mode 100644 index 0000000000..381abb9515 --- /dev/null +++ b/src/kernel/boot/loader/file_systems/bfs/Link.cpp @@ -0,0 +1,66 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ + + +#include "Link.h" + +#include + + +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 diff --git a/src/kernel/boot/loader/file_systems/bfs/Link.h b/src/kernel/boot/loader/file_systems/bfs/Link.h new file mode 100644 index 0000000000..167bfa07d6 --- /dev/null +++ b/src/kernel/boot/loader/file_systems/bfs/Link.h @@ -0,0 +1,33 @@ +/* +** Copyright 2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Distributed under the terms of the OpenBeOS License. +*/ +#ifndef LINK_H +#define LINK_H + + +#include + +#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 */ diff --git a/src/kernel/boot/loader/file_systems/bfs/Stream.cpp b/src/kernel/boot/loader/file_systems/bfs/Stream.cpp index a2caa11bff..bf0f7930f9 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Stream.cpp +++ b/src/kernel/boot/loader/file_systems/bfs/Stream.cpp @@ -1,6 +1,6 @@ /* Stream - inode stream access functions ** -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ @@ -8,6 +8,7 @@ #include "Stream.h" #include "Directory.h" #include "File.h" +#include "Link.h" #include @@ -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 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()) return new Directory(stream); + if (stream.IsSymlink()) + return new Link(stream); + return new File(stream); } diff --git a/src/kernel/boot/loader/file_systems/bfs/Stream.h b/src/kernel/boot/loader/file_systems/bfs/Stream.h index 264a90a0ad..908d0b4d14 100644 --- a/src/kernel/boot/loader/file_systems/bfs/Stream.h +++ b/src/kernel/boot/loader/file_systems/bfs/Stream.h @@ -1,6 +1,6 @@ /* Stream - inode stream access functions ** -** Copyright 2003, Axel Dörfler, axeld@pinc-software.de. All rights reserved. +** Copyright 2003-2004, Axel Dörfler, axeld@pinc-software.de. All rights reserved. ** Distributed under the terms of the OpenBeOS License. */ #ifndef STREAM_H @@ -31,7 +31,10 @@ class Stream : public bfs_inode { status_t GetName(char *name, size_t size) const; off_t Size() const { return data.Size(); } 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 IsSymlink() const { return S_ISLNK(Mode()); } static Node *NodeFactory(Volume &volume, off_t id);