diff options
author | Marvin Borner | 2022-01-01 18:20:11 +0100 |
---|---|---|
committer | Marvin Borner | 2022-01-01 18:20:11 +0100 |
commit | 6a1f4e4d394b3c5ff7a7d1c58a8775a645275e4a (patch) | |
tree | aecf46ad188b047301578f5707a171d7c63b2a8e | |
parent | 0d665f1bf585930b1b6c45f53fe23f6fa07b398f (diff) |
Implementing..
-rw-r--r-- | inc/spec.h | 12 | ||||
-rw-r--r-- | makefile | 4 | ||||
-rw-r--r-- | src/fuse.c | 120 |
3 files changed, 109 insertions, 27 deletions
@@ -17,7 +17,7 @@ #define MARFS_ENTRY_SIZE 1024 #define MARFS_DIR_ENTRY 1 -#define MARFS_FILE_ENTRY 2; +#define MARFS_FILE_ENTRY 2 #define MARFS_DIR_ENTRY_COUNT (MARFS_ENTRY_SIZE / sizeof(struct marfs_dir_entry_data)) @@ -35,24 +35,28 @@ struct marfs_header { struct marfs_entry_header { u32 type; + u32 id; u32 prev, next; // MARFS_END if end } PACKED; struct marfs_dir_entry_data { - char name[MARFS_NAME_LENGTH]; + char name[MARFS_NAME_LENGTH + 1]; + u32 length; struct marfs_pointer pointer; } PACKED; struct marfs_dir_entry { struct marfs_entry_header header; + u32 count; struct marfs_dir_entry_data entries[MARFS_DIR_ENTRY_COUNT]; - u8 padding[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header) - + u8 padding[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header) - sizeof(u32) - (MARFS_DIR_ENTRY_COUNT * sizeof(struct marfs_dir_entry_data))]; } PACKED; struct marfs_file_entry { struct marfs_entry_header header; - u8 data[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header)]; + u32 size; + u8 data[MARFS_ENTRY_SIZE - sizeof(struct marfs_entry_header) - sizeof(u32)]; } PACKED; #endif @@ -47,13 +47,13 @@ $(MNT): mount: disk $(MNT) @DEV=$$(losetup -a | grep $(BUILD)/disk.img | grep -m 1 -o '/dev/loop[[:digit:]]*') && \ PART="p1" && \ - ($(BUILD)/marfs_fuse "$$DEV$$PART" -f $(MNT) &) && \ + ($(SU) $(BUILD)/marfs_fuse "$$DEV$$PART" -f $(MNT) &) && \ echo "Mounted $$DEV$$PART" umount: @DEV=$$(losetup -a | grep $(BUILD)/disk.img | grep -m 1 -o '/dev/loop[[:digit:]]*') && \ $(SU) losetup -d "$$DEV" && \ - umount $(MNT) && \ + $(SU) umount $(MNT) && \ echo "Unmounted $$DEV$$PART" || \ echo "No disk to unmount" @@ -7,6 +7,7 @@ #include <spec.h> +#include <assert.h> #include <errno.h> #include <fuse.h> #include <limits.h> @@ -16,9 +17,11 @@ #include <sys/time.h> #include <time.h> -static char *image = 0; +static FILE *image = NULL; -static void marfs_debug(const char *fmt, ...) +static struct marfs_header header = { 0 }; + +static void debug(const char *fmt, ...) { printf("\t>>> "); va_list args; @@ -28,9 +31,56 @@ static void marfs_debug(const char *fmt, ...) printf("\n"); } +static void sector(u32 index, u32 size, void *buf) +{ + fseek(image, index * header.entry_size, SEEK_SET); + assert(fread(buf, 1, size, image) == size); +} + +// first -> start = header.main.head +static u8 read_entry_header(const char *path, u32 start, struct marfs_entry_header *entry_header) +{ + while (*path && *path == '/') + path++; + + struct marfs_entry_header h; + sector(start, sizeof(h), &h); + + if (h.type == MARFS_DIR_ENTRY) { + struct marfs_dir_entry entry; + sector(start, sizeof(entry), &entry); + assert(entry.count <= MARFS_DIR_ENTRY_COUNT); + for (u32 i = 0; i < entry.count; i++) { + struct marfs_dir_entry_data *data = &entry.entries[i]; + if (!strncmp(path, data->name, data->length)) { + if (path[data->length] == '/') { + return read_entry_header(path, data->pointer.head, + entry_header); + } + if (!path[data->length]) { + *entry_header = h; + return 1; + } + } + } + + if (entry.header.next != MARFS_END) + return read_entry_header(path, entry.header.next, entry_header); + } else if (h.type == MARFS_FILE_ENTRY) { + *entry_header = h; + return 1; + } + + return 0; +} + +/** + * Fuse operations + */ + static void *marfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) { - marfs_debug("init()"); + debug("init()"); UNUSED(conn); cfg->kernel_cache = 1; return NULL; @@ -38,26 +88,28 @@ static void *marfs_init(struct fuse_conn_info *conn, struct fuse_config *cfg) static void marfs_destroy(void *data) { - marfs_debug("destroy()"); + debug("destroy()"); + UNUSED(data); + if (image) - free(image); + fclose(image); } static int marfs_open(const char *file_path, struct fuse_file_info *file_info) { - marfs_debug("open() on %s", file_path); + debug("open() on %s", file_path); return 0; } static int marfs_opendir(const char *dir_path, struct fuse_file_info *file_info) { - marfs_debug("opendir() on %s", dir_path); + debug("opendir() on %s", dir_path); return 0; } static int marfs_getattr(const char *path, struct stat *stat, struct fuse_file_info *info) { - marfs_debug("getattr() on %s", path); + debug("getattr() on %s", path); UNUSED(info); memset(stat, 0, sizeof(*stat)); @@ -76,7 +128,7 @@ static int marfs_getattr(const char *path, struct stat *stat, struct fuse_file_i static int marfs_readdir(const char *path, void *buf, fuse_fill_dir_t fill, off_t offset, struct fuse_file_info *file_info, enum fuse_readdir_flags flags) { - marfs_debug("readdir() on %s and offset %lu", path, offset); + debug("readdir() on %s and offset %lu", path, offset); UNUSED(offset); UNUSED(file_info); @@ -93,70 +145,70 @@ static int marfs_readdir(const char *path, void *buf, fuse_fill_dir_t fill, off_ static int marfs_release(const char *path, struct fuse_file_info *file_info) { - marfs_debug("release() on %s", path); + debug("release() on %s", path); return 0; } static int marfs_releasedir(const char *path, struct fuse_file_info *file_info) { - marfs_debug("releasedir() on %s", path); + debug("releasedir() on %s", path); return 0; } static int marfs_read(const char *path, char *buf, size_t to_read, off_t offset, struct fuse_file_info *file_info) { - marfs_debug("read() on %s, %lu", path, to_read); + debug("read() on %s, %lu", path, to_read); return to_read; } static int marfs_write(const char *path, const char *buf, size_t to_write, off_t offset, struct fuse_file_info *file_info) { - marfs_debug("write() on %s", path); + debug("write() on %s", path); return to_write; } static int marfs_create(const char *path, mode_t mode, struct fuse_file_info *file_info) { - marfs_debug("create() on %s", path); + debug("create() on %s", path); return 0; } static int marfs_mkdir(const char *path, mode_t mode) { - marfs_debug("mkdir() on %s", path); + debug("mkdir() on %s", path); return 0; } static int marfs_unlink(const char *path) { - marfs_debug("unlink() on %s", path); + debug("unlink() on %s", path); return 0; } static int marfs_rmdir(const char *path) { - marfs_debug("rmdir() on %s", path); + debug("rmdir() on %s", path); return 0; } static int marfs_utimens(const char *path, const struct timespec tv[2], struct fuse_file_info *file_info) { - marfs_debug("utimens() on %s", path); + debug("utimens() on %s", path); return 0; } static int marfs_truncate(const char *path, off_t size, struct fuse_file_info *file_info) { - marfs_debug("truncate() on %s, size %lu", path, size); + debug("truncate() on %s, size %lu", path, size); return 0; } static int marfs_rename(const char *path, const char *new, unsigned int flags) { - marfs_debug("rename() on %s -> %s", path, new); + debug("rename() on %s -> %s", path, new); return 0; } @@ -188,10 +240,36 @@ int main(int argc, char **argv) } // I don't think that's how fuse is supposed to work but idc - image = strdup(argv[1]); + char *path = argv[1]; argv++; argc--; + image = fopen(path, "r"); + if (!image) { + fprintf(stderr, "error: invalid image path '%s' specified: %s\n", path, + strerror(errno)); + exit(1); + } + + int head_read = fread(&header, 1, sizeof(header), image); + if (head_read != sizeof(header)) { + fprintf(stderr, "error: could not read full header: %d\n", head_read); + fclose(image); + exit(1); + } + + if (strcmp(header.magic, MARFS_MAGIC) != 0) { + fprintf(stderr, "error: invalid header magic: %s\n", header.magic); + fclose(image); + exit(1); + } + + if (header.version != MARFS_SPEC_VERSION) { + fprintf(stderr, "error: non-supported spec-version %d\n", header.version); + fclose(image); + exit(1); + } + fuse_main(argc, argv, &operations, NULL); return 0; |