* AcessMicro VFS
* - Open, Close and ChDir
*/
+#define DEBUG 0
#include <common.h>
#include "vfs.h"
#include "vfs_int.h"
#include "vfs_ext.h"
-#define DEBUG 0
-
-#if DEBUG
-#else
-# undef ENTER
-# undef LOG
-# undef LEAVE
-# define ENTER(...)
-# define LOG(...)
-# define LEAVE(...)
-#endif
-
// === CONSTANTS ===
#define OPEN_MOUNT_ROOT 1
#define MAX_KERNEL_FILES 128
+#define MAX_PATH_SLASHES 256
// === IMPORTS ===
extern tVFS_Node gVFS_MemRoot;
char *ret;
int pathLen = strlen(Path);
int read, write;
- int pos, slashNum=0, baseLen;
- Uint slashOffsets[256];
+ int pos, endLen;
+ int slashNum = 0;
+ Uint slashOffsets[MAX_PATH_SLASHES];
char *cwd = CFGPTR(CFG_VFS_CWD);
int cwdLen;
// Memory File
if(Path[0] == '$') {
ret = malloc(strlen(Path)+1);
+ if(!ret) {
+ Warning("VFS_GetAbsPath - malloc() returned NULL");
+ return NULL;
+ }
strcpy(ret, Path);
LEAVE('p', ret);
return ret;
// Check if the path is already absolute
if(Path[0] == '/') {
+ endLen = pathLen + 1;
ret = malloc(pathLen + 1);
+ if(!ret) {
+ Warning("VFS_GetAbsPath - malloc() returned NULL");
+ return NULL;
+ }
strcpy(ret, Path);
- baseLen = 1;
} else {
cwdLen = strlen(cwd);
+ endLen = cwdLen + pathLen + 2;
// Prepend the current directory
- ret = malloc(cwdLen+pathLen+1);
+ ret = malloc(endLen);
strcpy(ret, cwd);
- strcpy(&ret[cwdLen], Path);
-
- // Pre-fill the slash positions
- pos = 0;
- while( (pos = strpos( &ret[pos+1], '/' )) != -1 )
- slashOffsets[slashNum++] = pos;
-
- baseLen = cwdLen;
+ ret[cwdLen] = '/';
+ strcpy(&ret[cwdLen+1], Path);
}
// Remove . and ..
- read = write = baseLen; // Cwd has already been parsed
- for(; read < baseLen+pathLen; read = pos+1)
+ read = write = 1; // Cwd has already been parsed
+ for(; read < endLen; read = pos+1)
{
pos = strpos( &ret[read], '/' );
// If we are in the last section, force a break at the end of the itteration
- if(pos == -1) pos = baseLen+pathLen;
+ if(pos == -1) pos = endLen;
else pos += read; // Else, Adjust to absolute
// Check Length
if(strncmp(&ret[read], "..", pos-read) == 0)
{
// If there is no higher, silently ignore
- if(!slashNum) continue;
+ if(slashNum < 1) {
+ write = 1;
+ continue;
+ }
// Reverse write pointer
- write = slashOffsets[ slashNum-- ];
+ write = slashOffsets[ --slashNum ];
continue;
}
}
// Only copy if the positions differ
if(read != write) {
+ //Log("write = %i, read = %i, pos-read+1 = %i", write, read, pos-read+1);
memcpy( &ret[write], &ret[read], pos-read+1 );
+ //Log("ret = '%s'", ret);
}
- write = pos+1;
- if(slashNum < 256)
- slashOffsets[ slashNum++ ] = pos;
+
+ if(slashNum < MAX_PATH_SLASHES)
+ slashOffsets[ slashNum++ ] = write;
else {
LOG("Path '%s' has too many elements", Path);
free(ret);
LEAVE('n');
return NULL;
}
+
+ // Increment write pointer
+ write += (pos-read)+1;
}
// `ret` should now be the absolute path
LEAVE('s', ret);
+ //Log("VFS_GetAbsPath: RETURN '%s'", ret);
return ret;
}
int VFS_ChDir(char *New)
{
char *buf;
- tVFS_Node *node;
+ int fd;
+ tVFS_Handle *h;
// Create Absolute
buf = VFS_GetAbsPath(New);
- if(buf == NULL) return -1;
+ if(buf == NULL) {
+ Log("VFS_ChDir: Path expansion failed");
+ return -1;
+ }
- // Check if path is valid
- node = VFS_ParsePath(buf, NULL);
- if(!node) return -1;
+ // Check if path exists
+ fd = VFS_Open(buf, VFS_OPENFLAG_EXEC);
+ if(fd == -1) {
+ Log("VFS_ChDir: Path is invalid");
+ return -1;
+ }
- // Check if is a directory
- if( !(node->Flags & VFS_FFLAG_DIRECTORY) ) {
- if(node->Close) node->Close(node);
+ // Get node so we can check for directory
+ h = VFS_GetHandle(fd);
+ if( !(h->Node->Flags & VFS_FFLAG_DIRECTORY) ) {
+ Log("VFS_ChDir: Path is not a directory");
+ VFS_Close(fd);
return -1;
}
- // Close node
- if(node->Close) node->Close(node);
- // Copy over
- strcpy(buf, New);
+ // Close file
+ VFS_Close(fd);
- // Free old and set new
- free( CFGPTR(CFG_VFS_CWD) );
+ // Free old working directory
+ if( CFGPTR(CFG_VFS_CWD) ) free( CFGPTR(CFG_VFS_CWD) );
+ // Set new
CFGPTR(CFG_VFS_CWD) = buf;
+ Log("Updated CWD to '%s'", buf);
+
return 1;
}