tVFS_Node *NativeFS_Mount(const char *Device, const char **Arguments);\r
void NativeFS_Unmount(tVFS_Node *Node);\r
tVFS_Node *NativeFS_FindDir(tVFS_Node *Node, const char *Name);\r
-char *NativeFS_ReadDir(tVFS_Node *Node, int Position);\r
+ int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX]);\r
size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer);\r
size_t NativeFS_Write(tVFS_Node *Node, _acess_off_t Offset, size_t Length, const void *Buffer);\r
void NativeFS_Close(tVFS_Node *Node);\r
return Inode_CacheNode(info->InodeHandle, &baseRet);\r
}\r
\r
-char *NativeFS_ReadDir(tVFS_Node *Node, int Position)\r
+int NativeFS_ReadDir(tVFS_Node *Node, int Position, char Dest[FILENAME_MAX])\r
{\r
struct dirent *ent;\r
DIR *dp = (void*)(tVAddr)Node->Inode;\r
- char *ret;\r
\r
ENTER("pNode iPosition", Node, Position);\r
\r
} while(Position-- && ent);\r
\r
if( !ent ) {\r
- LEAVE('n');\r
- return NULL;\r
+ LEAVE('i', -ENOENT);\r
+ return -ENOENT;\r
}\r
\r
- ret = strdup(ent->d_name);\r
+ strncpy(Dest, ent->d_name, FILENAME_MAX);\r
\r
// TODO: Unlock node \r
\r
- LEAVE('s', ret);\r
- return ret;\r
+ LEAVE('i', 0);\r
+ return 0;\r
}\r
\r
size_t NativeFS_Read(tVFS_Node *Node, _acess_off_t Offset, size_t Length, void *Buffer)\r
// === PROTOTYPES ===
int FIFO_Install(char **Arguments);
int FIFO_IOCtl(tVFS_Node *Node, int Id, void *Data);
-char *FIFO_ReadDir(tVFS_Node *Node, int Id);
+ int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
tVFS_Node *FIFO_FindDir(tVFS_Node *Node, const char *Filename);
- int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
void FIFO_Reference(tVFS_Node *Node);
void FIFO_Close(tVFS_Node *Node);
int FIFO_Unlink(tVFS_Node *Node, const char *OldName);
* \fn char *FIFO_ReadDir(tVFS_Node *Node, int Id)
* \brief Reads from the FIFO root
*/
-char *FIFO_ReadDir(tVFS_Node *Node, int Id)
+int FIFO_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX])
{
tPipe *tmp = gFIFO_NamedPipes;
// Entry 0 is Anon Pipes
- if(Id == 0) return strdup("anon");
+ if(Id == 0) {
+ strcpy(Dest, "anon");
+ return 0;
+ }
// Find the id'th node
while(--Id && tmp) tmp = tmp->Next;
- // If node found, return it
- if(tmp) return strdup(tmp->Name);
- // else error return
- return NULL;
+ // If the list ended, error return
+ if(!tmp)
+ return -EINVAL;
+ // Return good
+ strncpy(Dest, tmp->Name, FILENAME_MAX);
+ return 0;
}
/**
/**
* \fn int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
*/
-int FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *FIFO_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
{
return 0;
}
int PCI_Install(char **Arguments);\r
int PCI_ScanBus(int ID, int bFill);\r
\r
-char *PCI_int_ReadDirRoot(tVFS_Node *node, int pos);\r
+ int PCI_int_ReadDirRoot(tVFS_Node *node, int pos, char Dest[FILENAME_MAX]);\r
tVFS_Node *PCI_int_FindDirRoot(tVFS_Node *node, const char *filename);\r
Uint32 PCI_int_GetBusAddr(Uint16 Bus, Uint16 Slot, Uint16 Fcn, Uint8 Offset);\r
size_t PCI_int_ReadDevice(tVFS_Node *node, off_t Offset, size_t Length, void *buffer);\r
/**\r
* \brief Read from Root of PCI Driver\r
*/\r
-char *PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos)\r
+int PCI_int_ReadDirRoot(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])\r
{\r
ENTER("pNode iPos", Node, Pos);\r
if(Pos < 0 || Pos >= giPCI_DeviceCount) {\r
- LEAVE('n');\r
- return NULL;\r
+ LEAVE_RET('i', -EINVAL);\r
}\r
\r
- LEAVE('s', gPCI_Devices[Pos].Name);\r
- return strdup( gPCI_Devices[Pos].Name );\r
+ LOG("Name = %s", gPCI_Devices[Pos].Name);\r
+ strncpy(Dest, gPCI_Devices[Pos].Name, FILENAME_MAX);\r
+ LEAVE_RET('i', 0);\r
}\r
/**\r
*/\r
int SysFS_RemoveFile(int ID);
#endif
-char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Id);
+ int SysFS_Comm_ReadDir(tVFS_Node *Node, int Id, char Dest[FILENAME_MAX]);
tVFS_Node *SysFS_Comm_FindDir(tVFS_Node *Node, const char *Filename);
size_t SysFS_Comm_ReadFile(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
void SysFS_Comm_CloseFile(tVFS_Node *Node);
* \fn char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos)
* \brief Reads from a SysFS directory
*/
-char *SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos)
+int SysFS_Comm_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tSysFS_Ent *child = (tSysFS_Ent*)Node->ImplPtr;
- if(Pos < 0 || (Uint64)Pos >= Node->Size) return NULL;
+ if(Pos < 0 || (Uint64)Pos >= Node->Size)
+ return -EINVAL;
for( ; child; child = child->Next, Pos-- )
{
- if( Pos == 0 ) return strdup(child->Name);
+ if( Pos == 0 ) {
+ strncpy(Dest, child->Name, FILENAME_MAX);
+ return 0;
+ }
}
- return NULL;
+ return -ENOENT;
}
/**
// === PROTOTYPES ===
int VT_Install(char **Arguments);
-char *VT_ReadDir(tVFS_Node *Node, int Pos);
+ int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *VT_FindDir(tVFS_Node *Node, const char *Name);
int VT_Root_IOCtl(tVFS_Node *Node, int Id, void *Data);
size_t VT_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
* \fn char *VT_ReadDir(tVFS_Node *Node, int Pos)
* \brief Read from the VTerm Directory
*/
-char *VT_ReadDir(tVFS_Node *Node, int Pos)
+int VT_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- if(Pos < 0) return NULL;
- if(Pos >= NUM_VTS) return NULL;
- return strdup( gVT_Terminals[Pos].Name );
+ if(Pos < 0) return -EINVAL;
+ if(Pos >= NUM_VTS) return -EINVAL;
+ strncpy(Dest, gVT_Terminals[Pos].Name, FILENAME_MAX);
+ return 0;
}
/**
extern char *_strdup(const char *File, int Line, const char *Str);
extern char **str_split(const char *__str, char __ch);
extern char *strchr(const char *__s, int __c);
+extern char *strrchr(const char *__s, int __c);
extern int strpos(const char *Str, char Ch);
extern int strpos8(const char *str, Uint32 search);
extern void itoa(char *buf, Uint64 num, int base, int minLength, char pad);
EEXIST, // Already exists
ENFILE, // Too many open files
ENOTDIR, // Not a directory
+ EIO, // IO Error
EALREADY, // Operation was a NOP
EINTERNAL, // Internal Error
* \brief Read from a directory
* \param Node Pointer to this node
* \param Pos Offset in the directory
- * \return Pointer to the name of the item on the heap (will be freed
- * by the caller). If the directory end has been reached, NULL
- * will be returned.
- * If an item is required to be skipped either &::NULLNode,
- * ::VFS_SKIP or ::VFS_SKIPN(0...1023) will be returned.
+ * \param Dest Destination for filename
+ * \return Zero on success, negative on error or +ve for ignore entry
*/
- char *(*ReadDir)(struct sVFS_Node *Node, int Pos);
+ int (*ReadDir)(struct sVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
/**
* \brief Create a node in a directory
* \param Node Pointer to this node
* \param Name Name of the new child
* \param Flags Flags to apply to the new child (directory or symlink)
- * \return Zero on Success, non-zero on error (see errno.h)
+ * \return Created node or NULL on error
*/
- int (*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
+ tVFS_Node *(*MkNod)(struct sVFS_Node *Node, const char *Name, Uint Flags);
/**
* \brief Relink (Rename/Remove) a file/directory
typedef Uint32 tMount;
// === CONSTANTS ===
+#define FILENAME_MAX 256
//! Maximum size of a Memory Path generated by VFS_GetMemPath
#define VFS_MEMPATH_SIZE (3 + (BITS/4)*2)
/**
/**
* \brief Read from a directory
* \param FD File handle returned by ::VFS_Open
- * \param Dest Destination array for the file name (max 255 bytes)
+ * \param Dest Destination array for the file name (max FILENAME_MAX bytes)
* \return Boolean Success
*/
-extern int VFS_ReadDir(int FD, char *Dest);
+extern int VFS_ReadDir(int FD, char Dest[FILENAME_MAX]);
/**
* \brief Wait for an aciton on a file descriptor
* \param MaxHandle Maximum set handle in \a *Handles
EXPORT(strucmp);
EXPORT(strchr);
+EXPORT(strrchr);
EXPORT(strpos);
EXPORT(strlen);
EXPORT(strcpy);
return NULL;
}
+char *strrchr(const char *__s, int __c)
+{
+ size_t ofs = strlen(__s);
+ while(--ofs && __s[ofs] != __c);
+ if( __s[ofs] == __c )
+ return (char*)__s + ofs;
+ return NULL;
+}
+
/**
* \fn int strpos(const char *Str, char Ch)
* \brief Search a string for an ascii character
int pos = 0, oldpos = 0;
int next = 0;
tVFS_Node *parent;
- int ret;
+ tVFS_Node *ret;
ENTER("sPath xFlags", Path, Flags);
// Create node
ret = parent->Type->MkNod(parent, name, Flags);
+ _CloseNode(ret);
// Free allocated string
free(absPath);
_CloseNode(parent);
// Return whatever the driver said
- LEAVE('i', ret);
- return ret;
+ LEAVE('i', ret==NULL);
+ return ret==NULL;
}
/**
int VFS_ReadDir(int FD, char *Dest)
{
tVFS_Handle *h = VFS_GetHandle(FD);
- char *tmp;
+ int rv;
//ENTER("ph pDest", h, Dest);
}
do {
- tmp = h->Node->Type->ReadDir(h->Node, h->Position);
- if((Uint)tmp < (Uint)VFS_MAXSKIP)
- h->Position += (Uint)tmp;
+ rv = h->Node->Type->ReadDir(h->Node, h->Position, Dest);
+ if(rv > 0)
+ h->Position += rv;
else
h->Position ++;
- } while(tmp != NULL && (Uint)tmp < (Uint)VFS_MAXSKIP);
+ } while(rv > 0);
- //LOG("tmp = '%s'", tmp);
-
- if(!tmp) {
+ if(rv < 0) {
//LEAVE('i', 0);
return 0;
}
- strcpy(Dest, tmp);
- free(tmp);
-
//LEAVE('i', 1);
return 1;
}
#endif
tVFS_Node *DevFS_InitDevice(const char *Device, const char **Options);
void DevFS_Unmount(tVFS_Node *RootNode);
-char *DevFS_ReadDir(tVFS_Node *Node, int Pos);
+ int DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *DevFS_FindDir(tVFS_Node *Node, const char *Name);
// === GLOBALS ===
/**
* \fn char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
*/
-char *DevFS_ReadDir(tVFS_Node *Node, int Pos)
+int DevFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tDevFS_Driver *dev;
- if(Pos < 0) return NULL;
+ if(Pos < 0) return -EINVAL;
for(dev = gDevFS_Drivers;
dev && Pos--;
dev = dev->Next
);
- if(dev)
- return strdup(dev->Name);
- else
- return NULL;
+ if(dev) {
+ strncpy(Dest, dev->Name, FILENAME_MAX);
+ return 0;
+ }
+ else {
+ return -ENOENT;
+ }
}
/**
// === PROTOTYPES ===
tVFS_Node *Root_InitDevice(const char *Device, const char **Options);
- int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
tVFS_Node *Root_FindDir(tVFS_Node *Node, const char *Name);
-char *Root_ReadDir(tVFS_Node *Node, int Pos);
+ int Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
size_t Root_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
size_t Root_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
tRamFS_File *Root_int_AllocFile(void);
* \fn int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
* \brief Create an entry in the root directory
*/
-int Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *Root_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
{
tRamFS_File *parent = Node->ImplPtr;
tRamFS_File *child;
ENTER("pNode sName xFlags", Node, Name, Flags);
LOG("Sanity check name length - %i > %i", strlen(Name)+1, sizeof(child->Name));
- if(strlen(Name) + 1 > sizeof(child->Name))
- LEAVE_RET('i', EINVAL);
+ if(strlen(Name) + 1 > sizeof(child->Name)) {
+ errno = EINVAL;
+ LEAVE_RET('n', NULL);
+ }
// Find last child, while we're at it, check for duplication
for( child = parent->Data.FirstChild; child; prev = child, child = child->Next )
{
if(strcmp(child->Name, Name) == 0) {
LOG("Duplicate");
- LEAVE('i', EEXIST);
- return EEXIST;
+ errno = EEXIST;
+ LEAVE_RET('n', NULL);
}
}
parent->Node.Size ++;
- LEAVE('i', EOK);
- return EOK;
+ LEAVE('n', &child->Node);
+ return &child->Node;
}
/**
* \fn char *Root_ReadDir(tVFS_Node *Node, int Pos)
* \brief Get an entry from the filesystem
*/
-char *Root_ReadDir(tVFS_Node *Node, int Pos)
+int Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tRamFS_File *parent = Node->ImplPtr;
tRamFS_File *child = parent->Data.FirstChild;
for( ; child && Pos--; child = child->Next ) ;
- if(child) return strdup(child->Name);
+ if(child) {
+ strncpy(Dest, child->Name, FILENAME_MAX);
+ return 0;
+ }
- return NULL;
+ return -ENOENT;
}
/**
if( !node && (Flags & VFS_OPENFLAG_CREATE) )
{
// TODO: Translate `Mode` into ACL and node flags
- // Get parent, create node
- if( VFS_MkNod(absPath, 0) ) {
+ Uint new_flags = 0;
+
+ // Split path at final separator
+ char *file = strrchr(absPath, '/');
+ *file = '\0';
+ file ++;
+
+ // Get parent node
+ tVFS_Mount *pmnt;
+ tVFS_Node *pnode = VFS_ParsePath(absPath, NULL, &pmnt);
+ if(!pnode) {
+ LOG("Unable to open parent '%s'", absPath);
+ free(absPath);
+ errno = ENOENT;
+ LEAVE_RET('i', -1);
+ }
+
+ // TODO: Check ACLs on the parent
+ if( !VFS_CheckACL(pnode, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
+ _CloseNode(pnode);
+ pmnt->OpenHandleCount --;
free(absPath);
+ LEAVE('i', -1);
return -1;
}
- node = VFS_ParsePath(absPath, NULL, &mnt);
+
+ // Check that there's a MkNod method
+ if( !pnode->Type || !pnode->Type->MkNod ) {
+ Log_Warning("VFS", "VFS_Open - Directory has no MkNod method");
+ errno = EINVAL;
+ LEAVE_RET('i', -1);
+ }
+
+ node = pnode->Type->MkNod(pnode, file, new_flags);
+ // Fall through on error check
+
+ _CloseNode(pnode);
+ pmnt->OpenHandleCount --;
}
// Free generated path
* dir.c
* - Directory Handling
*/
-#define DEBUG 0
+#define DEBUG 1
#define VERBOSE 0
#include "ext2_common.h"
#define BLOCK_DIR_OFS(_data, _block) (((Uint16*)(_data))[(_block)])
// === PROTOTYPES ===
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+ int Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
- int Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
int Ext2_Unlink(tVFS_Node *Node, const char *OldName);
int Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
// --- Helpers ---
* \param Node Directory node
* \param Pos Position of desired element
*/
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
+int Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tExt2_Inode inode;
tExt2_DirEnt dirent;
// Check for the end of the list
if(size <= 0 || size > inode.i_size) {
- LEAVE('n');
- return NULL;
+ LEAVE('i', -ENOENT);
+ return -ENOENT;
}
// Read Entry
dirent.name[ dirent.name_len ] = '\0'; // Cap off string
if( dirent.name_len == 0 ) {
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP;
+ LEAVE('i', 1);
+ return 1;
}
// Ignore . and .. (these are done in the VFS)
if( (dirent.name[0] == '.' && dirent.name[1] == '\0')
|| (dirent.name[0] == '.' && dirent.name[1] == '.' && dirent.name[2]=='\0')) {
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP; // Skip
+ LEAVE('i', 1);
+ return 1; // Skip
}
- LEAVE('s', dirent.name);
- // Create new node
- return strdup(dirent.name);
+ LOG("Name '%s'", dirent.name);
+ strncpy(Dest, dirent.name, FILENAME_MAX);
+ LEAVE('i', 0);
+ return 0;
}
/**
* \fn int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
* \brief Create a new node
*/
-int Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
+tVFS_Node *Ext2_MkNod(tVFS_Node *Parent, const char *Name, Uint Flags)
{
ENTER("pParent sName xFlags", Parent, Name, Flags);
Uint64 inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
if( inodeNum == 0 ) {
LOG("Inode allocation failed");
- LEAVE('i', -1);
- return -1;
+ LEAVE_RET('n', NULL);
}
tVFS_Node *child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
if( !child ) {
Ext2_int_DereferenceInode(Parent->ImplPtr, inodeNum);
Log_Warning("Ext2", "Ext2_MkNod - Node creation failed");
- LEAVE('i', -1);
- return -1;
+ LEAVE_RET('n', NULL);
}
child->Flags = Flags & (VFS_FFLAG_DIRECTORY|VFS_FFLAG_SYMLINK|VFS_FFLAG_READONLY);
// TODO: Set up ACLs
int rv = Ext2_Link(Parent, Name, child);
- child->Type->Close(child);
- LEAVE('i', rv);
- return rv;
+ if( rv ) {
+ Ext2_CloseFile(child);
+ return NULL;
+ }
+ LEAVE_RET('p', child);
}
/**
extern int Ext2_int_ReadInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
extern int Ext2_int_WriteInode(tExt2_Disk *Disk, Uint32 InodeId, tExt2_Inode *Inode);
// --- Dir ---
-extern char *Ext2_ReadDir(tVFS_Node *Node, int Pos);
+extern int Ext2_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
extern tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
-extern int Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+extern tVFS_Node *Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
extern int Ext2_Link(tVFS_Node *Parent, const char *Name, tVFS_Node *Node);
// --- Read ---
extern size_t Ext2_Read(tVFS_Node *node, off_t offset, size_t length, void *buffer);
extern void FAT_int_WriteCluster(tFAT_VolInfo *Disk, Uint32 Cluster, const void *Buffer);
// --- Directory Access ---
-extern char *FAT_ReadDir(tVFS_Node *Node, int ID);
+extern int FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
extern tVFS_Node *FAT_FindDir(tVFS_Node *Node, const char *Name);
extern tVFS_Node *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
extern int FAT_int_GetEntryByCluster(tVFS_Node *DirNode, Uint32 Cluster, fat_filetable *Entry);
#if SUPPORT_WRITE
extern int FAT_int_WriteDirEntry(tVFS_Node *Node, int ID, fat_filetable *Entry);
-extern int FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
+extern tVFS_Node *FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
extern int FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *Node);
extern int FAT_Unlink(tVFS_Node *DirNode, const char *OldName);
#endif
// === PROTOTYPES ===
void FAT_int_ProperFilename(char *dest, const char *src);
-char *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName);
+ int FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName, char *Dest);
int FAT_int_ConvertUTF16_to_UTF8(Uint8 *Dest, const Uint16 *Source);
int FAT_int_ConvertUTF8_to_UTF16(Uint16 *Dest, const Uint8 *Source);
Uint16 *FAT_int_GetLFN(tVFS_Node *Node, int ID);
void FAT_int_DelLFN(tVFS_Node *Node, int ID);
#endif
-char *FAT_ReadDir(tVFS_Node *Node, int ID);
+ int FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
tVFS_Node *FAT_FindDir(tVFS_Node *Node, const char *Name);
tVFS_Node *FAT_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
#if SUPPORT_WRITE
- int FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *FAT_Mknod(tVFS_Node *Node, const char *Name, Uint Flags);
int FAT_int_IsValid83Filename(const char *Name);
int FAT_Link(tVFS_Node *DirNode, const char *NewName, tVFS_Node *Node);
int FAT_Relink(tVFS_Node *node, const char *OldName, const char *NewName);
* \param LongFileName Long file name pointer
* \return Filename as a heap string
*/
-char *FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName)
+int FAT_int_CreateName(fat_filetable *ft, const Uint16 *LongFileName, char *Dest)
{
- char *ret;
ENTER("pft sLongFileName", ft, LongFileName);
- //Log_Debug("FAT", "FAT_int_CreateName(ft=%p, LongFileName=%p'%s')", ft, LongFileName);
#if USE_LFN
if(LongFileName && LongFileName[0] != 0)
{
int len = FAT_int_ConvertUTF16_to_UTF8(NULL, LongFileName);
- ret = malloc( len + 1 );
- FAT_int_ConvertUTF16_to_UTF8((Uint8*)ret, LongFileName);
+ if( len > FILENAME_MAX ) {
+ return -1;
+ }
+ FAT_int_ConvertUTF16_to_UTF8((Uint8*)Dest, LongFileName);
}
else
{
#endif
- ret = (char*) malloc(13);
- if( !ret ) {
- Log_Warning("FAT", "FAT_int_CreateName: malloc(13) failed");
- return NULL;
- }
- FAT_int_ProperFilename(ret, ft->name);
+ FAT_int_ProperFilename(Dest, ft->name);
#if USE_LFN
}
#endif
- LEAVE('s', ret);
- return ret;
+ return 0;
}
#if USE_LFN
* \param ID Directory position
* \return Filename as a heap string, NULL or VFS_SKIP
*/
-char *FAT_ReadDir(tVFS_Node *Node, int ID)
+int FAT_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
{
fat_filetable fileinfo[16]; // sizeof(fat_filetable)=32, so 16 per sector
int a;
- char *ret;
#if USE_LFN
Uint16 *lfn = NULL;
#endif
if(FAT_int_ReadDirSector(Node, ID/16, fileinfo))
{
LOG("End of chain, end of dir");
- LEAVE('n');
- return NULL;
+ LEAVE('i', -EIO);
+ return -EIO;
}
// Offset in sector
if( fileinfo[a].name[0] == '\0' ) {
Node->Size = ID;
LOG("End of list");
- LEAVE('n');
- return NULL; // break
+ LEAVE('i', -ENOENT);
+ return -ENOENT; // break
}
// Check for empty entry
if( (Uint8)fileinfo[a].name[0] == 0xE5 ) {
LOG("Empty Entry");
- #if 0 // Stop on empty entry?
- LEAVE('n');
- return NULL; // Stop
- #else
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP; // Skip
- #endif
+ LEAVE_RET('i', 1); // Skip
}
#if USE_LFN
a = FAT_int_ParseLFN(&fileinfo[a], lfn);
if( a < 0 ) {
LOG("Invalid LFN, error");
- LEAVE('n');
- return NULL;
+ LEAVE_RET('i', -EIO);
}
-// LOG("lfn = '%s'", lfn);
- //Log_Debug("FAT", "lfn = '%s'", lfn);
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP;
+ LEAVE_RET('i', 1); // Skip
}
#endif
// Check if it is a volume entry
if(fileinfo[a].attrib & 0x08) {
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP;
+ LEAVE_RET('i', 1); // Skip
}
// Ignore .
if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == ' ') {
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP;
+ LEAVE_RET('i', 1); // Skip
}
// and ..
if(fileinfo[a].name[0] == '.' && fileinfo[a].name[1] == '.' && fileinfo[a].name[2] == ' ') {
- LEAVE('p', VFS_SKIP);
- return VFS_SKIP;
+ LEAVE_RET('i', 1); // Skip
}
LOG("name='%c%c%c%c%c%c%c%c.%c%c%c'",
#if USE_LFN
lfn = FAT_int_GetLFN(Node, ID);
//Log_Debug("FAT", "lfn = %p'%s'", lfn, lfn);
- ret = FAT_int_CreateName(&fileinfo[a], lfn);
+ FAT_int_CreateName(&fileinfo[a], lfn, Dest);
#else
- ret = FAT_int_CreateName(&fileinfo[a], NULL);
+ FAT_int_CreateName(&fileinfo[a], NULL, Dest);
#endif
- LEAVE('s', ret);
- return ret;
+ LEAVE('i', 0);
+ return 0;
}
/**
/**
* \brief Create a new node
*/
-int FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
+tVFS_Node *FAT_Mknod(tVFS_Node *DirNode, const char *Name, Uint Flags)
{
tFAT_VolInfo *disk = DirNode->ImplPtr;
int rv;
tVFS_Node *newnode = FAT_int_CreateNode(DirNode, &ft);
if( !newnode ) {
- return -1;
+ errno = -EINTERNAL;
+ return NULL;
}
LOG("newnode = %p", newnode);
if( (rv = FAT_Link(DirNode, Name, newnode)) ) {
newnode->ImplInt |= FAT_FLAG_DELETE;
}
- FAT_CloseFile(newnode);
- LEAVE('i', rv);
- return rv;
+ LEAVE('p', newnode);
+ return newnode;
}
/**
// === Functions ===
-extern size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
-extern char *InitRD_ReadDir(tVFS_Node *Node, int ID);
-extern tVFS_Node *InitRD_FindDir(tVFS_Node *Node, const char *Name);
+//extern size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
+//extern int InitRD_ReadDir(tVFS_Node *Node, int ID);
+//extern tVFS_Node *InitRD_FindDir(tVFS_Node *Node, const char *Name);
// === Globals ===
tVFS_NodeType gInitRD_DirType;
void InitRD_Unmount(tVFS_Node *Node);
tVFS_Node *InitRD_GetNodeFromINode(tVFS_Node *Root, Uint64 Inode);
size_t InitRD_ReadFile(tVFS_Node *Node, off_t Offset, size_t Size, void *Buffer);
-char *InitRD_ReadDir(tVFS_Node *Node, int ID);
+ int InitRD_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
tVFS_Node *InitRD_FindDir(tVFS_Node *Node, const char *Name);
void InitRD_DumpDir(tVFS_Node *Node, int Indent);
/**
* \brief Read from a directory
*/
-char *InitRD_ReadDir(tVFS_Node *Node, int ID)
+int InitRD_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
{
tInitRD_File *dir = Node->ImplPtr;
if(ID >= Node->Size)
- return NULL;
+ return -EINVAL;
- return strdup(dir[ID].Name);
+ strncpy(Dest, dir[ID].Name, FILENAME_MAX);
+ return 0;
}
/**
};
} PACKED tNTFS_FILE_Attrib;
+extern int NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
+extern tVFS_Node *NTFS_FindDir(tVFS_Node *Node, const char *Name);
+
#endif
#include "index.h"
// === PROTOTYPES ===
-char *NTFS_ReadDir(tVFS_Node *Node, int Pos);
+ int NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *NTFS_FindDir(tVFS_Node *Node, const char *Name);
Uint64 NTFS_int_IndexLookup(Uint64 Inode, const char *IndexName, const char *Str);
/**
* \brief Get the name of an indexed directory entry
*/
-char *NTFS_ReadDir(tVFS_Node *Node, int Pos)
+int NTFS_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- return NULL;
+ return -ENOTIMPL;
}
/**
#include "common.h"
#include <modules.h>
-// === IMPORTS ===
-extern char *NTFS_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node *NTFS_FindDir(tVFS_Node *Node, const char *Name);
-
// === PROTOTYPES ===
int NTFS_Install(char **Arguments);
tVFS_Node *NTFS_InitDevice(const char *Devices, const char **Options);
tVFS_Node *RAMFS_InitDevice(const char *Device, const char **Options);
void RAMFS_Unmount(tVFS_Node *Node);
// --- Directories ---
-char *RAMFS_ReadDir(tVFS_Node *Node, int Index);
+ int RAMFS_ReadDir(tVFS_Node *Node, int Index, char Dest[256]);
tVFS_Node *RAMFS_FindDir(tVFS_Node *Node, const char *Name);
- int RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
int RAMFS_Link(tVFS_Node *DirNode, const char *Name, tVFS_Node *Node);
int RAMFS_Unlink(tVFS_Node *Node, const char *Name);
// --- Files ---
}
// --- Directories ---
-char *RAMFS_ReadDir(tVFS_Node *Node, int Index)
+int RAMFS_ReadDir(tVFS_Node *Node, int Index, char Dest[FILENAME_MAX])
{
tRAMFS_Dir *dir = Node->ImplPtr;
for( tRAMFS_DirEnt *d = dir->FirstEnt; d; d = d->Next )
{
if( Index -- == 0 ) {
LOG("Return %s", d->Name);
- return strdup(d->Name);
+ strncpy(Dest, d->Name, FILENAME_MAX);
+ return 0;
}
}
- LOG("Return NULL");
- return NULL;
+ LOG("Return -ENOENT");
+ return -ENOENT;
}
tVFS_Node *RAMFS_FindDir(tVFS_Node *Node, const char *Name)
return NULL;
}
-int RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *RAMFS_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
{
tRAMFS_Dir *dir = Node->ImplPtr;
if( RAMFS_FindDir(Node, Name) != NULL )
- return -1;
+ return NULL;
tRAMFS_DirEnt *de = malloc( sizeof(tRAMFS_DirEnt) + strlen(Name) + 1 );
de->Next = NULL;
dir->FirstEnt = de;
dir->LastEnt = de;
- return 0;
+ return &de->Inode->Node;
}
int RAMFS_Link(tVFS_Node *DirNode, const char *Name, tVFS_Node *FileNode)
void *IPStack_Adapter_Add(const tIPStack_AdapterType *Type, void *Ptr, const void *HWAddr);
void IPStack_Adapter_Del(void *Handle);
// --- VFS API ---
-char *Adapter_ReadDir(tVFS_Node *Node, int Pos);
+ int Adapter_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]);
tVFS_Node *Adapter_FindDir(tVFS_Node *Node, const char *Name);
int Adapter_DirIOCtl(tVFS_Node *Node, int Num, void *Data);
int Adapter_IOCtl(tVFS_Node *Node, int Num, void *Data);
}
// --- VFS API ---
-char *Adapter_ReadDir(tVFS_Node *Node, int Pos)
+int Adapter_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- if( Pos < 0 ) return NULL;
+ if( Pos < 0 ) return -EINVAL;
// Loopback
if( Pos == 0 ) {
- return strdup("lo");
+ strcpy(Dest, "lo");
+ return 0;
}
Pos --;
tAdapter *a; int i;\
for(i=0,a=list; i < Pos && a; i ++, a = a->Next ); \
if( a ) { \
- return Adapter_GetName(a);\
+ strncpy(Dest, Adapter_GetName(a), FILENAME_MAX);\
+ return 0;\
} \
Pos -= i; \
} while(0);
CHECK_LIST(gpIP_AdapterList, "eth");
// TODO: Support other types of adapters (wifi, tap, ...)
- return NULL;
+ return -EINVAL;
}
tVFS_Node *Adapter_FindDir(tVFS_Node *Node, const char *Name)
--- /dev/null
+
+#ifndef _IPSTACK__INIT_H_
+#define _IPSTACK__INIT_H_
+
+extern int ARP_Initialise();
+extern void UDP_Initialise();
+extern void TCP_Initialise();
+extern int IPv4_Initialise();
+extern int IPv6_Initialise();
+
+#endif
+
#include "link.h"
#include <api_drv_common.h>
#include "include/adapters.h"
+#include "interface.h"
// === CONSTANTS ===
//! Default timeout value, 5 seconds
extern tVFS_Node gIP_AdaptersNode;
// === PROTOTYPES ===
-char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
int IPStack_AddFile(tSocketFile *File);
tInterface *IPStack_AddInterface(const char *Device, const char *Name);
-char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos);
+ int IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *IPStack_Iface_FindDir(tVFS_Node *Node, const char *Name);
int IPStack_Iface_IOCtl(tVFS_Node *Node, int ID, void *Data);
// === GLOBALS ===
+tVFS_NodeType gIP_RootNodeType = {
+ .ReadDir = IPStack_Root_ReadDir,
+ .FindDir = IPStack_Root_FindDir,
+ .IOCtl = IPStack_Root_IOCtl
+};
tVFS_NodeType gIP_InterfaceNodeType = {
.ReadDir = IPStack_Iface_ReadDir,
.FindDir = IPStack_Iface_FindDir,
/**
* \brief Read from the IP Stack's Device Directory
*/
-char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tInterface *iface;
- char *name;
ENTER("pNode iPos", Node, Pos);
// Routing Subdir
if( Pos == 0 ) {
- LEAVE('s', "routes");
- return strdup("routes");
+ strcpy(Dest, "routes");
+ return 0;
}
// Adapters
if( Pos == 1 ) {
- LEAVE('s', "adapters");
- return strdup("adapters");
+ strcpy(Dest, "adapters");
+ return 0;
}
// Pseudo Interfaces
if( Pos == 2 ) {
- LEAVE('s', "lo");
- return strdup("lo");
+ strcpy(Dest, "lo");
+ return 0;
}
Pos -= 3;
// Did we run off the end?
if(!iface) {
- LEAVE('n');
- return NULL;
- }
-
- name = malloc(4);
- if(!name) {
- Log_Warning("IPStack", "IPStack_Root_ReadDir - malloc error");
- LEAVE('n');
- return NULL;
+ LEAVE('i', -EINTERNAL);
+ return -EINVAL;
}
// Create the name
Pos = iface->Node.ImplInt;
- if(Pos < 10) {
- name[0] = '0' + Pos;
- name[1] = '\0';
- }
- else if(Pos < 100) {
- name[0] = '0' + Pos/10;
- name[1] = '0' + Pos%10;
- name[2] = '\0';
- }
- else {
- name[0] = '0' + Pos/100;
- name[1] = '0' + (Pos/10)%10;
- name[2] = '0' + Pos%10;
- name[3] = '\0';
- }
+ snprintf(Dest, FILENAME_MAX, "%i", Pos);
- LEAVE('s', name);
- // Return the pre-generated name
- return name;
+ LEAVE('i', 0);
+ return 0;
}
/**
/**
* \brief Read from an interface's directory
*/
-char *IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_Iface_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tSocketFile *file = gIP_FileTemplates;
while(Pos-- && file) {
file = file->Next;
}
- if(!file) return NULL;
+ if(!file)
+ return -EINVAL;
- return strdup(file->Name);
+ strncpy(Dest, file->Name, FILENAME_MAX);
+ return 0;
}
/**
--- /dev/null
+
+#ifndef _IPSTACK__INTERFACE_H_
+#define _IPSTACK__INTERFACE_H_
+
+extern tInterface gIP_LoopInterface;
+extern tVFS_NodeType gIP_RootNodeType;
+extern tInterface *IPStack_AddInterface(const char *Device, const char *Name);
+
+#endif
+
#include <modules.h>
#include <fs_devfs.h>
#include "include/adapters.h"
+#include "interface.h"
+#include "init.h"
// === IMPORTS ===
-extern int ARP_Initialise();
-extern void UDP_Initialise();
-extern void TCP_Initialise();
-extern int IPv4_Initialise();
-extern int IPv6_Initialise();
-
-extern char *IPStack_Root_ReadDir(tVFS_Node *Node, int Pos);
-extern tVFS_Node *IPStack_Root_FindDir(tVFS_Node *Node, const char *Name);
-extern int IPStack_Root_IOCtl(tVFS_Node *Node, int ID, void *Data);
-extern tInterface gIP_LoopInterface;
-extern tInterface *IPStack_AddInterface(const char *Device, const char *Name);
extern tRoute *IPStack_AddRoute(const char *Interface, void *Network, int SubnetBits, void *NextHop, int Metric);
// === PROTOTYPES ===
// === GLOBALS ===
MODULE_DEFINE(0, VERSION, IPStack, IPStack_Install, NULL, NULL);
-tVFS_NodeType gIP_RootNodeType = {
- .ReadDir = IPStack_Root_ReadDir,
- .FindDir = IPStack_Root_FindDir,
- .IOCtl = IPStack_Root_IOCtl
-};
tDevFS_Driver gIP_DriverInfo = {
NULL, "ip",
{
// === PROTOTYPES ===
// - Routes directory
-char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos);
+ int IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *IPStack_RouteDir_FindDir(tVFS_Node *Node, const char *Name);
- int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
+tVFS_Node *IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
int IPStack_RouteDir_Unlink(tVFS_Node *Node, const char *OldName);
tRoute *_Route_FindExactRoute(int Type, void *Network, int Subnet, int Metric);
int _Route_ParseRouteName(const char *Name, void *Addr, int *SubnetBits, int *Metric);
/**
* \brief ReadDir for the /Devices/ip/routes/ directory
*/
-char *IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos)
+int IPStack_RouteDir_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tRoute *rt;
for(rt = gIP_Routes; rt && Pos --; rt = rt->Next);
- if( !rt ) return NULL;
+ if( !rt ) return -EINVAL;
{
int addrlen = IPStack_GetAddressSize(rt->AddressType);
- int len = sprintf(NULL, "%i::%i:%i", rt->AddressType, rt->SubnetBits, rt->Metric) + addrlen*2;
- char buf[len+1];
int ofs;
- ofs = sprintf(buf, "%i:", rt->AddressType);
- ofs += Hex(buf+ofs, addrlen, rt->Network);
- sprintf(buf+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
- return strdup(buf);
+ ofs = sprintf(Dest, "%i:", rt->AddressType);
+ ofs += Hex(Dest+ofs, addrlen, rt->Network);
+ sprintf(Dest+ofs, ":%i:%i", rt->SubnetBits, rt->Metric);
+ return 0;
}
}
/**
* \brief Create a new route node
*/
-int IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
+tVFS_Node *IPStack_RouteDir_MkNod(tVFS_Node *Node, const char *Name, Uint Flags)
{
- if( Flags ) return -EINVAL;
- if( Threads_GetUID() != 0 ) return -EACCES;
+ if( Flags ) {
+ errno = EINVAL;
+ return NULL;
+ }
+ if( Threads_GetUID() != 0 ) {
+ errno = EACCES;
+ return NULL;
+ }
int type = _Route_ParseRouteName(Name, NULL, NULL, NULL);
- if( type <= 0 ) return -EINVAL;
+ if( type <= 0 ) {
+ errno = EINVAL;
+ return NULL;
+ }
int size = IPStack_GetAddressSize(type);
Uint8 addrdata[size];
_Route_ParseRouteName(Name, addrdata, &subnet, &metric);
// Check for duplicates
- if( _Route_FindExactRoute(type, addrdata, subnet, metric) )
- return -EEXIST;
+ if( _Route_FindExactRoute(type, addrdata, subnet, metric) ) {
+ errno = EEXIST;
+ return NULL;
+ }
- IPStack_Route_Create(type, addrdata, subnet, metric);
+ tRoute *rt = IPStack_Route_Create(type, addrdata, subnet, metric);
+ rt->Node.ReferenceCount ++;
- return 0;
+ return &rt->Node;
}
/**
int TCP_DeallocatePort(Uint16 Port);
// --- Server
tVFS_Node *TCP_Server_Init(tInterface *Interface);
-char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos);
+ int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Name[FILENAME_MAX]);
tVFS_Node *TCP_Server_FindDir(tVFS_Node *Node, const char *Name);
int TCP_Server_IOCtl(tVFS_Node *Node, int ID, void *Data);
void TCP_Server_Close(tVFS_Node *Node);
* \param Node Server node
* \param Pos Position (ignored)
*/
-char *TCP_Server_ReadDir(tVFS_Node *Node, int Pos)
+int TCP_Server_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
tTCPListener *srv = Node->ImplPtr;
tTCPConnection *conn;
- char *ret;
ENTER("pNode iPos", Node, Pos);
LOG("srv->NewConnections = %p", srv->NewConnections);
LOG("srv->ConnectionsTail = %p", srv->ConnectionsTail);
- ret = malloc(9);
- itoa(ret, conn->Node.ImplInt, 16, 8, '0');
- Log_Log("TCP", "Thread %i got '%s'", Threads_GetTID(), ret);
- LEAVE('s', ret);
- return ret;
+ itoa(Dest, conn->Node.ImplInt, 16, 8, '0');
+ Log_Log("TCP", "Thread %i got connection '%s'", Threads_GetTID(), Dest);
+ LEAVE('i', 0);
+ return 0;
}
/**
int Mouse_Install(char **Arguments);
int Mouse_Cleanup(void);
// - "User" side
-char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos);
+ int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name);
int Mouse_Dev_IOCtl(tVFS_Node *Node, int ID, void *Data);
size_t Mouse_Dev_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Data);
}
// --- VFS Interface ---
-char *Mouse_Root_ReadDir(tVFS_Node *Node, int Pos)
+int Mouse_Root_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- if( Pos != 0 ) return NULL;
- return strdup("system");
+ if( Pos != 0 )
+ return -EINVAL;
+ strcpy(Dest, "system");
+ return 0;
}
tVFS_Node *Mouse_Root_FindDir(tVFS_Node *Node, const char *Name)
int FDD_Install(char **Arguments);
int FDD_RegisterFS(void);
// --- VFS
-char *FDD_ReadDir(tVFS_Node *Node, int pos);
+ int FDD_ReadDir(tVFS_Node *Node, int pos, char dest[FILENAME_MAX]);
tVFS_Node *FDD_FindDir(tVFS_Node *dirNode, const char *Name);
int FDD_IOCtl(tVFS_Node *Node, int ID, void *Data);
size_t FDD_ReadFS(tVFS_Node *node, off_t Offset, size_t Len, void *buffer);
* \param Pos Position
* \return Heap string of node name
*/
-char *FDD_ReadDir(tVFS_Node *Node, int Pos)
+int FDD_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- char ret_tpl[2];
if(Pos < 0 || Pos > MAX_DISKS )
- return NULL;
+ return -ENOENT;
if(gaFDD_Disks[Pos].bValid)
- return VFS_SKIP;
+ return 1;
- ret_tpl[0] = '0' + Pos;
- ret_tpl[1] = '\0';
- return strdup(ret_tpl);
+ Dest[0] = '0' + Pos;
+ Dest[1] = '\0';
+ return 0;
}
/**
int LVM_Initialise(char **Arguments);
int LVM_Cleanup(void);
// ---
-char *LVM_Root_ReadDir(tVFS_Node *Node, int ID);
+ int LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name);
-char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID);
+ int LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX]);
tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name);
size_t LVM_Vol_Read(tVFS_Node *Node, off_t Offset, size_t Length, void *Buffer);
size_t LVM_Vol_Write(tVFS_Node *Node, off_t Offset, size_t Length, const void *Buffer);
// --------------------------------------------------------------------
// VFS Inteface
// --------------------------------------------------------------------
-char *LVM_Root_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Root_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
{
tLVM_Vol *vol;
- if( ID < 0 ) return NULL;
+ if( ID < 0 ) return -EINVAL;
for( vol = gpLVM_FirstVolume; vol && ID --; vol = vol->Next );
- if(vol)
- return strdup(vol->Name);
+ if(vol) {
+ strncpy(Dest, vol->Name, FILENAME_MAX);
+ return 0;
+ }
else
- return NULL;
+ return -ENOENT;
}
tVFS_Node *LVM_Root_FindDir(tVFS_Node *Node, const char *Name)
{
return NULL;
}
-char *LVM_Vol_ReadDir(tVFS_Node *Node, int ID)
+int LVM_Vol_ReadDir(tVFS_Node *Node, int ID, char Dest[FILENAME_MAX])
{
tLVM_Vol *vol = Node->ImplPtr;
+ const char *src;
if( ID < 0 || ID >= vol->nSubVolumes+1 )
- return NULL;
+ return -EINVAL;
- if( ID == 0 )
- return strdup("ROOT");
- else
- return strdup( vol->SubVolumes[ID-1]->Name );
+ if( ID == 0 ) {
+ src = "ROOT";
+ }
+ else {
+ src = vol->SubVolumes[ID-1]->Name;
+ }
+ strncpy(Dest, src, FILENAME_MAX);
+ return 0;
}
tVFS_Node *LVM_Vol_FindDir(tVFS_Node *Node, const char *Name)
{
// === PROTOTYPES ===
int USB_Install(char **Arguments);
void USB_Cleanup(void);
-char *USB_ReadDir(tVFS_Node *Node, int Pos);
+ int USB_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX]);
tVFS_Node *USB_FindDir(tVFS_Node *Node, const char *Name);
int USB_IOCtl(tVFS_Node *Node, int Id, void *Data);
* \fn char *USB_ReadDir(tVFS_Node *Node, int Pos)
* \brief Read from the USB root
*/
-char *USB_ReadDir(tVFS_Node *Node, int Pos)
+int USB_ReadDir(tVFS_Node *Node, int Pos, char Dest[FILENAME_MAX])
{
- return NULL;
+ return -ENOTIMPL;
}
/**