mirror of
https://github.com/deater/dos33fsprogs.git
synced 2025-01-13 22:30:49 +00:00
prodos: add subdir support to DUMP
This commit is contained in:
parent
b2e684247b
commit
1907caf2c4
@ -23,7 +23,6 @@ TODO:
|
||||
prodos:
|
||||
test! especially tree (files bigger than 128k)
|
||||
subdirectory support
|
||||
delete support
|
||||
support for setting attributes
|
||||
|
||||
|
||||
|
@ -432,7 +432,7 @@ static int prodos_add_file(struct voldir_t *voldir,
|
||||
file.creation_time=prodos_time(time(NULL));
|
||||
file.version=0;
|
||||
file.min_version=0;
|
||||
file.access=0;
|
||||
file.access=0xe3; // 0x21?
|
||||
file.aux_type=0;
|
||||
file.last_mod=prodos_time(time(NULL));
|
||||
file.header_pointer=PRODOS_VOLDIR_KEY_BLOCK;
|
||||
@ -880,6 +880,8 @@ static void display_help(char *name, int version_only) {
|
||||
printf("\tRENAME apple_file_old apple_file_new\n");
|
||||
printf("\tDUMP\n");
|
||||
printf("\tVOLUME volume_name\n");
|
||||
printf("\tMKDIR dir_name\n");
|
||||
printf("\tRMDIR dir_name\n");
|
||||
printf("\tTYPE TODO: set type\n");
|
||||
printf("\tAUX TODO: set aux\n");
|
||||
printf("\tTIMESTAMP TODO: set timestamp\n");
|
||||
@ -897,8 +899,10 @@ static void display_help(char *name, int version_only) {
|
||||
#define COMMAND_DUMP 5
|
||||
#define COMMAND_SHOWFREE 6
|
||||
#define COMMAND_VOLNAME 7
|
||||
#define COMMAND_MKDIR 8
|
||||
#define COMMAND_RMDIR 9
|
||||
|
||||
#define MAX_COMMAND 8
|
||||
#define MAX_COMMAND 10
|
||||
#define COMMAND_UNKNOWN 255
|
||||
|
||||
static struct command_type {
|
||||
@ -913,6 +917,8 @@ static struct command_type {
|
||||
{COMMAND_DUMP,"DUMP"},
|
||||
{COMMAND_SHOWFREE,"SHOWFREE"},
|
||||
{COMMAND_VOLNAME,"VOLNAME"},
|
||||
{COMMAND_MKDIR,"MKDIR"},
|
||||
{COMMAND_RMDIR,"RMDIR"},
|
||||
};
|
||||
|
||||
static int lookup_command(char *name) {
|
||||
@ -1314,12 +1320,12 @@ int main(int argc, char **argv) {
|
||||
|
||||
case COMMAND_DUMP:
|
||||
printf("Dumping %s!\n",image);
|
||||
prodos_dump(&voldir,prodos_fd);
|
||||
prodos_dump(&voldir);
|
||||
break;
|
||||
|
||||
case COMMAND_SHOWFREE:
|
||||
printf("Showing Free %s!\n",image);
|
||||
prodos_showfree(&voldir,prodos_fd);
|
||||
prodos_showfree(&voldir);
|
||||
break;
|
||||
|
||||
case COMMAND_RENAME:
|
||||
|
@ -28,6 +28,15 @@
|
||||
#define PRODOS_TYPE_VAR 0xFD
|
||||
#define PRODOS_TYPE_SYS 0xFF
|
||||
|
||||
/* Normal access is $C3 */
|
||||
/* Locked file is $01 */
|
||||
/* Non-empty directories often locked? */
|
||||
#define PRODOS_ACCESS_DESTROY 0x80 // can be deleted
|
||||
#define PRODOS_ACCESS_RENAME 0x40
|
||||
#define PRODOS_ACCESS_CHANGED 0x20 // has been changed since last backup
|
||||
#define PRODOS_ACCESS_WRITE 0x02
|
||||
#define PRODOS_ACCESS_READ 0x01
|
||||
|
||||
struct voldir_t {
|
||||
int fd;
|
||||
int interleave;
|
||||
@ -47,6 +56,26 @@ struct voldir_t {
|
||||
unsigned int creation_time;
|
||||
};
|
||||
|
||||
struct subdir_t {
|
||||
unsigned char storage_type;
|
||||
unsigned char name_length;
|
||||
unsigned char version;
|
||||
unsigned char min_version;
|
||||
unsigned char access;
|
||||
unsigned char entry_length;
|
||||
unsigned char entries_per_block;
|
||||
unsigned char parent_entry;
|
||||
unsigned char parent_entry_length;
|
||||
unsigned short file_count;
|
||||
unsigned short parent_pointer;
|
||||
// unsigned short next_block;
|
||||
// unsigned short bit_map_pointer;
|
||||
// unsigned short total_blocks;
|
||||
unsigned char subdir_name[16];
|
||||
unsigned int creation_time;
|
||||
};
|
||||
|
||||
|
||||
struct file_entry_t {
|
||||
unsigned char storage_type;
|
||||
unsigned char name_length;
|
||||
@ -81,8 +110,8 @@ void prodos_catalog(int dos_fd, struct voldir_t *voldir);
|
||||
//unsigned char prodos_file_type(int value);
|
||||
|
||||
/* prodos_dump.c */
|
||||
int prodos_dump(struct voldir_t *voldir, int fd);
|
||||
int prodos_showfree(struct voldir_t *voldir, int fd);
|
||||
int prodos_dump(struct voldir_t *voldir);
|
||||
int prodos_showfree(struct voldir_t *voldir);
|
||||
|
||||
/* prodos_read.c */
|
||||
int prodos_read_block(struct voldir_t *voldir,unsigned char *block, int blocknum);
|
||||
|
@ -6,7 +6,7 @@
|
||||
|
||||
#include "prodos.h"
|
||||
|
||||
//static int debug=0;
|
||||
extern int debug;
|
||||
|
||||
|
||||
/* returns the next valid catalog entry */
|
||||
|
@ -10,6 +10,8 @@
|
||||
#include "prodos.h"
|
||||
|
||||
|
||||
extern int debug;
|
||||
|
||||
#if 0
|
||||
static int dump_block(unsigned char *block_buffer) {
|
||||
|
||||
@ -56,11 +58,11 @@ static void prodos_print_time(int t) {
|
||||
|
||||
static void prodos_print_access(int access) {
|
||||
|
||||
if (access&0x80) printf("DESTROY ");
|
||||
if (access&0x40) printf("RENAME ");
|
||||
if (access&0x20) printf("VOLDIR_NEW ");
|
||||
if (access&0x2) printf("VOLDIR_WRITE ");
|
||||
if (access&0x1) printf("VOLDIR_READ ");
|
||||
if (access&PRODOS_ACCESS_DESTROY) printf("DESTROY ");
|
||||
if (access&PRODOS_ACCESS_RENAME) printf("RENAME ");
|
||||
if (access&PRODOS_ACCESS_CHANGED) printf("CHANGED ");
|
||||
if (access&PRODOS_ACCESS_WRITE) printf("WRITE ");
|
||||
if (access&PRODOS_ACCESS_READ) printf("READ ");
|
||||
|
||||
}
|
||||
|
||||
@ -183,40 +185,79 @@ static void dump_voldir(struct voldir_t *voldir) {
|
||||
}
|
||||
|
||||
|
||||
int prodos_dump(struct voldir_t *voldir, int fd) {
|
||||
int prodos_dump_subdir(struct voldir_t *voldir, int subdir_key_block) {
|
||||
|
||||
int catalog_block,catalog_offset,file;
|
||||
unsigned char catalog_buffer[PRODOS_BYTES_PER_BLOCK];
|
||||
unsigned char subdir_buffer[PRODOS_BYTES_PER_BLOCK];
|
||||
unsigned char file_desc[PRODOS_FILE_DESC_LEN];
|
||||
int result;
|
||||
struct file_entry_t file_entry;
|
||||
struct subdir_t subdir;
|
||||
int subdir_block,subdir_offset,file;
|
||||
|
||||
dump_voldir(voldir);
|
||||
printf("\n");
|
||||
printf("Dumping subdir at $%X\n",subdir_key_block);
|
||||
|
||||
prodos_voldir_dump_bitmap(voldir);
|
||||
result=prodos_read_block(voldir,subdir_buffer,subdir_key_block);
|
||||
|
||||
catalog_block=PRODOS_VOLDIR_KEY_BLOCK;
|
||||
catalog_offset=1; /* skip the header */
|
||||
subdir.storage_type=subdir_buffer[0x04]>>4;
|
||||
subdir.name_length=subdir_buffer[0x04]&0xf;
|
||||
memcpy(subdir.subdir_name,&subdir_buffer[0x05],15);
|
||||
subdir.subdir_name[subdir.name_length]=0;
|
||||
/* note 0x14 must be $75??? */
|
||||
subdir.creation_time=(subdir_buffer[0x1c]<<16)|
|
||||
(subdir_buffer[0x1d]<<24)|
|
||||
(subdir_buffer[0x1e]<<0)|
|
||||
(subdir_buffer[0x1f]<<8);
|
||||
subdir.version=subdir_buffer[0x20];
|
||||
subdir.min_version=subdir_buffer[0x21];
|
||||
subdir.access=subdir_buffer[0x22];
|
||||
subdir.entry_length=subdir_buffer[0x23];
|
||||
subdir.entries_per_block=subdir_buffer[0x24];
|
||||
subdir.file_count=(subdir_buffer[0x25]|(subdir_buffer[0x26]<<8));
|
||||
subdir.parent_pointer=(subdir_buffer[0x27]|(subdir_buffer[0x28]<<8));
|
||||
subdir.parent_entry=subdir_buffer[0x29];
|
||||
subdir.parent_entry_length=subdir_buffer[0x2A];
|
||||
|
||||
|
||||
printf("\tStorage type: ($%x): ",subdir.storage_type);
|
||||
prodos_print_storage_type(subdir.storage_type);
|
||||
printf("\tName length: $%x\n",subdir.name_length);
|
||||
printf("\tName: %s\n",subdir.subdir_name);
|
||||
printf("\tCreation Time (%x): ",subdir.creation_time);
|
||||
prodos_print_time(subdir.creation_time);
|
||||
printf("\n");
|
||||
printf("\tVersion: %d\n",subdir.version);
|
||||
printf("\tMin Version: %d\n",subdir.min_version);
|
||||
printf("\tAccess (%x): ",subdir.access);
|
||||
prodos_print_access(subdir.access);
|
||||
printf("\n");
|
||||
printf("\tEntry length: %d\n",subdir.entry_length);
|
||||
printf("\tEntries per block: %d\n",subdir.entries_per_block);
|
||||
printf("\tFile count: %d\n",subdir.file_count);
|
||||
printf("\tParent Pointer: $%x\n",subdir.parent_pointer);
|
||||
printf("\tParent Entry: $%x\n",subdir.parent_entry);
|
||||
printf("\tParent Entry Length: $%x\n",subdir.parent_entry_length);
|
||||
|
||||
subdir_block=subdir_key_block;
|
||||
subdir_offset=1; /* skip the header */
|
||||
|
||||
while(1) {
|
||||
|
||||
result=prodos_read_block(voldir,catalog_buffer,catalog_block);
|
||||
result=prodos_read_block(voldir,subdir_buffer,subdir_block);
|
||||
if (result<0) fprintf(stderr,"Error on I/O\n");
|
||||
|
||||
// dump_block(catalog_buffer);
|
||||
|
||||
for(file=catalog_offset;
|
||||
file<voldir->entries_per_block;file++) {
|
||||
for(file=subdir_offset;
|
||||
file<subdir.entries_per_block;file++) {
|
||||
|
||||
memcpy(file_desc,
|
||||
catalog_buffer+4+file*PRODOS_FILE_DESC_LEN,
|
||||
subdir_buffer+4+file*PRODOS_FILE_DESC_LEN,
|
||||
PRODOS_FILE_DESC_LEN);
|
||||
prodos_populate_filedesc(file_desc,&file_entry);
|
||||
|
||||
if (file_entry.storage_type==PRODOS_FILE_DELETED) continue;
|
||||
|
||||
printf("\n\n");
|
||||
printf("FILE %d: %s\n",file,file_entry.file_name);
|
||||
printf("FILE $%X-%d: %s\n",subdir_block,file,file_entry.file_name);
|
||||
printf("\t");
|
||||
prodos_print_storage_type(file_entry.storage_type);
|
||||
|
||||
@ -251,6 +292,92 @@ int prodos_dump(struct voldir_t *voldir, int fd) {
|
||||
|
||||
}
|
||||
|
||||
/* move to next */
|
||||
subdir_block=subdir_buffer[0x2]|(subdir_buffer[0x3]<<8);
|
||||
if (subdir_block==0) break;
|
||||
subdir_offset=0;
|
||||
|
||||
}
|
||||
|
||||
printf("\n");
|
||||
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prodos_dump(struct voldir_t *voldir) {
|
||||
|
||||
int catalog_block,catalog_offset,file;
|
||||
unsigned char catalog_buffer[PRODOS_BYTES_PER_BLOCK];
|
||||
unsigned char file_desc[PRODOS_FILE_DESC_LEN];
|
||||
int result;
|
||||
struct file_entry_t file_entry;
|
||||
|
||||
dump_voldir(voldir);
|
||||
|
||||
prodos_voldir_dump_bitmap(voldir);
|
||||
|
||||
catalog_block=PRODOS_VOLDIR_KEY_BLOCK;
|
||||
catalog_offset=1; /* skip the header */
|
||||
|
||||
while(1) {
|
||||
|
||||
result=prodos_read_block(voldir,catalog_buffer,catalog_block);
|
||||
if (result<0) fprintf(stderr,"Error on I/O\n");
|
||||
|
||||
// dump_block(catalog_buffer);
|
||||
|
||||
for(file=catalog_offset;
|
||||
file<voldir->entries_per_block;file++) {
|
||||
|
||||
memcpy(file_desc,
|
||||
catalog_buffer+4+file*PRODOS_FILE_DESC_LEN,
|
||||
PRODOS_FILE_DESC_LEN);
|
||||
prodos_populate_filedesc(file_desc,&file_entry);
|
||||
|
||||
if (file_entry.storage_type==PRODOS_FILE_DELETED) continue;
|
||||
|
||||
printf("\n\n");
|
||||
printf("FILE %d: %s\n",file,file_entry.file_name);
|
||||
printf("\t($%X): ",file_entry.storage_type);
|
||||
prodos_print_storage_type(file_entry.storage_type);
|
||||
|
||||
printf("\t");
|
||||
prodos_print_file_type(file_entry.file_type);
|
||||
|
||||
printf("\tKey pointer: $%x\n",file_entry.key_pointer);
|
||||
|
||||
printf("\tBlocks Used: %d\n",file_entry.blocks_used);
|
||||
|
||||
printf("\tFile size (eof): %d\n",file_entry.eof);
|
||||
|
||||
printf("\tCreation Time (%x): ",file_entry.creation_time);
|
||||
prodos_print_time(file_entry.creation_time);
|
||||
printf("\n");
|
||||
|
||||
printf("\tVersion: %d\n",file_entry.version);
|
||||
|
||||
printf("\tMin Version: %d\n",file_entry.min_version);
|
||||
|
||||
printf("\tAccess (%x): ",file_entry.access);
|
||||
prodos_print_access(file_entry.access);
|
||||
printf("\n");
|
||||
|
||||
printf("\tAux Type: %x\n",file_entry.aux_type);
|
||||
|
||||
printf("\tLast mod Time: (%x) ",file_entry.last_mod);
|
||||
prodos_print_time(file_entry.last_mod);
|
||||
printf("\n");
|
||||
|
||||
printf("\tHeader pointer: %x\n",file_entry.header_pointer);
|
||||
|
||||
if (file_entry.storage_type==PRODOS_FILE_SUBDIR) {
|
||||
prodos_dump_subdir(voldir,file_entry.key_pointer);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* move to next */
|
||||
catalog_block=catalog_buffer[0x2]|(catalog_buffer[0x3]<<8);
|
||||
if (catalog_block==0) break;
|
||||
@ -264,7 +391,9 @@ int prodos_dump(struct voldir_t *voldir, int fd) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int prodos_showfree(struct voldir_t *voldir, int fd) {
|
||||
|
||||
|
||||
int prodos_showfree(struct voldir_t *voldir) {
|
||||
#if 0
|
||||
int num_tracks,catalog_t,catalog_s,file,ts_t,ts_s,ts_total;
|
||||
int track,sector;
|
||||
|
Loading…
x
Reference in New Issue
Block a user