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
This commit is contained in:
Yann MAGNIN 2023-04-21 12:49:06 +02:00
parent b089b00882
commit 3a09acff4f
16 changed files with 343 additions and 40 deletions

View File

@ -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

View File

@ -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 */

View File

@ -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 */

View File

@ -4,6 +4,8 @@
#include <stdint.h>
#include <stddef.h>
#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;

View File

@ -0,0 +1,40 @@
#ifndef FSCTL_FUGUE_BITS_LOGGER_H
#define FSCTL_FUGUE_BITS_LOGGER_H 1
#include <stdint.h>
#include <stddef.h>
#include <sys/types.h>
#include <stdarg.h>
/* 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 */

View File

@ -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
);

View File

@ -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 */

View File

@ -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;

View File

@ -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)

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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;
}

104
src/fugue/logger.c Normal file
View File

@ -0,0 +1,104 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#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;
}

View File

@ -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;
}
}

View File

@ -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);

View File

@ -4,6 +4,7 @@
#include <gint/display.h>
#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)