Initial working version of Extract
This commit is contained in:
parent
8aaf926604
commit
43ce7299cc
121
prodos.tools.cpp
121
prodos.tools.cpp
|
@ -1298,59 +1298,106 @@ void ProDOS_FileDelete( const char *path )
|
|||
// Copy a file from the virtual file system back to the host
|
||||
// ProDOS attributes are saved in file.prodos_meta
|
||||
// ========================================================================
|
||||
void ProDOS_FileExtract( const char *path )
|
||||
bool ProDOS_FileExtract( const char *path )
|
||||
{
|
||||
int base = prodos_BlockGetPath( path );
|
||||
int offset = base + 4; // skip prev,next block pointers
|
||||
|
||||
#if DEBUG_FILE
|
||||
printf( "DEBUG: EXTRACT: path: %s\n", path );
|
||||
printf( "DEBUG: EXTRACT: Dir @ %04X\n", base );
|
||||
prodos_DumpFileHeader( gtLastDirFile );
|
||||
#endif
|
||||
|
||||
#if 0
|
||||
int base = prodos_BlockGetPath( path );
|
||||
ProDOS_FileHeader_t *pEntry = >LastDirFile;
|
||||
|
||||
#if DEBUG_EXTRACT
|
||||
printf( "DEBUG: CATALOG: Dir @ %04X\n", base );
|
||||
printf( "DEBUG: EXTRACT: path: %s\n", path );
|
||||
printf( "DEBUG: EXTRACT: Dir @ %04X\n", base );
|
||||
#endif
|
||||
|
||||
#if DEBUG_FILE
|
||||
prodos_DumpFileHeader( gtLastDirFile );
|
||||
#endif
|
||||
|
||||
if( !base )
|
||||
{
|
||||
if( path )
|
||||
printf( "ERROR: Couldn't find directory: %s\n", path );
|
||||
printf( "ERROR: Couldn't file to extract: %s\n", path );
|
||||
return false;
|
||||
}
|
||||
|
||||
int prev_block = 0;
|
||||
int next_block = 0;
|
||||
|
||||
do
|
||||
if( !pEntry->len )
|
||||
{
|
||||
prev_block = DskGet16( base + 0 );
|
||||
next_block = DskGet16( base + 2 );
|
||||
printf( "ERROR: Couldn't get file information\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
for( int iFile = 0; iFile < gVolume.entry_num; iFile++ )
|
||||
const int kind = pEntry->kind;
|
||||
if( false
|
||||
|| kind == ProDOS_KIND_DIR
|
||||
|| kind == ProDOS_KIND_SUB
|
||||
|| kind == ProDOS_KIND_ROOT
|
||||
)
|
||||
{
|
||||
printf( "ERROR: Can't extract a file of a directory type\n" );
|
||||
return false;
|
||||
}
|
||||
|
||||
const char sExt[] = "._meta";
|
||||
const size_t nExt = strlen( sExt );
|
||||
/* */ char sAttrib[ PRODOS_MAX_PATH ];
|
||||
int nAttrib = string_CopyUpper( sAttrib + 0, pEntry->name, pEntry->len );
|
||||
/* */ string_CopyUpper( sAttrib + nAttrib, sExt , nExt );
|
||||
|
||||
printf( "Saving meta... %s\n", sAttrib );
|
||||
FILE *pFileMeta = fopen( sAttrib, "w+b" );
|
||||
{
|
||||
fprintf( pFileMeta, "kind = 0x%02X\n", pEntry->kind );
|
||||
fprintf( pFileMeta, "date = 0x%04X\n", pEntry->date );
|
||||
fprintf( pFileMeta, "time = 0x%04X\n", pEntry->time );
|
||||
fprintf( pFileMeta, "cver = 0x%02X\n", pEntry->cur_ver );
|
||||
fprintf( pFileMeta, "mver = 0x%02X\n", pEntry->min_ver );
|
||||
fprintf( pFileMeta, "aux = 0x%04X\n", pEntry->aux );
|
||||
fprintf( pFileMeta, "modd = 0x%04X\n", pEntry->mod_date );
|
||||
fprintf( pFileMeta, "modt = 0x%04X\n", pEntry->mod_time );
|
||||
fclose( pFileMeta );
|
||||
}
|
||||
|
||||
int addr = pEntry->inode * PRODOS_BLOCK_SIZE;
|
||||
int size = pEntry->size;
|
||||
|
||||
printf( "Saving data... %s\n", pEntry->name );
|
||||
FILE *pFileData = fopen( pEntry->name, "w+b" );
|
||||
{
|
||||
// TODO:
|
||||
// printf( "WARNING: File exists. Use -i to ask if should over-write.\n" );
|
||||
|
||||
switch( kind )
|
||||
{
|
||||
ProDOS_VolumeHeader_t dir;
|
||||
ProDOS_FileHeader_t file;
|
||||
prodos_GetFileHeader( offset, &file );
|
||||
case ProDOS_KIND_SEED: // <= 512 bytes
|
||||
{
|
||||
fwrite( &gaDsk[ addr ], 1, size, pFileData );
|
||||
break;
|
||||
}
|
||||
case ProDOS_KIND_SAPL: // <= 128 KB
|
||||
{
|
||||
int nBlock = pEntry->blocks - 1; // 1st block is index block
|
||||
for( int iBlock = 0; iBlock < nBlock; iBlock++ )
|
||||
{
|
||||
int iDataBlock = DskGetIndexBlock( addr, iBlock );
|
||||
int iDataOffset = iDataBlock * PRODOS_BLOCK_SIZE;
|
||||
|
||||
if( (file.len == 0) || (file.name[0] == 0) )
|
||||
goto next_file;
|
||||
|
||||
if( file.kind == ProDOS_KIND_ROOT ) // Skip root Volume name entry
|
||||
goto next_file;
|
||||
|
||||
next_file:
|
||||
offset += gVolume.entry_len;
|
||||
if( iBlock != nBlock - 1 )
|
||||
fwrite( &gaDsk[ iDataOffset ], 1, PRODOS_BLOCK_SIZE, pFileData );
|
||||
else
|
||||
fwrite( &gaDsk[ iDataOffset ], 1, pEntry->size % PRODOS_BLOCK_SIZE, pFileData );
|
||||
}
|
||||
break;
|
||||
}
|
||||
case ProDOS_KIND_TREE:
|
||||
{
|
||||
printf( "ERROR: Tree files are not yet handled.\n" );
|
||||
break;
|
||||
}
|
||||
default:
|
||||
printf( "ERROR: Unhandled file type '%s' ($%02X)\n", gaProDOS_KindDescription[ kind ], kind );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
base = next_block * PRODOS_BLOCK_SIZE;
|
||||
offset = base + 4; // skip prev,next block pointers
|
||||
|
||||
} while( next_block );
|
||||
#endif
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
|
|
Loading…
Reference in New Issue