---
 fs/iso9660/iso9660_fs.c    |  275 ++++++++++++++++++++++++++++-----------------
 fs/iso9660/iso9660_lseek.c |    3 
 packages/init.c            |    3 
 packages/misc-files.c      |    1 
 packages/packages.h        |    1 
 5 files changed, 181 insertions(+), 102 deletions(-)

Index: openbios-devel/fs/iso9660/iso9660_fs.c
===================================================================
--- openbios-devel.orig/fs/iso9660/iso9660_fs.c	2010-05-28 21:03:51.000000000 +0200
+++ openbios-devel/fs/iso9660/iso9660_fs.c	2010-05-28 21:04:10.000000000 +0200
@@ -4,9 +4,14 @@
  *
  */
 
+#include "openbios/config.h"
+#include "openbios/bindings.h"
 #include "libiso9660.h"
 #include "fs/fs.h"
 #include "libc/vsprintf.h"
+#include "libc/diskio.h"
+
+extern void     iso9660_init( void );
 
 typedef struct {
 	enum { FILE, DIR } type;
@@ -16,152 +21,224 @@
 	};
 } iso9660_COMMON;
 
-static void
-umount( fs_ops_t *fs )
-{
-	iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
+typedef struct {
+	iso9660_VOLUME *volume;
+	iso9660_COMMON *common;
+} iso9660_info_t;
 
-	iso9660_umount( volume );
-}
+DECLARE_NODE( iso9660, 0, sizeof(iso9660_info_t), "+/packages/iso-9660-files" );
+
+/* ( -- success? ) */
 
 static void
-dir_fs ( file_desc_t *fd )
+files_open( iso9660_info_t *mi )
 {
-	iso9660_COMMON *common = (iso9660_COMMON *)fd;
-	struct iso_directory_record *idr;
-	char name_buf[256];
+	int fd;
+	char *path = my_args_copy();
 
-	if (common->type != DIR)
-		return;
+	if ( ! path )
+		RET( 0 );
 
-	forth_printf("\n");
-	while ( (idr = iso9660_readdir(common->dir)) ) {
+	fd = open_ih( my_parent() );
+	if ( fd == -1 ) {
+		free( path );
+		RET( 0 );
+	}
 
-		forth_printf("% 10d ", isonum_733(idr->size));
-		forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
-			     idr->date[0] + 1900, /* year */
-			     idr->date[1], /* month */
-                             idr->date[2], /* day */
-			     idr->date[3], idr->date[4], idr->date[5]);
-		iso9660_name(common->dir->volume, idr, name_buf);
-		if (idr->flags[0] & 2)
-			forth_printf("%s\\\n", name_buf);
-		else
-			forth_printf("%s\n", name_buf);
+	mi->volume = iso9660_mount( fd );
+	if ( mi->volume == NULL ) {
+		free( path );
+		close_io( fd );
+		RET( 0 );
+	}
+
+	mi->common->dir = iso9660_opendir( mi->volume, path );
+	if ( mi->common->dir == NULL ) {
+		mi->common->file = iso9660_open( mi->volume, path );
+		if (mi->common->file == NULL) {
+			iso9660_umount( mi->volume );
+			close_io( fd );
+			free( path );
+			RET( 0 );
+		}
+		mi->common->type = FILE;
+		free( path );
+		RET( -1 );
 	}
+	mi->common->type = DIR;
+	free( path );
+
+	RET( -1 );
 }
 
-static file_desc_t *
-open_path( fs_ops_t *fs, const char *path )
+/* ( -- ) */
+
+static void
+files_close( iso9660_info_t *mi )
 {
-	iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
-	iso9660_COMMON *common;
+	int fd = mi->volume->fd;
 
-	common = (iso9660_COMMON *)malloc(sizeof(*common));
-	if (common == NULL)
-		return NULL;
-
-	common->dir = iso9660_opendir(volume, path);
-	if (common->dir == NULL) {
-		common->file = iso9660_open(volume, path);
-		if (common->file == NULL) {
-			free(common);
-			return NULL;
-		}
-		common->type = FILE;
-		return (file_desc_t *)common;
-	}
-	common->type = DIR;
-	return (file_desc_t *)common;
+	if (mi->common->type == FILE )
+		iso9660_close( mi->common->file );
+	else if ( mi->common->type == DIR )
+		iso9660_closedir( mi->common->dir );
+	iso9660_umount( mi->volume );
+	close_io( fd );
 }
 
