From: Stefan E. <se...@us...> - 2002-05-02 15:24:23
|
Update of /cvsroot/blob/blob/src/lib In directory usw-pr-cvs1:/tmp/cvs-serv16462 Modified Files: tar.c Log Message: - use generic io framework to provide a tar reader w/o actually knowing where the data comes from. Index: tar.c =================================================================== RCS file: /cvsroot/blob/blob/src/lib/tar.c,v retrieving revision 1.1 retrieving revision 1.2 diff -u -d -r1.1 -r1.2 --- tar.c 26 Apr 2002 18:24:54 -0000 1.1 +++ tar.c 2 May 2002 15:24:21 -0000 1.2 @@ -20,6 +20,10 @@ * $Id$ * * $Log$ + * Revision 1.2 2002/05/02 15:24:21 seletz + * - use generic io framework to provide a tar reader w/o actually knowing + * where the data comes from. + * * Revision 1.1 2002/04/26 18:24:54 seletz * - first revision of minimal tar archive support. * - this module will be used to get a blob/ramdisk/kernel @@ -59,6 +63,8 @@ #include <blob/util.h> #include <blob/command.h> +#include <blob/init.h> +#include <blob/generic_io.h> #include <blob/tar.h> /********************************************************************** @@ -83,6 +89,7 @@ static char module_version[] = "$Id$"; + /********************************************************************** * static functions */ @@ -95,61 +102,137 @@ static int tar_hdr_fsize_get( tar_hdr_posix_t *hdr, unsigned long *size ); static int tar_from_oct( unsigned char *start, size_t digits, unsigned long *value ); +/* io driver stuff */ +int tar_io_conf( io_driver_t * io, void *conf ); +int tar_io_read( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ); +int tar_io_write( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ); + /**********************************************************************/ /**********************************************************************/ /**********************************************************************/ -/* simple memory block getter */ -int mem_block_get( unsigned char *buffer, void *priv ) +/* set debug level */ +void tar_dbg_set( int lvl ) { - struct mem *mp= (struct mem *)priv; + tar_dbg = lvl; +} - DBG( 15, "%s: priv=%p\n", __FUNCTION__, priv ); +/********************************************************************** + * io driver for tar archives + */ +void init_tar_default_io( void ) +{ + int ret; + static io_driver_t def_tar_io_driver; + static tar_arch_t def_tar_arch; - if ( !mp ) + tar_dbg_set(0); + + /* init default tar drv */ + ret = tar_io_init( &def_tar_io_driver, &def_tar_arch ); + if ( ret ) return; + + ret = io_register( &def_tar_io_driver, "TAR" ); + if ( ret ) return; +} +__initlist(init_tar_default_io, INIT_LEVEL_OTHER_STUFF + 2); + +int tar_io_init( io_driver_t *io, tar_arch_t *arch ) +{ + if ( !io || !arch ) return -EINVAL; - if ( !mp->curr ) - mp->curr=mp->start; + DBG( 5, "%s: driver=%p, arch=%p\n", __FUNCTION__, + driver, arch ); - DBG( 15, "%s: start=%p, curr=%p\n", __FUNCTION__, - mp->start, mp->curr ); + io->conf = tar_io_conf; + io->read = tar_io_read; + io->write = tar_io_write; + io->private_data = (void *)arch; - memcpy( buffer, mp->curr, 512 ); - mp->curr += 512; + /* filled by configure */ + io->io_size = 0; + + /* filled for us by io_chain() */ + io->child_io = NULL; return 0; } -/* memory block reset */ -int mem_block_reset( void *priv ) +/* the user gives us a filename in conf */ +int tar_io_conf( io_driver_t * io, void *conf ) { - struct mem *mp= (struct mem *)priv; + int ret; + char *name; + io_driver_t *child; + tar_arch_t *arch; - DBG( 15, "%s: priv=%p\n", __FUNCTION__, priv ); + DBG( 5, "%s: io=%p, conf=%p\n", __FUNCTION__, + io, conf ); - if ( !mp ) + if ( !io || !conf ) return -EINVAL; - DBG( 15, "%s: start=%p, curr=%p\n", __FUNCTION__, - mp->start, mp->curr ); + arch = (tar_arch_t*)io->private_data; + if ( !arch ) + return -EINVAL; - mp->curr=mp->start; + child = io_get_child( io ); + if ( !child ) + return -EINVAL; + + name = (char *)conf; + + /* init new archive struct */ + ret = tar_init( arch, child ); + if ( ret ) + return -EINVAL; + + /* try to find file */ + ret = tar_file_search( arch, name ); + if ( ret ) + return -EINVAL; + + /* set io_size to filesize */ + io->io_size = arch->f_size; return 0; } -/* set debug level */ -void tar_dbg_set( int lvl ) +int tar_io_read( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ) { - tar_dbg = lvl; + io_driver_t *child; + tar_arch_t *arch; + u32 offset; + + arch = (tar_arch_t*)io->private_data; + if ( !arch ) + return -EINVAL; + + child = io_get_child( io ); + if ( !child ) + return -EINVAL; + + offset = arch->f_start_block*512; + + DBG( 3, "%s: dest=%p, src=%p(=%p), amount=%d, child=%p\n", __FUNCTION__, + dest, src, (char *)((u32)src + offset), amount, child ); + + return io_read(dest, (unsigned char *)(offset + (u32)src), amount, child ); } +int tar_io_write( unsigned char *dest, unsigned char *src, size_t amount, io_driver_t *io ) +{ + return -EINVAL; +} + +/********************************************************************** + * TAR functions + */ /* init archive struct */ -int tar_init( tar_arch_t *arch, block_get_fn get, block_reset_fn reset, void *priv ) +int tar_init( tar_arch_t *arch, io_driver_t *io ) { - DBG( 1, "%s: arch=%p, get=%p, reset=%p, priv=%p\n", __FUNCTION__, - arch, get, reset, priv ); + DBG( 1, "%s: arch=%p, io=%p\n", __FUNCTION__, arch, io ); DBG( 1, "tar: version %s\n", module_version ); @@ -157,11 +240,10 @@ return -EINVAL; } - arch->block_get = get; - arch->block_reset=reset; - arch->block_get_priv = priv; - arch->size=0l; - arch->blocks=0l; + arch->io_driver=io; + arch->block = 0; + arch->f_size=0l; + arch->f_blocks=0l; arch->filename[0]=0; return 0; @@ -180,11 +262,7 @@ return -EINVAL; /* reset to block 0 */ - ret = arch->block_reset( arch->block_get_priv ); - if ( ret ) { - printf( "tar: cant reset to block 0: %d\n", ret ); - return ret; - } + arch->block = 0; while ( !fini ) { ret = tar_fileinfo_get( arch ); @@ -197,8 +275,8 @@ printf( "%s %ld bytes, %d blocks\n", arch->filename, - arch->size, - arch->blocks ); + arch->f_size, + arch->f_blocks ); /* skip file */ ret = tar_skip_file( arch ); @@ -225,11 +303,7 @@ return -EINVAL; /* reset to block 0 */ - ret = arch->block_reset( arch->block_get_priv ); - if ( ret ) { - printf( "tar: cant reset to block 0: %d\n", ret ); - return ret; - } + arch->block = 0; ret = tar_file_search( arch, filename ); if ( ret ) { @@ -246,7 +320,7 @@ } printf( "tar: extracted file '%s', %ld bytes (%d blocks).\n", - arch->filename, arch->size, arch->blocks ); + arch->filename, arch->f_size, arch->f_blocks ); return 0; } @@ -275,8 +349,8 @@ DBG( 5, "%s %ld bytes, %d blocks\n", arch->filename, - arch->size, - arch->blocks ); + arch->f_size, + arch->f_blocks ); if ( strncmp( arch->filename, file, 255 ) == 0 ) { found = 1; @@ -297,23 +371,13 @@ /* skip to next file, if any */ static int tar_skip_file( tar_arch_t *arch ) { - int ret = 0; - int block; - DBG( 1, "%s: arch=%p\n", __FUNCTION__, arch ); if ( !arch ) return -EINVAL; /* skip data */ - for ( block=0; block<arch->blocks; block++ ) { - ret = arch->block_get( arch->buffer, arch->block_get_priv ); - if ( ret ) { - printf( "tar: cant get block %d: %d\n", block, ret ); - return ret; - } - } - + arch->block += arch->f_blocks; return 0; } @@ -321,7 +385,6 @@ static int tar_xtract_blocks( tar_arch_t *arch, char *dest ) { int ret = 0; - int block; unsigned long size; DBG( 1, "%s: arch=%p, dest=%p\n", __FUNCTION__, arch, dest ); @@ -329,30 +392,13 @@ if ( !arch || !dest ) return -EINVAL; - size = arch->size; + size = arch->f_size; if ( !size ) return -EINVAL; - /* extract data */ - for ( block=0; block<arch->blocks; block++ ) { - ret = arch->block_get( arch->buffer, arch->block_get_priv ); - if ( ret ) { - printf( "tar: cant get block %d: %d\n", block, ret ); - return ret; - } - - DBG( 5, "%s: %ld bytes to go\n", __FUNCTION__, size ); - - if ( size>512 ) { - memcpy( dest, arch->buffer, 512 ); - size -= 512; - dest += 512; - } else { - memcpy( dest, arch->buffer, size ); - dest += size; - } - - } + ret = io_read( dest, (unsigned char*)(arch->f_start_block*512), arch->f_size, arch->io_driver ); + if ( ret ) + return ret; return 0; } @@ -367,11 +413,12 @@ return -EINVAL; /* get header */ - ret = arch->block_get( arch->buffer, arch->block_get_priv ); + ret = io_read( arch->buffer, (unsigned char *)(arch->block*512), 512, arch->io_driver ); if ( ret ) { printf( "tar: cant get block: %d\n", ret ); goto DONE; } + arch->block++; /* and decode infos */ phdr = (tar_hdr_posix_t*)arch->buffer; @@ -382,16 +429,17 @@ goto DONE; } - ret = tar_hdr_fsize_get( phdr, &arch->size ); + ret = tar_hdr_fsize_get( phdr, &arch->f_size ); if ( ret ) { printf( "tar: cant decode file size: %d\n", ret ); ret = ret; goto DONE; } - arch->blocks = (arch->size/512) + (arch->size%512?1:0); + arch->f_start_block = arch->block; + arch->f_blocks = (arch->f_size/512) + (arch->f_size%512?1:0); printf( "tar: %s %ld bytes, %d blocks\n", phdr->name, - arch->size, arch->blocks ); + arch->f_size, arch->f_blocks ); strncpy( arch->filename, phdr->name, 100 ); arch->filename[100] = 0; @@ -400,8 +448,9 @@ DONE: /* reset fileinfos on error */ if ( ret ) { - arch->size=0; - arch->blocks=0; + arch->f_size=0; + arch->f_start_block = 0; + arch->f_blocks=0; arch->filename[0]=0; } return ret; |