mirror of
https://gitlab.com/qemu-project/openbios.git
synced 2024-02-13 08:34:06 +08:00
Currently the dir word works by using /packages/misc-files to open a directory in a similar way to a file and then
special-casing directory actions. This is wrong in that in order to list the contents of a directory, open-dev must return true for any device which contains a valid filesystem, regardless of whether or not the supplied arguments reference a valid path. This causes us a problem because in order to implement multiple references in boot-device correctly, we have to fail if we open a specific device with invalid arguments (such as a non-existent file reference). This patch therefore makes the following changes: 1) Create a static method in each of the filesystem packages to implement dir 2) Enhance the partition/disk handlers to record the phandle of any detected filesystem during open 3) Create a new dir method in the partition/disk handlers which invokes the static dir method for the currently detected filesystem Hence we can now open a raw device/partition and invoke dir on its filesystem without having to open a specific file-reference first. Following shortly is a patch to switch the main dir word over to use this new system. Signed-off-by: Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk> git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@816 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
committed by
Mark Cave-Ayland
parent
930ce00f5f
commit
a5511ad95c
@@ -33,7 +33,7 @@ typedef struct {
|
||||
|
||||
DECLARE_NODE( ext2, 0, sizeof(ext2_info_t), "+/packages/ext2-files" );
|
||||
|
||||
/*
|
||||
|
||||
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] =
|
||||
@@ -83,28 +83,6 @@ print_date(time_t sec)
|
||||
year, month, day, hour, minute, second);
|
||||
}
|
||||
|
||||
static void
|
||||
dir_fs ( file_desc_t *fd)
|
||||
{
|
||||
ext2_COMMON *common = (ext2_COMMON *)fd;
|
||||
struct ext2_dir_entry_2 *entry;
|
||||
struct ext2_inode inode;
|
||||
|
||||
if (common->type != DIR)
|
||||
return;
|
||||
|
||||
forth_printf("\n");
|
||||
while ( (entry = ext2_readdir(common->dir)) ) {
|
||||
ext2_get_inode(common->dir->volume, entry->inode, &inode);
|
||||
forth_printf("% 10d ", inode.i_size);
|
||||
print_date(inode.i_mtime);
|
||||
if (S_ISDIR(inode.i_mode))
|
||||
forth_printf("%s\\\n", entry->name);
|
||||
else
|
||||
forth_printf("%s\n", entry->name);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
/************************************************************************/
|
||||
/* Standard package methods */
|
||||
@@ -233,6 +211,52 @@ ext2_files_get_fstype( ext2_info_t *mi )
|
||||
PUSH( (ucell)strdup("ext2") );
|
||||
}
|
||||
|
||||
/* static method, ( pathstr len ihandle -- ) */
|
||||
static void
|
||||
ext2_files_dir( ext2_info_t *dummy )
|
||||
{
|
||||
ext2_COMMON *common;
|
||||
ext2_VOLUME *volume;
|
||||
struct ext2_dir_entry_2 *entry;
|
||||
struct ext2_inode inode;
|
||||
int fd;
|
||||
|
||||
ihandle_t ih = POP();
|
||||
char *path = pop_fstr_copy();
|
||||
|
||||
fd = open_ih( ih );
|
||||
if ( fd == -1 ) {
|
||||
free( path );
|
||||
return;
|
||||
}
|
||||
|
||||
volume = ext2_mount(fd);
|
||||
if (!volume) {
|
||||
return;
|
||||
}
|
||||
|
||||
common = (ext2_COMMON*)malloc(sizeof(ext2_COMMON));
|
||||
common->dir = ext2_opendir(volume, path);
|
||||
|
||||
forth_printf("\n");
|
||||
while ( (entry = ext2_readdir(common->dir)) ) {
|
||||
ext2_get_inode(common->dir->volume, entry->inode, &inode);
|
||||
forth_printf("% 10d ", inode.i_size);
|
||||
print_date(inode.i_mtime);
|
||||
if (S_ISDIR(inode.i_mode))
|
||||
forth_printf("%s\\\n", entry->name);
|
||||
else
|
||||
forth_printf("%s\n", entry->name);
|
||||
}
|
||||
|
||||
ext2_closedir( common->dir );
|
||||
ext2_umount( volume );
|
||||
|
||||
close_io( fd );
|
||||
|
||||
free( common );
|
||||
free( path );
|
||||
}
|
||||
|
||||
/* static method, ( pos.d ih -- flag? ) */
|
||||
static void
|
||||
@@ -265,6 +289,7 @@ NODE_METHODS( ext2 ) = {
|
||||
{ "read", ext2_files_read },
|
||||
{ "seek", ext2_files_seek },
|
||||
{ "load", ext2_files_load },
|
||||
{ "dir", ext2_files_dir },
|
||||
|
||||
/* special */
|
||||
{ "get-path", ext2_files_get_path },
|
||||
|
||||
@@ -356,6 +356,15 @@ grubfs_files_probe( grubfs_info_t *dummy )
|
||||
RET ( 0 );
|
||||
}
|
||||
|
||||
/* static method, ( pathstr len ihandle -- ) */
|
||||
static void
|
||||
grubfs_files_dir( grubfs_info_t *mi )
|
||||
{
|
||||
forth_printf("dir method not implemented for grubfs filesystem\n");
|
||||
POP();
|
||||
POP();
|
||||
POP();
|
||||
}
|
||||
|
||||
static void
|
||||
grubfs_initializer( grubfs_info_t *dummy )
|
||||
@@ -370,6 +379,7 @@ NODE_METHODS( grubfs ) = {
|
||||
{ "read", grubfs_files_read },
|
||||
{ "seek", grubfs_files_seek },
|
||||
{ "load", grubfs_files_load },
|
||||
{ "dir", grubfs_files_dir },
|
||||
|
||||
/* special */
|
||||
{ "get-path", grubfs_files_get_path },
|
||||
|
||||
@@ -144,7 +144,6 @@ _do_search( hfs_info_t *mi, const char *sname )
|
||||
return mi->common->file;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
static const int days_month[12] =
|
||||
{ 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 };
|
||||
@@ -195,6 +194,7 @@ print_date(time_t sec)
|
||||
year, month, day, hour, minute, second);
|
||||
}
|
||||
|
||||
/*
|
||||
static void
|
||||
dir_fs( file_desc_t *fd )
|
||||
{
|
||||
@@ -485,6 +485,83 @@ hfs_files_volume_name( hfs_info_t *mi )
|
||||
PUSH ((ucell)volname);
|
||||
}
|
||||
|
||||
/* static method, ( pathstr len ihandle -- ) */
|
||||
static void
|
||||
hfs_files_dir( hfs_info_t *dummy )
|
||||
{
|
||||
hfsvol *volume;
|
||||
hfscommon *common;
|
||||
hfsdirent ent;
|
||||
const char *s;
|
||||
char buf[256], *tmppath;
|
||||
int fd;
|
||||
|
||||
ihandle_t ih = POP();
|
||||
char *path = pop_fstr_copy();
|
||||
|
||||
fd = open_ih( ih );
|
||||
if ( fd == -1 ) {
|
||||
free( path );
|
||||
return;
|
||||
}
|
||||
|
||||
volume = hfs_mount(fd, 0);
|
||||
if (!volume) {
|
||||
return;
|
||||
}
|
||||
|
||||
common = malloc(sizeof(hfscommon));
|
||||
|
||||
if (strcmp(path, "\\") == 0) {
|
||||
common->dir = hfs_opendir(volume, ":");
|
||||
} else {
|
||||
if (path[strlen(path) - 1] == '\\') {
|
||||
path[strlen(path) - 1] = 0;
|
||||
}
|
||||
|
||||
tmppath = path;
|
||||
for( tmppath-- ;; ) {
|
||||
int n;
|
||||
|
||||
s = ++tmppath;
|
||||
tmppath = strchr(s, '\\');
|
||||
if( !tmppath || !tmppath[1])
|
||||
break;
|
||||
n = MIN( sizeof(buf)-1, (path-s) );
|
||||
if( !n )
|
||||
continue;
|
||||
|
||||
strncpy( buf, s, n );
|
||||
buf[n] = 0;
|
||||
if( hfs_chdir(volume, buf) ) {
|
||||
free(common);
|
||||
free(path);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
common->dir = hfs_opendir(volume, s);
|
||||
}
|
||||
|
||||
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_closedir( common->dir );
|
||||
hfs_umount( volume );
|
||||
|
||||
close_io( fd );
|
||||
|
||||
free( common );
|
||||
free( path );
|
||||
}
|
||||
|
||||
/* static method, ( pos.d ih -- flag? ) */
|
||||
static void
|
||||
hfs_files_probe( hfs_info_t *dummy )
|
||||
@@ -515,6 +592,7 @@ NODE_METHODS( hfs ) = {
|
||||
{ "read", hfs_files_read },
|
||||
{ "seek", hfs_files_seek },
|
||||
{ "load", hfs_files_load },
|
||||
{ "dir", hfs_files_dir },
|
||||
|
||||
/* special */
|
||||
{ "open-nwrom", hfs_files_open_nwrom },
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
#include "unicode.h"
|
||||
#include "blockiter.h"
|
||||
#include "libc/diskio.h"
|
||||
#include "libc/vsprintf.h"
|
||||
|
||||
#define MAC_OS_ROM_CREATOR 0x63687270 /* 'chrp' */
|
||||
#define MAC_OS_ROM_TYPE 0x74627869 /* 'tbxi' */
|
||||
@@ -432,6 +433,16 @@ hfsp_files_volume_name( hfsp_info_t *mi )
|
||||
PUSH ((ucell)volname);
|
||||
}
|
||||
|
||||
/* static method, ( pathstr len ihandle -- ) */
|
||||
static void
|
||||
hfsp_files_dir( hfsp_info_t *dummy )
|
||||
{
|
||||
forth_printf("dir method not implemented for HFS+ filesystem\n");
|
||||
POP();
|
||||
POP();
|
||||
POP();
|
||||
}
|
||||
|
||||
/* static method, ( pos.d ih -- flag? ) */
|
||||
static void
|
||||
hfsp_files_probe( hfsp_info_t *dummy )
|
||||
@@ -449,7 +460,6 @@ hfsp_files_probe( hfsp_info_t *dummy )
|
||||
RET (ret);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
hfsp_initializer( hfsp_info_t *dummy )
|
||||
{
|
||||
@@ -463,6 +473,7 @@ NODE_METHODS( hfsp ) = {
|
||||
{ "read", hfsp_files_read },
|
||||
{ "seek", hfsp_files_seek },
|
||||
{ "load", hfsp_files_load },
|
||||
{ "dir", hfsp_files_dir },
|
||||
|
||||
/* special */
|
||||
{ "open-nwrom", hfsp_files_open_nwrom },
|
||||
|
||||
@@ -156,17 +156,37 @@ iso9660_files_load( iso9660_info_t *mi)
|
||||
PUSH( size );
|
||||
}
|
||||
|
||||
/* static method, ( pathstr len ihandle -- ) */
|
||||
static void
|
||||
iso9660_files_dir( iso9660_info_t *mi )
|
||||
iso9660_files_dir( iso9660_info_t *dummy )
|
||||
{
|
||||
iso9660_VOLUME *volume;
|
||||
iso9660_COMMON *common;
|
||||
struct iso_directory_record *idr;
|
||||
char name_buf[256];
|
||||
int fd;
|
||||
|
||||
if (mi->common->type != DIR)
|
||||
ihandle_t ih = POP();
|
||||
char *path = pop_fstr_copy();
|
||||
|
||||
fd = open_ih( ih );
|
||||
if ( fd == -1 ) {
|
||||
free( path );
|
||||
return;
|
||||
}
|
||||
|
||||
volume = iso9660_mount( fd );
|
||||
if ( volume == NULL ) {
|
||||
free ( path );
|
||||
close_io( fd );
|
||||
return;
|
||||
}
|
||||
|
||||
common = malloc(sizeof(iso9660_COMMON));
|
||||
common->dir = iso9660_opendir( volume, path );
|
||||
|
||||
forth_printf("\n");
|
||||
while ( (idr = iso9660_readdir(mi->common->dir)) ) {
|
||||
while ( (idr = iso9660_readdir(common->dir)) ) {
|
||||
|
||||
forth_printf("% 10d ", isonum_733(idr->size));
|
||||
forth_printf("%d-%02d-%02d %02d:%02d:%02d ",
|
||||
@@ -174,12 +194,20 @@ iso9660_files_dir( iso9660_info_t *mi )
|
||||
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);
|
||||
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);
|
||||
}
|
||||
|
||||
iso9660_closedir( common->dir );
|
||||
iso9660_umount( volume );
|
||||
|
||||
close_io( fd );
|
||||
|
||||
free( common );
|
||||
free( path );
|
||||
}
|
||||
|
||||
/* static method, ( pos.d ih -- flag? ) */
|
||||
|
||||
Reference in New Issue
Block a user