Move the separate ISO9660 handler into a new /packages/iso9660-files package in preparation for some future work. Based heavily

on Laurent's original patch posted to the list.

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


git-svn-id: svn://coreboot.org/openbios/trunk/openbios-devel@809 f158a5a8-5612-0410-a976-696ce0be7e32
This commit is contained in:
Mark Cave-Ayland
2010-07-03 14:39:49 +00:00
committed by Mark Cave-Ayland
parent 6e3c34c7b5
commit 5ed6ff34fc
10 changed files with 248 additions and 153 deletions

View File

@@ -1,12 +1,18 @@
/*
* /packages/iso9660-files filesystem handler
*
* (c) 2009 Laurent Vivier <Laurent@vivier.eu>
*
* (c) 2010 Mark Cave-Ayland <mark.cave-ayland@siriusit.co.uk>
*/
#include "config.h"
#include "libopenbios/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,34 +22,159 @@ typedef struct {
};
} 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/iso9660-files" );
/* ( -- success? ) */
static void
iso9660_files_open( iso9660_info_t *mi )
{
int fd;
char *path = my_args_copy();
if ( ! path )
RET( 0 );
fd = open_ih( my_parent() );
if ( fd == -1 ) {
free( path );
RET( 0 );
}
mi->volume = iso9660_mount( fd );
if ( mi->volume == NULL ) {
free( path );
close_io( fd );
RET( -1 );
}
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( -1 );
}
mi->common->type = FILE;
free( path );
RET( 0 );
}
mi->common->type = DIR;
free( path );
RET( -1 );
}
/* ( -- ) */
static void
iso9660_files_close( iso9660_info_t *mi )
{
int fd = mi->volume->fd;
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 );
}
/* ( buf len -- actlen ) */
static void
iso9660_files_read( iso9660_info_t *mi )
{
int count = POP();
char *buf = (char *)POP();
int ret;
if ( mi->common->type != FILE )
PUSH( 0 );
ret = iso9660_read( mi->common->file, buf, count );
PUSH( ret );
}
/* ( pos.d -- status ) */
static void
iso9660_files_seek( iso9660_info_t *mi )
{
llong pos = DPOP();
cell ret;
int offs = (int)pos;
int whence = SEEK_SET;
if (mi->common->type != FILE)
PUSH( -1 );
if( offs == -1 ) {
offs = 0;
whence = SEEK_END;
}
ret = iso9660_lseek(mi->common->file, offs, whence);
PUSH( (ret < 0)? -1 : 0 );
}
/* ( -- filepos.d ) */
static void
iso9660_files_offset( iso9660_info_t *mi )
{
if ( mi->common->type != FILE )
DPUSH( -1 );
DPUSH( mi->common->file->offset );
}
/* ( addr -- size ) */
static void
iso9660_files_load( iso9660_info_t *mi)
{
char *buf = (char*)POP();
int ret, size;
if ( mi->common->type != FILE )
PUSH( 0 );
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 void
dir_fs ( file_desc_t *fd )
iso9660_files_dir( iso9660_info_t *mi )
{
iso9660_COMMON *common = (iso9660_COMMON *)fd;
struct iso_directory_record *idr;
char name_buf[256];
if (common->type != DIR)
if (mi->common->type != DIR)
return;
forth_printf("\n");
while ( (idr = iso9660_readdir(common->dir)) ) {
while ( (idr = iso9660_readdir(mi->common->dir)) ) {
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);
iso9660_name(mi->common->dir->volume, idr, name_buf);
if (idr->flags[0] & 2)
forth_printf("%s\\\n", name_buf);
else
@@ -51,126 +182,50 @@ dir_fs ( file_desc_t *fd )
}
}
static file_desc_t *
open_path( fs_ops_t *fs, const char *path )
/* static method, ( pos.d ih -- flag? ) */
static void
iso9660_files_probe( iso9660_info_t *dummy )
{
iso9660_VOLUME *volume = (iso9660_VOLUME *)fs->fs_data;
iso9660_COMMON *common;
ihandle_t ih = POP_ih();
llong offs = DPOP();
int fd, ret = 0;
common = (iso9660_COMMON *)malloc(sizeof(*common));
if (common == NULL)
return NULL;
fd = open_ih(ih);
if (iso9660_probe(fd, offs))
ret = -1;
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;
}
close_io(fd);
static char *
get_path( file_desc_t *fd, char *buf, int size )
{
iso9660_COMMON *common = (iso9660_COMMON *)fd;
if (common->type != FILE)
return NULL;
strncpy(buf, common->file->path, size);
return buf;
}
static int
file_lseek( file_desc_t *fd, off_t offs, int whence )
{
iso9660_COMMON *common = (iso9660_COMMON *)fd;
if (common->type != FILE)
return -1;
return iso9660_lseek(common->file, offs, whence);
RET (ret);
}
static void
file_close( file_desc_t *fd )
iso9660_files_block_size( iso9660_info_t *dummy )
{
iso9660_COMMON *common = (iso9660_COMMON *)fd;
if (common->type == FILE)
iso9660_close(common->file);
else if (common->type == DIR)
iso9660_closedir(common->dir);
free(common);
PUSH(2048);
}
static int
file_read( file_desc_t *fd, void *buf, size_t count )
static void
iso9660_initializer( iso9660_info_t *dummy )
{
iso9660_COMMON *common = (iso9660_COMMON *)fd;
if (common->type != FILE)
return -1;
return iso9660_read(common->file, buf, count);
fword("register-fs-package");
}
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 = {
.dir = dir_fs,
.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,
NODE_METHODS( iso9660 ) = {
{ "probe", iso9660_files_probe },
{ "open", iso9660_files_open },
{ "close", iso9660_files_close },
{ "read", iso9660_files_read },
{ "seek", iso9660_files_seek },
{ "offset", iso9660_files_offset },
{ "load", iso9660_files_load },
{ "dir", iso9660_files_dir },
{ "block-size", iso9660_files_block_size },
{ NULL, iso9660_initializer },
};
int
fs_iso9660_probe( int fd, llong offs )
{
if (iso9660_probe(fd, offs))
return 0;
return -1;
}
int fs_iso9660_open(int fd, fs_ops_t *fs)
void
iso9660_init( void )
{
iso9660_VOLUME *volume;
volume = iso9660_mount(fd);
if (volume == NULL)
return -1;
*fs = iso9660_ops;
fs->fs_data = volume;
return 0;
REGISTER_NODE( iso9660 );
}