mirror of
https://github.com/bobbimanners/ProDOS-Utils.git
synced 2024-06-26 05:29:27 +00:00
Fixed terrible disk corruption bug!!
This commit is contained in:
parent
b469ec3ab4
commit
ab9057ddd4
155
sortdir.c
155
sortdir.c
|
@ -15,6 +15,7 @@
|
||||||
* v0.54 Make command line argument handling a compile time option.
|
* v0.54 Make command line argument handling a compile time option.
|
||||||
* v0.55 Can use *all* of largest heap block for filelist[]
|
* v0.55 Can use *all* of largest heap block for filelist[]
|
||||||
* v0.56 Minor improvements to conditional compilation
|
* v0.56 Minor improvements to conditional compilation
|
||||||
|
* v0.57 Fixed bugs in aux memory allocation
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#pragma debug 9
|
//#pragma debug 9
|
||||||
|
@ -41,7 +42,7 @@
|
||||||
#define CHECK /* Perform additional integrity checking */
|
#define CHECK /* Perform additional integrity checking */
|
||||||
#define SORT /* Enable sorting code */
|
#define SORT /* Enable sorting code */
|
||||||
#undef FREELIST /* Checking of free list */
|
#undef FREELIST /* Checking of free list */
|
||||||
#define AUXMEM /* Auxiliary memory support on //e and up */
|
#undef AUXMEM /* Auxiliary memory support on //e and up */
|
||||||
#undef CMDLINE /* Command line option parsing */
|
#undef CMDLINE /* Command line option parsing */
|
||||||
|
|
||||||
#define NLEVELS 4 /* Number of nested sorts permitted */
|
#define NLEVELS 4 /* Number of nested sorts permitted */
|
||||||
|
@ -95,6 +96,8 @@ struct pd_dirent {
|
||||||
|
|
||||||
#define BLKSZ 512 /* 512 byte blocks */
|
#define BLKSZ 512 /* 512 byte blocks */
|
||||||
#define PTRSZ 4 /* 4 bytes of pointers at beginning of each blk */
|
#define PTRSZ 4 /* 4 bytes of pointers at beginning of each blk */
|
||||||
|
#define ENTSZ 0x27 /* Normal ProDOS directory entry size */
|
||||||
|
#define ENTPERBLK 0x0d /* Normal ProDOS dirents per block */
|
||||||
#define FLSZ 8192 /* Bytes required for 64K block free-list */
|
#define FLSZ 8192 /* Bytes required for 64K block free-list */
|
||||||
|
|
||||||
/* Exit codes */
|
/* Exit codes */
|
||||||
|
@ -158,7 +161,7 @@ struct datetime {
|
||||||
* Globals
|
* Globals
|
||||||
*/
|
*/
|
||||||
#ifdef AUXMEM
|
#ifdef AUXMEM
|
||||||
#define STARTAUX 0x200
|
#define STARTAUX 0x800
|
||||||
static char *auxp = (char*)STARTAUX;
|
static char *auxp = (char*)STARTAUX;
|
||||||
#endif
|
#endif
|
||||||
#ifdef FREELIST
|
#ifdef FREELIST
|
||||||
|
@ -179,7 +182,7 @@ static uchar dowholedisk = 0; /* -D whole-disk option */
|
||||||
static uchar dorecurse = 0; /* -r recurse option */
|
static uchar dorecurse = 0; /* -r recurse option */
|
||||||
static uchar dowrite = 0; /* -w write option */
|
static uchar dowrite = 0; /* -w write option */
|
||||||
static uchar doverbose = 0; /* -v verbose option */
|
static uchar doverbose = 0; /* -v verbose option */
|
||||||
static uchar dodebug = 0; /* -V very verbose option */
|
static uchar dodebug = 1; /* -V very verbose option */
|
||||||
static uchar do_ctime = 0; /* -k ctime option */
|
static uchar do_ctime = 0; /* -k ctime option */
|
||||||
static uchar dozero = 0; /* -z zero free blocks option */
|
static uchar dozero = 0; /* -z zero free blocks option */
|
||||||
static char sortopts[NLEVELS+1] = ""; /* -s:abc list of sort options */
|
static char sortopts[NLEVELS+1] = ""; /* -s:abc list of sort options */
|
||||||
|
@ -230,6 +233,7 @@ 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, uint subdiridx);
|
void enqueuesubdir(uint blocknum, uint subdiridx);
|
||||||
int readdir(uint device, uint blocknum);
|
int readdir(uint device, uint blocknum);
|
||||||
|
void buildsorttable(void);
|
||||||
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);
|
||||||
int cmp_name_asc_ci(const void *a, const void *b);
|
int cmp_name_asc_ci(const void *a, const void *b);
|
||||||
|
@ -991,10 +995,10 @@ int subdirblocks(uchar device, uint keyblk, struct pd_dirent *ent,
|
||||||
hdr->parentry = blkentries;
|
hdr->parentry = blkentries;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (parentlen != 0x27) {
|
if (parentlen != ENTSZ) {
|
||||||
err(NONFATAL, "Bad parent entry length");
|
err(NONFATAL, "Bad parent entry length");
|
||||||
if (askfix() == 1) {
|
if (askfix() == 1) {
|
||||||
hdr->parentlen = 0x27;
|
hdr->parentlen = ENTSZ;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
dirname = buf + 0x05;
|
dirname = buf + 0x05;
|
||||||
|
@ -1040,8 +1044,7 @@ void enqueuesubdir(uint blocknum, uint subdiridx) {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read a directory, store the raw directory blocks in a linked list
|
* Read a directory, store the raw directory blocks in a linked list.
|
||||||
* and build filelist[] in preparation for sorting.
|
|
||||||
* device is the device number containing the directory
|
* device is the device number containing the directory
|
||||||
* blocknum is the block number of the first block of the directory
|
* blocknum is the block number of the first block of the directory
|
||||||
*/
|
*/
|
||||||
|
@ -1060,12 +1063,21 @@ int readdir(uint device, uint blocknum) {
|
||||||
numfiles = 0;
|
numfiles = 0;
|
||||||
|
|
||||||
blocks = (struct block*)malloc(sizeof(struct block));
|
blocks = (struct block*)malloc(sizeof(struct block));
|
||||||
|
printf("FIRST BLOCK %d at %p\n", blocknum, blocks);
|
||||||
if (!blocks)
|
if (!blocks)
|
||||||
err(FATALALLOC, "No memory!");
|
err(FATALALLOC, "No memory!");
|
||||||
curblk = blocks;
|
curblk = blocks;
|
||||||
curblk->next = NULL;
|
curblk->next = NULL;
|
||||||
curblk->blocknum = blocknum;
|
curblk->blocknum = blocknum;
|
||||||
|
|
||||||
|
#ifdef AUXMEM
|
||||||
|
curblk->data = auxalloc(BLKSZ);
|
||||||
|
curblk->sorteddata = auxalloc(BLKSZ);
|
||||||
|
// TODO ZERO sorteddata
|
||||||
|
#else
|
||||||
|
bzero(curblk->sorteddata, BLKSZ);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef FREELIST
|
#ifdef FREELIST
|
||||||
checkblock(blocknum, "Directory");
|
checkblock(blocknum, "Directory");
|
||||||
#endif
|
#endif
|
||||||
|
@ -1089,11 +1101,11 @@ int readdir(uint device, uint blocknum) {
|
||||||
hline();
|
hline();
|
||||||
|
|
||||||
#ifdef CHECK
|
#ifdef CHECK
|
||||||
if (entsz != 0x27) {
|
if (entsz != ENTSZ) {
|
||||||
err(NONFATAL, "Error - bad entry size");
|
err(NONFATAL, "Error - bad entry size");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (entperblk != 0x0d) {
|
if (entperblk != ENTPERBLK) {
|
||||||
err(NONFATAL, "Error - bad entries/block");
|
err(NONFATAL, "Error - bad entries/block");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
@ -1285,28 +1297,38 @@ int readdir(uint device, uint blocknum) {
|
||||||
++entries;
|
++entries;
|
||||||
}
|
}
|
||||||
if (blkentries == entperblk) {
|
if (blkentries == entperblk) {
|
||||||
blocknum = dirblkbuf[0x02] + 256U * dirblkbuf[0x03];
|
|
||||||
if (blocknum == 0) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
curblk->next = (struct block*)malloc(sizeof(struct block));
|
|
||||||
if (!curblk->next)
|
|
||||||
err(FATALALLOC, "No memory!");
|
|
||||||
curblk = curblk->next;
|
|
||||||
curblk->next = NULL;
|
|
||||||
curblk->blocknum = blocknum;
|
|
||||||
++blkcnt;
|
|
||||||
#ifdef FREELIST
|
|
||||||
checkblock(blocknum, "Directory");
|
|
||||||
#endif
|
|
||||||
#ifdef AUXMEM
|
#ifdef AUXMEM
|
||||||
copyaux(dirblkbuf, curblk->data, BLKSZ, TOAUX);
|
copyaux(dirblkbuf, curblk->data, BLKSZ, TOAUX);
|
||||||
bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ);
|
bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ);
|
||||||
copyaux(dirblkbuf, curblk->sorteddata, BLKSZ, TOAUX);
|
copyaux(dirblkbuf, curblk->sorteddata, BLKSZ, TOAUX);
|
||||||
#else
|
#else
|
||||||
memcpy(curblk->data, dirblkbuf, BLKSZ);
|
memcpy(curblk->data, dirblkbuf, BLKSZ);
|
||||||
bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ);
|
////// bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ);
|
||||||
memcpy(curblk->sorteddata, dirblkbuf, PTRSZ);
|
memcpy(curblk->sorteddata, dirblkbuf, PTRSZ);
|
||||||
|
#endif
|
||||||
|
blocknum = dirblkbuf[0x02] + 256U * dirblkbuf[0x03];
|
||||||
|
if (blocknum == 0) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
curblk->next = (struct block*)malloc(sizeof(struct block));
|
||||||
|
printf("NEXT BLOCK %d at %p\n", blocknum, curblk->next);
|
||||||
|
if (!curblk->next)
|
||||||
|
err(FATALALLOC, "No memory!");
|
||||||
|
curblk = curblk->next;
|
||||||
|
curblk->next = NULL;
|
||||||
|
curblk->blocknum = blocknum;
|
||||||
|
++blkcnt;
|
||||||
|
|
||||||
|
#ifdef AUXMEM
|
||||||
|
curblk->data = auxalloc(BLKSZ);
|
||||||
|
curblk->sorteddata = auxalloc(BLKSZ);
|
||||||
|
// TODO: Zero sorteddata
|
||||||
|
#else
|
||||||
|
bzero(curblk->sorteddata, BLKSZ);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef FREELIST
|
||||||
|
checkblock(blocknum, "Directory");
|
||||||
#endif
|
#endif
|
||||||
if (readdiskblock(device, blocknum, dirblkbuf) == -1) {
|
if (readdiskblock(device, blocknum, dirblkbuf) == -1) {
|
||||||
err(NONFATAL,"Error reading dir blk %d",
|
err(NONFATAL,"Error reading dir blk %d",
|
||||||
|
@ -1335,13 +1357,78 @@ int readdir(uint device, uint blocknum) {
|
||||||
copyaux(dirblkbuf, curblk->sorteddata, BLKSZ, TOAUX);
|
copyaux(dirblkbuf, curblk->sorteddata, BLKSZ, TOAUX);
|
||||||
#else
|
#else
|
||||||
memcpy(curblk->data, dirblkbuf, BLKSZ);
|
memcpy(curblk->data, dirblkbuf, BLKSZ);
|
||||||
bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ);
|
//// bzero(dirblkbuf + PTRSZ, BLKSZ - PTRSZ);
|
||||||
memcpy(curblk->sorteddata, dirblkbuf, PTRSZ);
|
memcpy(curblk->sorteddata, dirblkbuf, PTRSZ);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
return errcount - errsbefore;
|
return errcount - errsbefore;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Build filelist[] which the table used by the sorting algorithm.
|
||||||
|
*/
|
||||||
|
#if 0
|
||||||
|
void buildsorttable() {
|
||||||
|
static char namebuf[NMLEN+1];
|
||||||
|
uint off, blks, eof;
|
||||||
|
uchar entry, i;
|
||||||
|
struct datetime dt;
|
||||||
|
struct pd_dirent *ent;
|
||||||
|
uint idx = 0;
|
||||||
|
struct block *b = blocks;
|
||||||
|
uchar firstent = 1; /* Skip first entry of first block */
|
||||||
|
uchar blkidx = 0;
|
||||||
|
|
||||||
|
while (b) {
|
||||||
|
#ifdef AUXMEM
|
||||||
|
copyaux(b->data, dirblkbuf, BLKSZ, FROMAUX);
|
||||||
|
#else
|
||||||
|
memcpy(dirblkbuf, b->data, BLKSZ);
|
||||||
|
#endif
|
||||||
|
for (entry = firstent; entry < ENTPERBLK; ++entry) {
|
||||||
|
printf("blk %u entry %u\n", blkidx, entry);
|
||||||
|
off = PTRSZ + entry * ENTSZ;
|
||||||
|
ent = (struct pd_dirent*)(dirblkbuf + off);
|
||||||
|
|
||||||
|
if (ent->typ_len != 0) {
|
||||||
|
blks = ent->blksused[0] + 256U * ent->blksused[1];
|
||||||
|
eof = ent->eof[0] + 256L * ent->eof[1] + 65536L * ent->eof[2];
|
||||||
|
|
||||||
|
fixcase(ent->name, namebuf,
|
||||||
|
ent->vers, ent->minvers, ent->typ_len & 0x0f);
|
||||||
|
|
||||||
|
printf("%u %u - ", blkidx, entry);
|
||||||
|
fputs(namebuf,stdout);
|
||||||
|
printf(" %u %u\n", blks, eof);
|
||||||
|
|
||||||
|
for (i = 0; i < NMLEN + 1; ++i)
|
||||||
|
filelist[idx].name[i] = '\0';
|
||||||
|
//bzero(filelist[idx].name, NMLEN + 1);
|
||||||
|
for (i = 0; i < (ent->typ_len & 0x0f); ++i)
|
||||||
|
filelist[idx].name[i] = namebuf[i];
|
||||||
|
filelist[idx].type = ent->type;
|
||||||
|
filelist[idx].blockidx = blkidx;
|
||||||
|
filelist[idx].entrynum = entry;
|
||||||
|
filelist[idx].blocks = blks;
|
||||||
|
filelist[idx].eof = eof;
|
||||||
|
|
||||||
|
readdatetime(do_ctime ? ent->ctime : ent->mtime, &dt);
|
||||||
|
sprintf(filelist[idx].datetime,
|
||||||
|
"%04d-%02d-%02d %02d:%02d %s",
|
||||||
|
dt.year, dt.month, dt.day, dt.hour, dt.minute,
|
||||||
|
(dt.ispd25format ? "*" : " "));
|
||||||
|
++idx;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b = b->next;
|
||||||
|
++blkidx;
|
||||||
|
firstent = 0;
|
||||||
|
}
|
||||||
|
numfiles = idx - 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
#ifdef SORT
|
#ifdef SORT
|
||||||
/*
|
/*
|
||||||
* Compare - filename sort in ascending order
|
* Compare - filename sort in ascending order
|
||||||
|
@ -1699,18 +1786,19 @@ void sortblocks(uint device) {
|
||||||
* Write out the sorted directory
|
* Write out the sorted directory
|
||||||
*/
|
*/
|
||||||
int writedir(uchar device) {
|
int writedir(uchar device) {
|
||||||
struct block *i = blocks;
|
struct block *b = blocks;
|
||||||
while (i) {
|
while (b) {
|
||||||
|
printf("WRITING BLOCK %d from %p\n", b->blocknum, b);
|
||||||
#ifdef AUXMEM
|
#ifdef AUXMEM
|
||||||
copyaux(i->sorteddata, dirblkbuf, BLKSZ, FROMAUX);
|
copyaux(b->sorteddata, dirblkbuf, BLKSZ, FROMAUX);
|
||||||
if (writediskblock(device, i->blocknum, dirblkbuf) == -1) {
|
if (writediskblock(device, b->blocknum, dirblkbuf) == -1) {
|
||||||
#else
|
#else
|
||||||
if (writediskblock(device, i->blocknum, i->sorteddata) == -1) {
|
if (writediskblock(device, b->blocknum, b->sorteddata) == -1) {
|
||||||
#endif
|
#endif
|
||||||
err(NONFATAL, "Can't write block %u", i->blocknum);
|
err(NONFATAL, "Can't write block %u", b->blocknum);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
i = i->next;
|
b = b->next;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1734,7 +1822,7 @@ void interactive(void) {
|
||||||
|
|
||||||
doverbose = 1;
|
doverbose = 1;
|
||||||
|
|
||||||
puts("S O R T D I R v0.56 alpha Use ^ to return to previous question");
|
puts("S O R T D I R v0.57 alpha Use ^ to return to previous question");
|
||||||
|
|
||||||
q1:
|
q1:
|
||||||
fputs("\nEnter path (e.g.: /H1) of starting directory> ", stdout);
|
fputs("\nEnter path (e.g.: /H1) of starting directory> ", stdout);
|
||||||
|
@ -1853,6 +1941,7 @@ void processdir(uint device, uint blocknum) {
|
||||||
uchar i, errs;
|
uchar i, errs;
|
||||||
flushall();
|
flushall();
|
||||||
errs = readdir(device, blocknum);
|
errs = readdir(device, blocknum);
|
||||||
|
//buildsorttable();
|
||||||
// if (doverbose) {
|
// if (doverbose) {
|
||||||
// printlist();
|
// printlist();
|
||||||
// }
|
// }
|
||||||
|
|
BIN
sortdir.po
BIN
sortdir.po
Binary file not shown.
Loading…
Reference in New Issue
Block a user