Made recursive mode depth-first

This commit is contained in:
Bobbi Webber-Manners 2020-02-13 17:22:26 -05:00
parent 8d8511f331
commit 4e443534c2

View File

@ -1,15 +1,20 @@
/* /*
* Bobbi January-February 2020 * Bobbi January-February 2020
* *
* TODO: Error counting & fix error return codes
* TODO: Error log file option
* TODO: Whole volume mode - check all unused blocks are free * TODO: Whole volume mode - check all unused blocks are free
* TODO: Check no disk blocks are used more than once * TODO: Check no disk blocks are used more than once
* TODO: Fix mode * TODO: Fix mode
* TODO: Tool for 'extending' volume dir to more than 4 blocks * TODO: Sort by mtime, ctime, size ...
* TODO: Tool for lower/upper/camel casing filenames * TODO: Tool for lower/upper/camel casing filenames
* TODO: Tool for 'extending' volume dir to more than 4 blocks
* TODO: Legacy/extended date format conversion * TODO: Legacy/extended date format conversion
* TODO: Trimming unused directory blocks * TODO: Trimming unused directory blocks
* TODO: Improve output and user interface * TODO: Improve output and user interface
* TODO: Use segment to make more memory available * TODO: Use segment to make more memory available
* TODO: Needs a manpage
* TODO: Maybe make a version that doesn't need GNO
*/ */
#pragma debug 25 /* Enable stack checking */ #pragma debug 25 /* Enable stack checking */
@ -142,7 +147,7 @@ int treeblocks(uchar device, uint keyblk, uint *blkcnt);
int forkblocks(uchar device, uint keyblk, uint *blkcnt); int forkblocks(uchar device, uint keyblk, uint *blkcnt);
int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent, int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent,
uint blocknum, uint blkentries, uint *blkcnt); uint blocknum, uint blkentries, uint *blkcnt);
void enqueuesubdir(uint blocknum); void enqueuesubdir(uint blocknum, uint subdiridx);
int readdir(uint device, uint blocknum); int readdir(uint device, uint blocknum);
int cmp_name_asc(const void *a, const void *b); int cmp_name_asc(const void *a, const void *b);
int cmp_name_desc(const void *a, const void *b); int cmp_name_desc(const void *a, const void *b);
@ -157,9 +162,8 @@ void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent, uint device);
void sortblocks(uint device); void sortblocks(uint device);
int writedir(uchar device); int writedir(uchar device);
void freeblocks(void); void freeblocks(void);
void freedirs(void);
void usage(void); void usage(void);
void processonedir(uint device, uint blocknum); void processdir(uint device, uint blocknum);
/* Print error string to stderr */ /* Print error string to stderr */
void prerr(char *s) { void prerr(char *s) {
@ -324,7 +328,8 @@ int readfreelist(uchar device) {
} }
uint flblk = buf[0x27] + 256U * buf[0x28]; uint flblk = buf[0x27] + 256U * buf[0x28];
uint totblks = buf[0x29] + 256U * buf[0x2a]; uint totblks = buf[0x29] + 256U * buf[0x2a];
printf("Volume has %u blocks\n", totblks); if (doverbose)
printf("Volume has %u blocks\n", totblks);
uint flsize = totblks / 4096U; uint flsize = totblks / 4096U;
if ((flsize % 4096) >0) if ((flsize % 4096) >0)
++flsize; ++flsize;
@ -523,22 +528,25 @@ int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent,
/* /*
* Record the keyblock of a subdirectory to be processed subsequently * Record the keyblock of a subdirectory to be processed subsequently
* blocknum is the block number of the subdirectory keyblock
* subdiridx is a sequential counter of the subdirs in the current directory
*/ */
void enqueuesubdir(uint blocknum) { void enqueuesubdir(uint blocknum, uint subdiridx) {
struct dirblk *p = (struct dirblk*)malloc(sizeof(struct dirblk)); struct dirblk *p = (struct dirblk*)malloc(sizeof(struct dirblk));
if (!p) { if (!p) {
puts("** Unable to allocate memory **"); puts("** Unable to allocate memory **");
exit(3); exit(3);
} }
p->blocknum = blocknum; p->blocknum = blocknum;
p->next = NULL; static struct dirblk *prev;
static struct dirblk *end; if (subdiridx == 0) { /* First subdir is inserted at head of list */
if (!dirs) p->next = dirs;
end = dirs = p; dirs = p;
else { } else { /* Subsequent subdirs follow the previous */
end->next = p; p->next = prev->next;
end = p; prev->next = p;
} }
prev = p;
} }
/* /*
@ -599,6 +607,7 @@ int readdir(uint device, uint blocknum) {
uint idx = entsz + PTRSZ; /* Skip header */ uint idx = entsz + PTRSZ; /* Skip header */
uchar blkentries = 2; uchar blkentries = 2;
uchar entries = 0; uchar entries = 0;
uint subdirs = 0;
while (1) { while (1) {
struct pd_dirent *ent = (struct pd_dirent*)(curblk->data + idx); struct pd_dirent *ent = (struct pd_dirent*)(curblk->data + idx);
@ -653,7 +662,7 @@ int readdir(uint device, uint blocknum) {
switch (ent->typ_len & 0xf0) { switch (ent->typ_len & 0xf0) {
case 0xd0: case 0xd0:
/* Subdirectory */ /* Subdirectory */
enqueuesubdir(keyblk); enqueuesubdir(keyblk, subdirs++);
subdirblocks(device, keyblk, ent, subdirblocks(device, keyblk, ent,
blocknum, blkentries, &count); blocknum, blkentries, &count);
break; break;
@ -732,7 +741,7 @@ int readdir(uint device, uint blocknum) {
} }
if (filecount != entries) if (filecount != entries)
printf("Filecount %u wrong, should be %u\n", filecount, entries); printf("Filecount %u wrong, should be %u\n", filecount, entries);
return 0; return 0; // TODO: THIS SHOULD BE NUMBER OF ERRORS
} }
/* /*
@ -969,16 +978,6 @@ void freeblocks(void) {
blocks = NULL; blocks = NULL;
} }
void freedirs(void) {
struct dirblk *i = dirs, *j;
while (i) {
j = i->next;
free(i);
i = j;
}
dirs = NULL;
}
void usage(void) { void usage(void) {
prerr("usage: sortdir [-s xxx] [-rwv] path\n"); prerr("usage: sortdir [-s xxx] [-rwv] path\n");
prerr(" Options: -s xxx Directory sort options"); prerr(" Options: -s xxx Directory sort options");
@ -1008,7 +1007,7 @@ void usage(void) {
* Performs all actions for a single directory * Performs all actions for a single directory
* blocknum is the keyblock of the directory to process * blocknum is the keyblock of the directory to process
*/ */
void processonedir(uint device, uint blocknum) { void processdir(uint device, uint blocknum) {
uchar err = readdir(device, blocknum); uchar err = readdir(device, blocknum);
if (doverbose) { if (doverbose) {
printlist(); printlist();
@ -1077,15 +1076,16 @@ int main(int argc, char *argv[]) {
exit(1); exit(1);
} }
readfreelist(dev); readfreelist(dev);
processonedir(dev, blk); processdir(dev, blk);
if (dorecurse) { if (dorecurse) {
struct dirblk *d = dirs; while (dirs) {
while (d) { struct dirblk *d = dirs;
processonedir(dev, d->blocknum); blk = dirs->blocknum;
d = d->next; dirs = d->next;
free(d);
processdir(dev, blk);
} }
} }
freedirs();
return 0; return 0;
} }