#include #include #include #include #include static uint16_t duckfs_initialized = 0; static duckfs_file_header_t duckfs_root; const char* duckfs_versions[18] = { DFS_VERSION_0, DFS_VERSION_1, DFS_VERSION_2, DFS_VERSION_3, DFS_VERSION_4 }; int32_t duckfs_init(int16_t drive) { char duckfs_header_block[512]; if (ide_read48(drive, 0xA, 1, duckfs_header_block) != 0) { printf("[ DEBUG ] Disk read error on drive #%i\n", drive); return -1; } duckfs_superblock_t* superblock = (duckfs_superblock_t*)duckfs_header_block; /* if (superblock->duckfs_magic != (int32_t) DFS_MAGIC) { return -2; } bool compliant = false; for (int16_t i = 0; i < 5; ++i) { if (strcmp(superblock->duckfs_version_string, duckfs_versions[i]) == 0) { compliant = true; } } if (compliant == false) { return -3; }*/ memset(&duckfs_root, 0, sizeof(duckfs_root)); strncpy(duckfs_root.filename, "/", DFS_MAX_FILENAME_LEN); strncpy(duckfs_root.permissions, "RW", sizeof(duckfs_root.permissions)); duckfs_root.num_sectors = -1; duckfs_root.type = DFS_FILE_DIRECTORY; duckfs_root.next = NULL; duckfs_root.prev = NULL; duckfs_root.contents = NULL; duckfs_root.lba_start = 0; duckfs_root.lba_end = 0; duckfs_root.contents = malloc(sizeof(duckfs_file_header_t) * DFS_MAX_FILES); if (!duckfs_root.contents) { printf("Memory allocation failed for duckfs_root.contents\n"); return -4; } for (int32_t i = 0; i < DFS_MAX_FILES; i++) { duckfs_root.contents[i].type = DFS_FILE_UNUSED; } duckfs_initialized = 1; return 0; } void duckfs_format(int16_t drive) { /* Nothing to do, DuckFS does not require formatting. */ } int32_t duckfs_makedir(const char* filename, const char* perms) { duckfs_file_header_t* dir = malloc(sizeof(duckfs_file_header_t)); if (!dir) { return -1; } if (strlen(perms) < 3) { return -2; } char p[3] = { "." }; p[0] = perms[0]; p[1] = perms[1]; p[2] = perms[2]; char filen[DFS_MAX_FILENAME_LEN + 1]; char perma[3]; strcpy(filen, filename); strcpy(perma, perms); strncpy(dir->filename, filen, sizeof(dir->filename) - 1); dir->filename[sizeof(dir->filename) - 1] = '\0'; strncpy(dir->permissions, p, sizeof(dir->permissions)); dir->type = DFS_FILE_DIRECTORY; dir->contents = malloc(sizeof(duckfs_file_header_t) * DFS_MAX_FILES); if (!dir->contents) { free(dir); return -1; } for (int i = 0; i < DFS_MAX_FILES; i++) { dir->contents[i].type = DFS_FILE_UNUSED; } return 0; } void duckfs_free_directory(duckfs_file_header_t* dir) { if (!dir || dir->type != DFS_FILE_DIRECTORY || !dir->contents) { return; } for (int i = 0; i < DFS_MAX_FILES; i++) { duckfs_file_header_t* entry = &dir->contents[i]; if (entry->type == DFS_FILE_UNUSED) { continue; } if (entry->type == DFS_FILE_DIRECTORY) { duckfs_free_directory(entry); } } free(dir->contents); dir->contents = NULL; } bool duckfs_add_entry(duckfs_file_header_t* dir, duckfs_file_header_t* entry) { if (dir->type != DFS_FILE_DIRECTORY || !dir->contents) { return false; } for (int i = 0; i < DFS_MAX_FILES; i++) { if (dir->contents[i].type == DFS_FILE_UNUSED) { dir->contents[i] = *entry; return true; } } return false; /* Directory full */ } duckfs_file_header_t duckfs_create_entry(const char* name, const char* perms, const char* type) { duckfs_file_header_t entry = {0}; strncpy(entry.filename, name, DFS_MAX_FILENAME_LEN); strncpy(entry.permissions, perms, sizeof(entry.permissions) - 1); int16_t itype = DFS_FILE_UNUSED; if (strcmp(type, "text") == 0) { itype = DFS_FILE_TEXT; } else if (strcmp(type, "bin") == 0) { itype = DFS_FILE_BINARY; } else if (strcmp(type, "dir") == 0) { itype = DFS_FILE_BINARY; } else { duckfs_file_header_t vvvv = { .type = DFS_FILE_ERROR }; return vvvv; } entry.num_sectors = 0; entry.type = itype; entry.next = NULL; entry.prev = NULL; entry.contents = NULL; entry.lba_start = 0; entry.lba_end = 0; if (itype == DFS_FILE_DIRECTORY) { entry.contents = malloc(sizeof(duckfs_file_header_t) * DFS_MAX_FILES); if (entry.contents) { for (int i = 0; i < DFS_MAX_FILES; i++) { entry.contents[i].type = DFS_FILE_UNUSED; } } } return entry; } duckfs_file_header_t duckfs_makefile(const char* filename, const char* perms, duckfs_file_header_t parent) { }