mirror of
https://github.com/bobbimanners/GNO-Extras.git
synced 2024-12-22 17:30:13 +00:00
Added argument handling, reverse sort
This commit is contained in:
parent
d47d8558d7
commit
df8b246940
@ -1,7 +1,8 @@
|
|||||||
/*
|
/*
|
||||||
* Bobbi January 2020
|
* Bobbi January 2020
|
||||||
*
|
*
|
||||||
* TODO: Sort by type, reverse sort, combinations etc.
|
* TODO: Fix bugs!!!!
|
||||||
|
* TODO: Sort by type, combinations etc.
|
||||||
* TODO: Improve checking code
|
* TODO: Improve checking code
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@ -102,12 +103,15 @@ static uint numfiles = 0;
|
|||||||
static uchar entsz; /* Bytes per file entry */
|
static uchar entsz; /* Bytes per file entry */
|
||||||
static uchar entperblk; /* Number of entries per block */
|
static uchar entperblk; /* Number of entries per block */
|
||||||
static char buf[BLKSZ]; /* General purpose scratch buffer */
|
static char buf[BLKSZ]; /* General purpose scratch buffer */
|
||||||
|
static uchar dowrite = 0;
|
||||||
|
static uchar doreverse = 0;
|
||||||
|
|
||||||
static uint stack; // DEBUG
|
static uint stack; // DEBUG
|
||||||
|
|
||||||
//#define STACK(msg) asm {tsc; sta stack }; fputs(msg, stdout); fputs(" ", stdout); pr_int(stack); putchar('\n');
|
//#define STACK(msg) asm {tsc; sta stack }; fputs(msg, stdout); fputs(" ", stdout); pr_int(stack); putchar('\n');
|
||||||
|
|
||||||
/* Prototypes */
|
/* Prototypes */
|
||||||
|
void prerr(char *s);
|
||||||
void reverse(char *s);
|
void reverse(char *s);
|
||||||
void itoa(int n, char s[]);
|
void itoa(int n, char s[]);
|
||||||
void uitoa(uint n, char s[]);
|
void uitoa(uint n, char s[]);
|
||||||
@ -121,11 +125,16 @@ 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);
|
||||||
uint device, uchar write);
|
void sortblocks(uint device);
|
||||||
void sortblocks(uint device, uchar write);
|
|
||||||
int writedir(uchar device);
|
int writedir(uchar device);
|
||||||
void freeblocks(void);
|
void freeblocks(void);
|
||||||
|
void usage(void);
|
||||||
|
|
||||||
|
void prerr(char *s) {
|
||||||
|
fputs(s, stderr);
|
||||||
|
fputs("\n", stderr);
|
||||||
|
}
|
||||||
|
|
||||||
/* Reverse the characters of the string s */
|
/* Reverse the characters of the string s */
|
||||||
void reverse(char *s) {
|
void reverse(char *s) {
|
||||||
@ -297,7 +306,7 @@ uchar firstblk(char *dirname, uchar *device, uint *block) {
|
|||||||
|
|
||||||
#ifdef CHECK
|
#ifdef CHECK
|
||||||
if ((hdr->typ_len & 0xf0) != 0xe0) {
|
if ((hdr->typ_len & 0xf0) != 0xe0) {
|
||||||
perror("Bad storage type");
|
prerr("Bad storage type");
|
||||||
rv = 1;
|
rv = 1;
|
||||||
goto ret;
|
goto ret;
|
||||||
}
|
}
|
||||||
@ -338,7 +347,7 @@ int readdir(uint device, uint blocknum) {
|
|||||||
|
|
||||||
blocks = (struct block*)malloc(BLKSZ);
|
blocks = (struct block*)malloc(BLKSZ);
|
||||||
if (!blocks) {
|
if (!blocks) {
|
||||||
perror("Unable to allocate memory");
|
prerr("Unable to allocate memory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
struct block *curblk = blocks;
|
struct block *curblk = blocks;
|
||||||
@ -377,11 +386,11 @@ int readdir(uint device, uint blocknum) {
|
|||||||
|
|
||||||
#ifdef CHECK
|
#ifdef CHECK
|
||||||
if (entsz != 0x27) {
|
if (entsz != 0x27) {
|
||||||
perror("Error - bad entry size");
|
prerr("Error - bad entry size");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (entperblk != 0x0d) {
|
if (entperblk != 0x0d) {
|
||||||
perror("Error - bad entries/block");
|
prerr("Error - bad entries/block");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -423,27 +432,27 @@ int readdir(uint device, uint blocknum) {
|
|||||||
hdr->parptr[0] + 256U * hdr->parptr[1];
|
hdr->parptr[0] + 256U * hdr->parptr[1];
|
||||||
|
|
||||||
if (parblk != blocknum) {
|
if (parblk != blocknum) {
|
||||||
perror("Bad parent block number");
|
prerr("Bad parent block number");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (parentry != blkentries) {
|
if (parentry != blkentries) {
|
||||||
perror("Bad parent block entry num");
|
prerr("Bad parent block entry num");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
if (parentlen != 0x27) {
|
if (parentlen != 0x27) {
|
||||||
perror("Bad parent entry length");
|
prerr("Bad parent entry length");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
char *dirname = buf + 0x05;
|
char *dirname = buf + 0x05;
|
||||||
if (strncmp(dirname, ent->name, NMLEN)) {
|
if (strncmp(dirname, ent->name, NMLEN)) {
|
||||||
perror("Subdirectory name mismatch");
|
prerr("Subdirectory name mismatch");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
++numfiles;
|
++numfiles;
|
||||||
if (numfiles == MAXFILES) {
|
if (numfiles == MAXFILES) {
|
||||||
perror("Too many files");
|
prerr("Too many files");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
++entries;
|
++entries;
|
||||||
@ -454,7 +463,7 @@ int readdir(uint device, uint blocknum) {
|
|||||||
curblk->data[0x02] + 256U*curblk->data[0x03];
|
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) {
|
||||||
perror("Unable to allocate memory");
|
prerr("Unable to allocate memory");
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
curblk = curblk->next;
|
curblk = curblk->next;
|
||||||
@ -487,8 +496,10 @@ int readdir(uint device, uint blocknum) {
|
|||||||
* Compare two filenames
|
* Compare two filenames
|
||||||
*/
|
*/
|
||||||
int compare(const void *a, const void *b) {
|
int compare(const void *a, const void *b) {
|
||||||
return(
|
int rc;
|
||||||
strncmp(((struct fileent*)a)->name, ((struct fileent*)b)->name, 15));
|
rc = strncmp(((struct fileent*)a)->name,
|
||||||
|
((struct fileent*)b)->name, 15);
|
||||||
|
return (doreverse ? !rc : rc);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -520,8 +531,7 @@ void printlist(void) {
|
|||||||
* 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) {
|
||||||
uint device, uchar write) {
|
|
||||||
|
|
||||||
fputs(" from blk ", stdout);
|
fputs(" from blk ", stdout);
|
||||||
pr_uint(srcblk);
|
pr_uint(srcblk);
|
||||||
@ -550,14 +560,14 @@ void copyent(uint srcblk, uint srcent, uint dstblk, uint dstent,
|
|||||||
struct pd_dirent *ent = (struct pd_dirent *)dstptr;
|
struct pd_dirent *ent = (struct pd_dirent *)dstptr;
|
||||||
uint block = ent->keyptr[0] + 256U * ent->keyptr[1];
|
uint block = ent->keyptr[0] + 256U * ent->keyptr[1];
|
||||||
if (readdiskblock(device, block, buf) == -1) {
|
if (readdiskblock(device, block, buf) == -1) {
|
||||||
perror("Can't read subdirectory");
|
prerr("Can't read subdirectory");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
struct pd_dirhdr *hdr = (struct pd_dirhdr*)(buf + PTRSZ);
|
struct pd_dirhdr *hdr = (struct pd_dirhdr*)(buf + PTRSZ);
|
||||||
hdr->parentry = dstent;
|
hdr->parentry = dstent;
|
||||||
if (write) {
|
if (dowrite) {
|
||||||
if (writediskblock(device, block, buf) == -1) {
|
if (writediskblock(device, block, buf) == -1) {
|
||||||
perror("Can't write subdirectory");
|
prerr("Can't write subdirectory");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -570,13 +580,13 @@ void copyent(uint srcblk, uint srcent, uint dstblk, uint 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(uint device, uchar write) {
|
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) {
|
||||||
puts(filelist[i].name);
|
puts(filelist[i].name);
|
||||||
copyent(filelist[i].blockidx, filelist[i].entrynum,
|
copyent(filelist[i].blockidx, filelist[i].entrynum,
|
||||||
destblk, destentry, device, write);
|
destblk, destentry, device);
|
||||||
++destentry;
|
++destentry;
|
||||||
if (destentry == entperblk) {
|
if (destentry == entperblk) {
|
||||||
++destblk;
|
++destblk;
|
||||||
@ -612,26 +622,45 @@ void freeblocks(void) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void usage(void) {
|
||||||
|
prerr("usage: sortdir [-w] [-r] path\n");
|
||||||
|
prerr(" Flags: -w Enable writing to disk");
|
||||||
|
prerr(" -r Reverse sort order\n");
|
||||||
|
exit(2);
|
||||||
|
}
|
||||||
|
|
||||||
int main(int argc, char *argv[]) {
|
int main(int argc, char *argv[]) {
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
perror("usage: softdir [-w] path\n");
|
usage();
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
uchar dowrite = 0;
|
int opt;
|
||||||
if (argc > 2) {
|
while ((opt = getopt(argc, argv, "rw")) != -1) {
|
||||||
if (!strcmp(argv[1], "-w"))
|
switch (opt) {
|
||||||
|
case 'r':
|
||||||
|
doreverse = 1;
|
||||||
|
break;
|
||||||
|
case 'w':
|
||||||
dowrite = 1;
|
dowrite = 1;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
usage();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (optind >= argc)
|
||||||
|
usage();
|
||||||
|
|
||||||
uchar dev;
|
uchar dev;
|
||||||
uint blk;
|
uint blk;
|
||||||
if (firstblk(argv[argc-1], &dev, &blk) != 0) {
|
if (firstblk(argv[optind], &dev, &blk) != 0) {
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
uchar err = readdir(dev, blk);
|
uchar err = readdir(dev, blk);
|
||||||
if (!err) {
|
if (!err) {
|
||||||
printlist();
|
printlist();
|
||||||
sortlist();
|
sortlist();
|
||||||
sortblocks(dev, dowrite);
|
sortblocks(dev);
|
||||||
if (dowrite)
|
if (dowrite)
|
||||||
err = writedir(dev);
|
err = writedir(dev);
|
||||||
else
|
else
|
||||||
|
Loading…
Reference in New Issue
Block a user