From 791c9151cb8cf96714fed027bb4a052e40618420 Mon Sep 17 00:00:00 2001 From: Bobbi Webber-Manners Date: Fri, 14 Feb 2020 22:49:50 -0500 Subject: [PATCH] Added whole-disk mode, sorting by blocks & EOF --- bobbi/sortdir.c#b00008 | 119 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 109 insertions(+), 10 deletions(-) diff --git a/bobbi/sortdir.c#b00008 b/bobbi/sortdir.c#b00008 index 3ed4ae7..32e140d 100644 --- a/bobbi/sortdir.c#b00008 +++ b/bobbi/sortdir.c#b00008 @@ -1,11 +1,10 @@ /* * Bobbi January-February 2020 * - * TODO: Only do freelist checking if whole-volume mode specified * TODO: Error counting & fix error return codes * TODO: Error log file option * TODO: Fix mode - * TODO: Sort by mtime, ctime, size ... + * TODO: Sort by mtime, ctime * 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 @@ -36,7 +35,8 @@ #define CHECK /* Perform additional integrity checking */ typedef unsigned char uchar; -typedef unsigned int uint; +typedef unsigned int uint; +typedef unsigned long ulong; #define NMLEN 15 /* Length of filename */ #define MAXFILES 1000 /* Max files per directory */ @@ -103,6 +103,8 @@ struct block { struct fileent { char name[NMLEN+1];/* Name converted to upper/lower case */ uchar type; /* ProDOS file type */ + uint blocks; /* Size in blocks */ + ulong eof; /* EOF position in bytes */ uint order; /* Hack to make qsort() stable */ uchar blockidx; /* Index of dir block (1,2,3 ...) */ uchar entrynum; /* Entry within the block */ @@ -130,6 +132,7 @@ static uchar entperblk; /* Number of entries per block */ static char buf[BLKSZ]; /* General purpose scratch buffer */ static char buf2[BLKSZ]; /* General purpose scratch buffer */ static char buf3[BLKSZ]; /* General purpose scratch buffer */ +static uchar dowholedisk = 0; /* -D whole-disk option */ static uchar dorecurse = 0; /* -r recurse option */ static uchar dowrite = 0; /* -w write option */ static uchar doverbose = 0; /* -v verbose option */ @@ -160,6 +163,10 @@ int cmp_type_asc(const void *a, const void *b); int cmp_type_desc(const void *a, const void *b); int cmp_dir_beg(const void *a, const void *b); int cmp_dir_end(const void *a, const void *b); +int cmp_blocks_asc(const void *a, const void *b); +int cmp_blocks_desc(const void *a, const void *b); +int cmp_eof_asc(const void *a, const void *b); +int cmp_eof_desc(const void *a, const void *b); void sortlist(char s); void printlist(void); uint blockidxtoblocknum(uint idx); @@ -695,6 +702,9 @@ int readdir(uint device, uint blocknum) { } puts(namebuf); #endif + uint blks = ent->blksused[0] + 256U * ent->blksused[1]; + ulong eof = ent->eof[0] + 256L * ent->eof[1] + + 65536L * ent->eof[2]; for (uchar i=0; ityp_len & 0x0f); ++i) @@ -702,6 +712,8 @@ int readdir(uint device, uint blocknum) { filelist[numfiles].type = ent->type; filelist[numfiles].blockidx = blkcnt; filelist[numfiles].entrynum = blkentries; + filelist[numfiles].blocks = blks; + filelist[numfiles].eof = eof; #ifdef CHECK uint keyblk = ent->keyptr[0] + 256U * ent->keyptr[1]; uint hdrblk = ent->hdrptr[0] + 256U * ent->hdrptr[1]; @@ -709,7 +721,6 @@ int readdir(uint device, uint blocknum) { printf(" Header ptr %u should be %u\n", hdrblk, hdrblknum); } - uint blks = ent->blksused[0] + 256U * ent->blksused[1]; uint count; switch (ent->typ_len & 0xf0) { case 0xd0: @@ -863,6 +874,56 @@ int cmp_dir_end(const void *a, const void *b) { return aa->order - bb->order; } +/* + * Compare - sort in increasing order of blocks used + */ +int cmp_blocks_asc(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + int rc = aa->blocks - bb->blocks; + return rc != 0 ? rc : aa->order - bb->order; +} + +/* + * Compare - sort in decreasing order of blocks used + */ +int cmp_blocks_desc(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + int rc = bb->blocks - aa->blocks; + return rc != 0 ? rc : aa->order - bb->order; +} + +/* + * Compare - sort in increasing order of EOF position + */ +int cmp_eof_asc(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + long diff = aa->eof - bb->eof; + if (diff == 0) + return aa->order - bb->order; + if (diff > 0) + return 1; + else + return -1; +} + +/* + * Compare - sort in decreasing order of EOF position + */ +int cmp_eof_desc(const void *a, const void *b) { + struct fileent *aa = (struct fileent*)a; + struct fileent *bb = (struct fileent*)b; + long diff = bb->eof - aa->eof; + if (diff == 0) + return aa->order - bb->order; + if (diff > 0) + return 1; + else + return -1; +} + /* * Sort filelist[] * s defines the field to sort on @@ -896,6 +957,22 @@ void sortlist(char s) { qsort(filelist, numfiles, sizeof(struct fileent), cmp_dir_end); break; + case 'b': + qsort(filelist, numfiles, sizeof(struct fileent), + cmp_blocks_asc); + break; + case 'B': + qsort(filelist, numfiles, sizeof(struct fileent), + cmp_blocks_desc); + break; + case 'e': + qsort(filelist, numfiles, sizeof(struct fileent), + cmp_eof_asc); + break; + case 'E': + qsort(filelist, numfiles, sizeof(struct fileent), + cmp_eof_desc); + break; default: puts("Invalid sort option"); exit(2); @@ -908,13 +985,17 @@ void sortlist(char s) { void printlist(void) { puts("---------------------------------------------------------"); printf("numfiles=%u\n", numfiles); - puts("Dirblk Entry Type : Name"); - for(uint i=0; i