[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