summaryrefslogtreecommitdiffstats
path: root/qemu/roms/openbios/fs/iso9660/iso9660_opendir.c
diff options
context:
space:
mode:
Diffstat (limited to 'qemu/roms/openbios/fs/iso9660/iso9660_opendir.c')
-rw-r--r--qemu/roms/openbios/fs/iso9660/iso9660_opendir.c133
1 files changed, 133 insertions, 0 deletions
diff --git a/qemu/roms/openbios/fs/iso9660/iso9660_opendir.c b/qemu/roms/openbios/fs/iso9660/iso9660_opendir.c
new file mode 100644
index 000000000..49eab4b42
--- /dev/null
+++ b/qemu/roms/openbios/fs/iso9660/iso9660_opendir.c
@@ -0,0 +1,133 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent@vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+
+static inline int iso9660_is_directory(struct iso_directory_record * idr)
+{
+ return ((idr->flags[0] & 2) != 0);
+}
+
+static iso9660_DIR* iso9660_opendir_node(iso9660_VOLUME *volume, struct iso_directory_record *node)
+{
+ iso9660_DIR *dir;
+
+ dir = (iso9660_DIR*)malloc(sizeof(iso9660_DIR));
+ if (dir == NULL)
+ return NULL;
+
+ dir->extent = isonum_733((char *)node->extent);
+ dir->len = isonum_733((char *)node->size);
+ dir->index = sizeof (dir->buffer);
+ dir->volume = volume;
+
+ return dir;
+}
+
+static struct iso_directory_record* idr_new(struct iso_directory_record* idr)
+{
+ struct iso_directory_record* result;
+ int size = sizeof(*idr) + (int)idr->name_len[0];
+
+ result = (struct iso_directory_record*)malloc(size);
+ memcpy(result, idr, size);
+
+ return result;
+}
+
+static struct iso_directory_record * seek_name(iso9660_VOLUME *volume,
+ struct iso_directory_record *idr,
+ char *name)
+{
+ struct iso_directory_record *result;
+ char name_buf[256];
+ iso9660_DIR *dir;
+
+ dir = iso9660_opendir_node(volume, idr);
+ if (dir == NULL)
+ return NULL;
+
+ while ((idr = iso9660_readdir(dir)) != NULL)
+ {
+ iso9660_name(volume, idr, name_buf);
+ if (strcasecmp(name, name_buf) == 0)
+ {
+ result = idr_new(idr);
+ iso9660_closedir(dir);
+ return result;
+ }
+ }
+ iso9660_closedir(dir);
+ return NULL;
+}
+
+struct iso_directory_record* iso9660_get_node(
+ iso9660_VOLUME *volume,
+ struct iso_directory_record *dirnode,
+ const char *path)
+{
+ struct iso_directory_record* result;
+ struct iso_directory_record* current;
+ char name[256];
+ int i;
+
+ current = idr_new(dirnode);
+ while(1)
+ {
+ /* ignore head '\' */
+
+ while (*path && *path == '\\')
+ path++;
+
+ if (*path == 0)
+ break;
+
+ /* extract first path component */
+
+ i = 0;
+ while (*path && *path != '\\')
+ name[i++] = *path++;
+ name[i] = 0;
+
+ /* seek first component in current directory */
+
+ result = seek_name(volume, current, name);
+ if (result == NULL)
+ return NULL;
+
+ free(current);
+ current = result;
+ }
+ return current;
+}
+
+iso9660_DIR* iso9660_opendir(iso9660_VOLUME *volume, const char *name)
+{
+ iso9660_DIR *dir;
+ struct iso_directory_record *node;
+
+ node = iso9660_get_root_node((iso9660_VOLUME*)volume);
+ if (node == NULL)
+ return NULL;
+
+ node = iso9660_get_node((iso9660_VOLUME*)volume, node, name);
+ if (node == NULL)
+ return NULL;
+ if (!iso9660_is_directory(node)) {
+ free(node);
+ return NULL;
+ }
+
+ dir = iso9660_opendir_node((iso9660_VOLUME*)volume, node);
+
+ free(node);
+
+ dir->volume = (iso9660_VOLUME*)volume;
+
+ return dir;
+}