Sorting source tree a bit
[tpg/acess2.git] / Modules / Filesystems / Ext2 / dir.c
diff --git a/Modules/Filesystems/Ext2/dir.c b/Modules/Filesystems/Ext2/dir.c
deleted file mode 100644 (file)
index 5eb476f..0000000
+++ /dev/null
@@ -1,397 +0,0 @@
-/*
- * Acess OS
- * Ext2 Driver Version 1
- */
-/**
- * \file dir.c
- * \brief Second Extended Filesystem Driver
- * \todo Implement file full write support
- */
-#define DEBUG  1
-#define VERBOSE        0
-#include "ext2_common.h"
-
-// === MACROS ===
-#define BLOCK_DIR_OFS(_data, _block)   ((Uint16*)(_data)[(_block)])
-
-// === PROTOTYPES ===
-char   *Ext2_ReadDir(tVFS_Node *Node, int Pos);
-tVFS_Node      *Ext2_FindDir(tVFS_Node *Node, const char *FileName);
- int   Ext2_MkNod(tVFS_Node *Node, const char *Name, Uint Flags);
- int   Ext2_Relink(tVFS_Node *Node, const char *OldName, const char *NewName);
- int   Ext2_Link(tVFS_Node *Parent, tVFS_Node *Node, const char *Name);
-// --- Helpers ---
-tVFS_Node      *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeId);
-
-// === GLOBALS ===
-tVFS_NodeType  gExt2_DirType = {
-       .TypeName = "ext2-dir",
-       .ReadDir = Ext2_ReadDir,
-       .FindDir = Ext2_FindDir,
-       .MkNod = Ext2_MkNod,
-       .Relink = Ext2_Relink,
-       .Link = Ext2_Link,
-       .Close = Ext2_CloseFile
-       };
-tVFS_NodeType  gExt2_FileType = {
-       .TypeName = "ext2-file",
-       .Read = Ext2_Read,
-       .Write = Ext2_Write,
-       .Close = Ext2_CloseFile
-       };
-
-// === CODE ===
-/**
- * \brief Reads a directory entry
- * \param Node Directory node
- * \param Pos  Position of desired element
- */
-char *Ext2_ReadDir(tVFS_Node *Node, int Pos)
-{
-       tExt2_Inode     inode;
-       tExt2_DirEnt    dirent;
-       Uint64  Base;   // Block's Base Address
-        int    block = 0;
-       Uint    ofs = 0;
-        int    entNum = 0;
-       tExt2_Disk      *disk = Node->ImplPtr;
-       Uint    size;
-       
-       ENTER("pNode iPos", Node, Pos);
-       
-       // Read directory's inode
-       Ext2_int_ReadInode(disk, Node->Inode, &inode);
-       size = inode.i_size;
-       
-       LOG("inode.i_block[0] = 0x%x", inode.i_block[0]);
-       
-       // Find Entry
-       // Get First Block
-       // - Do this ourselves as it is a simple operation
-       Base = inode.i_block[0] * disk->BlockSize;
-       // Scan directory
-       while(Pos -- && size > 0)
-       {
-               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
-               ofs += dirent.rec_len;
-               size -= dirent.rec_len;
-               entNum ++;
-               
-               if(ofs >= disk->BlockSize) {
-                       block ++;
-                       if( ofs > disk->BlockSize ) {
-                               Log_Warning("EXT2", "Directory Entry %i of inode %i extends over a block boundary, ignoring",
-                                       entNum-1, Node->Inode);
-                       }
-                       ofs = 0;
-                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
-               }
-       }
-       
-       // Check for the end of the list
-       if(size <= 0) {
-               LEAVE('n');
-               return NULL;
-       }
-       
-       // Read Entry
-       VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent );
-       //LOG("dirent.inode = %i", dirent.inode);
-       //LOG("dirent.rec_len = %i", dirent.rec_len);
-       //LOG("dirent.name_len = %i", dirent.name_len);
-       dirent.name[ dirent.name_len ] = '\0';  // Cap off string
-       
-       
-       // 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('s', dirent.name);
-       // Create new node
-       return strdup(dirent.name);
-}
-
-/**
- * \brief Gets information about a file
- * \param Node Parent Node
- * \param Filename     Name of wanted file
- * \return VFS Node of file
- */
-tVFS_Node *Ext2_FindDir(tVFS_Node *Node, const char *Filename)
-{
-       tExt2_Disk      *disk = Node->ImplPtr;
-       tExt2_Inode     inode;
-       tExt2_DirEnt    dirent;
-       Uint64  Base;   // Block's Base Address
-        int    block = 0;
-       Uint    ofs = 0;
-        int    entNum = 0;
-       Uint    size;
-        int    filenameLen = strlen(Filename);
-       
-       // Read directory's inode
-       Ext2_int_ReadInode(disk, Node->Inode, &inode);
-       size = inode.i_size;
-       
-       // Get First Block
-       // - Do this ourselves as it is a simple operation
-       Base = inode.i_block[0] * disk->BlockSize;
-       // Find File
-       while(size > 0)
-       {
-               VFS_ReadAt( disk->FD, Base+ofs, sizeof(tExt2_DirEnt), &dirent);
-               dirent.name[ dirent.name_len ] = '\0';  // Cap off string
-               // If it matches, create a node and return it
-               if(dirent.name_len == filenameLen && strcmp(dirent.name, Filename) == 0)
-                       return Ext2_int_CreateNode( disk, dirent.inode );
-               // Increment pointers
-               ofs += dirent.rec_len;
-               size -= dirent.rec_len;
-               entNum ++;
-               
-               // Check for end of block
-               if(ofs >= disk->BlockSize) {
-                       block ++;
-                       if( ofs > disk->BlockSize ) {
-                               Log_Warning("EXT2", "Directory Entry %i of inode %i extends over a block boundary, ignoring",
-                                       entNum-1, Node->Inode);
-                       }
-                       ofs = 0;
-                       Base = Ext2_int_GetBlockAddr( disk, inode.i_block, block );
-               }
-       }
-       
-       return NULL;
-}
-
-/**
- * \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)
-{
-       #if 0
-       tVFS_Node       *child;
-       Uint64  inodeNum;
-       tExt2_Inode     inode;
-       inodeNum = Ext2_int_AllocateInode(Parent->ImplPtr, Parent->Inode);
-       
-       memset(&inode, 0, sizeof(tExt2_Inode));
-       
-       // File type
-       inode.i_mode = 0664;
-       if( Flags & VFS_FFLAG_READONLY )
-               inode.i_mode &= ~0222;
-       if( Flags & VFS_FFLAG_SYMLINK )
-               inode.i_mode |= EXT2_S_IFLNK;
-       else if( Flags & VFS_FFLAG_DIRECTORY )
-               inode.i_mode |= EXT2_S_IFDIR | 0111;
-       
-       inode.i_uid = Threads_GetUID();
-       inode.i_gid = Threads_GetGID();
-       inode.i_ctime =
-               inode.i_mtime =
-               inode.i_atime = now() / 1000;
-       
-       child = Ext2_int_CreateNode(Parent->ImplPtr, inodeNum);
-       return Ext2_Link(Parent, child, Name);
-       #else
-       return 1;
-       #endif
-}
-
-/**
- * \brief Rename a file
- * \param Node This (directory) node
- * \param OldName      Old name of file
- * \param NewName      New name for file
- * \return Boolean Failure - See ::tVFS_Node.Relink for info
- */
-int Ext2_Relink(tVFS_Node *Node, const char *OldName, const char *NewName)
-{
-       return 1;
-}
-
-/**
- * \brief Links an existing node to a new name
- * \param Parent       Parent (directory) node
- * \param Node Node to link
- * \param Name New name for the node
- * \return Boolean Failure - See ::tVFS_Node.Link for info
- */
-int Ext2_Link(tVFS_Node *Node, tVFS_Node *Child, const char *Name)
-{      
-       #if 0
-       tExt2_Disk      *disk = Node->ImplPtr;
-       tExt2_Inode     inode;
-       tExt2_DirEnt    dirent;
-       tExt2_DirEnt    newEntry;
-       Uint64  Base;   // Block's Base Address
-        int    block = 0, ofs = 0;
-       Uint    size;
-       void    *blockData;
-        int    bestMatch = -1, bestSize, bestBlock, bestOfs;
-        int    nEntries;
-       
-       blockData = malloc(disk->BlockSize);
-       
-       // Read child inode (get's the file type)
-       Ext2_int_ReadInode(disk, Child->Inode, &inode);
-       
-       // Create a stub entry
-       newEntry.inode = Child->Inode;
-       newEntry.name_len = strlen(Name);
-       newEntry.rec_len = (newEntry.name_len+3+8)&~3;
-       newEntry.type = inode.i_mode >> 12;
-       memcpy(newEntry.name, Name, newEntry.name_len);
-       
-       // Read directory's inode
-       Ext2_int_ReadInode(disk, Node->Inode, &inode);
-       size = inode.i_size;
-       
-       // Get a lock on the inode
-       Ext2_int_LockInode(disk, Node->Inode);
-       
-       // Get First Block
-       // - Do this ourselves as it is a simple operation
-       base = inode.i_block[0] * disk->BlockSize;
-       VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
-       block = 0;
-       // Find File
-       while(size > 0)
-       {
-               dirent = blockData + ofs;
-               // Sanity Check the entry
-               if(ofs + dirent->rec_len > disk->BlockSize) {
-                       Log_Warning("EXT2",
-                               "Directory entry %i of inode 0x%x extends over a block boundary",
-                               nEntries, (Uint)Node->Inode);
-               }
-               else {
-               
-                       // Free entry
-                       if(dirent->type == 0) {
-                               if( dirent->rec_len >= newEntry.rec_len
-                                && (bestMatch == -1 || bestSize > dirent->rec_len) )
-                               {
-                                       bestMatch = nEntries;
-                                       bestSize = dirent->rec_len;
-                                       bestBlock = block;
-                                       bestOfs = ofs;
-                               }
-                       }
-                       // Non free - check name to avoid duplicates
-                       else {
-                               if(strncmp(Name, dirent->name, dirent->name_len) == 0) {
-                                       Ext2_int_UnlockInode(disk, Node->Inode);
-                                       return 1;       // ERR_???
-                               }
-                       }
-               }
-               
-               // Increment the pointer
-               nEntries ++;
-               ofs += dirent->rec_len;
-               if( ofs >= disk->BlockSize ) {
-                       // Read the next block if needed
-                       BLOCK_DIR_OFS(Node->Data, block) = nEntries;
-                       block ++;
-                       ofs = 0;
-                       base = Ext2_int_GetBlockAddr(disk, inode.i_block, block);
-                       VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
-               }
-       }
-       
-       // Check if a free slot was found
-       if( bestMatch >= 0 ) {
-               // Read-Modify-Write
-               bestBlock = Ext2_int_GetBlockAddr(disk, inode.i_block, bestBlock);
-               if( block > 0 )
-                       bestMatch = BLOCK_DIR_OFS(Node->Data, bestBlock);
-               VFS_ReadAt( disk->FD, base, disk->BlockSize, blockData );
-               dirent = blockData + bestOfs;
-               memcpy(dirent, newEntry, newEntry.rec_len);
-               VFS_WriteAt( disk->FD, base, disk->BlockSize, blockData );
-       }
-       else {
-               // Allocate block, Write
-               block = Ext2_int_AllocateBlock(Disk, block);
-               Log_Warning("EXT2", "");
-       }
-
-       Ext2_int_UnlockInode(disk, Node->Inode);
-       return 0;
-       #else
-       return 1;
-       #endif
-}
-
-// ---- INTERNAL FUNCTIONS ----
-/**
- * \fn vfs_node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
- * \brief Create a new VFS Node
- */
-tVFS_Node *Ext2_int_CreateNode(tExt2_Disk *Disk, Uint InodeID)
-{
-       tExt2_Inode     inode;
-       tVFS_Node       retNode;
-       tVFS_Node       *tmpNode;
-       
-       if( !Ext2_int_ReadInode(Disk, InodeID, &inode) )
-               return NULL;
-       
-       if( (tmpNode = Inode_GetCache(Disk->CacheID, InodeID)) )
-               return tmpNode;
-       
-       
-       // Set identifiers
-       retNode.Inode = InodeID;
-       retNode.ImplPtr = Disk;
-       
-       // Set file length
-       retNode.Size = inode.i_size;
-       retNode.Data = NULL;
-       
-       // Set Access Permissions
-       retNode.UID = inode.i_uid;
-       retNode.GID = inode.i_gid;
-       retNode.NumACLs = 3;
-       retNode.ACLs = VFS_UnixToAcessACL(inode.i_mode & 0777, inode.i_uid, inode.i_gid);
-       
-       //  Set Function Pointers
-       retNode.Type = &gExt2_FileType;
-       
-       switch(inode.i_mode & EXT2_S_IFMT)
-       {
-       // Symbolic Link
-       case EXT2_S_IFLNK:
-               retNode.Flags = VFS_FFLAG_SYMLINK;
-               break;
-       // Regular File
-       case EXT2_S_IFREG:
-               retNode.Flags = 0;
-               retNode.Size |= (Uint64)inode.i_dir_acl << 32;
-               break;
-       // Directory
-       case EXT2_S_IFDIR:
-               retNode.Type = &gExt2_DirType;
-               retNode.Flags = VFS_FFLAG_DIRECTORY;
-               retNode.Data = calloc( sizeof(Uint16), DivUp(retNode.Size, Disk->BlockSize) );
-               break;
-       // Unknown, Write protect it to be safe 
-       default:
-               retNode.Flags = VFS_FFLAG_READONLY;
-               break;
-       }
-       
-       // Set Timestamps
-       retNode.ATime = inode.i_atime * 1000;
-       retNode.MTime = inode.i_mtime * 1000;
-       retNode.CTime = inode.i_ctime * 1000;
-       
-       // Save in node cache and return saved node
-       return Inode_CacheNode(Disk->CacheID, &retNode);
-}

UCC git Repository :: git.ucc.asn.au