Patch #1594533: morphos fs backend

svn-id: r24690
This commit is contained in:
Max Horn 2006-11-12 11:43:46 +00:00
parent b648aaf64b
commit fb795dabd0

View File

@ -24,8 +24,12 @@
#include <proto/dos.h> #include <proto/dos.h>
#include <stdio.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" #include "backends/fs/abstract-fs.h"
/* /*
@ -43,10 +47,13 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
public: public:
ABoxFilesystemNode(); ABoxFilesystemNode();
ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL); ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name = NULL);
ABoxFilesystemNode(const String &p);
ABoxFilesystemNode(const ABoxFilesystemNode &node);
~ABoxFilesystemNode(); ~ABoxFilesystemNode();
virtual String displayName() const { return _displayName; } 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 isValid() const { return _isValid; }
virtual bool isDirectory() const { return _isDirectory; } virtual bool isDirectory() const { return _isDirectory; }
virtual String path() const { return _path; } virtual String path() const { return _path; }
@ -54,7 +61,7 @@ class ABoxFilesystemNode : public AbstractFilesystemNode {
virtual bool listDir(AbstractFSList &list, ListMode mode) const; virtual bool listDir(AbstractFSList &list, ListMode mode) const;
static AbstractFSList listRoot(); static AbstractFSList listRoot();
virtual AbstractFilesystemNode *parent() const; 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(); return AbstractFilesystemNode::getRoot();
} }
AbstractFilesystemNode *AbstractFilesystemNode::getNodeForPath(const String &path) {
return new ABoxFilesystemNode(path);
}
AbstractFilesystemNode *AbstractFilesystemNode::getRoot() AbstractFilesystemNode *AbstractFilesystemNode::getRoot()
{ {
return new ABoxFilesystemNode(); return new ABoxFilesystemNode();
@ -83,28 +94,29 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
_lock = NULL; _lock = NULL;
for (;;) for (;;)
{ {
char n[bufsize]; char name[bufsize];
if (NameFromLock(lock, n, bufsize) != DOSFALSE) if (NameFromLock(lock, name, bufsize) != DOSFALSE)
{ {
_path = n; _path = name;
_displayName = display_name ? display_name : FilePart(n); _displayName = display_name ? display_name : FilePart(name);
break; break;
} }
if (IoErr() != ERROR_LINE_TOO_LONG) if (IoErr() != ERROR_LINE_TOO_LONG)
{ {
_isValid = false; _isValid = false;
warning("Error while retrieving path name: %d", IoErr()); debug(6, "Error while retrieving path name: %ld", IoErr());
return; return;
} }
bufsize *= 2; bufsize *= 2;
} }
_isDirectory = false;
_isValid = false; _isValid = false;
FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL); FileInfoBlock *fib = (FileInfoBlock*) AllocDosObject(DOS_FIB, NULL);
if (fib == NULL) if (fib == NULL)
{ {
warning("Failed to allocate memory for FileInfoBlock"); debug(6, "Failed to allocate memory for FileInfoBlock");
return; return;
} }
@ -119,11 +131,79 @@ ABoxFilesystemNode::ABoxFilesystemNode(BPTR lock, CONST_STRPTR display_name)
_isValid = (_lock != NULL); _isValid = (_lock != NULL);
} }
else else
{
_isValid = true; _isValid = true;
}
} }
FreeDosObject(DOS_FIB, fib); 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() ABoxFilesystemNode::~ABoxFilesystemNode()
{ {
if (_lock) if (_lock)
@ -136,10 +216,15 @@ ABoxFilesystemNode::~ABoxFilesystemNode()
bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
{ {
if (!_isValid) if (!_isValid)
error("listDir() called on invalid node"); {
debug(6, "listDir() called on invalid node");
return false;
}
if (!_isDirectory) if (!_isDirectory)
error("listDir() called on file node"); {
debug(6, "listDir() called on file node");
return false;
}
if (_lock == NULL) if (_lock == NULL)
{ {
@ -153,7 +238,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
if (fib == NULL) if (fib == NULL)
{ {
warning("Failed to allocate memory for FileInfoBlock"); debug(6, "Failed to allocate memory for FileInfoBlock");
return false; return false;
} }
@ -165,7 +250,8 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
String full_path; String full_path;
BPTR lock; 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))) (fib->fib_EntryType < 0 && (mode & FilesystemNode::kListFilesOnly)))
{ {
full_path = _path; full_path = _path;
@ -173,7 +259,7 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
lock = Lock(full_path.c_str(), SHARED_LOCK); lock = Lock(full_path.c_str(), SHARED_LOCK);
if (lock) if (lock)
{ {
entry = new ABoxFilesystemNode(lock); entry = new ABoxFilesystemNode(lock, fib->fib_FileName);
if (entry) if (entry)
{ {
if (entry->isValid()) if (entry->isValid())
@ -187,12 +273,12 @@ bool ABoxFilesystemNode::listDir(AbstractFSList &myList, ListMode mode) const
} }
if (IoErr() != ERROR_NO_MORE_ENTRIES) 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); FreeDosObject(DOS_FIB, fib);
return tree; return true;
} }
AbstractFilesystemNode *ABoxFilesystemNode::parent() const AbstractFilesystemNode *ABoxFilesystemNode::parent() const
@ -200,11 +286,14 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
AbstractFilesystemNode *node = NULL; AbstractFilesystemNode *node = NULL;
if (!_isDirectory) if (!_isDirectory)
error("parent() called on file node"); {
debug(6, "parent() called on file node");
return NULL;
}
if (_lock == NULL) { if (_lock == NULL) {
/* Parent of the root is the root itself */ /* Parent of the root is the root itself */
node = 0; return new ABoxFilesystemNode(*this);
} else { } else {
BPTR parent_lock = ParentDir(_lock); BPTR parent_lock = ParentDir(_lock);
if (parent_lock) { if (parent_lock) {
@ -217,8 +306,24 @@ AbstractFilesystemNode *ABoxFilesystemNode::parent() const
return node; return node;
} }
AbstractFilesystemNode *ABoxFilesystemNode::child(const String &n) const { AbstractFilesystemNode *ABoxFilesystemNode::child(const String &name) const {
TODO 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() AbstractFSList ABoxFilesystemNode::listRoot()
@ -226,12 +331,11 @@ AbstractFSList ABoxFilesystemNode::listRoot()
AbstractFSList myList; AbstractFSList myList;
DosList *dosList; DosList *dosList;
CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES; CONST ULONG lockDosListFlags = LDF_READ | LDF_VOLUMES;
char n[256]; char name[256];
dosList = LockDosList(lockDosListFlags); dosList = LockDosList(lockDosListFlags);
if (dosList == NULL) if (dosList == NULL)
{ {
warning("Could not lock dos list");
return myList; 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; CONST_STRPTR device_name = (CONST_STRPTR)((struct Task *)dosList->dol_Task->mp_SigTask)->tc_Node.ln_Name;
BPTR volume_lock; BPTR volume_lock;
strcpy(n, volume_name); strcpy(name, volume_name);
strcat(n, ":"); strcat(name, ":");
volume_lock = Lock(n, SHARED_LOCK); volume_lock = Lock(name, SHARED_LOCK);
if (volume_lock) if (volume_lock)
{ {
sprintf(n, "%s (%s)", volume_name, device_name); sprintf(name, "%s (%s)", volume_name, device_name);
entry = new ABoxFilesystemNode(volume_lock, n); entry = new ABoxFilesystemNode(volume_lock, name);
if (entry) if (entry)
{ {
if (entry->isValid()) if (entry->isValid())