From 3a09acff4f1ea8c9e66be8fd9abf8aa422f02017 Mon Sep 17 00:00:00 2001 From: Yann MAGNIN Date: Fri, 21 Apr 2023 12:49:06 +0200 Subject: [PATCH] fsctl - v0.0.0-2 : add fugue logger *add* > [fugue] | [logger] add logger interface *update* > [fugue] | [dirent] proper rename "dir" to more appropriate "dirent" | [dirent] proper isolate dirent initialisation routine | [cluster] prepare cluster walk handling (WIP) | [dir] proper isolate dirent handling > [menu] | [info] display fs logger | [list] proper opendir handling > [utils] | [fs_table] initialize fs logger --- CMakeLists.txt | 4 +- include/fsctl/fugue.h | 8 +- include/fsctl/fugue/bits/{dir.h => dirent.h} | 6 +- include/fsctl/fugue/bits/fs.h | 3 + include/fsctl/fugue/bits/logger.h | 40 +++++++ include/fsctl/fugue/dirent.h | 9 +- include/fsctl/fugue/logger.h | 28 +++++ include/fsctl/utils/fs_table.h | 1 + src/fugue/core/cluster.c | 8 ++ src/fugue/core/dirent.c | 32 +++++- src/fugue/core/fat.c | 1 - src/fugue/dir.c | 33 +++--- src/fugue/logger.c | 104 +++++++++++++++++++ src/menu/info.c | 98 ++++++++++++++++- src/menu/list.c | 5 +- src/utils/fs_table.c | 3 + 16 files changed, 343 insertions(+), 40 deletions(-) rename include/fsctl/fugue/bits/{dir.h => dirent.h} (79%) create mode 100644 include/fsctl/fugue/bits/logger.h create mode 100644 include/fsctl/fugue/logger.h create mode 100644 src/fugue/logger.c diff --git a/CMakeLists.txt b/CMakeLists.txt index 6088550..5996a9d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -8,11 +8,13 @@ set(SOURCES src/main.c # fugue - src/fugue/mount.c src/fugue/dir.c + src/fugue/mount.c + src/fugue/logger.c src/fugue/core/cluster.c src/fugue/core/sector.c src/fugue/core/fat.c + src/fugue/core/dirent.c # menu src/menu/rom.c diff --git a/include/fsctl/fugue.h b/include/fsctl/fugue.h index 830cbad..6006e6b 100644 --- a/include/fsctl/fugue.h +++ b/include/fsctl/fugue.h @@ -2,7 +2,7 @@ #define FSCTL_FUGUE_H 1 #include "fsctl/fugue/bits/fs.h" -#include "fsctl/fugue/bits/dir.h" +#include "fsctl/fugue/bits/dirent.h" #include "fsctl/fugue/bits/file.h" //--- @@ -13,12 +13,12 @@ extern int fugue_fs_mount(fugue_fs_t *fsinfo, void *addr); /* fugue_fs_opendir() : opendir-like function */ -extern int fugue_fs_opendir(fugue_dir_t *dir); +extern int fugue_fs_opendir(fugue_dirent_t *dirent); /* fugue_fs_readdir() : readdir-like function */ -extern int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file); +extern int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file); /* fugue_fs_closedir() : closedir-like function */ -extern int fugue_fs_closedir(fugue_dir_t *dir); +extern int fugue_fs_closedir(fugue_dirent_t *dirent); #endif /* FSCTL_FUGUE_H */ diff --git a/include/fsctl/fugue/bits/dir.h b/include/fsctl/fugue/bits/dirent.h similarity index 79% rename from include/fsctl/fugue/bits/dir.h rename to include/fsctl/fugue/bits/dirent.h index bccfc9d..ecaf2ce 100644 --- a/include/fsctl/fugue/bits/dir.h +++ b/include/fsctl/fugue/bits/dirent.h @@ -6,8 +6,8 @@ #include "fsctl/fugue/bits/fs.h" -/* fugue_dir : Fugue directory abstraction */ -struct fugue_dir +/* fugue_dirent : Fugue directory abstraction */ +struct fugue_dirent { /* middle-level information */ uintptr_t current_dir_addr; @@ -21,6 +21,6 @@ struct fugue_dir } _private; }; -typedef struct fugue_dir fugue_dir_t; +typedef struct fugue_dirent fugue_dirent_t; #endif /* FSCTL_FUGUE_BITS_DIR_H */ diff --git a/include/fsctl/fugue/bits/fs.h b/include/fsctl/fugue/bits/fs.h index a343fc0..4ff6efe 100644 --- a/include/fsctl/fugue/bits/fs.h +++ b/include/fsctl/fugue/bits/fs.h @@ -4,6 +4,8 @@ #include #include +#include "fsctl/fugue/bits/logger.h" + /* fugue_fs : Fugue File System abstraction */ struct fugue_fs { @@ -41,6 +43,7 @@ struct fugue_fs void *fat0; void *fat1; void *root; + fugue_logger_t *logger; } _private; }; typedef struct fugue_fs fugue_fs_t; diff --git a/include/fsctl/fugue/bits/logger.h b/include/fsctl/fugue/bits/logger.h new file mode 100644 index 0000000..8eebd5d --- /dev/null +++ b/include/fsctl/fugue/bits/logger.h @@ -0,0 +1,40 @@ +#ifndef FSCTL_FUGUE_BITS_LOGGER_H +#define FSCTL_FUGUE_BITS_LOGGER_H 1 + +#include +#include +#include +#include + +/* fugue_logger : simple FS logger information */ +struct fugue_logger +{ +#if 0 + /* logger primitive (can be NULL) + * - init() : initialize buffer and internal information + * - clear() : clear the content of the buffer (reset) + * - vwrite() : inject a text in the buffer (va_arg version) + * - getlines() : fetch the line starting at `*lineptr` + * - quit() : uninitialize buffer and internal information */ + struct { + int (*init)(struct fugue_logger *l, size_t buffer_size); + int (*clear)(struct fugue_logger *l); + ssize_t (*vwrite)(struct fugue_logger *l, char *text, va_list ap); + ssize_t (*getline)(struct fugue_logger *l, char **lineptr, size_t *n); + int (*quit)(struct fugue_logger *logger); + } primitive; +#endif + /* buffer geometry information + * - buffer.data : buffer data + * - buffer.size : buffer size + * - buffer.inject_pos : text injection position + * */ + struct { + char *data; + size_t size; + int pos; + } buffer; +}; +typedef struct fugue_logger fugue_logger_t; + +#endif /* FSCTL_FUGUE_BITS_LOGGER_H */ diff --git a/include/fsctl/fugue/dirent.h b/include/fsctl/fugue/dirent.h index 224907f..1e88e17 100644 --- a/include/fsctl/fugue/dirent.h +++ b/include/fsctl/fugue/dirent.h @@ -1,19 +1,22 @@ #ifndef FSCTL_FUGUE_DIRENT_H #define FSCTL_FUGUE_DIRENT_H 1 -#include "fsctl/fugue/bits/dir.h" +#include "fsctl/fugue/bits/dirent.h" #include "fsctl/fugue/bits/file.h" //--- // API //--- +/* fugue_dirent_init() : init dirent object */ +extern int fugue_dirent_init(fugue_dirent_t *dirent, fugue_fs_t *fs); + /* fugue_dirent_dir_fetch() : fetch the current dir blob and walk to next */ -extern void *fugue_dirent_dir_fetch(fugue_dir_t *dirent); +extern void *fugue_dirent_dir_fetch(fugue_dirent_t *dirent); /* fugue_dirent_name_fetch() : fetch fragment */ extern int fugue_dirent_name_fetch( - fugue_dir_t *dirent, + fugue_dirent_t *dirent, fugue_file_t *file, void *dir ); diff --git a/include/fsctl/fugue/logger.h b/include/fsctl/fugue/logger.h new file mode 100644 index 0000000..d4f52fb --- /dev/null +++ b/include/fsctl/fugue/logger.h @@ -0,0 +1,28 @@ +#ifndef FUGUE_LOGGER_H +#define FUGUE_LOGGER_H 1 + +#include "fsctl/fugue/bits/logger.h" + +//--- +// API +//--- + +/* fugue_logger_init() : initialize internal logger buffer at fixed size */ +extern int fugue_logger_init(fugue_logger_t *logger, size_t buffer_size); + +/* fugue_logger_quit() : uninit logger internal information */ +extern int fugue_logger_quit(fugue_logger_t *logger); + +/* fugue_logger_clear() : clear buffer content */ +extern int fugue_logger_clear(fugue_logger_t *logger); + +/* fugue_logger_getline() : getline-like function */ +extern ssize_t fugue_logger_getline(fugue_logger_t *l, char **s, size_t *n); + +/* fugue_logger_vwrite() : write primitive (va-arg) */ +extern ssize_t fugue_logger_vwrite(fugue_logger_t *l, char *f, va_list ap); + +/* fugue_logger_write() : write primitive */ +extern ssize_t fugue_logger_write(fugue_logger_t *l, char *f, ...); + +#endif /* FUGUE_LOGGER_H */ diff --git a/include/fsctl/utils/fs_table.h b/include/fsctl/utils/fs_table.h index 614980d..437852c 100644 --- a/include/fsctl/utils/fs_table.h +++ b/include/fsctl/utils/fs_table.h @@ -16,6 +16,7 @@ struct fs_table bool is_valid; uintptr_t vbr; fugue_fs_t fs; + fugue_logger_t logger; }; typedef struct fs_table fs_table_t; diff --git a/src/fugue/core/cluster.c b/src/fugue/core/cluster.c index 0509466..95740cf 100644 --- a/src/fugue/core/cluster.c +++ b/src/fugue/core/cluster.c @@ -6,6 +6,14 @@ // Public //--- +/* fugue_cluster_find_next() : find the next cluster address if available */ +uintptr_t fugue_cluster_find_next(fugue_fs_t *fs, uint32_t cluster_idx) +{ + (void)fs; + (void)cluster_idx; + return 0x00000000; +} + /* fugue_cluster_is_valid() : check cluster validity */ //TODO : support FAT12 / FAT32 int fugue_cluster_is_valid(fugue_fs_t *fs, int cluster_idx) diff --git a/src/fugue/core/dirent.c b/src/fugue/core/dirent.c index f368b5b..125bd0f 100644 --- a/src/fugue/core/dirent.c +++ b/src/fugue/core/dirent.c @@ -1,5 +1,6 @@ #include "fsctl/fugue/dirent.h" #include "fsctl/fugue/cluster.h" +#include "fsctl/fugue/logger.h" #include "fsctl/fugue/bits/fat.h" //--- @@ -32,8 +33,22 @@ static uint8_t _fugue_dirent_checksum(uintptr_t directory) // Public //--- +/* fugue_dirent_init() : init dirent object */ +int fugue_dirent_init(fugue_dirent_t *dirent, fugue_fs_t *fs) +{ + if (fs == NULL || dirent == NULL) + return -1; + memset(dirent, 0x00, sizeof(fugue_dirent_t)); + memcpy(&dirent->_private.fs, &fs, sizeof(fugue_fs_t)); + dirent->current_dir_addr = (uintptr_t)fs->_private.root; + dirent->cluster_addr_start = (uintptr_t)fs->_private.root; + dirent->cluster_addr_end = (uintptr_t)fs->_private.root; + dirent->cluster_addr_end += fs->props.sector_root_nb * 512; + return 0; +} + /* fugue_dirent_dir_fetch() : fetch the current dir blob and walk to next */ -void *fugue_dirent_dir_fetch(fugue_dir_t *dirent) +void *fugue_dirent_dir_fetch(fugue_dirent_t *dirent) { void *dir; @@ -56,11 +71,16 @@ void *fugue_dirent_dir_fetch(fugue_dir_t *dirent) } /* fugue_dirent_name_fetch() : fetch fragment */ -int fugue_dirent_name_fetch(fugue_dir_t *dirent, fugue_file_t *file, void *dir) -{ +int fugue_dirent_name_fetch( + fugue_dirent_t *dirent, + fugue_file_t *file, + void *dir +) { + fugue_logger_t *log; struct fugue_fat_dir_name *lfn; lfn = (void *)dir; + log = dirent->_private.fs._private.logger; //--- // check directory block validity @@ -73,13 +93,17 @@ int fugue_dirent_name_fetch(fugue_dir_t *dirent, fugue_file_t *file, void *dir) if (lfn->DIR_FstClus != 0x0000) return -3; //TODO : check Secquence validity - if (lfn->checksum != _fugue_dirent_checksum(dirent->current_dir_addr)) + if (lfn->checksum != _fugue_dirent_checksum(dirent->current_dir_addr)) { + fugue_logger_write(log, "[WARN] checksum error at %p", lfn); return -5; + } //--- // Dump name fragment //--- //TODO: dump + (void)file; + fugue_logger_write(log, "[ERR] name dump error at %p", lfn); return -1; } diff --git a/src/fugue/core/fat.c b/src/fugue/core/fat.c index dfe3f55..5e0b540 100644 --- a/src/fugue/core/fat.c +++ b/src/fugue/core/fat.c @@ -68,7 +68,6 @@ int fugue_fat_is_vaild(fugue_fs_t *fs) continue; } fs->props.cluster_error += 1; - fs->props.test = cluster; } return 0; } diff --git a/src/fugue/dir.c b/src/fugue/dir.c index 644a993..7a21782 100644 --- a/src/fugue/dir.c +++ b/src/fugue/dir.c @@ -15,27 +15,22 @@ //--- /* fugue_fs_opendir() : opendir-like function */ -int fugue_fs_opendir(fugue_dir_t *dir) +int fugue_fs_opendir(fugue_dirent_t *dirent) { fugue_fs_t fs; - if (dir == NULL) + if (dirent == NULL) return -1; if (fs_table_info(&fs, NULL, NULL) != 0) return -2; - memset(dir, 0x00, sizeof(fugue_dir_t)); - memcpy(&dir->_private.fs, &fs, sizeof(fugue_fs_t)); - dir->current_dir_addr = (uintptr_t)fs._private.root; - dir->cluster_addr = (uintptr_t)fs._private.root; - dir->cluster_size = fs.props.sector_root_nb * 512; - return 0; + return fugue_dirent_init(dirent, &fs); } /* fugue_fs_readdir() : readdir-like function */ -int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file) +int fugue_fs_readdir(fugue_dirent_t *dirent, fugue_file_t *file) { struct fugue_fat_dir *dir; - fugue_dir_t dirent_backup; + fugue_dirent_t dirent_backup; bool error; bool vfat; @@ -47,7 +42,7 @@ int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file) return -2; memset(file, 0x00, sizeof(fugue_file_t)); - memcpy(&dirent_backup, dirent, sizeof(fugue_dir_t)); + memcpy(&dirent_backup, dirent, sizeof(fugue_dirent_t)); vfat = false; error = false; @@ -100,8 +95,8 @@ int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file) switch(dir->DIR_Attr) { /* handle file name fragment */ - case FUGUE_DIR_ATTR_VNAME: - fugue_dirent_name_fetch(dirent, file); + case FUGUE_DIR_ATTR_LFN: + fugue_dirent_name_fetch(dirent, file, dir); vfat = true; break; @@ -126,19 +121,19 @@ int fugue_fs_readdir(fugue_dir_t *dirent, fugue_file_t *file) } /* error handling */ - memcpy(dirent, &dirent_backup, sizeof(fugue_dir_t)); + memcpy(dirent, &dirent_backup, sizeof(fugue_dirent_t)); memset(file, 0x00, sizeof(fugue_file_t)); return -1; } /* fugue_fs_closedir() : closedir-like function */ -int fugue_fs_closedir(fugue_dir_t *dir) +int fugue_fs_closedir(fugue_dirent_t *dir) { if (dir == NULL) return -1; - memset(dir, 0x00, sizeof(fugue_dir_t)); - dir->current_dir_addr = 0x00000000; - dir->cluster_addr = 0x00000000; - dir->cluster_size = 0; + memset(dir, 0x00, sizeof(fugue_dirent_t)); + dir->current_dir_addr = 0x00000000; + dir->cluster_addr_start = 0x00000000; + dir->cluster_addr_end = 0; return 0; } diff --git a/src/fugue/logger.c b/src/fugue/logger.c new file mode 100644 index 0000000..6960f2d --- /dev/null +++ b/src/fugue/logger.c @@ -0,0 +1,104 @@ +#include +#include +#include + +#include "fsctl/fugue/logger.h" + +//--- +// Public +//--- + +/* fugue_logger_init() : initialize internal logger buffer at fixed size */ +int fugue_logger_init(fugue_logger_t *logger, size_t buffer_size) +{ + if (logger == NULL) + return -1; + logger->buffer.data = calloc(buffer_size, sizeof(char)); + if (logger->buffer.data == NULL) + return -1; + logger->buffer.size = buffer_size; + logger->buffer.pos = 0; + return 0; +} + +/* fugue_logger_quit() : uninit logger internal information */ +int fugue_logger_quit(fugue_logger_t *logger) +{ + if (logger == NULL) + return -1; + if (logger->buffer.data == NULL) + return -1; + free(logger->buffer.data); + logger->buffer.data = NULL; + logger->buffer.size = 0; + logger->buffer.pos = 0; + return 0; +} + +/* fugue_logger_clear() : clear buffer content */ +int fugue_logger_clear(fugue_logger_t *logger) +{ + if (logger == NULL) + return -1; + memset(logger->buffer.data, 0x00, logger->buffer.size); + logger->buffer.pos = 0; + return 0; +} + +/* fugue_logger_getline() : getline-like function */ +ssize_t fugue_logger_getline(fugue_logger_t *logger, char **str, size_t *ssz) +{ + char *str_end; + + if (logger == NULL) + return -1; + if (*str == NULL) { + *str = &logger->buffer.data[0]; + } else { + str_end = &((*str)[*ssz]); + if (str_end[0] == '\0') { + *str = NULL; + *ssz = 0; + return -1; + } + if (str_end[0] == '\n') { + *str = &str_end[1]; + } + } + str_end = strchrnul(*str, '\n'); + *ssz = (ptrdiff_t)(str_end - *str); + return 0; +} + +/* fugue_logger_vwrite() : write primitive (va-arg) */ +ssize_t fugue_logger_vwrite(fugue_logger_t *logger, char *format, va_list ap) +{ + int sz; + + if (logger == NULL) + return -1; + if (logger->buffer.pos >= (signed)logger->buffer.size) + return -1; + sz = vsnprintf( + &logger->buffer.data[logger->buffer.pos], + logger->buffer.size - logger->buffer.pos, + format, + ap + ); + logger->buffer.pos += sz; + return sz; +} + +/* fugue_logger_write() : write primitive (va-arg) */ +ssize_t fugue_logger_write(fugue_logger_t *logger, char *format, ...) +{ + va_list ap; + ssize_t sz; + + if (logger == NULL) + return -1; + va_start(ap, format); + sz = fugue_logger_vwrite(logger, format, ap); + va_end(ap); + return sz; +} diff --git a/src/menu/info.c b/src/menu/info.c index 3f22432..23c9dc2 100644 --- a/src/menu/info.c +++ b/src/menu/info.c @@ -2,6 +2,7 @@ #include "fsctl/menu/info.h" #include "fsctl/fugue.h" +#include "fsctl/fugue/logger.h" #include "fsctl/utils/display.h" #include "fsctl/utils/fs_table.h" @@ -9,24 +10,92 @@ // Public //--- +static int logs_line_start; +static int logs_line_disp; +static int logs_test; + /* info_menu_init() : init menu */ void info_menu_init(void) { - ; + logs_line_start = 0; + logs_line_disp = 17; + logs_test = -1; } /* info_menu_display() : display menu */ //TODO : logger display void info_menu_display(void) { + fugue_logger_t *log; fugue_fs_t fs; - int y; + char *str; + size_t ssz; + int line_nb; + int line_curr; fs_table_dtitle(); if (fs_table_info(&fs, NULL, NULL) != 0) return; - y = 0; + log = fs._private.logger; + + switch(logs_test) + { + case 1: + fugue_logger_clear(log); + logs_line_start = 0; + break; + case 2: + fugue_logger_write(log, "one line log test\n"); + break; + case 3: + fugue_logger_write(log, "two lines log test\n-line 2\n"); + break; + case 4: + fugue_logger_write(log, "two lines log test\n- unfinished"); + break; + } + logs_test = -1; + + ssz = 0; + str = NULL; + line_nb = 0; + while (fugue_logger_getline(log, &str, &ssz) == 0) + { + if (line_nb < logs_line_start) { + line_nb += 1; + continue; + } + line_curr = line_nb - logs_line_start; + if (line_curr >= logs_line_disp) { + line_nb += 1; + continue; + } + + dtext_opt( + 1, 15 + (line_curr * 11), + C_BLACK, C_NONE, + DTEXT_TOP, DTEXT_LEFT, + str, ssz + 1 + ); + line_nb += 1; + } + + if (line_nb > logs_line_disp + 1) + { + int granularity = 190 / line_nb; + int y_start = granularity * logs_line_start; + int y_size = granularity * logs_line_disp; + dline(390, 1 + y_start, 390, y_start + y_size, C_BLACK); + dline(391, 1 + y_start, 391, y_start + y_size, C_BLACK); + dline(393, 0, 393, 190, C_BLACK); + } + + dprint(300, 15, C_BLACK, "start=%d", logs_line_start); + dprint(300, 26, C_BLACK, "line_nb=%d", line_nb); + +#if 0 + int y = 0; _printXY(0, ++y, "FS type = %s", fs.props.type); _printXY(0, ++y, "capacity = %d", fs.props.capacity); _printXY(0, ++y, "cluster free = %d", fs.props.cluster_free); @@ -42,6 +111,7 @@ void info_menu_display(void) _printXY(0, ++y, "FAT0 size = %d", fs.props.fat0_size); _printXY(0, ++y, "FAT1 size = %d", fs.props.fat1_size); _printXY(0, ++y, "Root addr = %p", fs._private.root); +#endif } /* info_menu_keyboard() : handle keyboard */ @@ -55,5 +125,27 @@ void info_menu_keyboard(int key) case KEY_RIGHT: fs_table_select_right(); break; + case KEY_UP: + if (logs_line_start > 0) + logs_line_start -= 1; + break; + case KEY_DOWN: + logs_line_start += 1; + break; + + /* test */ + + case KEY_1: + logs_test = 1; + break; + case KEY_2: + logs_test = 2; + break; + case KEY_3: + logs_test = 3; + break; + case KEY_4: + logs_test = 4; + break; } } diff --git a/src/menu/list.c b/src/menu/list.c index 9ad8b06..23986cd 100644 --- a/src/menu/list.c +++ b/src/menu/list.c @@ -16,14 +16,15 @@ void list_menu_init(void) /* fat1_menu_display() : display menu */ void list_menu_display(void) { - fugue_dir_t dir; + fugue_dirent_t dir; fugue_file_t file; int y; fs_table_dtitle(); + if (fugue_fs_opendir(&dir) != 0) + return; y = 0; - fugue_fs_opendir(&dir); while (fugue_fs_readdir(&dir, &file) == 0) { _printXY(0, ++y, "(%d) %s", file.size, file.name); diff --git a/src/utils/fs_table.c b/src/utils/fs_table.c index c702148..36f3df0 100644 --- a/src/utils/fs_table.c +++ b/src/utils/fs_table.c @@ -4,6 +4,7 @@ #include #include "fsctl/utils/fs_table.h" +#include "fsctl/fugue/logger.h" //--- // Internals @@ -30,6 +31,8 @@ static int fs_table_append(fugue_fs_t *fs) return -1; memcpy(&check[fs_table.slots].fs, fs, sizeof(fugue_fs_t)); + fugue_logger_init(&check[fs_table.slots].logger, 4096); + check[fs_table.slots].fs._private.logger = &check[fs_table.slots].logger; fs_table.table = check; fs_table.slots = fs_table.slots + 1; if (fs_table.idx < 0)