[OpenBIOS] [commit] r812 - in trunk/openbios-devel: fs/hfs packages

repository service svn at openbios.org
Sun Jul 4 01:29:37 CEST 2010


Author: mcayland
Date: Sun Jul  4 01:29:37 2010
New Revision: 812
URL: http://tracker.coreboot.org/trac/openbios/changeset/812

Log:
Move the HFS filesystem handler into its own new package /packages/hfs-files.

Signed-off-by: Mark Cave-Ayland <mark.cave-ayland at siriusit.co.uk>

Modified:
   trunk/openbios-devel/fs/hfs/hfs_fs.c
   trunk/openbios-devel/packages/init.c
   trunk/openbios-devel/packages/misc-files.c
   trunk/openbios-devel/packages/packages.h

Modified: trunk/openbios-devel/fs/hfs/hfs_fs.c
==============================================================================
--- trunk/openbios-devel/fs/hfs/hfs_fs.c	Sun Jul  4 01:22:21 2010	(r811)
+++ trunk/openbios-devel/fs/hfs/hfs_fs.c	Sun Jul  4 01:29:37 2010	(r812)
@@ -2,11 +2,12 @@
  *   Creation Date: <2001/05/06 22:47:23 samuel>
  *   Time-stamp: <2004/01/12 10:24:35 samuel>
  *
- *	<hfs_fs.c>
+ *	/packages/hfs-files
  *
  *	HFS world interface
  *
  *   Copyright (C) 2001-2004 Samuel Rydh (samuel at ibrium.se)
+ *   Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland at siriusit.co.uk)
  *
  *   This program is free software; you can redistribute it and/or
  *   modify it under the terms of the GNU General Public License
@@ -15,8 +16,10 @@
  */
 
 #include "config.h"
+#include "libopenbios/bindings.h"
 #include "fs/fs.h"
 #include "libc/vsprintf.h"
+#include "libc/diskio.h"
 #include "libhfs.h"
 
 #define MAC_OS_ROM_CREATOR	0x63687270	/* 'chrp' */
@@ -28,6 +31,10 @@
 #define SYSTEM_TYPE		0x7A737973	/* 'zsys' */
 #define SYSTEM_CREATOR		0x4D414353	/* 'MACS' */
 
+#define VOLNAME_SIZE	64
+
+extern void     hfs_init( void );
+
 typedef struct {
 	enum { FILE, DIR } type;
 	union {
@@ -36,6 +43,12 @@
 	};
 } hfscommon;
 
+typedef struct {
+	hfsvol *vol;
+	hfscommon *common;
+} hfs_info_t;
+
+DECLARE_NODE( hfs, 0, sizeof(hfs_info_t), "+/packages/hfs-files" );
 
 /************************************************************************/
 /*	Search Functions						*/
@@ -64,7 +77,7 @@
 
 /* ret: 0=success, 1=not_found, 2=not_a_dir */
 static int
-_search( hfsvol *vol, const char *path, const char *sname, file_desc_t **ret_fd )
+_search( hfsvol *vol, const char *path, const char *sname, hfsfile **ret_fd )
 {
 	hfsdir *dir;
 	hfsdirent ent;
@@ -111,7 +124,7 @@
 				|| _find_file( vol, path, SYSTEM_TYPE, SYSTEM_CREATOR );
 		}
 	}
-	if( !status && topdir && ret_fd && !(*ret_fd=(file_desc_t*)hfs_open(vol, buf)) ) {
+	if( !status && topdir && ret_fd && !(*ret_fd=hfs_open(vol, buf)) ) {
 		printk("Unexpected error: failed to open matched ROM\n");
 		status = 1;
 	}
@@ -120,154 +133,139 @@
 	return status;
 }
 
