[OpenBIOS] r626 - in trunk/openbios-devel: config/examples config/scripts fs fs/iso9660 include/openbios modules
svn at openbios.org
svn at openbios.org
Sun Nov 22 10:26:51 CET 2009
Author: laurent
Date: 2009-11-22 10:26:50 +0100 (Sun, 22 Nov 2009)
New Revision: 626
Added:
trunk/openbios-devel/fs/iso9660/
trunk/openbios-devel/fs/iso9660/build.xml
trunk/openbios-devel/fs/iso9660/iso9660.h
trunk/openbios-devel/fs/iso9660/iso9660_close.c
trunk/openbios-devel/fs/iso9660/iso9660_closedir.c
trunk/openbios-devel/fs/iso9660/iso9660_fs.c
trunk/openbios-devel/fs/iso9660/iso9660_fs.h
trunk/openbios-devel/fs/iso9660/iso9660_lseek.c
trunk/openbios-devel/fs/iso9660/iso9660_mount.c
trunk/openbios-devel/fs/iso9660/iso9660_open.c
trunk/openbios-devel/fs/iso9660/iso9660_opendir.c
trunk/openbios-devel/fs/iso9660/iso9660_read.c
trunk/openbios-devel/fs/iso9660/iso9660_readdir.c
trunk/openbios-devel/fs/iso9660/libiso9660.h
Modified:
trunk/openbios-devel/config/examples/cross-ppc_config.xml
trunk/openbios-devel/config/examples/ppc_config.xml
trunk/openbios-devel/config/scripts/switch-arch
trunk/openbios-devel/fs/build.xml
trunk/openbios-devel/include/openbios/fs.h
trunk/openbios-devel/modules/filesystems.c
Log:
Add a cleaner implementation of ISO9660.
Enable it for powerpc and cross-powerpc
Signed-off-by: Laurent Vivier <Laurent at vivier.Eu>
Modified: trunk/openbios-devel/config/examples/cross-ppc_config.xml
===================================================================
--- trunk/openbios-devel/config/examples/cross-ppc_config.xml 2009-11-22 09:04:27 UTC (rev 625)
+++ trunk/openbios-devel/config/examples/cross-ppc_config.xml 2009-11-22 09:26:50 UTC (rev 626)
@@ -50,6 +50,7 @@
<option name="CONFIG_FS" type="boolean" value="true"/>
<option name="CONFIG_HFS" type="boolean" value="true"/>
<option name="CONFIG_HFSP" type="boolean" value="true"/>
+ <option name="CONFIG_ISO9660" type="boolean" value="true"/>
<option name="CONFIG_GRUBFS" type="boolean" value="true"/>
<option name="CONFIG_FSYS_EXT2FS" type="boolean" value="true"/>
<option name="CONFIG_FSYS_FAT" type="boolean" value="false"/>
@@ -58,7 +59,7 @@
<option name="CONFIG_FSYS_REISERFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_XFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_UFS" type="boolean" value="false"/>
- <option name="CONFIG_FSYS_ISO9660" type="boolean" value="true"/>
+ <option name="CONFIG_FSYS_ISO9660" type="boolean" value="false"/>
<option name="CONFIG_FSYS_FFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_VSTAFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_NTFS" type="boolean" value="false"/>
Modified: trunk/openbios-devel/config/examples/ppc_config.xml
===================================================================
--- trunk/openbios-devel/config/examples/ppc_config.xml 2009-11-22 09:04:27 UTC (rev 625)
+++ trunk/openbios-devel/config/examples/ppc_config.xml 2009-11-22 09:26:50 UTC (rev 626)
@@ -51,6 +51,7 @@
<option name="CONFIG_FS" type="boolean" value="true"/>
<option name="CONFIG_HFS" type="boolean" value="true"/>
<option name="CONFIG_HFSP" type="boolean" value="true"/>
+ <option name="CONFIG_ISO9660" type="boolean" value="true"/>
<option name="CONFIG_GRUBFS" type="boolean" value="true"/>
<option name="CONFIG_FSYS_EXT2FS" type="boolean" value="true"/>
<option name="CONFIG_FSYS_FAT" type="boolean" value="false"/>
@@ -59,7 +60,7 @@
<option name="CONFIG_FSYS_REISERFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_XFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_UFS" type="boolean" value="false"/>
- <option name="CONFIG_FSYS_ISO9660" type="boolean" value="true"/>
+ <option name="CONFIG_FSYS_ISO9660" type="boolean" value="false"/>
<option name="CONFIG_FSYS_FFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_VSTAFS" type="boolean" value="false"/>
<option name="CONFIG_FSYS_NTFS" type="boolean" value="false"/>
Modified: trunk/openbios-devel/config/scripts/switch-arch
===================================================================
--- trunk/openbios-devel/config/scripts/switch-arch 2009-11-22 09:04:27 UTC (rev 625)
+++ trunk/openbios-devel/config/scripts/switch-arch 2009-11-22 09:26:50 UTC (rev 626)
@@ -166,6 +166,7 @@
mkdir -p $OBJDIR/target/fs/grubfs
mkdir -p $OBJDIR/target/fs/hfs
mkdir -p $OBJDIR/target/fs/hfsplus
+ mkdir -p $OBJDIR/target/fs/iso9660
mkdir -p $OBJDIR/target/drivers
mkdir -p $OBJDIR/target/libc
mkdir -p $OBJDIR/host/include
Modified: trunk/openbios-devel/fs/build.xml
===================================================================
--- trunk/openbios-devel/fs/build.xml 2009-11-22 09:04:27 UTC (rev 625)
+++ trunk/openbios-devel/fs/build.xml 2009-11-22 09:26:50 UTC (rev 626)
@@ -8,5 +8,6 @@
<include href="grubfs/build.xml"/>
<include href="hfs/build.xml"/>
<include href="hfsplus/build.xml"/>
+ <include href="iso9660/build.xml"/>
</build>
Added: trunk/openbios-devel/fs/iso9660/build.xml
===================================================================
--- trunk/openbios-devel/fs/iso9660/build.xml (rev 0)
+++ trunk/openbios-devel/fs/iso9660/build.xml 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,13 @@
+<build>
+ <library name="fs" type="static" target="target">
+ <object source="iso9660_fs.c" condition="ISO9660"/>
+ <object source="iso9660_close.c" condition="ISO9660"/>
+ <object source="iso9660_closedir.c" condition="ISO9660"/>
+ <object source="iso9660_lseek.c" condition="ISO9660"/>
+ <object source="iso9660_mount.c" condition="ISO9660"/>
+ <object source="iso9660_open.c" condition="ISO9660"/>
+ <object source="iso9660_opendir.c" condition="ISO9660"/>
+ <object source="iso9660_read.c" condition="ISO9660"/>
+ <object source="iso9660_readdir.c" condition="ISO9660"/>
+ </library>
+</build>
Added: trunk/openbios-devel/fs/iso9660/iso9660.h
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660.h (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660.h 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,58 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#ifndef __ISO9660_H__
+#define __ISO9660_H__
+
+#include "iso9660_fs.h"
+
+typedef struct iso9660_VOLUME {
+ int ucs_level;
+ struct iso_primary_descriptor *descriptor;
+ int fd;
+} iso9660_VOLUME;
+
+typedef struct iso9660_DIR {
+ iso9660_VOLUME *volume;
+ int extent;
+ int len;
+ int index;
+ unsigned char buffer[ISOFS_BLOCK_SIZE];
+} iso9660_DIR;
+
+typedef struct iso9660_FILE {
+ iso9660_VOLUME *volume;
+ char *path;
+ int base; /* first extent of the file */
+ int size; /* size of the file */
+ int offset;
+ int current;
+ unsigned char buffer[ISOFS_BLOCK_SIZE];
+} iso9660_FILE;
+
+static inline int isonum_721(char *p)
+{
+ return ((p[0] & 0xff)
+ | ((p[1] & 0xff) << 8));
+}
+
+static inline int isonum_723(char *p)
+{
+ return (isonum_721(p));
+}
+
+static inline int isonum_733(char *p)
+{
+ return ((p[0] & 0xff) | ((p[1] & 0xff) << 8) |
+ ((p[2] & 0xff) << 16) | ((p[3] & 0xff) << 24));
+}
+
+extern struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume);
+extern struct iso_directory_record* iso9660_get_node(iso9660_VOLUME *volume, struct iso_directory_record *dirnode, const char *path);
+
+#endif /* __ISO9660_H__ */
Added: trunk/openbios-devel/fs/iso9660/iso9660_close.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_close.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_close.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,15 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE bootloader, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+
+void iso9660_close(iso9660_FILE *file)
+{
+ free(file->path);
+ free(file);
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_closedir.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_closedir.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_closedir.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,19 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+
+int iso9660_closedir(iso9660_DIR *dir)
+{
+ if (dir == NULL)
+ return -1;
+
+ free(dir);
+
+ return 0;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_fs.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_fs.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_fs.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,104 @@
+/*
+ *
+ * (c) 2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ */
+
+#include "libiso9660.h"
+#include "openbios/fs.h"
+
+static void
+umount( fs_ops_t *fs )
+{
+ iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
+
+ iso9660_umount( volume );
+}
+
+static file_desc_t *
+open_path( fs_ops_t *fs, const char *path )
+{
+ iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
+ iso9660_FILE *file;
+
+ file = iso9660_open(volume, path);
+
+ return (file_desc_t *)file;
+}
+
+static char *
+get_path( file_desc_t *fd, char *buf, int size )
+{
+ iso9660_FILE *file = (iso9660_FILE*)fd;
+
+ strncpy(buf, file->path, size);
+
+ return buf;
+}
+
+static int
+file_lseek( file_desc_t *fd, off_t offs, int whence )
+{
+ iso9660_FILE *file = (iso9660_FILE*)fd;
+
+ return iso9660_lseek(file, offs, whence);
+}
+
+static void
+file_close( file_desc_t *fd )
+{
+ iso9660_FILE *file = (iso9660_FILE*)fd;
+
+ iso9660_close(file);
+}
+
+static int
+file_read( file_desc_t *fd, void *buf, size_t count )
+{
+ iso9660_FILE *file = (iso9660_FILE*)fd;
+
+ return iso9660_read(file, buf, count);
+}
+
+static char *
+vol_name( fs_ops_t *fs, char *buf, int size )
+{
+ iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
+
+ strncpy(buf, volume->descriptor->volume_id, size);
+
+ return buf;
+}
+
+static const char *
+get_fstype( fs_ops_t *fs )
+{
+ return "ISO9660";
+}
+
+static const fs_ops_t iso9660_ops = {
+ .close_fs = umount,
+
+ .open_path = open_path,
+ .get_path = get_path,
+ .close = file_close,
+ .read = file_read,
+ .lseek = file_lseek,
+
+ .vol_name = vol_name,
+ .get_fstype = get_fstype,
+};
+
+int fs_iso9660_open(int fd, fs_ops_t *fs)
+{
+ iso9660_VOLUME *volume;
+
+ volume = iso9660_mount(fd);
+ if (volume == NULL)
+ return -1;
+
+ *fs = iso9660_ops;
+ fs->fs_data = volume;
+
+ return 0;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_fs.h
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_fs.h (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_fs.h 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,161 @@
+#ifndef _ISO9660_FS_H
+#define _ISO9660_FS_H
+
+/* this file has been copied from linux 2.6.26 */
+
+/*
+ * The isofs filesystem constants/structures
+ */
+
+/* This part borrowed from the bsd386 isofs */
+#define ISODCL(from, to) (to - from + 1)
+
+struct iso_volume_descriptor {
+ char type[ISODCL(1,1)]; /* 711 */
+ char id[ISODCL(2,6)];
+ char version[ISODCL(7,7)];
+ char data[ISODCL(8,2048)];
+};
+
+/* volume descriptor types */
+#define ISO_VD_PRIMARY 1
+#define ISO_VD_SUPPLEMENTARY 2
+#define ISO_VD_END 255
+
+#define ISO_STANDARD_ID "CD001"
+
+struct iso_primary_descriptor {
+ char type [ISODCL ( 1, 1)]; /* 711 */
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)]; /* 711 */
+ char unused1 [ISODCL ( 8, 8)];
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char unused2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ char unused3 [ISODCL ( 89, 120)];
+ char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ char path_table_size [ISODCL (133, 140)]; /* 733 */
+ char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ char unused4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char unused5 [ISODCL (1396, 2048)];
+};
+
+/* Almost the same as the primary descriptor but two fields are specified */
+struct iso_supplementary_descriptor {
+ char type [ISODCL ( 1, 1)]; /* 711 */
+ char id [ISODCL ( 2, 6)];
+ char version [ISODCL ( 7, 7)]; /* 711 */
+ char flags [ISODCL ( 8, 8)]; /* 853 */
+ char system_id [ISODCL ( 9, 40)]; /* achars */
+ char volume_id [ISODCL ( 41, 72)]; /* dchars */
+ char unused2 [ISODCL ( 73, 80)];
+ char volume_space_size [ISODCL ( 81, 88)]; /* 733 */
+ char escape [ISODCL ( 89, 120)]; /* 856 */
+ char volume_set_size [ISODCL (121, 124)]; /* 723 */
+ char volume_sequence_number [ISODCL (125, 128)]; /* 723 */
+ char logical_block_size [ISODCL (129, 132)]; /* 723 */
+ char path_table_size [ISODCL (133, 140)]; /* 733 */
+ char type_l_path_table [ISODCL (141, 144)]; /* 731 */
+ char opt_type_l_path_table [ISODCL (145, 148)]; /* 731 */
+ char type_m_path_table [ISODCL (149, 152)]; /* 732 */
+ char opt_type_m_path_table [ISODCL (153, 156)]; /* 732 */
+ char root_directory_record [ISODCL (157, 190)]; /* 9.1 */
+ char volume_set_id [ISODCL (191, 318)]; /* dchars */
+ char publisher_id [ISODCL (319, 446)]; /* achars */
+ char preparer_id [ISODCL (447, 574)]; /* achars */
+ char application_id [ISODCL (575, 702)]; /* achars */
+ char copyright_file_id [ISODCL (703, 739)]; /* 7.5 dchars */
+ char abstract_file_id [ISODCL (740, 776)]; /* 7.5 dchars */
+ char bibliographic_file_id [ISODCL (777, 813)]; /* 7.5 dchars */
+ char creation_date [ISODCL (814, 830)]; /* 8.4.26.1 */
+ char modification_date [ISODCL (831, 847)]; /* 8.4.26.1 */
+ char expiration_date [ISODCL (848, 864)]; /* 8.4.26.1 */
+ char effective_date [ISODCL (865, 881)]; /* 8.4.26.1 */
+ char file_structure_version [ISODCL (882, 882)]; /* 711 */
+ char unused4 [ISODCL (883, 883)];
+ char application_data [ISODCL (884, 1395)];
+ char unused5 [ISODCL (1396, 2048)];
+};
+
+
+#define HS_STANDARD_ID "CDROM"
+
+struct hs_volume_descriptor {
+ char foo [ISODCL ( 1, 8)]; /* 733 */
+ char type [ISODCL ( 9, 9)]; /* 711 */
+ char id [ISODCL ( 10, 14)];
+ char version [ISODCL ( 15, 15)]; /* 711 */
+ char data[ISODCL(16,2048)];
+};
+
+
+struct hs_primary_descriptor {
+ char foo [ISODCL ( 1, 8)]; /* 733 */
+ char type [ISODCL ( 9, 9)]; /* 711 */
+ char id [ISODCL ( 10, 14)];
+ char version [ISODCL ( 15, 15)]; /* 711 */
+ char unused1 [ISODCL ( 16, 16)]; /* 711 */
+ char system_id [ISODCL ( 17, 48)]; /* achars */
+ char volume_id [ISODCL ( 49, 80)]; /* dchars */
+ char unused2 [ISODCL ( 81, 88)]; /* 733 */
+ char volume_space_size [ISODCL ( 89, 96)]; /* 733 */
+ char unused3 [ISODCL ( 97, 128)]; /* 733 */
+ char volume_set_size [ISODCL (129, 132)]; /* 723 */
+ char volume_sequence_number [ISODCL (133, 136)]; /* 723 */
+ char logical_block_size [ISODCL (137, 140)]; /* 723 */
+ char path_table_size [ISODCL (141, 148)]; /* 733 */
+ char type_l_path_table [ISODCL (149, 152)]; /* 731 */
+ char unused4 [ISODCL (153, 180)]; /* 733 */
+ char root_directory_record [ISODCL (181, 214)]; /* 9.1 */
+};
+
+/* We use this to help us look up the parent inode numbers. */
+
+struct iso_path_table{
+ unsigned char name_len[2]; /* 721 */
+ char extent[4]; /* 731 */
+ char parent[2]; /* 721 */
+ char name[0];
+} __attribute__((packed));
+
+/* high sierra is identical to iso, except that the date is only 6 bytes, and
+ there is an extra reserved byte after the flags */
+
+struct iso_directory_record {
+ char length [ISODCL (1, 1)]; /* 711 */
+ char ext_attr_length [ISODCL (2, 2)]; /* 711 */
+ char extent [ISODCL (3, 10)]; /* 733 */
+ char size [ISODCL (11, 18)]; /* 733 */
+ char date [ISODCL (19, 25)]; /* 7 by 711 */
+ char flags [ISODCL (26, 26)];
+ char file_unit_size [ISODCL (27, 27)]; /* 711 */
+ char interleave [ISODCL (28, 28)]; /* 711 */
+ char volume_sequence_number [ISODCL (29, 32)]; /* 723 */
+ unsigned char name_len [ISODCL (33, 33)]; /* 711 */
+ char name [0];
+} __attribute__((packed));
+
+#define ISOFS_BLOCK_BITS 11
+#define ISOFS_BLOCK_SIZE (1 << ISOFS_BLOCK_BITS)
+
+#endif /* _ISO9660_FS_H */
Added: trunk/openbios-devel/fs/iso9660/iso9660_lseek.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_lseek.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_lseek.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,37 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+
+int iso9660_lseek(iso9660_FILE *_file, long offset, int whence)
+{
+ iso9660_FILE *file = (iso9660_FILE*)_file;
+ long new_offset;
+
+ switch(whence)
+ {
+ case SEEK_SET:
+ new_offset = offset;
+ break;
+ case SEEK_CUR:
+ new_offset = file->offset + offset;
+ break;
+ case SEEK_END:
+ new_offset = file->size + offset;
+ break;
+ default:
+ return -1;
+ }
+
+ if ( (new_offset < 0) || (new_offset > file->size) )
+ return -1;
+
+ file->offset = new_offset;
+
+ return new_offset;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_mount.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_mount.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_mount.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,195 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ * some parts from mkisofs (c) J. Schilling
+ *
+ */
+
+#include "libiso9660.h"
+#include "openbios/bindings.h"
+#include "libc/diskio.h"
+
+void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record *idr, char *buffer)
+{
+ int j;
+ unsigned char uh, ul, uc;
+
+ buffer[0] = 0;
+ if (idr->name_len[0] == 1 && idr->name[0] == 0)
+ strcpy(buffer, ".");
+ else if (idr->name_len[0] == 1 && idr->name[0] == 1)
+ strcpy(buffer, "..");
+ else {
+ switch (volume->ucs_level) {
+ case 3:
+ case 2:
+ case 1:
+ /*
+ * Unicode name.
+ */
+
+ for (j = 0; j < (int)idr->name_len[0] / 2; j++) {
+ uh = idr->name[j*2];
+ ul = idr->name[j*2+1];
+
+ /*
+ * unicode convertion
+ * up = unls->unls_uni2cs[uh];
+ *
+ * if (up == NULL)
+ * uc = '\0';
+ * else
+ * uc = up[ul];
+ *
+ * we use only low byte
+ */
+
+ uc = ul;
+
+ buffer[j] = uc ? uc : '_';
+ }
+ buffer[idr->name_len[0]/2] = '\0';
+ break;
+ case 0:
+ /*
+ * Normal non-Unicode name.
+ */
+ strncpy(buffer, idr->name, idr->name_len[0]);
+ buffer[idr->name_len[0]] = 0;
+ break;
+ default:
+ /*
+ * Don't know how to do these yet. Maybe they are the same
+ * as one of the above.
+ */
+ break;
+ }
+ }
+}
+
+iso9660_VOLUME *iso9660_mount(int fd)
+{
+ iso9660_VOLUME* volume;
+ struct iso_primary_descriptor *jpd;
+ struct iso_primary_descriptor ipd;
+ int block;
+ int ucs_level = 0;
+
+ /* read filesystem descriptor */
+
+ seek_io(fd, 16 * ISOFS_BLOCK_SIZE);
+ read_io(fd, &ipd, sizeof (ipd));
+
+ /*
+ * High sierra:
+ *
+ * DESC TYPE == 1 (VD_SFS) offset 8 len 1
+ * STR ID == "CDROM" offset 9 len 5
+ * STD_VER == 1 offset 14 len 1
+ */
+
+ /* High Sierra format ? */
+
+ if ((((char *)&ipd)[8] == 1) &&
+ (strncmp(&((char *)&ipd)[9], "CDROM", 5) == 0) &&
+ (((char *)&ipd)[14] == 1)) {
+ printk("Incompatible format: High Sierra format\n");
+ return NULL;
+ }
+
+ /*
+ * ISO 9660:
+ *
+ * DESC TYPE == 1 (VD_PVD) offset 0 len 1
+ * STR ID == "CD001" offset 1 len 5
+ * STD_VER == 1 offset 6 len 1
+ */
+
+ /* NOT ISO 9660 format ? */
+
+ if ((ipd.type[0] != ISO_VD_PRIMARY) ||
+ (strncmp(ipd.id, ISO_STANDARD_ID, sizeof (ipd.id)) != 0) ||
+ (ipd.version[0] != 1)) {
+ return NULL;
+ }
+
+ /* UCS info */
+
+ block = 16;
+
+ jpd = (struct iso_primary_descriptor *)
+ malloc(sizeof(struct iso_primary_descriptor));
+ if (jpd == NULL)
+ return NULL;
+
+ memcpy(jpd, &ipd, sizeof (ipd));
+ while ((uint8_t)jpd->type[0] != ISO_VD_END) {
+
+ /*
+ * If Joliet UCS escape sequence found, we may be wrong
+ */
+
+ if (jpd->unused3[0] == '%' &&
+ jpd->unused3[1] == '/' &&
+ (jpd->unused3[3] == '\0' ||
+ jpd->unused3[3] == ' ') &&
+ (jpd->unused3[2] == '@' ||
+ jpd->unused3[2] == 'C' ||
+ jpd->unused3[2] == 'E')) {
+
+ if (jpd->version[0] != 1)
+ break;
+ }
+
+ block++;
+ seek_io(fd, block * ISOFS_BLOCK_SIZE);
+ read_io(fd, jpd, sizeof (*jpd));
+ }
+
+ ucs_level = 0;
+ if (((unsigned char) jpd->type[0] == ISO_VD_END)) {
+ memcpy(jpd, &ipd, sizeof (ipd));
+ } else {
+ switch (jpd->unused3[2]) {
+ case '@':
+ ucs_level = 1;
+ break;
+ case 'C':
+ ucs_level = 2;
+ break;
+ case 'E':
+ ucs_level = 3;
+ break;
+ }
+
+ if (ucs_level && jpd->unused3[3] == ' ')
+ printk("Warning: Joliet escape sequence uses illegal space at offset 3\n");
+ }
+
+ volume = (iso9660_VOLUME*)malloc(sizeof(iso9660_VOLUME));
+ if (volume == NULL)
+ return NULL;
+
+ volume->descriptor = jpd;
+ volume->ucs_level = ucs_level;
+ volume->fd = fd;
+
+ return volume;
+}
+
+int iso9660_umount(iso9660_VOLUME* volume)
+{
+ if (volume == NULL)
+ return -1;
+ free(volume->descriptor);
+ free(volume);
+ return 0;
+}
+
+struct iso_directory_record *iso9660_get_root_node(iso9660_VOLUME* volume)
+{
+ return (struct iso_directory_record *)volume->descriptor->root_directory_record;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_open.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_open.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_open.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,39 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+
+iso9660_FILE* iso9660_open(iso9660_VOLUME *volume, const char* pathname)
+{
+ struct iso_directory_record *root;
+ struct iso_directory_record *idr;
+ iso9660_FILE *file;
+
+ root = iso9660_get_root_node(volume);
+ if (root == NULL)
+ return NULL;
+
+ idr = iso9660_get_node(volume, root, pathname);
+ if (idr == NULL)
+ return NULL;
+
+ file = (iso9660_FILE*)malloc(sizeof(iso9660_FILE));
+ if (file == NULL)
+ return NULL;
+
+ file->base = isonum_733((char *)idr->extent);
+ file->size = isonum_733((char *)idr->size);
+ file->offset = 0;
+ file->current = -1;
+ file->volume = volume;
+ file->path = strdup(pathname);
+
+ free(idr);
+
+ return file;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_opendir.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_opendir.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_opendir.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,133 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at 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 (strcmp(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;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_read.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_read.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_read.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,74 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+#include "openbios/bindings.h"
+#include "libc/diskio.h"
+
+size_t iso9660_read(iso9660_FILE *_file, char *buf, size_t count)
+{
+ iso9660_FILE *file = (iso9660_FILE*)_file;
+ size_t read = 0;
+
+ if ( count > (file->size - file->offset) )
+ count = file->size - file->offset;
+
+ while (count > 0)
+ {
+ size_t part;
+ int offset_extent;
+ int offset_index;
+
+ offset_extent = file->base +
+ (file->offset / ISOFS_BLOCK_SIZE);
+ offset_index = file->offset % ISOFS_BLOCK_SIZE;
+
+ if (file->current != offset_extent)
+ {
+ if ( (offset_index == 0) &&
+ (count >= ISOFS_BLOCK_SIZE) )
+ {
+ /* direct i/o */
+
+ int extents_nb;
+
+ extents_nb = count / ISOFS_BLOCK_SIZE;
+
+ part = extents_nb * ISOFS_BLOCK_SIZE;
+
+ seek_io(file->volume->fd,
+ offset_extent * ISOFS_BLOCK_SIZE);
+ read_io(file->volume->fd, buf + read, part);
+
+ file->offset += part;
+ count -= part;
+ read += part;
+
+ continue;
+ }
+
+ file->current = offset_extent;
+ seek_io(file->volume->fd,
+ offset_extent * ISOFS_BLOCK_SIZE);
+ read_io(file->volume->fd, file->buffer,
+ ISOFS_BLOCK_SIZE);
+ }
+
+ part = ISOFS_BLOCK_SIZE - offset_index;
+ if (count < part)
+ part = count;
+
+ memcpy(buf + read, file->buffer + offset_index, part);
+
+ file->offset += part;
+ count -= part;
+ read += part;
+ }
+
+ return read;
+}
Added: trunk/openbios-devel/fs/iso9660/iso9660_readdir.c
===================================================================
--- trunk/openbios-devel/fs/iso9660/iso9660_readdir.c (rev 0)
+++ trunk/openbios-devel/fs/iso9660/iso9660_readdir.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,50 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#include "libiso9660.h"
+#include "openbios/bindings.h"
+#include "libc/diskio.h"
+
+#define offsetof(t,m) ((long)&(((t *)0)->m))
+
+static void read_extent(iso9660_DIR *dir)
+{
+ seek_io(dir->volume->fd, dir->extent * ISOFS_BLOCK_SIZE);
+ read_io(dir->volume->fd, dir->buffer, ISOFS_BLOCK_SIZE);
+
+ dir->len -= ISOFS_BLOCK_SIZE;
+ dir->extent ++;
+ dir->index = 0;
+}
+
+struct iso_directory_record *iso9660_readdir(iso9660_DIR *dir)
+{
+ struct iso_directory_record *idr;
+
+ if (dir->index >
+ ISOFS_BLOCK_SIZE - offsetof(struct iso_directory_record, name[0]))
+ {
+ if (dir->len <= 0)
+ return NULL;
+
+ read_extent(dir);
+ }
+
+ idr = (struct iso_directory_record *) &dir->buffer[dir->index];
+ if (idr->length[0] == 0) {
+ if (dir->len <= 0)
+ return NULL;
+
+ read_extent(dir);
+ idr = (struct iso_directory_record *) &dir->buffer[dir->index];
+ }
+
+ dir->index += dir->buffer[dir->index];
+
+ return idr;
+}
Added: trunk/openbios-devel/fs/iso9660/libiso9660.h
===================================================================
--- trunk/openbios-devel/fs/iso9660/libiso9660.h (rev 0)
+++ trunk/openbios-devel/fs/iso9660/libiso9660.h 2009-11-22 09:26:50 UTC (rev 626)
@@ -0,0 +1,26 @@
+/*
+ *
+ * (c) 2005-2009 Laurent Vivier <Laurent at vivier.eu>
+ *
+ * This file has been copied from EMILE, http://emile.sf.net
+ *
+ */
+
+#ifndef __LIBISO9660_H__
+#define __LIBISO9660_H__
+
+#include "openbios/config.h"
+#include "iso9660.h"
+
+extern iso9660_VOLUME* iso9660_mount(int fd);
+extern int iso9660_umount(iso9660_VOLUME *volume);
+extern iso9660_DIR* iso9660_opendir(iso9660_VOLUME *, const char *name);
+extern iso9660_FILE* iso9660_open(iso9660_VOLUME *, const char *pathname);
+extern int iso9660_closedir(iso9660_DIR *dir);
+extern struct iso_directory_record *iso9660_readdir(iso9660_DIR *dir);
+extern size_t iso9660_read(iso9660_FILE *file, char *buf, size_t count);
+extern void iso9660_close(iso9660_FILE *file);
+extern int iso9660_lseek(iso9660_FILE *file, long offset, int whence);
+extern void iso9660_name(iso9660_VOLUME *volume, struct iso_directory_record * idr, char *buffer);
+
+#endif /* __LIBISO9660_H__ */
Modified: trunk/openbios-devel/include/openbios/fs.h
===================================================================
--- trunk/openbios-devel/include/openbios/fs.h 2009-11-22 09:04:27 UTC (rev 625)
+++ trunk/openbios-devel/include/openbios/fs.h 2009-11-22 09:26:50 UTC (rev 626)
@@ -62,6 +62,12 @@
static inline int fs_hfs_open( int fd, fs_ops_t *fs ) { return -1; }
#endif
+#ifdef CONFIG_ISO9660
+extern int fs_iso9660_open( int fd, fs_ops_t *fs );
+#else
+static inline int fs_iso9660_open( int fd, fs_ops_t *fs ) { return -1; }
+#endif
+
#ifdef CONFIG_GRUBFS
extern int fs_grubfs_open( int fd, fs_ops_t *fs );
#else
Modified: trunk/openbios-devel/modules/filesystems.c
===================================================================
--- trunk/openbios-devel/modules/filesystems.c 2009-11-22 09:04:27 UTC (rev 625)
+++ trunk/openbios-devel/modules/filesystems.c 2009-11-22 09:26:50 UTC (rev 626)
@@ -47,6 +47,7 @@
if( !err ) {
err=fs_hfsp_open(fd, fs);
if( err ) err = fs_hfs_open(fd, fs);
+ if( err ) err = fs_iso9660_open(fd, fs);
if( err ) err = fs_grubfs_open(fd, fs);
}
More information about the OpenBIOS
mailing list