prodos: add subdir support to rest of utils

WARNING: not tested, also won't work if you have to grow
a directory list
This commit is contained in:
Vince Weaver
2021-08-04 16:06:52 -04:00
parent 2e7be027ff
commit 7ea2033caf
2 changed files with 57 additions and 15 deletions

View File

@@ -1,6 +1,7 @@
============= =============
prodos-utils prodos-utils
============= =============
by Vince `deater` Weaver <vince @ deater.net>
Tools for manipulating Apple II prodos filesystems Tools for manipulating Apple II prodos filesystems
@@ -22,7 +23,8 @@ TODO:
prodos: prodos:
test! especially tree (files bigger than 128k) test! especially tree (files bigger than 128k)
subdirectory support test! subdirectory support
subdir currently broken if have to grow the directory
support for setting attributes support for setting attributes

View File

@@ -71,14 +71,15 @@ static int prodos_lookup_file(struct voldir_t *voldir,
/* Given filename, return voldir/offset */ /* Given filename, return voldir/offset */
/* FIXME: allocate new voldir block if all full */ /* FIXME: allocate new voldir block if all full */
static int prodos_allocate_directory_entry(struct voldir_t *voldir) { static int prodos_allocate_directory_entry(
struct voldir_t *voldir,int dir_block) {
int voldir_block,voldir_offset; int voldir_block,voldir_offset;
struct file_entry_t file_entry; struct file_entry_t file_entry;
unsigned char voldir_buffer[PRODOS_BYTES_PER_BLOCK]; unsigned char voldir_buffer[PRODOS_BYTES_PER_BLOCK];
int result,file; int result,file;
voldir_block=PRODOS_VOLDIR_KEY_BLOCK; voldir_block=dir_block;
voldir_offset=1; /* skip the header */ voldir_offset=1; /* skip the header */
while(1) { while(1) {
@@ -117,12 +118,13 @@ static int prodos_allocate_directory_entry(struct voldir_t *voldir) {
/* Checks if "filename" exists */ /* Checks if "filename" exists */
/* returns file type */ /* returns file type */
static int prodos_check_file_exists(struct voldir_t *voldir, static int prodos_check_file_exists(struct voldir_t *voldir,
int dir_block,
char *filename) { char *filename) {
int result; int result;
result=prodos_lookup_file(voldir,PRODOS_VOLDIR_KEY_BLOCK,filename); result=prodos_lookup_file(voldir,dir_block,filename);
return result; return result;
} }
@@ -234,7 +236,7 @@ static struct prodos_file_type {
/* creates file apple_filename on the image from local file filename */ /* creates file apple_filename on the image from local file filename */
/* returns ?? */ /* returns ?? */
static int prodos_add_file(struct voldir_t *voldir, static int prodos_add_file(struct voldir_t *voldir,
int fd, char *type, int dir_block, char *type,
int address, int length, int address, int length,
char *filename, char *apple_filename) { char *filename, char *apple_filename) {
@@ -442,10 +444,10 @@ static int prodos_add_file(struct voldir_t *voldir,
file.access=0xe3; // 0x21? file.access=0xe3; // 0x21?
file.aux_type=0; file.aux_type=0;
file.last_mod=prodos_time(time(NULL)); file.last_mod=prodos_time(time(NULL));
file.header_pointer=PRODOS_VOLDIR_KEY_BLOCK; file.header_pointer=dir_block;
inode=prodos_allocate_directory_entry(voldir); inode=prodos_allocate_directory_entry(voldir,dir_block);
if (inode<0) { if (inode<0) {
return inode; return inode;
} }
@@ -775,7 +777,8 @@ static int prodos_rename_file(struct voldir_t *voldir,
} }
static int prodos_delete_file(struct voldir_t *voldir,char *apple_filename) { static int prodos_delete_file(struct voldir_t *voldir,
int dir_block,char *apple_filename) {
unsigned char data_buffer[PRODOS_BYTES_PER_BLOCK]; unsigned char data_buffer[PRODOS_BYTES_PER_BLOCK];
unsigned char index_block[PRODOS_BYTES_PER_BLOCK]; unsigned char index_block[PRODOS_BYTES_PER_BLOCK];
@@ -786,7 +789,7 @@ static int prodos_delete_file(struct voldir_t *voldir,char *apple_filename) {
/* get the voldir/entry for file */ /* get the voldir/entry for file */
inode=prodos_lookup_file(voldir,PRODOS_VOLDIR_KEY_BLOCK,apple_filename); inode=prodos_lookup_file(voldir,dir_block,apple_filename);
if (inode<0) { if (inode<0) {
fprintf(stderr,"Error! %s not found!\n", fprintf(stderr,"Error! %s not found!\n",
@@ -1383,9 +1386,22 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,apple_path,temp); truncate_filename(apple_filename,apple_path,temp);
} }
if (debug) printf("\tApple filename: %s\n",apple_filename); if (apple_path[0]==0) {
dir_block=PRODOS_VOLDIR_KEY_BLOCK;
}
else {
dir_block=prodos_get_directory(&voldir,apple_path);
if (dir_block<0) {
fprintf(stderr,"Error, couldn't open directory %s\n",argv[optind]);
return -1;
}
}
file_exists=prodos_check_file_exists(&voldir,apple_filename); if (debug) printf("\tApple filename: %s, path: %s\n",
apple_filename,apple_path);
file_exists=prodos_check_file_exists(&voldir,
dir_block,apple_filename);
if (file_exists>=0) { if (file_exists>=0) {
fprintf(stderr,"Warning! %s exists!\n",apple_filename); fprintf(stderr,"Warning! %s exists!\n",apple_filename);
@@ -1398,7 +1414,7 @@ int main(int argc, char **argv) {
} }
} }
fprintf(stderr,"Deleting previous version...\n"); fprintf(stderr,"Deleting previous version...\n");
prodos_delete_file(&voldir,apple_filename); prodos_delete_file(&voldir,dir_block,apple_filename);
} }
prodos_add_file(&voldir,prodos_fd,type, prodos_add_file(&voldir,prodos_fd,type,
@@ -1419,13 +1435,25 @@ int main(int argc, char **argv) {
truncate_filename(apple_filename,apple_path,argv[optind]); truncate_filename(apple_filename,apple_path,argv[optind]);
file_exists=prodos_check_file_exists(&voldir,apple_filename); if (apple_path[0]==0) {
dir_block=PRODOS_VOLDIR_KEY_BLOCK;
}
else {
dir_block=prodos_get_directory(&voldir,apple_path);
if (dir_block<0) {
fprintf(stderr,"Error, couldn't open directory %s\n",argv[optind]);
return -1;
}
}
file_exists=prodos_check_file_exists(&voldir,
dir_block,apple_filename);
if (file_exists<0) { if (file_exists<0) {
fprintf(stderr, "Error! File %s does not exist\n", fprintf(stderr, "Error! File %s does not exist\n",
apple_filename); apple_filename);
goto exit_and_close; goto exit_and_close;
} }
prodos_delete_file(&voldir,apple_filename); prodos_delete_file(&voldir,dir_block,apple_filename);
break; break;
@@ -1463,8 +1491,20 @@ int main(int argc, char **argv) {
truncate_filename(new_filename,apple_path,argv[optind]); truncate_filename(new_filename,apple_path,argv[optind]);
if (apple_path[0]==0) {
dir_block=PRODOS_VOLDIR_KEY_BLOCK;
}
else {
dir_block=prodos_get_directory(&voldir,apple_path);
if (dir_block<0) {
fprintf(stderr,"Error, couldn't open directory %s\n",argv[optind]);
return -1;
}
}
/* get the entry/track/sector for file */ /* get the entry/track/sector for file */
file_exists=prodos_check_file_exists(&voldir,apple_filename); file_exists=prodos_check_file_exists(&voldir,
dir_block,apple_filename);
if (file_exists<0) { if (file_exists<0) {
fprintf(stderr,"Error! %s not found!\n", fprintf(stderr,"Error! %s not found!\n",
apple_filename); apple_filename);