:: commit b1c305abc50f3f62891ebc6f6acc43c7f1008b52

Shreyas Lad <shadowtemplates@gmail.com> — 2020-04-21 20:03

parents: 55137edb33

Added ext2 subdirectory support (#6)

* updated ext2-test rule

* added strtok

* added ext2 subdirectory support

* reverted partition numbers

* simplified parsing

* reworked parsing logic

* reverted qloader2.cfg
diff --git a/src/fs/ext2fs.c b/src/fs/ext2fs.c
index 7fc58244..b703e922 100644
--- a/src/fs/ext2fs.c
+++ b/src/fs/ext2fs.c
@@ -200,32 +200,61 @@ static int ext2fs_get_inode(struct ext2fs_inode *ret, uint64_t drive, struct par
     return 0;

 }

 

-static int ext2fs_parse_dirent(struct ext2fs_dir_entry *dir, struct ext2fs_file_handle *fd, const char *filename) {

-    uint64_t offset = fd->root_inode.i_blocks[0] * fd->block_size;

+static int ext2fs_parse_dirent(struct ext2fs_dir_entry *dir, struct ext2fs_file_handle *fd, struct ext2fs_superblock *sb, const char *path) {

+    int path_len = strlen(path);

 

-    while (offset < fd->root_inode.i_size + offset) {

-        // preliminary read

-        read_partition(fd->drive, &fd->part, dir, offset, sizeof(struct ext2fs_dir_entry));

+    char *cpy = path;

 

-        // name read

-        char* name = balloc(dir->name_len);

-        read_partition(fd->drive, &fd->part, name, offset + sizeof(struct ext2fs_dir_entry), dir->name_len);

+    if (*cpy = '/')

+        cpy++;

 

-        int r = strncmp(filename, name, dir->name_len);

+    int token_count;

+    for (int i = 0; i < path_len; i++) {

+        if (cpy[i] == '/')

+            token_count++;

+    }

+

+    const char *delimiter = "/";

+    char *token;

+    struct ext2fs_inode *current = &fd->root_inode;

+

+    for (int i = 0; i < (token_count + 1); i++) {

+        token = strtok(cpy, delimiter);

+

+        uint64_t offset = current->i_blocks[0] * fd->block_size;

+

+        while (offset < current->i_size + offset) {

+            // preliminary read

+            read_partition(fd->drive, &fd->part, dir, offset, sizeof(struct ext2fs_dir_entry));

 

-        brewind(dir->name_len);

+            // name read

+            char* name = balloc(dir->name_len);

+            read_partition(fd->drive, &fd->part, name, offset + sizeof(struct ext2fs_dir_entry), dir->name_len);

 

-        if (!r) {

-            return 0;

+            int r = strncmp(token, name, dir->name_len);

+

+            brewind(dir->name_len);

+

+            if (!r) {

+                if (i == token_count)

+                    return 0;

+                else

+                    break;

+            }

+

+            offset += dir->rec_len;

         }

 

-        offset += dir->rec_len;

+        cpy = NULL;

+

+        // update the current inode

+        ext2fs_get_inode(current, fd->drive, &fd->part, dir->inode, sb);

     }

 

     return 1;

 }

 

-int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const char* filename) {

+int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const char *path) {

     get_part(&ret->part, drive, partition);

 

     ret->drive = drive;

@@ -238,14 +267,14 @@ int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const
     ext2fs_get_inode(&ret->root_inode, drive, &ret->part, 2, &sb);

 

     struct ext2fs_dir_entry entry;

-    ext2fs_parse_dirent(&entry, ret, filename);

+    ext2fs_parse_dirent(&entry, ret, &sb, path);

     ext2fs_get_inode(&ret->inode, drive, &ret->part, entry.inode, &sb);

     ret->size = ret->inode.i_size;

 

     return 0;

 }

 

-int ext2fs_read(struct ext2fs_file_handle *file, void* buf, uint64_t loc, uint64_t count) {

+int ext2fs_read(struct ext2fs_file_handle *file, void *buf, uint64_t loc, uint64_t count) {

     // TODO: add support for the indirect block pointers

 

     for (uint64_t progress = 0; progress < count;) {

diff --git a/src/fs/ext2fs.h b/src/fs/ext2fs.h
index 71fd291d..2faf8e30 100644
--- a/src/fs/ext2fs.h
+++ b/src/fs/ext2fs.h
@@ -3,6 +3,7 @@
 

 #include <stdint.h>

 #include <stddef.h>

+#include <stdbool.h>

 #include <drivers/disk.h>

 #include <lib/libc.h>

 #include <lib/blib.h>

@@ -61,7 +62,7 @@ struct ext2fs_file_handle {
 

 int ext2fs_check_signature(int drive, int partition);

 

-int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const char* filename);

-int ext2fs_read(struct ext2fs_file_handle *file, void* buf, uint64_t loc, uint64_t count);

+int ext2fs_open(struct ext2fs_file_handle *ret, int drive, int partition, const char *path);

+int ext2fs_read(struct ext2fs_file_handle *file, void *buf, uint64_t loc, uint64_t count);

 

 #endif

diff --git a/src/lib/libc.c b/src/lib/libc.c
index 28674fca..f6ee8b32 100644
--- a/src/lib/libc.c
+++ b/src/lib/libc.c
@@ -111,3 +111,36 @@ size_t strlen(const char *str) {
 
     return len;
 }
+
+char *strtok(char *str, const char *delimiter) {
+    static char* buffer;
+
+    if (str != NULL) {
+        buffer = str;
+    }
+
+    if (buffer[0] == '\0') {
+        return NULL;
+    }
+
+    char* ret = buffer;
+
+    for (char* b = buffer; *b != '\0'; b++) {
+        for (const char* d = delimiter; *d != '\0'; d++) {
+            if(*b == *d) {
+                *b     = '\0';
+                buffer = b + 1;
+
+                // Skip the beginning delimiters
+                if (b == ret) {
+                    ret++;
+                    continue;
+                }
+
+                return ret;
+            }
+        }
+    }
+
+    return ret;
+}
diff --git a/src/lib/libc.h b/src/lib/libc.h
index 9699f4ae..2035ac41 100644
--- a/src/lib/libc.h
+++ b/src/lib/libc.h
@@ -13,5 +13,6 @@ char *strncpy(char *, const char *, size_t);
 size_t strlen(const char *);
 int strcmp(const char *, const char *);
 int strncmp(const char *, const char *, size_t);
+char *strtok(char *str, const char *delimiter);
 
 #endif
tab: 248 wrap: offon