Sorting source tree a bit
[tpg/acess2.git] / KernelLand / Kernel / vfs / dir.c
diff --git a/KernelLand/Kernel/vfs/dir.c b/KernelLand/Kernel/vfs/dir.c
new file mode 100644 (file)
index 0000000..d4c1530
--- /dev/null
@@ -0,0 +1,192 @@
+/*
+ * Acess2 VFS
+ * - Directory Management Functions
+ */
+#define DEBUG  0
+#include <acess.h>
+#include <vfs.h>
+#include <vfs_int.h>
+
+// === IMPORTS ===
+extern tVFS_Mount      *gRootMount;
+
+// === PROTOTYPES ===
+#if 0
+ int   VFS_MkDir(const char *Path);
+ int   VFS_MkNod(const char *Path, Uint Flags);
+ int   VFS_Symlink(const char *Name, const char *Link);
+#endif
+
+// === CODE ===
+/**
+ * \fn int VFS_MkDir(char *Path)
+ * \brief Create a new node
+ * \param Path Path of directory to create
+ */
+int VFS_MkDir(const char *Path)
+{
+       return VFS_MkNod(Path, VFS_FFLAG_DIRECTORY);
+}
+
+/**
+ * \fn int VFS_MkNod(char *Path, Uint Flags)
+ * \brief Create a new node in a directory
+ * \param Path Path of new node
+ * \param Flags        Flags to apply to the node
+ */
+int VFS_MkNod(const char *Path, Uint Flags)
+{
+       char    *absPath, *name;
+        int    pos = 0, oldpos = 0;
+        int    next = 0;
+       tVFS_Node       *parent;
+        int    ret;
+       
+       ENTER("sPath xFlags", Path, Flags);
+       
+       absPath = VFS_GetAbsPath(Path);
+       LOG("absPath = '%s'", absPath);
+       
+       while( (next = strpos(&absPath[pos+1], '/')) != -1 ) {
+               LOG("next = %i", next);
+               pos += next+1;
+               LOG("pos = %i", pos);
+               oldpos = pos;
+       }
+       absPath[oldpos] = '\0'; // Mutilate path
+       name = &absPath[oldpos+1];
+       
+       LOG("absPath = '%s', name = '%s'", absPath, name);
+       
+       // Check for root
+       if(absPath[0] == '\0')
+               parent = VFS_ParsePath("/", NULL, NULL);
+       else
+               parent = VFS_ParsePath(absPath, NULL, NULL);
+       
+       LOG("parent = %p", parent);
+       
+       if(!parent) {
+               LEAVE('i', -1);
+               return -1;      // Error Check
+       }
+       
+       // Permissions Check
+       if( !VFS_CheckACL(parent, VFS_PERM_EXECUTE|VFS_PERM_WRITE) ) {
+               _CloseNode(parent);
+               free(absPath);
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       LOG("parent = %p", parent);
+       
+       if(!parent->Type || !parent->Type->MkNod) {
+               Warning("VFS_MkNod - Directory has no MkNod method");
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       // Create node
+       ret = parent->Type->MkNod(parent, name, Flags);
+       
+       // Free allocated string
+       free(absPath);
+       
+       // Free Parent
+       _CloseNode(parent);
+       
+       // Error Check
+       if(ret == 0) {
+               LEAVE('i', -1);
+               return -1;
+       }
+       
+       LEAVE('i', 0);
+       return 0;
+}
+
+/**
+ * \fn int VFS_Symlink(const char *Name, const char *Link)
+ * \brief Creates a symlink called \a Name to \a Link
+ * \param Name Name of symbolic link
+ * \param Link Destination of symbolic link
+ */
+int VFS_Symlink(const char *Name, const char *Link)
+{
+       char    *realLink;
+        int    fp;
+       
+       ENTER("sName sLink", Name, Link);
+       
+       // Get absolue path name
+       realLink = VFS_GetAbsPath( Link );
+       if(!realLink) {
+               Log_Warning("VFS", "Path '%s' is badly formed", Link);
+               LEAVE('i', -1);
+               return -1;
+       }
+
+       LOG("realLink = '%s'", realLink);
+
+       // Make node
+       if( VFS_MkNod(Name, VFS_FFLAG_SYMLINK) != 0 ) {
+               Log_Warning("VFS", "Unable to create link node '%s'", Name);
+               free(realLink);
+               LEAVE('i', -2);
+               return -2;      // Make link node
+       }
+       
+       // Write link address
+       fp = VFS_Open(Name, VFS_OPENFLAG_WRITE|VFS_OPENFLAG_NOLINK);
+       VFS_Write(fp, strlen(realLink), realLink);
+       VFS_Close(fp);
+       
+       free(realLink);
+       
+       LEAVE('i', 1);
+       return 1;
+}
+
+/**
+ * \fn int VFS_ReadDir(int FD, char *Dest)
+ * \brief Read from a directory
+ */
+int VFS_ReadDir(int FD, char *Dest)
+{
+       tVFS_Handle     *h = VFS_GetHandle(FD);
+       char    *tmp;
+       
+       //ENTER("ph pDest", h, Dest);
+       
+       if(!h || !h->Node->Type || !h->Node->Type->ReadDir) {
+               //LEAVE('i', 0);
+               return 0;
+       }
+       
+       if(h->Node->Size != -1 && h->Position >= h->Node->Size) {
+               //LEAVE('i', 0);
+               return 0;
+       }
+       
+       do {
+               tmp = h->Node->Type->ReadDir(h->Node, h->Position);
+               if((Uint)tmp < (Uint)VFS_MAXSKIP)
+                       h->Position += (Uint)tmp;
+               else
+                       h->Position ++;
+       } while(tmp != NULL && (Uint)tmp < (Uint)VFS_MAXSKIP);
+       
+       //LOG("tmp = '%s'", tmp);
+       
+       if(!tmp) {
+               //LEAVE('i', 0);
+               return 0;
+       }
+       
+       strcpy(Dest, tmp);
+       free(tmp);
+       
+       //LEAVE('i', 1);
+       return 1;
+}

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