-static char *
-get_path( file_desc_t *fd, char *buf, int size )
+/* ( buf len -- actlen ) */
+
+static void
+files_read( iso9660_info_t *mi )
 {
-	iso9660_COMMON *common = (iso9660_COMMON *)fd;
+	int count = POP();
+	char *buf = (char *)POP();
+	int ret;
 
-	if (common->type != FILE)
-		return NULL;
+	if ( mi->common->type != FILE )
+		RET( 0 );
 
-	strncpy(buf, common->file->path, size);
+	ret = iso9660_read( mi->common->file, buf, count );
 
-	return buf;
+	PUSH( ret );
 }
 
-static int
-file_lseek( file_desc_t *fd, off_t offs, int whence )
+/* ( pos.d -- status ) */
+
+static void
+files_seek( iso9660_info_t *mi )
 {
-	iso9660_COMMON *common = (iso9660_COMMON *)fd;
+	llong pos = DPOP();
+	cell ret;
+	int offs = (int)pos;
+	int whence = SEEK_SET;
+
+	if (mi->common->type != FILE)
+		RET( -1 );
+
+	if( offs == -1 ) {
+		offs = 0;
+		whence = SEEK_END;
+	}
 
-	if (common->type != FILE)
-		return -1;
+	ret = iso9660_lseek(mi->common->file, offs, whence);
 
-	return iso9660_lseek(common->file, offs, whence);
+	PUSH( (ret < 0)? -1 : 0 );
 }
 
+/* ( -- filepos.d ) */
+
 static void
-file_close( file_desc_t *fd )
+files_offset( iso9660_info_t *mi )
 {
-	iso9660_COMMON *common = (iso9660_COMMON *)fd;
+	if ( mi->common->type != FILE )
+		RET( -1 );
 
-	if (common->type == FILE)
-		iso9660_close(common->file);
-	else if (common->type == DIR)
-		iso9660_closedir(common->dir);
-	free(common);
+	DPUSH( mi->common->file->offset );
 }
 
-static int
-file_read( file_desc_t *fd, void *buf, size_t count )
+/* ( addr -- size ) */
+
+static void
+files_load( iso9660_info_t *mi)
 {
-	iso9660_COMMON *common = (iso9660_COMMON *)fd;
+	char *buf = (char*)POP();
+	int ret, size;
 
-	if (common->type != FILE)
-		return -1;
+	if ( mi->common->type != FILE )
+		RET( 0 );
 
-	return iso9660_read(common->file, buf, count);
+	size = 0;
+	while(1) {
+		ret = iso9660_read( mi->common->file, buf, 512 );
+		if (ret <= 0)
+			break;
+		buf += ret;
+		size += ret;
+		if (ret != 512)
+			break;
+	}
+	PUSH( size );
 }
 
-static char *
-vol_name( fs_ops_t *fs, char *buf, int size )
+static void
+files_dir( iso9660_info_t *mi )
 {
-	iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
+	struct iso_directory_record *idr;
+	char name_buf[256];
 
-	strncpy(buf, volume->descriptor->volume_id, size);
+	if (mi->common->type != DIR)
+		return;
+
+	forth_printf("\n");
+	while ( (idr = iso9660_readdir(mi->common->dir)) ) {
 
-	return buf;
+		forth_printf("% 10d ", isonum_733(idr->size));
+		forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
+			     idr->date[0] + 1900, /* year */
+			     idr->date[1], /* month */
+                             idr->date[2], /* day */
+			     idr->date[3], idr->date[4], idr->date[5]);
+		iso9660_name(mi->common->dir->volume, idr, name_buf);
+		if (idr->flags[0] & 2)
+			forth_printf("%s\\\n", name_buf);
+		else
+			forth_printf("%s\n", name_buf);
+	}
 }
 
