home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Hall of Fame
/
HallofFameCDROM.cdr
/
util4
/
ax1k.lzh
/
AX.C
next >
Wrap
Text File
|
1989-02-11
|
7KB
|
242 lines
#include <dos.h>
#include <io.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#define MAX_FILEMEM 2300
#define MAX_DOS_LINE 128
/* recommended linker parameters: /st:0x80ff /se:28 /cp:1 */
main(argc, argv)
int argc;
char *argv[];
{
struct find_t filespec; /* MS C file data structure */
int filecount = 0; /* number of files found */
int i = 0; /* general purpose integer */
int pathlen; /* length of path part of file spec */
char vidout[81]; /* strings to be displayed on screen */
char del_ans; /* answer to "Delete these files?" */
char fil_ans; /* answer to "Delete this file?" */
char fullname[MAX_DOS_LINE]; /* complete file spec */
char path[MAX_DOS_LINE]; /* path of file spec + some filename */
unsigned long bytes = 0; /* total size of matching files */
char flist[MAX_FILEMEM][14]; /* place to remember filenames */
/* make sure there is one and only one command line argument to ax */
if (argc != 2) {
say("\nAx deleter version 1k\nby D. David Kaufman\n\n");
say("syntax: ax <filespec>\n");
return;
}
strcpy(fullname, argv[1]); /* store file spec in fullname */
i = (strlen(fullname) - 1); /* see if adding *.* or \*.* needed */
if (fullname[i] == '.') {
/* special handling for filespecs ending with dot */
strcat(fullname, "\\*.*");
} else if ((fullname[i] == '\\') || (fullname[i] == ':')) {
/* special handling for filespecs ending with \ or : */
strcat(fullname, "*.*");
}
if (_dos_findfirst(fullname, _A_NORMAL, &filespec)) {
/* no files match the spec, but maybe a subdir does */
if (_dos_findfirst(fullname, _A_SUBDIR, &filespec) == 0) {
/* yes, it's a subdir */
/* convert to a complete filespec by adding \*.* */
strcat(fullname, "\\*.*");
/* then repeat test for matching files */
if (_dos_findfirst(fullname, _A_NORMAL, &filespec)) {
/* still no matches, so gripe and exit */
nomatch();
return;
}
} else {
/* no files, no subdir, so gripe and exit */
nomatch();
return;
}
}
say("\n");
dispname(filespec.name); /* display filename */
bytes = bytes + (unsigned long)filespec.size; /* add size to total */
strcpy(flist[filecount++], filespec.name); /* remember filename */
while (_dos_findnext(&filespec) == 0) {
/* and repeat until no more files found */
dispname(filespec.name);
bytes = bytes + (unsigned long)filespec.size;
if (filecount < MAX_FILEMEM) {
/* still room in array to remember filename */
strcpy(flist[filecount++], filespec.name);
} else {
/* oh well, too many names to remember anyway */
filecount++;
}
}
/* at end of showing files, display an extra line */
/* unless we already wrapped from stopping at column 80 */
if ((filecount % 5) !=0) {
say("\n\n");
} else {
say("\n");
}
/* say how many bytes the files add up to */
outcomma(ultoa(bytes, vidout, 10));
if (bytes != 1) {
say(" bytes in ");
} else {
say(" byte in ");
}
/* and how many files were found, and prompt user about deleting */
if (filecount == 1) {
say("1 file. Delete? (yes/NO) ");
} else {
itoa(filecount, vidout, 10);
outcomma(vidout);
say(" files. Delete? (yes/NO/prompt) ");
}
del_ans = (getch() | 32);
if (del_ans == 'p') {
/* user selected prompt mode */
if (filecount == 1) {
/* but we don't do prompt mode for just one file */
del_ans = 'n';
} else {
say("Prompt\n\n");
}
} else if (del_ans == 'y') {
/* user said yes to delete */
say("Yes\n");;
}
if ((del_ans == 'p') || (del_ans == 'y')) {
/* user wants to delete (either prompted or not) */
/* now figure out path component of fullname */
strcpy(path, fullname); /* copy path from fullname */
i = strlen(path);
while ((path[i] != '\\') && (path[i] != ':') && (i >= 0)) {
/* chop path at rightmost colon or backslash */
path[i--] = 0;
}
/* path now contains only the path data from fullname.
* filenames are tacked on to the end of the path and passed
* to the eatfile routine, which can only eat one file at a
* time. each new filename overwrites the old filename in the
* path string, which is why we bother to note the length of
* the actual path component */
pathlen = strlen(path);
if (filecount <= MAX_FILEMEM) {
/* delete using list in memory if not too many files */
for (i = 0; i < filecount; i++) {
eatfile(path, pathlen, flist[i], del_ans);
}
} else {
/* otherwise, delete by getting the names from disk */
_dos_findfirst(fullname, _A_NORMAL, &filespec);
eatfile(path, pathlen, filespec.name, del_ans);
while (_dos_findnext(&filespec) == 0) {
eatfile(path, pathlen, filespec.name, del_ans);
}
}
} else {
/* user said no to deleting the files, so just echo and exit */
say("No\n");
}
}
say(vidout) /* this routine just displays a string */
char vidout[]; /* (printf comes with a lot of unnecessary code) */
{
int i = 0;
while (vidout[i]) {
if (vidout[i] == '\n') {
putch(13);
}
putch(vidout[i++]);
}
}
nodel(path) /* routine to inform user that delete request failed */
char path[];
{
say("\nDOS won't erase ");
say(path);
}
dispname(filename) /* routine to display a filename in 16-byte field */
char filename[13];
{
int i;
say(filename);
i = strlen(filename);
while (i++ < 16) {
putch(' ');
}
}
nomatch() /* routine to inform user that no files matched the spec */
{
say("\nNo files match.\n");
}
eatfile(path, pathlen, filename, del_ans) /* delete a file */
char path[];
int pathlen;
char filename[];
char del_ans;
{
char fil_ans;
strcpy(&path[pathlen], filename); /* overwrite old filename */
if (del_ans == 'p') {
/* we are in prompt mode, so prompt for each deletion */
dispname(filename);
say("Delete? (yes/NO) ");
fil_ans = (getch() | 32);
if (fil_ans == 'y') {
say("Yes\n");;
if (remove(path) == -1) { /* delete it, or */
nodel(path); /* gripe if attempt failed */
}
} else {
say("No\n");
}
} else if (remove(path) == -1) { /* prompt mode off, just ax */
nodel(path); /* gripe if attempt failed */
}
}
outcomma(string) /* display a numeric string in nice comma format */
char string[];
{
int i, length;
length = strlen(string);
for (i = 0; i < length; i++) {
/* dividing an int by 3 will cause significant bits to
* be lost unless it was a multiple of 3 already.
* we multiply by 3 and see if we got what we started
* with. if so, then a comma should be displayed before
* the digit in this position (except when no digit has been
* displayed at all yet) */
if (((((length - i) / 3) * 3) == (length - i)) && (i > 0)) {
putch(','); /* time to print a comma */
}
putch(string[i]); /* print the digit */
}
}