-static file_desc_t *
-_do_search( fs_ops_t *fs, const char *sname )
+static hfsfile *
+_do_search( hfs_info_t *mi, const char *sname )
 {
 	hfsvol *vol = hfs_getvol( NULL );
-	file_desc_t *ret_fd = NULL;
 
-	(void)_search( vol, ":", sname, &ret_fd );
-	return ret_fd;
+	mi->common->type = FILE;
+	(void)_search( vol, ":", sname, &mi->common->file );
+
+	return mi->common->file;
 }
 
-static file_desc_t *
-search_rom( fs_ops_t *fs )
+/*
+
+static const int days_month[12] =
+	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+static const int days_month_leap[12] =
+	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
+
+static inline int is_leap(int year)
 {
-	return _do_search( fs, NULL );
+	return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
 }
 
-static file_desc_t *
-search_file( fs_ops_t *fs, const char *sname )
+static void
+print_date(time_t sec)
 {
-	return _do_search( fs, sname );
-}
+	unsigned int second, minute, hour, month, day, year;
+	int current;
+	const int *days;
 
+	second = sec % 60;
+	sec /= 60;
 
-/************************************************************************/
-/*	file/fs ops							*/
-/************************************************************************/
+	minute = sec % 60;
+	sec /= 60;
 
-static void
-file_close( file_desc_t *fd )
-{
-	hfscommon *common = (hfscommon*)fd;
-	if (common->type == FILE)
-		hfs_close( common->file );
-	else if (common->type == DIR)
-		hfs_closedir( common->dir );
-	free(common);
-}
+	hour = sec % 24;
+	sec /= 24;
 
-static int
-file_lseek( file_desc_t *fd, off_t offs, int whence )
-{
-	hfscommon *common = (hfscommon*)fd;
+	year = sec * 100 / 36525;
+	sec -= year * 36525 / 100;
+	year += 1970;
 
-	if (common->type != FILE)
-		return -1;
+	days = is_leap(year) ?  days_month_leap : days_month;
 
-	switch( whence ) {
-	case SEEK_CUR:
-		whence = HFS_SEEK_CUR;
-		break;
-	case SEEK_END:
-		whence = HFS_SEEK_END;
-		break;
-	default:
-	case SEEK_SET:
-		whence = HFS_SEEK_SET;
-		break;
+	current = 0;
+	month = 0;
+	while (month < 12) {
+		if (sec <= current + days[month]) {
+			break;
+		}
+		current += days[month];
+		month++;
 	}
+	month++;
 
-	return hfs_seek( common->file, offs, whence );
-}
+	day = sec - current + 1;
 
-static int
-file_read( file_desc_t *fd, void *buf, size_t count )
-{
-	hfscommon *common = (hfscommon*)fd;
-	if (common->type != FILE)
-		return -1;
-	return hfs_read( common->file, buf, count );
+	forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
+		     year, month, day, hour, minute, second);
 }
 
