/* Calcite, src/kernel/fs.c * Copyright 2025 Benji Dial * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * for more details. * * You should have received a copy of the GNU General Public License along * with this program. If not, see . */ #include "iso9660.h" #include "utility.h" #include "debug.h" #include "heap.h" #include "fs.h" #include enum fs_access_result create_fs_info( const struct drive_info *drive, struct fs_info *fs_out, const char *fs_type) { if (strequ(fs_type, "iso9660")) return create_iso9660_info(drive, fs_out); return FAR_UNKNOWN_FS_TYPE; } struct set_fs { const char *name; const struct fs_info *fs; }; struct set_fs *set_fses; int set_fses_buffer_length = 0; int set_fses_count = 0; #define SET_FSES_INITIAL_LENGTH 16 void set_fs(const char *name, const struct fs_info *fs) { assert(get_fs(name) == 0) if (set_fses_buffer_length == 0) { set_fses = heap_alloc(SET_FSES_INITIAL_LENGTH * sizeof(struct set_fs)); set_fses_buffer_length = SET_FSES_INITIAL_LENGTH; } else if (set_fses_count == set_fses_buffer_length) { struct set_fs *new_set_fses = heap_alloc(2 * set_fses_buffer_length * sizeof(struct set_fs)); memcpy(new_set_fses, set_fses, set_fses_count * sizeof(struct set_fs)); heap_dealloc(set_fses, set_fses_count * sizeof(struct set_fs)); set_fses = new_set_fses; set_fses_buffer_length *= 2; } set_fses[set_fses_count].name = name; set_fses[set_fses_count].fs = fs; ++set_fses_count; } const struct fs_info *get_fs(const char *name) { for (int i = 0; i < set_fses_count; ++i) if (strequ(set_fses[i].name, name)) return set_fses[i].fs; return 0; } enum fs_access_result look_up_file( const char *uri, const struct fs_info **fs_out, void **node_out) { int colon = 0; while (1) { if (uri[colon] == ':') break; if (uri[colon] == 0) panic("bad uri") ++colon; } if (uri[colon + 1] != '/' || uri[colon + 2] != '/') panic("bad uri") char *uri_copy = heap_alloc(colon + 1); memcpy(uri_copy, uri, colon); uri_copy[colon] = 0; *fs_out = get_fs(uri_copy); heap_dealloc(uri_copy, colon + 1); if (!*fs_out) return FAR_NOT_FOUND; return (*(*fs_out)->look_up_file)(*fs_out, node_out, &uri[colon + 3]); }