diff --git a/bobbi/sortdir.c#b00008 b/bobbi/sortdir.c#b00008 index e248d5f..0976d4b 100644 --- a/bobbi/sortdir.c#b00008 +++ b/bobbi/sortdir.c#b00008 @@ -119,25 +119,17 @@ static uchar dowrite = 0; static uchar doverbose = 0; static char sortopts[5] = "n"; -static uint stack; // DEBUG - -//#define STACK(msg) asm {tsc; sta stack }; fputs(msg, stdout); fputs(" ", stdout); pr_int(stack); putchar('\n'); - /* Prototypes */ void prerr(char *s); -void reverse(char *s); -void itoa(int n, char s[]); -void uitoa(uint n, char s[]); -void pr_int(int a); -void pr_uint(uint a); -void print_uint(uint i); int readdiskblock(uchar device, uint blocknum, char *buf); int writediskblock(uchar device, uint blocknum, char *buf); -void fixcase(char *in, char *out, uchar minvers, uchar vers); +void fixcase(char *in, char *out, uchar minvers, uchar vers, uchar len); int readfreelist(uchar device); int isfree(uint blk); int saplingblocks(uchar device, uint keyblk, uint *blkcnt); int treeblocks(uchar device, uint keyblk, uint *blkcnt); +int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent, + uint blocknum, uint blkentries, uint *blkcnt); int readdir(uint device, uint blocknum); int cmp_name_asc(const void *a, const void *b); int cmp_name_desc(const void *a, const void *b); @@ -159,75 +151,18 @@ void prerr(char *s) { fputs("\n", stderr); } -/* Reverse the characters of the string s */ -void reverse(char *s) { - char buf[10]; - int l = strlen(s); - for (int i=0; i 0); - if (sign < 0) - s[i++] = '-'; - s[i] = '\0'; - reverse(s); -} - -/* Unsigned verson of itoa() */ -void uitoa(uint n, char s[]) { - int i; - - i = 0; - do { - s[i++] = n % 10 + '0'; - } while ((n /= 10) > 0); - s[i] = '\0'; - reverse(s); -} - -/* Print an integer */ -void pr_int(int a) { - char buf[10]; - itoa(a, buf); - fputs(buf, stdout); -} - -/* Print an unsigned integer */ -void pr_uint(unsigned int a) { - char buf[10]; - uitoa(a, buf); - fputs(buf, stdout); -} - /* * Read block from disk using ProDOS call * buf must point to buffer with at least 512 bytes */ int readdiskblock(uchar device, uint blocknum, char *buf) { #ifdef DEBUG - fputs("Reading dev ", stdout); - pr_int(device); - fputs(" block ", stdout); - pr_uint(blocknum); - putchar('\n'); + printf("Reading dev %2u block %5u\n", device, blocknum); #endif #ifdef CHECK if (flloaded) if (isfree(blocknum)) - printf(" 1)Block %u is marked free!\n", - blocknum); + printf(" Block %u is marked free!\n", blocknum); #endif BlockRec br; br.blockDevNum = device; @@ -248,11 +183,7 @@ int readdiskblock(uchar device, uint blocknum, char *buf) { */ int writediskblock(uchar device, uint blocknum, char *buf) { #ifdef DEBUG - fputs("Writing dev ", stdout); - pr_int(device); - fputs(" block ", stdout); - pr_uint(blocknum); - putchar('\n'); + printf("Writing dev %2u block %5u\n", device, blocknum); #endif DIORecGS dr; dr.pCount = 6; @@ -272,11 +203,12 @@ int writediskblock(uchar device, uint blocknum, char *buf) { * as a bitmap representing which characters are upper and which are * lowercase */ -void fixcase(char *in, char *out, uchar minvers, uchar vers) { +void fixcase(char *in, char *out, uchar minvers, uchar vers, uchar len) { uchar idx = 0; - if (!(vers&0x80)) { + if (!(vers & 0x80)) { for (idx=0; idxparentry; + uchar parentlen = hdr->parentlen; + uint parblk = hdr->parptr[0] + 256U * hdr->parptr[1]; + + if (parblk != blocknum) { + printf(" Bad parent block %u", parblk); + printf(", should be %u\n", blocknum); + } + if (parentry != blkentries) { + printf(" Bad parent block entry %u", parentry); + printf(", should be %u\n", blkentries); + } + if (parentlen != 0x27) + puts(" Bad parent entry length"); + char *dirname = buf + 0x05; + if (strncmp(dirname, ent->name, NMLEN)) + puts(" Subdirectory name mismatch"); + + blocknum = buf[0x02] + 256U * buf[0x03]; + while (blocknum) { + if (readdiskblock(device, blocknum, buf) == -1) { + printf(" Error reading dir block %u\n", blocknum); + return -1; + } + ++(*blkcnt); + blocknum = buf[0x02] + 256U * buf[0x03]; + } + return 0; +} + /* * Read a directory, store the raw directory blocks in a linked list * and build filelist[] in preparation for sorting. @@ -481,23 +456,19 @@ int readdir(uint device, uint blocknum) { entperblk = hdr->entperblk; uint filecount = hdr->filecnt[0] + 256U * hdr->filecnt[1]; + static char namebuf[NMLEN+1]; + + fixcase(hdr->name, namebuf, + hdr->vers, hdr->minvers, hdr->typ_len & 0x0f); + + puts("---------------------------------------------------------"); + printf("Directory %s (%d entries)\n", namebuf, filecount); + puts("---------------------------------------------------------"); + /* Copy pointers and header to sorteddata[], zero the rest */ bzero(curblk->sorteddata, BLKSZ); memcpy(curblk->sorteddata, curblk->data, PTRSZ + entsz); - -#ifdef DEBUG - fputs("entsz=", stdout); - pr_uint(entsz); - putchar('\n'); - fputs("entperblk=", stdout); - pr_uint(entperblk); - putchar('\n'); - fputs("filecount=", stdout); - pr_uint(filecount); - putchar('\n'); -#endif - #ifdef CHECK if (entsz != 0x27) { puts("Error - bad entry size"); @@ -512,14 +483,36 @@ int readdir(uint device, uint blocknum) { uchar blkentries = 2; uchar entries = 0; - static char namebuf[NMLEN]; - while (1) { struct pd_dirent *ent = (struct pd_dirent*)(curblk->data + idx); if (ent->typ_len != 0) { - fixcase(ent->name, namebuf, ent->vers, ent->minvers); + fixcase(ent->name, namebuf, + ent->vers, ent->minvers, ent->typ_len & 0x0f); #ifdef CHECK - printf("File: %s\n", namebuf); + switch (ent->typ_len & 0xf0) { + case 0x10: + fputs("Seed ", stdout); + break; + case 0x20: + fputs("Sapl ", stdout); + break; + case 0x30: + fputs("Tree ", stdout); + break; + case 0x40: + fputs("Pasc ", stdout); + break; + case 0x50: + fputs("Fork ", stdout); + break; + case 0xd0: + fputs("Dir ", stdout); + break; + default: + fputs("???? ", stdout); + break; + } + puts(namebuf); #endif for (uchar i=0; ityp_len & 0xf0) { case 0xd0: /* Subdirectory */ - if (readdiskblock(device, keyblk, buf) == -1) { - printf(" Error reading keyblock %u\n", - keyblk); - return 1; - } - hdr = (struct pd_dirhdr*)(buf + PTRSZ); - uchar parentry = hdr->parentry; - uchar parentlen = hdr->parentlen; - uint parblk = - hdr->parptr[0] + 256U * hdr->parptr[1]; - - if (parblk != blocknum) { - printf(" Bad parent block %u", parblk); - printf(", should be %u\n", blocknum); - } - if (parentry != blkentries) { - printf(" Bad parent block entry %u", - parentry); - printf(", should be %u\n", blkentries); - } - if (parentlen != 0x27) - puts(" Bad parent entry length"); - char *dirname = buf + 0x05; - if (strncmp(dirname, ent->name, NMLEN)) - puts(" Subdirectory name mismatch"); - - // - // TODO: COUNT DIRECTORY BLOCKS - // - count = 0; + subdirblocks(device, keyblk, ent, + blocknum, blkentries, &count); break; case 0x10: /* Seedling */ @@ -592,34 +557,33 @@ int readdir(uint device, uint blocknum) { count = 0; break; default: - printf( "%s: unexpected storage type 0x%x\n", + printf(" %s: unexpected storage type 0x%x\n", namebuf, ent->typ_len & 0xf0); count = 0; } if (blks != count) { if (count != 0) { printf(" Size %u is incorrect", blks); - printf(", should be %u\n", blkcnt); + printf(", should be %u\n", count); } } #endif ++numfiles; if (numfiles == MAXFILES) { - puts("Too many files!"); + puts("** Too many files! **"); return 1; } ++entries; } if (blkentries == entperblk) { - blocknum = - curblk->data[0x02] + 256U*curblk->data[0x03]; + blocknum = curblk->data[0x02] + 256U*curblk->data[0x03]; if (blocknum == 0) { break; } curblk->next = (struct block*)malloc(sizeof(struct block)); if (!curblk->next) { - puts("Unable to allocate memory"); + puts("** Unable to allocate memory **"); return 1; } curblk = curblk->next; @@ -628,7 +592,7 @@ int readdir(uint device, uint blocknum) { ++blkcnt; if ( readdiskblock(device, blocknum, curblk->data) == -1) { - printf("Error reading dir block %d\n", blkcnt); + printf(" Error reading dir block %d\n", blkcnt); return 1; } /* Copy ptrs to sorteddata[], zero the rest */ @@ -754,7 +718,7 @@ void sortlist(char s) { * Print the file info stored in filelist[] */ void printlist(void) { - puts("----------------------------------------------------"); + puts("---------------------------------------------------------"); printf("numfiles=%u\n", numfiles); puts("Dirblk Entry Type : Name"); for(uint i=0; i