-static char *
-get_path( file_desc_t *fd, char *retbuf, int len )
+static void
+dir_fs( file_desc_t *fd )
 {
-	char buf[256], buf2[256];
 	hfscommon *common = (hfscommon*)fd;
-	hfsvol *vol = hfs_getvol( NULL );
 	hfsdirent ent;
-	int start, ns;
-	ulong id;
 
-	if (common->type != FILE)
-		return NULL;
-
-	hfs_fstat( common->file, &ent );
-	start = sizeof(buf) - strlen(ent.name) - 1;
-	if( start <= 0 )
-		return NULL;
-	strcpy( buf+start, ent.name );
-	buf[--start] = '\\';
+	if (common->type != DIR)
+		return;
 
-	ns = start;
-	for( id=ent.parid ; !hfs_dirinfo(vol, &id, buf2) ; ) {
-		start = ns;
-		ns -= strlen(buf2);
-		if( ns <= 0 )
-			return NULL;
-		strcpy( buf+ns, buf2 );
-		buf[--ns] = buf[start] = '\\';
+	forth_printf("\n");
+	while( !hfs_readdir(common->dir, &ent) ) {
+		forth_printf("% 10d ", ent.u.file.dsize);
+		print_date(ent.mddate);
+		if( ent.flags & HFS_ISDIR )
+			forth_printf("%s\\\n", ent.name);
+		else
+			forth_printf("%s\n", ent.name);
 	}
-	if( strlen(buf + start) >= len )
-		return NULL;
-
-	strcpy( retbuf, buf+start );
-	return retbuf;
-}
-
-static char *
-vol_name( fs_ops_t *fs, char *buf, int size )
-{
-	return get_hfs_vol_name( fs->fd, buf, size );
 }
+*/
 
+/************************************************************************/
+/*	Standard package methods						*/
+/************************************************************************/
 
-static file_desc_t *
-open_path( fs_ops_t *fs, const char *fullpath )
+/* ( -- success? ) */
+static void
+hfs_files_open( hfs_info_t *mi )
 {
-	hfsvol *vol = (hfsvol*)fs->fs_data;
+	int fd;
+	char *path = my_args_copy();
+
 	const char *s;
 	char buf[256];
-	hfscommon *common;
-	char *path = strdup(fullpath);
+
+	fd = open_ih( my_parent() );
+	if ( fd == -1 ) {
+		free( path );
+		RET( 0 );
+	}
+
+	mi->vol = hfs_mount(fd, 0);
+	if (!mi->vol) {
+		RET( 0 );
+	}
 
 	if( !strncmp(path, "\\\\", 2) ) {
 		hfsvolent ent;
 
 		/* \\ is an alias for the (blessed) system folder */
-		if( hfs_vstat(vol, &ent) < 0 || hfs_setcwd(vol, ent.blessed) ) {
+		if( hfs_vstat(mi->vol, &ent) < 0 || hfs_setcwd(mi->vol, ent.blessed) ) {
 			free(path);
-			return NULL;
+			RET( -1 );
 		}
 		path += 2;
 	} else {
-		hfs_chdir( vol, ":" );
+		hfs_chdir( mi->vol, ":" );
 	}
 
-	common = malloc(sizeof(*common));
-	if (!common) {
+	mi->common = malloc(sizeof(hfscommon));
+	if (!mi->common) {
 		free(path);
-		return NULL;
+		RET( 0 );
 	}
 
 	if (strcmp(path, "\\") == 0) {
 		/* root directory is in fact ":" */
-		common->dir = hfs_opendir(vol, ":");
-		common->type = DIR;
+		mi->common->dir = hfs_opendir(mi->vol, ":");
+		mi->common->type = DIR;
 		free(path);
-		return (file_desc_t*)common;
+		RET( -1 );
 	}
 
 	if (path[strlen(path) - 1] == '\\') {
@@ -287,183 +285,248 @@
 
 		strncpy( buf, s, n );
 		buf[n] = 0;
-		if( hfs_chdir(vol, buf) ) {
-			free(common);
+		if( hfs_chdir(mi->vol, buf) ) {
+			free(mi->common);
 			free(path);
-			return NULL;
+			RET( 0 );
 		}
 	}
 
 	/* support the ':filetype' syntax */
 	if( *s == ':' ) {
-		unsigned long id, oldid = hfs_getcwd(vol);
-		file_desc_t *ret = NULL;
+		unsigned long id, oldid = hfs_getcwd(mi->vol);
 		hfsdirent ent;
 		hfsdir *dir;
 
 		s++;
 		id = oldid;
-		hfs_dirinfo( vol, &id, buf );
-		hfs_setcwd( vol, id );
+		hfs_dirinfo( mi->vol, &id, buf );
+		hfs_setcwd( mi->vol, id );
 
-		if( !(dir=hfs_opendir(vol, buf)) ) {
-			free(common);
+		if( !(dir=hfs_opendir(mi->vol, buf)) ) {
+			free(mi->common);
 			free(path);
-			return NULL;
+			RET( 0 );
 		}
-		hfs_setcwd( vol, oldid );
+		hfs_setcwd( mi->vol, oldid );
 
 		while( !hfs_readdir(dir, &ent) ) {
 			if( ent.flags & HFS_ISDIR )
 				continue;
 			if( !strncmp(s, ent.u.file.type, 4) ) {
-				common->type = FILE;
-				common->file = hfs_open( vol, ent.name );
-				ret = (file_desc_t*)common;
+				mi->common->type = FILE;
+				mi->common->file = hfs_open( mi->vol, ent.name );
 				break;
 			}
 		}
 		hfs_closedir( dir );
 		free(path);
-		return ret;
+		RET( -1 );
 	}
 
-	common->dir = hfs_opendir(vol, s);
-	if (!common->dir) {
-		common->file = hfs_open( vol, s );
-		if (common->file == NULL) {
-			free(common);
+	mi->common->dir = hfs_opendir(mi->vol, s);
+	if (!mi->common->dir) {
+		mi->common->file = hfs_open( mi->vol, s );
+		if (mi->common->file == NULL) {
+			free(mi->common);
 			free(path);
-			return NULL;
+			RET( 0 );
 		}
-		common->type = FILE;
+		mi->common->type = FILE;
 		free(path);
-		return (file_desc_t*)common;
+		RET( -1 );
 	}
-	common->type = DIR;
+	mi->common->type = DIR;
 	free(path);
-	return (file_desc_t*)common;
+	
+	RET( -1 );
 }
 
+/* ( -- ) */
 static void
-close_fs( fs_ops_t *fs )
+hfs_files_close( hfs_info_t *mi )
 {
-	hfsvol *vol = (hfsvol*)fs->fs_data;
-
-	hfs_umount( vol );
-	/* callers responsibility to call free(fs) */
+	hfscommon *common = mi->common;
+	if (common->type == FILE)
+		hfs_close( common->file );
+	else if (common->type == DIR)
+		hfs_closedir( common->dir );
+	free(common);
 }
 
-static const int days_month[12] =
-	{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-static const int days_month_leap[12] =
-	{ 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
-
-static inline int is_leap(int year)
+/* ( buf len -- actlen ) */
+static void
+hfs_files_read( hfs_info_t *mi )
 {
-	return ((year % 4 == 0) && (year % 100 != 0)) || (year % 400 == 0);
+	int count = POP();
+	char *buf = (char *)POP();
+
+	hfscommon *common = mi->common;
+	if (common->type != FILE)
+		RET( -1 );
+
+	RET ( hfs_read( common->file, buf, count ) );
 }
 
+/* ( pos.d -- status ) */
 static void
-print_date(time_t sec)
+hfs_files_seek( hfs_info_t *mi )
 {
-	unsigned int second, minute, hour, month, day, year;
-	int current;
-	const int *days;
+	llong pos = DPOP();
+	int offs = (int)pos;
+	int whence = SEEK_SET;
+	int ret;
+	hfscommon *common = mi->common;
 
-	second = sec % 60;
-	sec /= 60;
+	if (common->type != FILE)
+		RET( -1 );
 
-	minute = sec % 60;
-	sec /= 60;
+	switch( whence ) {
+	case SEEK_END:
+		whence = HFS_SEEK_END;
+		break;
+	default:
+	case SEEK_SET:
+		whence = HFS_SEEK_SET;
+		break;
+	}
 
-	hour = sec % 24;
-	sec /= 24;
+	ret = hfs_seek( common->file, offs, whence );
+	if (ret)
+		RET( -1 );
+	else
+		RET( 0 );
+}
 
-	year = sec * 100 / 36525;
-	sec -= year * 36525 / 100;
-	year += 1970;
+/* ( addr -- size ) */
+static void
+hfs_files_load( hfs_info_t *mi )
+{
+	char *buf = (char *)POP();
+	int count;
 
-	days = is_leap(year) ?  days_month_leap : days_month;
+	hfscommon *common = mi->common;
+	if (common->type != FILE)
+		RET( -1 );
 
-	current = 0;
-	month = 0;
-	while (month < 12) {
-		if (sec <= current + days[month]) {
-			break;
-		}
-		current += days[month];
-		month++;
-	}
-	month++;
+	/* Seek to the end in order to get the file size */
+	hfs_seek(common->file, 0, HFS_SEEK_END);
+	count = common->file->pos;
+	hfs_seek(common->file, 0, HFS_SEEK_SET);
 
-	day = sec - current + 1;
+	RET ( hfs_read( common->file, buf, count ) );
+}
 
-	forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
-		     year, month, day, hour, minute, second);
+/* ( -- success? ) */
+static void
+hfs_files_open_nwrom( hfs_info_t *mi )
+{
+	/* Switch to an existing ROM image file on the fs! */
+	if ( _do_search( mi, NULL ) )
+		RET( -1 );
+	
+	RET( 0 );
 }
 
+/* ( -- cstr ) */
 static void
-dir_fs( file_desc_t *fd )
+hfs_files_get_path( hfs_info_t *mi )
 {
-	hfscommon *common = (hfscommon*)fd;
+	char buf[256], buf2[256];
+	hfscommon *common = mi->common;
+	hfsvol *vol = hfs_getvol( NULL );
 	hfsdirent ent;
+	int start, ns;
+	ulong id;
 
-	if (common->type != DIR)
-		return;
+	if (common->type != FILE)
+		RET( 0 );
 
-	forth_printf("\n");
-	while( !hfs_readdir(common->dir, &ent) ) {
-		forth_printf("% 10d ", ent.u.file.dsize);
-		print_date(ent.mddate);
-		if( ent.flags & HFS_ISDIR )
-			forth_printf("%s\\\n", ent.name);
-		else
-			forth_printf("%s\n", ent.name);
+	hfs_fstat( common->file, &ent );
+	start = sizeof(buf) - strlen(ent.name) - 1;
+	if( start <= 0 )
+		RET ( 0 );
+	strcpy( buf+start, ent.name );
+	buf[--start] = '\\';
+
+	ns = start;
+	for( id=ent.parid ; !hfs_dirinfo(vol, &id, buf2) ; ) {
+		start = ns;
+		ns -= strlen(buf2);
+		if( ns <= 0 )
+			RET( 0 );
+		strcpy( buf+ns, buf2 );
+		buf[--ns] = buf[start] = '\\';
 	}
+	if( strlen(buf) >= sizeof(buf) )
+		RET( 0 );
+
+	RET( (ucell) strdup(buf+start) );
 }
 
-static const char *
-get_fstype( fs_ops_t *fs )
+/* ( -- cstr ) */
+static void
+hfs_files_get_fstype( hfs_info_t *mi )
 {
-	return ("HFS");
+	PUSH( (ucell)strdup("HFS") );
 }
 
-static const fs_ops_t hfs_ops = {
-	.dir		= dir_fs,
-	.close_fs	= close_fs,
-	.open_path	= open_path,
-	.search_rom	= search_rom,
-	.search_file	= search_file,
-	.vol_name	= vol_name,
-
-	.get_path	= get_path,
-	.close		= file_close,
-	.read		= file_read,
-	.lseek		= file_lseek,
+/* ( -- cstr|0 ) */
+static void
+hfs_files_volume_name( hfs_info_t *mi )
+{
+	int fd;
+	char *volname = malloc(VOLNAME_SIZE);
 
-	.get_fstype	= get_fstype,
-};
+	fd = open_ih(my_self());
+	get_hfs_vol_name(fd, volname, VOLNAME_SIZE);
+	close_io(fd);
+
+	PUSH ((ucell)volname);
+}
 
-int
-fs_hfs_open( int os_fd, fs_ops_t *fs )
+/* static method, ( pos.d ih -- flag? ) */
+static void
+hfs_files_probe( hfs_info_t *dummy )
 {
-	hfsvol *vol = hfs_mount( os_fd, 0 );
+	ihandle_t ih = POP_ih();
+	llong offs = DPOP(); 
+	int fd, ret = 0;
 
-	if( !vol )
-		return -1;
+	fd = open_ih(ih);
+	if (hfs_probe(fd, offs))
+		ret = -1;
 
-	*fs = hfs_ops;
-	fs->fs_data = vol;
+	close_io(fd);
 
-	return 0;
+	RET (ret);
 }
 
-int 
-fs_hfs_probe( int fd, llong offs )
+static void
+hfs_initializer( hfs_info_t *dummy )
 {
-	if (hfs_probe(fd, offs))
-		return 0;
+	fword("register-fs-package");
+}
+
+NODE_METHODS( hfs ) = {
+	{ "probe",	hfs_files_probe	},
+	{ "open",	hfs_files_open	},
+	{ "close",	hfs_files_close },
+	{ "read",	hfs_files_read	},
+	{ "seek",	hfs_files_seek	},
+	{ "load",	hfs_files_load	},
+
+	/* special */
+	{ "open-nwrom",	 	hfs_files_open_nwrom 	},
+	{ "get-path",		hfs_files_get_path	},
+	{ "get-fstype",		hfs_files_get_fstype	},
+	{ "volume-name",	hfs_files_volume_name	},
 
-	return -1;
+	{ NULL,		hfs_initializer	},
+};
+
+void
+hfs_init( void )
+{
+	REGISTER_NODE( hfs );
 }

Modified: trunk/openbios-devel/packages/init.c
==============================================================================
--- trunk/openbios-devel/packages/init.c	Sun Jul  4 01:22:21 2010	(r811)
+++ trunk/openbios-devel/packages/init.c	Sun Jul  4 01:29:37 2010	(r812)
@@ -33,6 +33,9 @@
 #ifdef CONFIG_HFSP
 	hfsp_init();
 #endif
+#ifdef CONFIG_HFS
+	hfs_init();
+#endif
 #ifdef CONFIG_ISO9660
 	iso9660_init();
 #endif

Modified: trunk/openbios-devel/packages/misc-files.c
==============================================================================
--- trunk/openbios-devel/packages/misc-files.c	Sun Jul  4 01:22:21 2010	(r811)
+++ trunk/openbios-devel/packages/misc-files.c	Sun Jul  4 01:29:37 2010	(r812)
@@ -57,12 +57,9 @@
 	err = (fd = open_ih(ih)) == -1;
 
 	if( !err ) {
-		err = fs_hfs_open(fd, fs);
-		
-		if( err ) {
-			err = fs_ext2_open(fd, fs);
-			DPRINTF("--- ext2 returned %d\n", err);
-		}
+
+		err = fs_ext2_open(fd, fs);
+		DPRINTF("--- ext2 returned %d\n", err);
 
 		if( err ) {
 			err = fs_grubfs_open(fd, fs);
@@ -341,13 +338,8 @@
 	err = (fd = open_ih(ih)) == -1;
 	if( !err ) {
 
-		err = fs_hfs_probe(fd, offs);
-		DPRINTF("--- HFS returned %d\n", err);
-
-		if( err ) {
-			err = fs_ext2_probe(fd, offs);
-			DPRINTF("--- ext2 returned %d\n", err);
-		}
+		err = fs_ext2_probe(fd, offs);
+		DPRINTF("--- ext2 returned %d\n", err);
 
 		if( err ) {
 			err = fs_grubfs_probe(fd, offs);

Modified: trunk/openbios-devel/packages/packages.h
==============================================================================
--- trunk/openbios-devel/packages/packages.h	Sun Jul  4 01:22:21 2010	(r811)
+++ trunk/openbios-devel/packages/packages.h	Sun Jul  4 01:29:37 2010	(r812)
@@ -22,6 +22,7 @@
 extern void	files_init( void );
 extern void	iso9660_init( void );
 extern void 	hfsp_init( void );
+extern void 	hfs_init( void );
 extern void	macparts_init( void );
 extern void	pcparts_init( void );
 extern void	sunparts_init( void );



More information about the OpenBIOS mailing list