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@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@ibrium.se) + * Copyright (C) 2010 Mark Cave-Ayland (mark.cave-ayland@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 );