147 lines
3.9 KiB
C
147 lines
3.9 KiB
C
#include "vfs.h"
|
|
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <gint/bfile.h>
|
|
#include <gint/cpu.h>
|
|
#include <gint/drivers.h>
|
|
#include <gint/keyboard.h>
|
|
#include <gint/kmalloc.h>
|
|
|
|
#include <printf.h>
|
|
|
|
#include "../term.h"
|
|
|
|
extern void _name_to_str(char *dest, const uint16_t *source, int n);
|
|
extern void _str_to_name(uint16_t *dest, const char *source, int n);
|
|
extern int _find_first(const uint16_t *pathname, int *FindHandle, const uint16_t *foundfile, struct BFile_FileInfo *fileinfo);
|
|
extern int _find_next(int FindHandle, const uint16_t *foundfile, struct BFile_FileInfo *fileinfo);
|
|
|
|
static vfs_entry_t vfs_root;
|
|
|
|
static vfs_entry_t *vfs_new_dir(const char *name, vfs_entry_t *parent) {
|
|
vfs_entry_t *newdir = kmalloc(sizeof(vfs_entry_t), NULL);
|
|
|
|
strcpy((char *)&newdir->name, name);
|
|
newdir->parent = parent;
|
|
newdir->type = vfs_dir;
|
|
newdir->driver = 0;
|
|
newdir->childs = NULL;
|
|
newdir->next = NULL;
|
|
|
|
newdir->next = parent->childs;
|
|
parent->childs = newdir;
|
|
|
|
return newdir;
|
|
}
|
|
|
|
static vfs_entry_t *vfs_new_file(const char *name, vfs_entry_t *parent) {
|
|
vfs_entry_t *newfile = kmalloc(sizeof(vfs_entry_t), NULL);
|
|
|
|
strcpy((char *)&newfile->name, name);
|
|
newfile->parent = parent;
|
|
newfile->type = vfs_file;
|
|
newfile->driver = 0;
|
|
newfile->childs = NULL;
|
|
newfile->next = NULL;
|
|
|
|
newfile->next = parent->childs;
|
|
parent->childs = newfile;
|
|
|
|
return newfile;
|
|
}
|
|
|
|
static void vfs_debug_tree_(int indent, vfs_entry_t *subtree) {
|
|
vfs_entry_t *child = subtree->childs;
|
|
|
|
while (child != NULL) {
|
|
for (int i = 0; i < indent; i++)
|
|
term_print(" ");
|
|
|
|
if (child->type == vfs_file)
|
|
term_printf("%s\n", child->name);
|
|
else if (child->type == vfs_dir) {
|
|
term_printf("%s/\n", child->name);
|
|
vfs_debug_tree_(indent + 1, child);
|
|
}
|
|
|
|
child = child->next;
|
|
}
|
|
}
|
|
|
|
static void vfs_debug_tree(void) {
|
|
term_print("/\n");
|
|
vfs_debug_tree_(1, &vfs_root);
|
|
}
|
|
|
|
static int shandle;
|
|
static void populate_vfs(const char *path, vfs_entry_t *dir) {
|
|
char glob[64];
|
|
strcpy(glob, path);
|
|
strcat(glob, "\\*");
|
|
|
|
uint16_t glob_c16[64];
|
|
_str_to_name(glob_c16, glob, 64);
|
|
|
|
uint16_t foundfile[64];
|
|
struct BFile_FileInfo fileinfo;
|
|
int ret = _find_first(glob_c16, &shandle, foundfile, &fileinfo);
|
|
while (ret == 0) {
|
|
char foundfile_str[64];
|
|
_name_to_str(foundfile_str, foundfile, 64);
|
|
|
|
if (foundfile_str[0] != '@' && strcmp(foundfile_str, ".") != 0 && strcmp(foundfile_str, "..") != 0) {
|
|
if (fileinfo.type == BFile_Type_Directory) {
|
|
vfs_new_dir(foundfile_str, dir);
|
|
} else {
|
|
vfs_new_file(foundfile_str, dir);
|
|
}
|
|
}
|
|
|
|
ret = _find_next(shandle, foundfile, &fileinfo);
|
|
}
|
|
BFile_FindClose(shandle);
|
|
|
|
// we do the recursive search when the search handle
|
|
// has been closed to avoid using too much handles
|
|
|
|
vfs_entry_t *child = dir->childs;
|
|
while (child != NULL) {
|
|
if (child->type == vfs_dir) {
|
|
char new_path[64];
|
|
sprintf(new_path, "%s\\%s", path, child->name);
|
|
|
|
populate_vfs(new_path, child);
|
|
}
|
|
|
|
child = child->next;
|
|
}
|
|
}
|
|
|
|
void vfs_init(void) {
|
|
// init fs root
|
|
strcpy((char *)&vfs_root.name, "");
|
|
vfs_root.parent = NULL;
|
|
vfs_root.type = vfs_dir;
|
|
vfs_root.driver = 0;
|
|
vfs_root.childs = NULL;
|
|
vfs_root.next = NULL;
|
|
|
|
vfs_entry_t *native = vfs_new_dir("native", &vfs_root);
|
|
vfs_entry_t *flash = vfs_new_dir("flash", native);
|
|
|
|
cpu_atomic_start();
|
|
// gint_world_switch_in(gint_world_addin, gint_world_os);
|
|
populate_vfs("\\\\fls0", flash);
|
|
// gint_world_switch_in(gint_world_os, gint_world_addin);
|
|
cpu_atomic_end();
|
|
|
|
vfs_debug_tree();
|
|
}
|
|
|
|
// const vfs_entry_t *vfs_get_root(void) { return &vfs_root; }
|
|
|
|
// vfs_entry* find_entry(const char* path) {
|
|
// // TODO
|
|
// }
|