-static const char *
-get_fstype( fs_ops_t *fs )
+/* static method, ( ih -- flag? ) */
+static void
+files_probe( iso9660_info_t *dummy )
 {
-	return "ISO9660";
-}
+	int fd;
+	iso9660_VOLUME *volume;
+	ihandle_t ih = POP_ih();
 
-static const fs_ops_t iso9660_ops = {
-	.dir		= dir_fs,
-	.close_fs	= umount,
+	fd = open_ih( ih );
+	if ( fd == -1 )
+		RET( 0 );
 
-	.open_path	= open_path,
-	.get_path	= get_path,
-	.close		= file_close,
-	.read		= file_read,
-	.lseek		= file_lseek,
+	volume = iso9660_mount( fd );
+	if (volume == NULL)
+		RET( 0 );
 
-	.vol_name	= vol_name,
-	.get_fstype	= get_fstype,
-};
+	iso9660_umount( volume );
 
-int fs_iso9660_open(int fd, fs_ops_t *fs)
+	close_io( fd );
+
+	RET( -1 );
+}
+
+static void
+files_block_size( iso9660_info_t *dummy )
 {
-	iso9660_VOLUME *volume;
+	PUSH(2048);
+}
 
-	volume = iso9660_mount(fd);
-	if (volume == NULL)
-		return -1;
+static void
+files_initializer( iso9660_info_t *dummy )
+{
+	fword("register-fs-package");
+}
 
-	*fs = iso9660_ops;
-	fs->fs_data = volume;
+NODE_METHODS( iso9660 ) = {
+	{ "probe",	files_probe		},
+	{ "open",	files_open		},
+	{ "close",	files_close		},
+	{ "read",	files_read		},
+	{ "seek",	files_seek		},
+	{ "offset",	files_offset		},
+	{ "load",	files_load		},
+	{ "dir",	files_dir		},
+	{ "block-size",	files_block_size	},
 
-	return 0;
+	{ NULL,		files_initializer	},
+};
+
+
+void
+iso9660_init( void )
+{
+	REGISTER_NODE( iso9660 );
 }
Index: openbios-devel/fs/iso9660/iso9660_lseek.c
===================================================================
--- openbios-devel.orig/fs/iso9660/iso9660_lseek.c	2010-05-28 21:03:51.000000000 +0200
+++ openbios-devel/fs/iso9660/iso9660_lseek.c	2010-05-28 21:04:10.000000000 +0200
@@ -8,9 +8,8 @@
 
 #include "libiso9660.h"
 
-int iso9660_lseek(iso9660_FILE *_file, long offset, int whence)
+int iso9660_lseek(iso9660_FILE *file, long offset, int whence)
 {
-	iso9660_FILE *file = (iso9660_FILE*)_file;
 	long new_offset;
 
 	switch(whence)
Index: openbios-devel/packages/init.c
===================================================================
--- openbios-devel.orig/packages/init.c	2010-05-28 21:03:51.000000000 +0200
+++ openbios-devel/packages/init.c	2010-05-28 21:04:10.000000000 +0200
@@ -30,6 +30,9 @@
 #ifdef CONFIG_DISK_LABEL
 	disklabel_init();
 #endif
+#ifdef CONFIG_ISO9660
+	iso9660_init();
+#endif
 #ifdef CONFIG_FS
 	files_init();
 #endif
Index: openbios-devel/packages/misc-files.c
===================================================================
--- openbios-devel.orig/packages/misc-files.c	2010-05-28 21:03:51.000000000 +0200
+++ openbios-devel/packages/misc-files.c	2010-05-28 21:04:10.000000000 +0200
@@ -47,7 +47,6 @@
 	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_ext2_open(fd, fs);
 		if( err ) err = fs_grubfs_open(fd, fs);
 	}
Index: openbios-devel/packages/packages.h
===================================================================
--- openbios-devel.orig/packages/packages.h	2010-05-28 21:03:51.000000000 +0200
+++ openbios-devel/packages/packages.h	2010-05-28 21:04:10.000000000 +0200
@@ -20,6 +20,7 @@
 extern void	deblocker_init( void );
 extern void	disklabel_init( void );
 extern void	files_init( void );
+extern void	iso9660_init( void );
 extern void	macparts_init( void );
 extern void	pcparts_init( void );
 extern void	sunparts_init( void );
