mirror of
https://github.com/Michaelangel007/apple2_prodos_utils.git
synced 2024-05-28 12:41:35 +00:00
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
|
// Copy a file from the virtual file system back to the host
|
||||||
// ProDOS attributes are saved in file.prodos_meta
|
// 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 base = prodos_BlockGetPath( path );
|
||||||
int offset = base + 4; // skip prev,next block pointers
|
ProDOS_FileHeader_t *pEntry = >LastDirFile;
|
||||||
|
|
||||||
#if DEBUG_FILE
|
|
||||||
printf( "DEBUG: EXTRACT: path: %s\n", path );
|
|
||||||
printf( "DEBUG: EXTRACT: Dir @ %04X\n", base );
|
|
||||||
prodos_DumpFileHeader( gtLastDirFile );
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
|
|
||||||
#if DEBUG_EXTRACT
|
#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
|
#endif
|
||||||
|
|
||||||
if( !base )
|
if( !base )
|
||||||
{
|
{
|
||||||
if( path )
|
printf( "ERROR: Couldn't file to extract: %s\n", path );
|
||||||
printf( "ERROR: Couldn't find directory: %s\n", path );
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
int prev_block = 0;
|
if( !pEntry->len )
|
||||||
int next_block = 0;
|
|
||||||
|
|
||||||
do
|
|
||||||
{
|
{
|
||||||
prev_block = DskGet16( base + 0 );
|
printf( "ERROR: Couldn't get file information\n" );
|
||||||
next_block = DskGet16( base + 2 );
|
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;
|
case ProDOS_KIND_SEED: // <= 512 bytes
|
||||||
ProDOS_FileHeader_t file;
|
{
|
||||||
prodos_GetFileHeader( offset, &file );
|
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) )
|
if( iBlock != nBlock - 1 )
|
||||||
goto next_file;
|
fwrite( &gaDsk[ iDataOffset ], 1, PRODOS_BLOCK_SIZE, pFileData );
|
||||||
|
else
|
||||||
if( file.kind == ProDOS_KIND_ROOT ) // Skip root Volume name entry
|
fwrite( &gaDsk[ iDataOffset ], 1, pEntry->size % PRODOS_BLOCK_SIZE, pFileData );
|
||||||
goto next_file;
|
}
|
||||||
|
break;
|
||||||
next_file:
|
}
|
||||||
offset += gVolume.entry_len;
|
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;
|
return true;
|
||||||
offset = base + 4; // skip prev,next block pointers
|
|
||||||
|
|
||||||
} while( next_block );
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user