mirror of
https://github.com/bobbimanners/GNO-Extras.git
synced 2024-12-22 17:30:13 +00:00
Improvements to sortdir. Still WIP!!
This commit is contained in:
parent
733e9928e8
commit
624b4076c2
@ -1,8 +1,11 @@
|
|||||||
/*
|
/*
|
||||||
* Bobbi January 2020
|
* Bobbi January 2020
|
||||||
|
*
|
||||||
|
* TODO: Sort by type, reverse sort, combinations etc.
|
||||||
|
* TODO: Improve checking code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
//#pragma debug -1
|
#pragma debug 25 /* Enable stack checking */
|
||||||
#pragma lint -1
|
#pragma lint -1
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
@ -16,7 +19,9 @@
|
|||||||
#include <gsos.h>
|
#include <gsos.h>
|
||||||
#include <prodos.h>
|
#include <prodos.h>
|
||||||
|
|
||||||
#define DEBUG
|
|
||||||
|
#define DEBUG /* Enable additional debug printout */
|
||||||
|
#define CHECK /* Perform additional integrity checking */
|
||||||
|
|
||||||
typedef unsigned char uchar;
|
typedef unsigned char uchar;
|
||||||
typedef unsigned int uint;
|
typedef unsigned int uint;
|
||||||
@ -24,6 +29,26 @@ typedef unsigned int uint;
|
|||||||
#define NMLEN 15 /* Length of filename */
|
#define NMLEN 15 /* Length of filename */
|
||||||
#define MAXFILES 1000 /* Max files per directory */
|
#define MAXFILES 1000 /* Max files per directory */
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ProDOS directory header
|
||||||
|
* See ProDOS-8 Tech Ref pp. 152
|
||||||
|
*/
|
||||||
|
struct pd_dirhdr {
|
||||||
|
uchar typ_len;
|
||||||
|
char name[NMLEN];
|
||||||
|
char reserved[8];
|
||||||
|
uchar ctime[4];
|
||||||
|
uchar vers;
|
||||||
|
uchar minvers;
|
||||||
|
uchar access;
|
||||||
|
uchar entlen;
|
||||||
|
uchar entperblk;
|
||||||
|
uchar filecnt[2];
|
||||||
|
uchar parptr[2]; /* Bitmap pointer in volume dir */
|
||||||
|
uchar parentry; /* Total blocks LSB in volume dir */
|
||||||
|
uchar parentlen; /* Total blocks MSB in volume dir */
|
||||||
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* ProDOS file entry
|
* ProDOS file entry
|
||||||
* See ProDOS-8 Tech Ref pp. 155
|
* See ProDOS-8 Tech Ref pp. 155
|
||||||
@ -41,9 +66,10 @@ struct pd_dirent {
|
|||||||
uchar access;
|
uchar access;
|
||||||
uchar auxtype[2];
|
uchar auxtype[2];
|
||||||
uchar mtime[4];
|
uchar mtime[4];
|
||||||
uchar headerptr[2];
|
uchar hdrptr[2];
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
#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 */
|
||||||
|
|
||||||
@ -70,31 +96,95 @@ struct fileent {
|
|||||||
uchar entrynum; /* Entry within the block */
|
uchar entrynum; /* Entry within the block */
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fileent filelist[MAXFILES];
|
/* Globals */
|
||||||
uint numfiles = 0;
|
static struct fileent filelist[MAXFILES];
|
||||||
|
static uint numfiles = 0;
|
||||||
|
static uchar entsz; /* Bytes per file entry */
|
||||||
|
static uchar entperblk; /* Number of entries per block */
|
||||||
|
static char buf[BLKSZ]; /* General purpose scratch buffer */
|
||||||
|
|
||||||
uchar entsz; /* Bytes per file entry */
|
static uint stack; // DEBUG
|
||||||
uchar entperblk; /* Number of entries per block */
|
|
||||||
|
|
||||||
|
//#define STACK(msg) asm {tsc; sta stack }; fputs(msg, stdout); fputs(" ", stdout); pr_int(stack); putchar('\n');
|
||||||
|
|
||||||
|
/* Prototypes */
|
||||||
|
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 readdiskblock(uchar device, uint blocknum, char *buf);
|
||||||
int writediskblock(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);
|
||||||
int readdir(uchar device, uint blocknum);
|
int readdir(uint device, uint blocknum);
|
||||||
int compare(const void *a, const void *b);
|
int compare(const void *a, const void *b);
|
||||||
void sortlist(void);
|
void sortlist(void);
|
||||||
void printlist(void);
|
void printlist(void);
|
||||||
void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent);
|
void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent, uint device);
|
||||||
void sortblocks(void);
|
void sortblocks(uint device);
|
||||||
int writedir(uchar device);
|
int writedir(uchar device);
|
||||||
void freeblocks(void);
|
void freeblocks(void);
|
||||||
|
|
||||||
|
void reverse(char *s) {
|
||||||
|
char buf[10];
|
||||||
|
int l = strlen(s);
|
||||||
|
for (int i=0; i<l; ++i)
|
||||||
|
buf[i] = s[i];
|
||||||
|
for (int i=0; i<l; ++i)
|
||||||
|
s[i] = buf[l-i-1];
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Stolen from K&R 2nd Ed. pp 64 */
|
||||||
|
void itoa(int n, char s[]) {
|
||||||
|
int i, sign;
|
||||||
|
|
||||||
|
if ((sign = n) < 0)
|
||||||
|
n = -1;
|
||||||
|
i = 0;
|
||||||
|
do {
|
||||||
|
s[i++] = n % 10 + '0';
|
||||||
|
} while ((n /= 10) > 0);
|
||||||
|
if (sign < 0)
|
||||||
|
s[i++] = '-';
|
||||||
|
s[i] = '\0';
|
||||||
|
reverse(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pr_int(int a) {
|
||||||
|
char buf[10];
|
||||||
|
itoa(a, buf);
|
||||||
|
fputs(buf, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
|
void pr_uint(unsigned int a) {
|
||||||
|
char buf[10];
|
||||||
|
uitoa(a, buf);
|
||||||
|
fputs(buf, stdout);
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Read block from disk using ProDOS call
|
* Read block from disk using ProDOS call
|
||||||
* buf must point to buffer with at least 512 bytes
|
* buf must point to buffer with at least 512 bytes
|
||||||
*/
|
*/
|
||||||
int readdiskblock(uchar device, uint blocknum, char *buf) {
|
int readdiskblock(uchar device, uint blocknum, char *buf) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Reading dev %u block %u\n", device, blocknum);
|
fputs("Reading dev ", stdout);
|
||||||
|
pr_int(device);
|
||||||
|
fputs(" block ", stdout);
|
||||||
|
pr_uint(blocknum);
|
||||||
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
BlockRec br;
|
BlockRec br;
|
||||||
br.blockDevNum = device;
|
br.blockDevNum = device;
|
||||||
@ -115,7 +205,11 @@ int readdiskblock(uchar device, uint blocknum, char *buf) {
|
|||||||
*/
|
*/
|
||||||
int writediskblock(uchar device, uint blocknum, char *buf) {
|
int writediskblock(uchar device, uint blocknum, char *buf) {
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("Writing dev %u block %u\n", device, blocknum);
|
fputs("Writing dev ", stdout);
|
||||||
|
pr_int(device);
|
||||||
|
fputs(" block ", stdout);
|
||||||
|
pr_uint(blocknum);
|
||||||
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
DIORecGS dr;
|
DIORecGS dr;
|
||||||
dr.pCount = 6;
|
dr.pCount = 6;
|
||||||
@ -158,7 +252,6 @@ void fixcase(char *in, char *out, uchar minvers, uchar vers) {
|
|||||||
* number of the first block of the directory.
|
* number of the first block of the directory.
|
||||||
*/
|
*/
|
||||||
uchar firstblk(char *dirname, uchar *device, uint *block) {
|
uchar firstblk(char *dirname, uchar *device, uint *block) {
|
||||||
char buf[BLKSZ];
|
|
||||||
int fp;
|
int fp;
|
||||||
uchar rv = 0;
|
uchar rv = 0;
|
||||||
|
|
||||||
@ -189,16 +282,26 @@ uchar firstblk(char *dirname, uchar *device, uint *block) {
|
|||||||
|
|
||||||
*device = st.st_dev;
|
*device = st.st_dev;
|
||||||
|
|
||||||
|
struct pd_dirhdr *hdr = (struct pd_dirhdr*)(buf + PTRSZ);
|
||||||
|
|
||||||
/* Detect & handle volume directory */
|
/* Detect & handle volume directory */
|
||||||
if ((buf[0x04] & 0xf0) == 0xf0) {
|
if ((hdr->typ_len & 0xf0) == 0xf0) {
|
||||||
*block = 2;
|
*block = 2;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CHECK
|
||||||
|
if ((hdr->typ_len & 0xf0) != 0xe0) {
|
||||||
|
perror("Bad storage type");
|
||||||
|
rv = 1;
|
||||||
|
goto ret;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Handle subdirectory */
|
/* Handle subdirectory */
|
||||||
uint parentblk = buf[0x27] + 256U * buf[0x28];
|
uint parentblk = hdr->parptr[0] + 256U * hdr->parptr[1];
|
||||||
uint parententry = buf[0x29];
|
uint parententry = hdr->parentry;
|
||||||
uint parententlen = buf[0x2a];
|
uint parententlen = hdr->parentlen;
|
||||||
|
|
||||||
/* Read parent directory block */
|
/* Read parent directory block */
|
||||||
if (readdiskblock(*device, parentblk, buf) == -1) {
|
if (readdiskblock(*device, parentblk, buf) == -1) {
|
||||||
@ -224,12 +327,13 @@ ret:
|
|||||||
* 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
|
||||||
*/
|
*/
|
||||||
int readdir(uchar device, uint blocknum) {
|
int readdir(uint device, uint blocknum) {
|
||||||
uchar blkcnt = 1;
|
uchar blkcnt = 1;
|
||||||
|
uint hdrblknum = blocknum;
|
||||||
|
|
||||||
blocks = (struct block*)malloc(BLKSZ);
|
blocks = (struct block*)malloc(BLKSZ);
|
||||||
if (!blocks) {
|
if (!blocks) {
|
||||||
fprintf(stderr, "Unable to allocate memory\n");
|
perror("Unable to allocate memory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
struct block *curblk = blocks;
|
struct block *curblk = blocks;
|
||||||
@ -241,11 +345,11 @@ int readdir(uchar device, uint blocknum) {
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
entsz = curblk->data[0x23];
|
struct pd_dirhdr *hdr = (struct pd_dirhdr*)(curblk->data + PTRSZ);
|
||||||
entperblk = curblk->data[0x24];
|
|
||||||
uint filecount = curblk->data[0x25] + 256U * curblk->data[0x26];
|
|
||||||
|
|
||||||
blocknum = curblk->data[0x02] + 256U * curblk->data[0x03];
|
entsz = hdr->entlen;
|
||||||
|
entperblk = hdr->entperblk;
|
||||||
|
uint filecount = hdr->filecnt[0] + 256U * hdr->filecnt[1];
|
||||||
|
|
||||||
/* Copy pointers and header to sorteddata[], zero the rest */
|
/* Copy pointers and header to sorteddata[], zero the rest */
|
||||||
bzero(curblk->sorteddata, BLKSZ);
|
bzero(curblk->sorteddata, BLKSZ);
|
||||||
@ -253,40 +357,99 @@ int readdir(uchar device, uint blocknum) {
|
|||||||
|
|
||||||
|
|
||||||
#ifdef DEBUG
|
#ifdef DEBUG
|
||||||
printf("entsz=%d\n", entsz);
|
fputs("entsz=", stdout);
|
||||||
printf("entperblk=%d\n", entperblk);
|
pr_uint(entsz);
|
||||||
printf("filecount=%d\n", filecount);
|
putchar('\n');
|
||||||
|
fputs("entperblk=", stdout);
|
||||||
|
pr_uint(entperblk);
|
||||||
|
putchar('\n');
|
||||||
|
fputs("filecount=", stdout);
|
||||||
|
pr_uint(filecount);
|
||||||
|
putchar('\n');
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// TODO: Add a check that the filecount is correct
|
||||||
|
|
||||||
|
#ifdef CHECK
|
||||||
|
if (entsz != 0x27) {
|
||||||
|
perror("Error - bad entry size");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (entperblk != 0x0d) {
|
||||||
|
perror("Error - bad entries/block");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
uint idx = entsz + PTRSZ; /* Skip header */
|
uint idx = entsz + PTRSZ; /* Skip header */
|
||||||
uchar blkentries = 2;
|
uchar blkentries = 2;
|
||||||
uchar entries = 0;
|
uchar entries = 0;
|
||||||
|
|
||||||
char numbuf[NMLEN];
|
static char namebuf[NMLEN];
|
||||||
|
|
||||||
while (entries < filecount) {
|
while (entries < filecount) {
|
||||||
struct pd_dirent *ent = (struct pd_dirent*)(curblk->data + idx);
|
struct pd_dirent *ent = (struct pd_dirent*)(curblk->data + idx);
|
||||||
if (ent->typ_len != 0) {
|
if (ent->typ_len != 0) {
|
||||||
fixcase(ent->name, numbuf, ent->vers, ent->minvers);
|
fixcase(ent->name, namebuf, ent->vers, ent->minvers);
|
||||||
for (uchar i=0; i<NMLEN+1; ++i)
|
for (uchar i=0; i<NMLEN+1; ++i)
|
||||||
filelist[numfiles].name[i] = '\0';
|
filelist[numfiles].name[i] = '\0';
|
||||||
for (uchar i=0; i<(ent->typ_len & 0x0f); ++i)
|
for (uchar i=0; i<(ent->typ_len & 0x0f); ++i)
|
||||||
filelist[numfiles].name[i] = numbuf[i];
|
filelist[numfiles].name[i] = namebuf[i];
|
||||||
filelist[numfiles].blockidx = blkcnt;
|
filelist[numfiles].blockidx = blkcnt;
|
||||||
filelist[numfiles].entrynum = blkentries;
|
filelist[numfiles].entrynum = blkentries;
|
||||||
|
#ifdef CHECK
|
||||||
|
uint keyblk = ent->keyptr[0] + 256U * ent->keyptr[1];
|
||||||
|
uint hdrblk = ent->hdrptr[0] + 256U * ent->hdrptr[1];
|
||||||
|
if (hdrblk != hdrblknum) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"%s: Header ptr %u should be %u\n",
|
||||||
|
namebuf, hdrblk, hdrblknum);
|
||||||
|
}
|
||||||
|
if ((ent->typ_len & 0xf0) == 0xd0) {
|
||||||
|
if (readdiskblock(device, keyblk, buf) == -1) {
|
||||||
|
fprintf(stderr,
|
||||||
|
"Error reading blk %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) {
|
||||||
|
perror("Bad parent block number");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (parentry != blkentries) {
|
||||||
|
perror("Bad parent block entry num");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (parentlen != 0x27) {
|
||||||
|
perror("Bad parent entry length");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
char *dirname = buf + 0x05;
|
||||||
|
if (strncmp(dirname, ent->name, NMLEN)) {
|
||||||
|
perror("Subdirectory name mismatch");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
++numfiles;
|
++numfiles;
|
||||||
if (numfiles == MAXFILES) {
|
if (numfiles == MAXFILES) {
|
||||||
fprintf(stderr, "Too many files\n");
|
perror("Too many files");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
++entries;
|
++entries;
|
||||||
}
|
}
|
||||||
if (entries < filecount) {
|
if (entries < filecount) {
|
||||||
if (blkentries == entperblk) {
|
if (blkentries == entperblk) {
|
||||||
|
blocknum =
|
||||||
|
curblk->data[0x02] + 256U*curblk->data[0x03];
|
||||||
curblk->next = (struct block*)malloc(BLKSZ);
|
curblk->next = (struct block*)malloc(BLKSZ);
|
||||||
if (!curblk->next) {
|
if (!curblk->next) {
|
||||||
fprintf(stderr,
|
perror("Unable to allocate memory");
|
||||||
"Unable to allocate memory\n");
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
curblk = curblk->next;
|
curblk = curblk->next;
|
||||||
@ -301,8 +464,6 @@ int readdir(uchar device, uint blocknum) {
|
|||||||
blkcnt);
|
blkcnt);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
blocknum = curblk->data[0x02] +
|
|
||||||
256U * curblk->data[0x03];
|
|
||||||
/* Copy ptrs to sorteddata[], zero the rest */
|
/* Copy ptrs to sorteddata[], zero the rest */
|
||||||
bzero(curblk->sorteddata, BLKSZ);
|
bzero(curblk->sorteddata, BLKSZ);
|
||||||
memcpy(curblk->sorteddata, curblk->data, PTRSZ);
|
memcpy(curblk->sorteddata, curblk->data, PTRSZ);
|
||||||
@ -314,6 +475,7 @@ int readdir(uchar device, uint blocknum) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -335,44 +497,75 @@ void sortlist(void) {
|
|||||||
* Print the file info stored in filelist[]
|
* Print the file info stored in filelist[]
|
||||||
*/
|
*/
|
||||||
void printlist(void) {
|
void printlist(void) {
|
||||||
for(uint i=0; i<numfiles; ++i)
|
fputs("numfiles=", stdout);
|
||||||
printf("blk=%d ent=%d: %s\n",
|
pr_int(numfiles);
|
||||||
filelist[i].blockidx,
|
putchar('\n');
|
||||||
filelist[i].entrynum,
|
for(uint i=0; i<numfiles; ++i) {
|
||||||
filelist[i].name);
|
fputs("blk=", stdout);
|
||||||
|
pr_int(filelist[i].blockidx);
|
||||||
|
fputs(" ent=", stdout);
|
||||||
|
pr_int(filelist[i].entrynum);
|
||||||
|
putchar('\t');
|
||||||
|
fputs(filelist[i].name, stdout);
|
||||||
|
putchar('\n');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Copy a file entry from one srcblk, srcent to dstblk, dstent
|
* Copy a file entry from one srcblk, srcent to dstblk, dstent
|
||||||
* All indices are 1-based.
|
* All indices are 1-based.
|
||||||
*/
|
*/
|
||||||
void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent) {
|
void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent, uint device) {
|
||||||
printf(" from blk %d entry %d\n", srcblk, srcent);
|
|
||||||
printf(" to blk %d entry %d\n", dstblk, dstent);
|
fputs(" from blk ", stdout);
|
||||||
|
pr_uint(srcblk);
|
||||||
|
fputs(" entry ", stdout);
|
||||||
|
pr_uint(srcent);
|
||||||
|
putchar('\n');
|
||||||
|
fputs(" to blk ", stdout);
|
||||||
|
pr_uint(dstblk);
|
||||||
|
fputs(" entry ", stdout);
|
||||||
|
pr_uint(dstent);
|
||||||
|
putchar('\n');
|
||||||
|
|
||||||
struct block *source = blocks;
|
struct block *source = blocks;
|
||||||
struct block *dest = blocks;
|
struct block *dest = blocks;
|
||||||
while (--srcblk > 0)
|
while (--srcblk > 0)
|
||||||
source = source->next;
|
source = source->next;
|
||||||
while (--dstblk > 0)
|
while (--dstblk > 0)
|
||||||
dest = dest->next;
|
dest = dest->next;
|
||||||
memcpy(dest->sorteddata + PTRSZ + (dstent-1) * entsz,
|
char *dstptr = dest->sorteddata + PTRSZ + (dstent-1) * entsz;
|
||||||
|
memcpy(dstptr,
|
||||||
source->data + PTRSZ + (srcent-1) * entsz,
|
source->data + PTRSZ + (srcent-1) * entsz,
|
||||||
entsz);
|
entsz);
|
||||||
|
|
||||||
|
/* For directories, update the parent dir entry number */
|
||||||
|
if ((*dstptr & 0xf0) == 0xd0) {
|
||||||
|
struct pd_dirent *ent = (struct pd_dirent *)dstptr;
|
||||||
|
uint block = ent->keyptr[0] + 256U * ent->keyptr[1];
|
||||||
|
if (readdiskblock(device, block, buf) == -1) {
|
||||||
|
perror("Can't read subdirectory");
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
struct pd_dirhdr *hdr = (struct pd_dirhdr*)buf;
|
||||||
|
hdr->parentry = dstent;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Use the sorted list in filelist[] to create a sorted set of directory
|
* Use the sorted list in filelist[] to create a sorted set of directory
|
||||||
* blocks. Note that the block and entry numbers are 1-based indices.
|
* blocks. Note that the block and entry numbers are 1-based indices.
|
||||||
*/
|
*/
|
||||||
void sortblocks(void) {
|
void sortblocks(uint device) {
|
||||||
uchar destblk = 1;
|
uchar destblk = 1;
|
||||||
uchar destentry = 2; /* Skip header on first block */
|
uchar destentry = 2; /* Skip header on first block */
|
||||||
for(uint i=0; i<numfiles; ++i) {
|
for(uint i=0; i<numfiles; ++i) {
|
||||||
printf("%s\n", filelist[i].name);
|
puts(filelist[i].name);
|
||||||
copyent(filelist[i].blockidx,
|
copyent(filelist[i].blockidx,
|
||||||
filelist[i].entrynum,
|
filelist[i].entrynum,
|
||||||
destblk,
|
destblk,
|
||||||
destentry);
|
destentry,
|
||||||
|
device);
|
||||||
++destentry;
|
++destentry;
|
||||||
if (destentry == entperblk) {
|
if (destentry == entperblk) {
|
||||||
++destblk;
|
++destblk;
|
||||||
@ -409,22 +602,29 @@ void freeblocks(void) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc != 2) {
|
if (argc < 2) {
|
||||||
fprintf(stderr, "usage: softdir path\n");
|
perror("usage: softdir [-w] path\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
uchar dowrite = 0;
|
||||||
|
if (argc > 2) {
|
||||||
|
if (!strcmp(argv[1], "-w"))
|
||||||
|
dowrite = 1;
|
||||||
|
}
|
||||||
uchar dev;
|
uchar dev;
|
||||||
uint blk;
|
uint blk;
|
||||||
if (firstblk(argv[1], &dev, &blk) != 0) {
|
if (firstblk(argv[argc-1], &dev, &blk) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
printf("Sorting %s ...\n", argv[1]); /* NEED THIS FOR SOME REASON */
|
|
||||||
uchar err = readdir(dev, blk);
|
uchar err = readdir(dev, blk);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
printlist();
|
printlist();
|
||||||
sortlist();
|
sortlist();
|
||||||
sortblocks();
|
sortblocks(dev);
|
||||||
err = writedir(dev);
|
if (dowrite)
|
||||||
|
err = writedir(dev);
|
||||||
|
else
|
||||||
|
puts("Not writing to disk\n");
|
||||||
}
|
}
|
||||||
freeblocks();
|
freeblocks();
|
||||||
return err;
|
return err;
|
||||||
|
Loading…
Reference in New Issue
Block a user