aboutsummaryrefslogtreecommitdiff
path: root/src/kernel/fs/iso9660.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/kernel/fs/iso9660.c')
-rw-r--r--src/kernel/fs/iso9660.c113
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 :*/