231 lines
4.7 KiB
C
231 lines
4.7 KiB
C
|
#include <fs/ramfs.h>
|
||
|
#include <stdlib.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
#include <fs/vfs.h>
|
||
|
|
||
|
|
||
|
/*
|
||
|
Note: the special FILE value -128 means the current directory.
|
||
|
-32 means stdin
|
||
|
-33 means stdout (which can be read)
|
||
|
*/
|
||
|
|
||
|
bool vfs_initialized = false;
|
||
|
ramfs_file_header_t* vfs_current_dir = NULL;
|
||
|
|
||
|
void vfs_init(void)
|
||
|
{
|
||
|
if (!vfs_initialized)
|
||
|
{
|
||
|
ramfs_init();
|
||
|
|
||
|
ramfs_make_root();
|
||
|
|
||
|
vfs_initialized = true;
|
||
|
vfs_current_dir = ramfs_get_root();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/* ramfs_file_header_t* ramfs_create_file(char* name, char type, char encryption, ramfs_file_header_t* parent); */
|
||
|
|
||
|
FILE create_file(char* filename, char type, char encryption, FILE parent)
|
||
|
{
|
||
|
if (!filename)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (parent == -128)
|
||
|
{
|
||
|
parent = vfs_current_dir->fd;
|
||
|
}
|
||
|
|
||
|
ramfs_file_header_t* file = ramfs_create_file(filename, type, encryption, ramfs_resolve_fd(parent));
|
||
|
if (!file)
|
||
|
{
|
||
|
return -4; /* error code for failed creation */
|
||
|
}
|
||
|
|
||
|
return file->fd;
|
||
|
}
|
||
|
|
||
|
int32_t delete_file(FILE file)
|
||
|
{
|
||
|
/*
|
||
|
XXX WARNING: ANY AND ALL PROCESSES CAN DELETE A FILE VIA THIS INTERFACE!!! XXX
|
||
|
XXX THIS MUST BE PACHED SOON!!! OR AT LEAST ADD PERMISSION CHECKING IN THE SYSCALL INTERFACE XXX
|
||
|
XXX OR IN THE C LIBRARIES!!! XXX
|
||
|
*/
|
||
|
|
||
|
if (file < 1)
|
||
|
{
|
||
|
return -4;
|
||
|
}
|
||
|
|
||
|
ramfs_file_header_t* _file = ramfs_resolve_fd_dir(vfs_current_dir, file);
|
||
|
return ramfs_delete_file(_file);
|
||
|
}
|
||
|
|
||
|
|
||
|
/*
|
||
|
Open a file based on a string.
|
||
|
Return a file descriptor on success, a negative value on failure.
|
||
|
|
||
|
return values:
|
||
|
(positive non-zero value) - File descriptor
|
||
|
-1 - Insufficient permissions to open file
|
||
|
-2 - File does not exist ( or at least, File not found. )
|
||
|
-3 - No filesystem is initialized
|
||
|
-4 - Internal error, perhaps try again
|
||
|
*/
|
||
|
FILE open_file(char* filename)
|
||
|
{
|
||
|
if (ramfs_get_initialized() && vfs_initialized)
|
||
|
{
|
||
|
ramfs_file_header_t* _file = ramfs_resolve_path(filename);
|
||
|
|
||
|
if (!_file)
|
||
|
{
|
||
|
return (FILE)-2;
|
||
|
}
|
||
|
|
||
|
return (FILE)_file->fd;
|
||
|
}
|
||
|
|
||
|
return (FILE)-3;
|
||
|
}
|
||
|
|
||
|
|
||
|
FILE write_file(FILE file, void* data, size_t len)
|
||
|
{
|
||
|
|
||
|
if (file < 1 || !data || len == 0)
|
||
|
{
|
||
|
return file;
|
||
|
}
|
||
|
|
||
|
if (ramfs_get_initialized() && vfs_initialized)
|
||
|
{
|
||
|
|
||
|
ramfs_file_header_t* _file = ramfs_resolve_fd_dir(vfs_current_dir, file);
|
||
|
|
||
|
if (!_file)
|
||
|
{
|
||
|
return -4;
|
||
|
}
|
||
|
|
||
|
if (_file->type == RAMFS_FILE_DIR)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
if (_file->data_begin)
|
||
|
{
|
||
|
free(_file->data_begin);
|
||
|
_file->data_begin = NULL;
|
||
|
_file->data_end = NULL;
|
||
|
}
|
||
|
|
||
|
void* new_buf = malloc(len);
|
||
|
if (!new_buf)
|
||
|
{
|
||
|
return -2;
|
||
|
}
|
||
|
|
||
|
memcpy(new_buf, data, len);
|
||
|
|
||
|
_file->data_begin = new_buf;
|
||
|
_file->data_end = (void*)((uint8_t*)new_buf + len);
|
||
|
|
||
|
return file;
|
||
|
}
|
||
|
|
||
|
return -3;
|
||
|
}
|
||
|
|
||
|
|
||
|
int32_t read_file(FILE file, void* buf, size_t buflen)
|
||
|
{
|
||
|
if (file < 1 || !buf || buflen == 0)
|
||
|
{
|
||
|
return -1; /* Invalid arguments */
|
||
|
}
|
||
|
|
||
|
if (ramfs_get_initialized() && vfs_initialized)
|
||
|
{
|
||
|
ramfs_file_header_t* _file = ramfs_resolve_fd_dir(vfs_current_dir, file);
|
||
|
|
||
|
if (!_file || _file->type == RAMFS_FILE_DIR)
|
||
|
{
|
||
|
return -2; /* Not a file or trying to read a directory */
|
||
|
}
|
||
|
|
||
|
if (!_file->data_begin || !_file->data_end)
|
||
|
{
|
||
|
return 0; /* Empty file */
|
||
|
}
|
||
|
|
||
|
size_t total_len = (size_t)((uint8_t*)_file->data_end - (uint8_t*)_file->data_begin);
|
||
|
|
||
|
if (_file->read_offset >= (int32_t)total_len)
|
||
|
{
|
||
|
return 0; /* End of file */
|
||
|
}
|
||
|
|
||
|
size_t available = total_len - _file->read_offset;
|
||
|
size_t to_copy = (buflen < available) ? buflen : available;
|
||
|
|
||
|
memcpy(buf, (uint8_t*)_file->data_begin + _file->read_offset, to_copy);
|
||
|
|
||
|
_file->read_offset += to_copy;
|
||
|
|
||
|
return (int32_t)to_copy;
|
||
|
}
|
||
|
|
||
|
return -3; /* FS not initialized */
|
||
|
}
|
||
|
|
||
|
int32_t reset_read_offset(FILE file)
|
||
|
{
|
||
|
if (file < 1)
|
||
|
{
|
||
|
return -1;
|
||
|
}
|
||
|
|
||
|
ramfs_file_header_t* _file = ramfs_resolve_fd_dir(vfs_current_dir, file);
|
||
|
|
||
|
if (!_file)
|
||
|
{
|
||
|
return -2;
|
||
|
}
|
||
|
|
||
|
_file->read_offset = 0;
|
||
|
return 0;
|
||
|
}
|
||
|
|
||
|
int32_t seek_file(FILE file, int32_t offset)
|
||
|
{
|
||
|
if (file < 0 && file != -32 && file != -33)
|
||
|
{
|
||
|
return -1; /* Invalid file descriptor */
|
||
|
}
|
||
|
|
||
|
ramfs_file_header_t* _file = ramfs_resolve_fd_dir(vfs_current_dir, file);
|
||
|
|
||
|
if (!_file || _file->type == RAMFS_FILE_DIR)
|
||
|
return -2; // Invalid file or directory
|
||
|
|
||
|
if (!_file->data_begin || !_file->data_end)
|
||
|
return -3; // Empty file
|
||
|
|
||
|
size_t file_size = (size_t)((uint8_t*)_file->data_end - (uint8_t*)_file->data_begin);
|
||
|
|
||
|
if (offset < 0 || (size_t)offset > file_size)
|
||
|
return -4; // Offset out of bounds
|
||
|
|
||
|
_file->read_offset = offset;
|
||
|
return 0; // Success
|
||
|
}
|
||
|
|