diff options
Diffstat (limited to 'src/kernel/fs')
-rw-r--r-- | src/kernel/fs/iso9660.c | 113 |
1 files changed, 50 insertions, 63 deletions
diff --git a/src/kernel/fs/iso9660.c b/src/kernel/fs/iso9660.c index 958bd9a..192f8ae 100644 --- a/src/kernel/fs/iso9660.c +++ b/src/kernel/fs/iso9660.c @@ -8,14 +8,14 @@ static void iso9660_fs_shutdown(fs_ptr f); static bool iso9660_node_stat(fs_node_ptr n, stat_t *st); static void iso9660_node_dispose(fs_node_ptr n); -static bool iso9660_dir_open(fs_node_ptr n, int mode, fs_handle_t *s); +static void iso9660_node_close(fs_node_ptr f); + +static bool iso9660_dir_open(fs_node_ptr n, int mode); static bool iso9660_dir_walk(fs_node_ptr n, const char* file, struct fs_node *node_d); -static bool iso9660_file_open(fs_node_ptr n, int mode, fs_handle_t *s); +static bool iso9660_dir_readdir(fs_node_ptr f, size_t ent_no, dirent_t *d); -static size_t iso9660_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf); -static void iso9660_fh_close(fs_handle_ptr f); -static bool iso9660_dh_readdir(fs_handle_ptr f, dirent_t *d); -static void iso9660_dh_close(fs_handle_ptr f); +static bool iso9660_file_open(fs_node_ptr n, int mode); +static size_t iso9660_file_read(fs_node_ptr f, size_t offset, size_t len, char* buf); static fs_driver_ops_t iso9660_driver_ops = { .make = iso9660_make, @@ -34,6 +34,11 @@ static fs_node_ops_t iso9660_dir_ops = { .delete = 0, .move = 0, .create = 0, + .readdir = iso9660_dir_readdir, + .close = iso9660_node_close, + .read = 0, + .write = 0, + .ioctl = 0, }; static fs_node_ops_t iso9660_file_ops = { @@ -44,26 +49,11 @@ static fs_node_ops_t iso9660_file_ops = { .delete = 0, .move = 0, .create = 0, -}; - -static fs_handle_ops_t iso9660_dh_ops = { - .readdir = iso9660_dh_readdir, - .close = iso9660_dh_close, - .read = 0, - .write = 0, - .ioctl = 0, - .get_page = 0, - .commit_page = 0, -}; - -static fs_handle_ops_t iso9660_fh_ops = { .readdir = 0, - .close = iso9660_fh_close, - .read = iso9660_fh_read, + .close = iso9660_node_close, + .read = iso9660_file_read, .write = 0, .ioctl = 0, - .get_page = 0, - .commit_page = 0, }; void register_iso9660_driver() { @@ -144,7 +134,7 @@ static void dr_stat(iso9660_dr_t *dr, stat_t *st) { if (dr->flags & ISO9660_DR_FLAG_DIR) { st->type = FT_DIR; st->access = FM_READDIR; - st->size = (dr->size.lsb / 256); + st->size = dr->size.lsb; // TODO: precise item count ? } else { st->type = FT_REGULAR; st->access = FM_READ; @@ -166,21 +156,13 @@ void iso9660_node_dispose(fs_node_ptr n) { free(node); } -bool iso9660_dir_open(fs_node_ptr n, int mode, fs_handle_t *s) { - iso9660_node_t *node = (iso9660_node_t*)n; +void iso9660_node_close(fs_node_ptr f) { + // nothing to do +} +bool iso9660_dir_open(fs_node_ptr n, int mode) { if (mode != FM_READDIR) return false; - iso9660_dh_t *handle = (iso9660_dh_t*)malloc(sizeof(iso9660_dh_t)); - if (handle == 0) return false; - - handle->n = node; - handle->pos = 0; - - s->mode = mode; - s->data = handle; - s->ops = &iso9660_dh_ops; - return true; } @@ -220,7 +202,11 @@ bool iso9660_dir_walk(fs_node_ptr n, const char* search_for, struct fs_node *nod n->fs = node->fs; node_d->data = n; - node_d->ops = (dr->flags & ISO9660_DR_FLAG_DIR ? &iso9660_dir_ops : &iso9660_file_ops); + if (dr->flags & ISO9660_DR_FLAG_DIR) { + node_d->ops = &iso9660_dir_ops; + } else { + node_d->ops = &iso9660_file_ops; + } return true; } @@ -228,18 +214,13 @@ bool iso9660_dir_walk(fs_node_ptr n, const char* search_for, struct fs_node *nod return false; // not found } -bool iso9660_file_open(fs_node_ptr n, int mode, fs_handle_t *s) { - iso9660_node_t *node = (iso9660_node_t*)n; - +bool iso9660_file_open(fs_node_ptr n, int mode) { if (mode != FM_READ) return false; - s->data = node; - s->ops = &iso9660_fh_ops; - s->mode = mode; return true; } -size_t iso9660_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf) { +size_t iso9660_file_read(fs_node_ptr f, size_t offset, size_t len, char* buf) { iso9660_node_t *node = (iso9660_node_t*)f; if (offset >= node->dr.size.lsb) return 0; @@ -277,43 +258,49 @@ size_t iso9660_fh_read(fs_handle_ptr f, size_t offset, size_t len, char* buf) { return ret; } -void iso9660_fh_close(fs_handle_ptr f) { +void iso9660_file_close(fs_node_ptr f) { // nothing to do } -bool iso9660_dh_readdir(fs_handle_ptr f, dirent_t *d) { - iso9660_dh_t *handle = (iso9660_dh_t*)f; - iso9660_node_t *node = handle->n; +bool iso9660_dir_readdir(fs_node_ptr n, size_t ent_no, dirent_t *d) { + // Very nonefficient !! - while (true) { - if (handle->pos >= node->dr.size.lsb) return false; + iso9660_node_t *node = (iso9660_node_t*)n; - if (handle->pos % 2048 == 0) { - if (file_read(node->fs->disk, node->dr.lba_loc.lsb * 2048 + handle->pos, 2048, handle->buffer) != 2048) + char buffer[2048]; + size_t dr_len = 0; + size_t idx = 0; + for (size_t pos = 0; pos < node->dr.size.lsb; pos += dr_len) { + if (pos % 2048 == 0) { + if (file_read(node->fs->disk, node->dr.lba_loc.lsb * 2048 + pos, 2048, buffer) != 2048) return false; } - iso9660_dr_t *dr = (iso9660_dr_t*)(handle->buffer + (handle->pos % 2048)); - if (node->fs->use_lowercase) convert_dr_to_lowercase(dr); + iso9660_dr_t *dr = (iso9660_dr_t*)(buffer + (pos % 2048)); + dr_len = dr->len; + if (dr_len == 0) return false; - handle->pos += dr->len; + if (node->fs->use_lowercase) convert_dr_to_lowercase(dr); + char* name = dr->name; size_t len = dr->name_len - 2; - if (dr->name_len > 0 && dr->name[len] == ';') { + + if (name[len] != ';') continue; + + if (idx == ent_no) { + // Found the node we are interested in if (len >= DIR_MAX) len = DIR_MAX - 1; - memcpy(d->name, dr->name, len); + memcpy(d->name, name, len); d->name[len] = 0; + dr_stat(dr, &d->st); return true; + } else { + idx++; } - // else skip this record } -} - -void iso9660_dh_close(fs_handle_ptr f) { - iso9660_dh_t* handle = (iso9660_dh_t*)f; - free(handle); + return false; // not found } /* vim: set ts=4 sw=4 tw=0 noet :*/ |