mirror of
https://github.com/deater/dos33fsprogs.git
synced 2024-06-16 07:29:29 +00:00
prodos: add support for tree files
I only am testing on floppies so no files >128k to test
This commit is contained in:
parent
166f24075f
commit
960b705596
|
@ -12,7 +12,7 @@
|
||||||
#include "prodos.h"
|
#include "prodos.h"
|
||||||
|
|
||||||
static int ignore_errors=0;
|
static int ignore_errors=0;
|
||||||
int debug=1;
|
int debug=0;
|
||||||
|
|
||||||
/* Read volume directory into a buffer */
|
/* Read volume directory into a buffer */
|
||||||
static int prodos_read_voldir(int fd, struct voldir_t *voldir, int interleave) {
|
static int prodos_read_voldir(int fd, struct voldir_t *voldir, int interleave) {
|
||||||
|
@ -510,8 +510,8 @@ static int prodos_load_file(struct voldir_t *voldir,
|
||||||
int output_fd;
|
int output_fd;
|
||||||
unsigned char data[PRODOS_BYTES_PER_BLOCK];
|
unsigned char data[PRODOS_BYTES_PER_BLOCK];
|
||||||
unsigned char index_block[PRODOS_BYTES_PER_BLOCK];
|
unsigned char index_block[PRODOS_BYTES_PER_BLOCK];
|
||||||
unsigned char sector_buffer[PRODOS_BYTES_PER_BLOCK];
|
unsigned char master_index_block[PRODOS_BYTES_PER_BLOCK];
|
||||||
int result,chunk,chunk_block;
|
int result,chunk,chunk_block,index,blocks_left,read_blocks;
|
||||||
struct file_entry_t file;
|
struct file_entry_t file;
|
||||||
|
|
||||||
/* FIXME! Warn if overwriting file! */
|
/* FIXME! Warn if overwriting file! */
|
||||||
|
@ -547,7 +547,9 @@ static int prodos_load_file(struct voldir_t *voldir,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRODOS_FILE_SAPLING:
|
case PRODOS_FILE_SAPLING:
|
||||||
/* Just a single block */
|
/* Index block points to up to 256 blocks */
|
||||||
|
/* Addresses are stored low-byte (256 bytes) then hi-byte */
|
||||||
|
/* Address of zero means file hole, all zeros */
|
||||||
if (debug) fprintf(stderr,"Loading index "
|
if (debug) fprintf(stderr,"Loading index "
|
||||||
"block $%x\n",
|
"block $%x\n",
|
||||||
file.key_pointer);
|
file.key_pointer);
|
||||||
|
@ -560,12 +562,19 @@ static int prodos_load_file(struct voldir_t *voldir,
|
||||||
for(chunk=0;chunk<file.blocks_used;chunk++) {
|
for(chunk=0;chunk<file.blocks_used;chunk++) {
|
||||||
chunk_block=(index_block[chunk])|(index_block[chunk+256]<<8);
|
chunk_block=(index_block[chunk])|(index_block[chunk+256]<<8);
|
||||||
|
|
||||||
result=prodos_read_block(voldir,data,
|
if (chunk_block==0) {
|
||||||
chunk_block);
|
/* FILE hole */
|
||||||
if (result<0) {
|
lseek(output_fd,
|
||||||
return result;
|
PRODOS_BYTES_PER_BLOCK,
|
||||||
|
SEEK_CUR);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
result=prodos_read_block(voldir,data,
|
||||||
|
chunk_block);
|
||||||
|
if (result<0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
result=write(output_fd,data,PRODOS_BYTES_PER_BLOCK);
|
result=write(output_fd,data,PRODOS_BYTES_PER_BLOCK);
|
||||||
if (result!=PRODOS_BYTES_PER_BLOCK) {
|
if (result!=PRODOS_BYTES_PER_BLOCK) {
|
||||||
|
@ -579,6 +588,61 @@ static int prodos_load_file(struct voldir_t *voldir,
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PRODOS_FILE_TREE:
|
case PRODOS_FILE_TREE:
|
||||||
|
/* Master Index block points to up to 256 index blocks */
|
||||||
|
/* Addresses are stored low-byte (256 bytes) then hi-byte */
|
||||||
|
/* Index block points to up to 256 blocks */
|
||||||
|
/* Addresses are stored low-byte (256 bytes) then hi-byte */
|
||||||
|
/* Address of zero means file hole, all zeros */
|
||||||
|
|
||||||
|
blocks_left=file.blocks_used;
|
||||||
|
|
||||||
|
if (debug) fprintf(stderr,"Loading master index "
|
||||||
|
"block $%x\n",
|
||||||
|
file.key_pointer);
|
||||||
|
result=prodos_read_block(voldir,master_index_block,
|
||||||
|
file.key_pointer);
|
||||||
|
if (result<0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(index=0;index<file.blocks_used/256;index++) {
|
||||||
|
result=prodos_read_block(voldir,
|
||||||
|
index_block,
|
||||||
|
(master_index_block[index])|
|
||||||
|
(master_index_block[256+index]<<8));
|
||||||
|
if (result<0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (blocks_left<256) {
|
||||||
|
read_blocks=blocks_left;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
read_blocks=256;
|
||||||
|
}
|
||||||
|
|
||||||
|
for(chunk=0;chunk<read_blocks;chunk++) {
|
||||||
|
chunk_block=(index_block[chunk])|
|
||||||
|
(index_block[chunk+256]<<8);
|
||||||
|
|
||||||
|
result=prodos_read_block(voldir,data,
|
||||||
|
chunk_block);
|
||||||
|
if (result<0) {
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
result=write(output_fd,data,PRODOS_BYTES_PER_BLOCK);
|
||||||
|
if (result!=PRODOS_BYTES_PER_BLOCK) {
|
||||||
|
fprintf(stderr,"Error writing file!\n");
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* truncate to actual size of file */
|
||||||
|
ftruncate(output_fd,file.eof);
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
|
||||||
case PRODOS_FILE_SUBDIR:
|
case PRODOS_FILE_SUBDIR:
|
||||||
|
@ -843,7 +907,6 @@ int main(int argc, char **argv) {
|
||||||
int inode;
|
int inode;
|
||||||
int address=0, length=0;
|
int address=0, length=0;
|
||||||
struct voldir_t voldir;
|
struct voldir_t voldir;
|
||||||
struct file_entry_t file;
|
|
||||||
|
|
||||||
/* Check command line arguments */
|
/* Check command line arguments */
|
||||||
while ((c = getopt (argc, argv,"a:i:l:t:s:dhvxy"))!=-1) {
|
while ((c = getopt (argc, argv,"a:i:l:t:s:dhvxy"))!=-1) {
|
||||||
|
|
Loading…
Reference in New Issue
Block a user