aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/fs/vfs.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/fs/vfs.c')
-rw-r--r--src/kernel/fs/vfs.c153
1 files changed, 151 insertions, 2 deletions
diff --git a/src/kernel/fs/vfs.c b/src/kernel/fs/vfs.c
index 2b4cda4..6d29eed 100644
--- a/src/kernel/fs/vfs.c
+++ b/src/kernel/fs/vfs.c
@@ -3,6 +3,8 @@
#include <kernel/fs/vfs.h>
#include <kernel/fs/ext2.h>
#include <kernel/lib/stdlib.h>
+#include <kernel/memory/alloc.h>
+#include <kernel/system.h>
struct fs_node *fs_root = NULL;
@@ -27,7 +29,7 @@ void fs_open(struct fs_node *node)
if (node->open != NULL)
node->open(node);
else // TODO: Better ext2 default open workaround
- ext2_root->open(node);
+ fs_root->open(node);
}
void fs_close(struct fs_node *node)
@@ -35,7 +37,7 @@ void fs_close(struct fs_node *node)
if (node->close != NULL)
node->close(node);
else
- ext2_root->open(node);
+ fs_root->open(node);
}
struct dirent *fs_read_dir(struct fs_node *node, uint32_t index)
@@ -52,4 +54,151 @@ struct fs_node *fs_find_dir(struct fs_node *node, char *name)
return node->find_dir(node, name);
else
return (struct fs_node *)NULL;
+}
+
+// TODO: This should be somewhere else ig
+char *next_str(char *str)
+{
+ str = &str[strlen(str)];
+
+ int i = 0;
+ while (str[i] == 0)
+ i++;
+
+ return &str[i];
+}
+
+// By far not the fastest algorithm
+struct fs_node *fs_path(struct fs_node *node, char *name)
+{
+ if (name[0] == '/')
+ return node;
+
+ char *cpy = (char *)kmalloc(strlen(name) + 2);
+ strcpy(cpy, name);
+ cpy[strlen(name) + 1] = 1;
+
+ name = cpy;
+ char *end = &name[strlen(name)];
+
+ int len = strlen(name);
+ for (int i = 0; i < len; i++)
+ if (name[i] == '/')
+ name[i] = 0;
+
+ if (strlen(name) == 0)
+ name = next_str(name);
+
+ do {
+ node = node->node_ptr;
+
+ while (node != NULL) {
+ if (strcmp(node->name, name) == 0)
+ break;
+
+ node = node->link;
+ }
+
+ if (node == NULL) {
+ kfree(cpy);
+ return NULL;
+ }
+
+ name = next_str(name);
+ } while ((uint32_t)name < (uint32_t)end);
+
+ kfree(cpy);
+ return node;
+}
+
+void vfs_ls(char *path)
+{
+ struct fs_node *dir = fs_path(fs_root, path);
+ if (dir == NULL) {
+ warn("Invalid path");
+ return;
+ }
+
+ struct fs_node *link = dir->node_ptr;
+
+ log("Listing for %s", path);
+ while (link != NULL) {
+ log(link->name);
+ link = link->link;
+ }
+}
+
+struct fs_node *vfs_get_dir(struct fs_node *node, char *name)
+{
+ char *cpy = (char *)kmalloc(strlen(name) + 2);
+ char *ref = cpy;
+ strcpy(cpy, name);
+ cpy[strlen(name) + 1] = 1;
+ name = cpy;
+
+ for (int i = strlen(name); i >= 0; i--)
+ if (name[i] == '/') {
+ name[i] = 0;
+ break;
+ }
+
+ struct fs_node *output;
+ if (strlen(name) == 0)
+ output = fs_root;
+ else
+ output = fs_path(node, name);
+
+ kfree(ref);
+ return output;
+}
+
+char *basename(char *name)
+{
+ int i;
+ for (i = strlen(name); i >= 0; i--)
+ if (name[i] == '/')
+ return &name[i + 1];
+
+ return name;
+}
+
+// TODO: Implement file touching in ext2
+struct fs_node *vfs_touch(struct fs_node *node, char *name)
+{
+ struct fs_node *dir = vfs_get_dir(node, name);
+
+ if (dir == NULL)
+ return NULL;
+
+ struct fs_node *file = (struct fs_node *)kmalloc(sizeof(struct fs_node));
+ ext2_node_init(file);
+ file->type = FILE_NODE;
+ strcpy(file->name, basename(name));
+
+ //ext2_file *entry = ext2_new_file();
+ //strcpy(file->name, entry->name);
+
+ file->link = dir->node_ptr;
+ dir->node_ptr = file;
+
+ return file;
+}
+
+struct fs_node *vfs_mkdir(struct fs_node *node, char *name)
+{
+ struct fs_node *dir = vfs_get_dir(node, name);
+ if (dir == NULL) {
+ warn("Invalid path");
+ return NULL;
+ }
+
+ struct fs_node *file = (struct fs_node *)kmalloc(sizeof(struct fs_node));
+ ext2_node_init(file);
+ file->type = DIR_NODE;
+ strcpy(file->name, basename(name));
+
+ file->link = dir->node_ptr;
+ dir->node_ptr = file;
+
+ return file;
} \ No newline at end of file