aboutsummaryrefslogtreecommitdiff
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/fs/morphos/abox-fs.cpp160
1 files changed, 132 insertions, 28 deletions
diff --git a/backends/fs/morphos/abox-fs.cpp b/backends/fs/morphos/abox-fs.cpp
index 17b6879f5e..e88eb19c00 100644
--- a/backends/fs/morphos/abox-fs.cpp
+++ b/backends/fs/morphos/abox-fs.cpp
@@ -24,8 +24,12 @@
#include <proto/dos.h>
#include <stdio.h>
+#include <sys/stat.h>
-#include "engines/engine.h"
+#include <common/stdafx.h>
+
+#include "common/util.h"
+#include "base/engine.h"
#include "backends/fs/abstract-fs.h"
/*
@@ -43,10 +47,13 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
public:
ABoxFilesystemNode();
ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL);
+ ABoxFilesystemNode(const String &p);
+ ABoxFilesystemNode(const ABoxFilesystemNode &node);
+
~ABoxFilesystemNode();
virtual String displayName() const { return _displayName; }
- virtual String name() const { return _displayName; }
+ virtual String name() const { return _displayName; };
virtual bool isValid() const { return _isValid; }
virtual bool isDirectory() const { return _isDirectory; }
virtual String path() const { return _path; }
@@ -54,7 +61,7 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
virtual bool listDir(AbstractFSList &list, ListMode mode) const;
static AbstractFSList listRoot();
virtual AbstractFilesystemNode *parent() const;
- virtual AbstractFilesystemNode *child(const String &n) const;
+ virtual AbstractFilesystemNode *child(const String &name) const;
};
@@ -62,6 +69,10 @@ AbstractFilesystemNode *AbstractFilesystemNode::getCurrentDirectory() {
return AbstractFilesystemNode::getRoot();
}
+AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
+ return new ABoxFilesystemNode(path);
+}
+
AbstractFilesystemNode *AbstractFilesystemNode::getRoot()
{
return new ABoxFilesystemNode();
@@ -83,28 +94,29 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
_lock = NULL;
for (;;)
{
- char n[bufsize];
- if (NameFromLock(lock, n, bufsize) != DOSFALSE)
+ char name[bufsize];
+ if (NameFromLock(lock, name, bufsize) != DOSFALSE)
{
- _path = n;
- _displayName = display_name ? display_name : FilePart(n);
+ _path = name;
+ _displayName = display_name ? display_name : FilePart(name);
break;
}
if (IoErr() != ERROR_LINE_TOO_LONG)
{
_isValid = false;
- warning("Error while retrieving path name: %d", IoErr());
+ debug(6, "Error while retrieving path name: %ld", IoErr());
return;
}
bufsize *= 2;
}
+ _isDirectory = false;
_isValid = false;
FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL);
if (fib == NULL)
{
- warning("Failed to allocate memory for FileInfoBlock");
+ debug(6, "Failed to allocate memory for FileInfoBlock");
return;
}
@@ -119,11 +131,79 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
_isValid = (_lock != NULL);
}
else
+ {
_isValid = true;
+ }
+ }
+ FreeDosObject(DOS_FIB, fib);
+}
+
+ABoxFilesystemNode::ABoxFilesystemNode(const String &p) {
+ int len = 0, offset = p.size();
+
+ assert(offset > 0);
+
+ _path = p;
+
+ // Extract last component from path
+ const char *str = p.c_str();
+ while (offset > 0 && (str[offset-1] == '/' || str[offset-1] == ':') )
+ offset--;
+ while (offset > 0 && (str[offset-1] != '/' && str[offset-1] != ':')) {
+ len++;
+ offset--;
+ }
+ _displayName = String(str + offset, len);
+ _lock = NULL;
+ _isDirectory = false;
+
+ struct FileInfoBlock *fib = (struct FileInfoBlock *)AllocDosObject(DOS_FIB, NULL);
+ if (!fib)
+ {
+ debug(6, "FileInfoBlock is NULL");
+ return;
+ }
+
+ // Check whether the node exists and if it is a directory
+
+ BPTR pLock = Lock((STRPTR)_path.c_str(), SHARED_LOCK);
+ if (pLock)
+ {
+ if (Examine(pLock, fib) != DOSFALSE) {
+ if (fib->fib_EntryType > 0)
+ {
+ _isDirectory = true;
+ _lock = DupLock(pLock);
+ _isValid = (_lock != 0);
+
+ // Add a trailing slash if it is needed
+ const char c = _path.lastChar();
+ if (c != '/' && c != ':')
+ _path += '/';
+
+ }
+ else
+ {
+ _isDirectory = false;
+ _isValid = true;
+ }
+ }
+
+ UnLock(pLock);
}
+
FreeDosObject(DOS_FIB, fib);
}
+ABoxFilesystemNode::ABoxFilesystemNode(const ABoxFilesystemNode& node)
+{
+ _displayName = node._displayName;
+ _isValid = node._isValid;
+ _isDirectory = node._isDirectory;
+ _path = node._path;
+ _lock = DupLock(node._lock);
+}
+
ABoxFilesystemNode::~ABoxFilesystemNode()
{
if (_lock)
@@ -136,10 +216,15 @@ ABoxFilesystemNode::~ABoxFilesystemNode()
bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
{
if (!_isValid)
- error("listDir() called on invalid node");
-
+ {
+ debug(6, "listDir() called on invalid node");
+ return false;
+ }
if (!_isDirectory)
- error("listDir() called on file node");
+ {
+ debug(6, "listDir() called on file node");
+ return false;
+ }
if (_lock == NULL)
{
@@ -153,7 +238,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
if (fib == NULL)
{
- warning("Failed to allocate memory for FileInfoBlock");
+ debug(6, "Failed to allocate memory for FileInfoBlock");
return false;
}
@@ -165,7 +250,8 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
String full_path;
BPTR lock;
- if ((fib->fib_EntryType > 0 && (mode & FilesystemNode::kListDirectoriesOnly)) ||
+ if ((mode == FilesystemNode::kListAll) ||
+ (fib->fib_EntryType > 0 && (mode & FilesystemNode::kListDirectoriesOnly)) ||
(fib->fib_EntryType < 0 && (mode & FilesystemNode::kListFilesOnly)))
{
full_path = _path;
@@ -173,7 +259,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
lock = Lock(full_path.c_str(), SHARED_LOCK);
if (lock)
{
- entry = new ABoxFilesystemNode(lock);
+ entry = new ABoxFilesystemNode(lock, fib->fib_FileName);
if (entry)
{
if (entry->isValid())
@@ -187,12 +273,12 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
}
if (IoErr() != ERROR_NO_MORE_ENTRIES)
- warning("Error while reading directory: %d", IoErr());
+ debug(6, "Error while reading directory: %ld", IoErr());
}
FreeDosObject(DOS_FIB, fib);
- return tree;
+ return true;
}
AbstractFilesystemNode *ABoxFilesystemNode::parent() const
@@ -200,11 +286,14 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
AbstractFilesystemNode *node = NULL;
if (!_isDirectory)
- error("parent() called on file node");
+ {
+ debug(6, "parent() called on file node");
+ return NULL;
+ }
if (_lock == NULL) {
/* Parent of the root is the root itself */
- node = 0;
+ return new ABoxFilesystemNode(*this);
} else {
BPTR parent_lock = ParentDir(_lock);
if (parent_lock) {
@@ -217,8 +306,24 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
return node;
}
-AbstractFilesystemNode *ABoxFilesystemNode::child(const String &n) const {
- TODO
+AbstractFilesystemNode *ABoxFilesystemNode::child(const String &name) const {
+ assert(_isDirectory);
+ String newPath(_path);
+
+ if (_path.lastChar() != '/')
+ newPath += '/';
+ newPath += name;
+
+ BPTR lock = Lock(newPath.c_str(), SHARED_LOCK);
+
+ if (!lock)
+ {
+ return 0;
+ }
+
+ UnLock(lock);
+
+ return new ABoxFilesystemNode(newPath);
}
AbstractFSList ABoxFilesystemNode::listRoot()
@@ -226,12 +331,11 @@ AbstractFSList ABoxFilesystemNode::listRoot()
AbstractFSList myList;
DosList *dosList;
CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
- char n[256];
+ char name[256];
dosList = LockDosList(lockDosListFlags);
if (dosList == NULL)
{
- warning("Could not lock dos list");
return myList;
}
@@ -248,13 +352,13 @@ AbstractFSList ABoxFilesystemNode::listRoot()
CONST_STRPTR device_name = (CONST_STRPTR)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;
BPTR volume_lock;
- strcpy(n, volume_name);
- strcat(n, ":");
- volume_lock = Lock(n, SHARED_LOCK);
+ strcpy(name, volume_name);
+ strcat(name, ":");
+ volume_lock = Lock(name, SHARED_LOCK);
if (volume_lock)
{
- sprintf(n, "%s (%s)", volume_name, device_name);
- entry = new ABoxFilesystemNode(volume_lock, n);
+ sprintf(name, "%s (%s)", volume_name, device_name);
+ entry = new ABoxFilesystemNode(volume_lock, name);
if (entry)
{
if (entry->isValid())