#include <xfbuf.h>
#include <ascii.h>

char *strip_path();
#define same(s1,s2) (strcmp(s1,s2)==0)

/*

	W <filespec>

	locates all files or directories matching <filespec> 
	on the (given) drive, listing full file info. 

	Tom Jennings
	26 Jan 92
*/

char filename[80];

char work[80];		/* simple workspace */
int level;		/* how deep we are, */
char drive;
char stopfile;		/* 1 == don't go deeper if stopfile.z present */
char query;		/* 1 == verify deletes */
char list_info;		/* 1 == list all files */
char list_changed;	/* 1 == list only changed files */
char kill;		/* 1 == delete matching files */
char space;		/* 1 == list space consumed */
char crawl;		/* 1 == crawl the tree */
char nomatter;		/* 1 == no matter what */
char pause;		/* 1 == pause every 24 lines */
char tag;		/* 1 == tag files */
char line;		/* current lines output */
long totl_bytes;	/* total file size */
long totl_space;	/* total space consumed */
unsigned blksize;	/* allocation size */

#define RO 0x01		/* Read only attribute. */
#define HI 0x02		/* Hidden attribute, */
#define SY 0x04		/* System attribute, */
#define VO 0x08		/* Volume ID */
#define DI 0x10		/* directory */
#define AR 0x20		/* Archive, */
#define TG1 0x40	/* Tag #1 */
#define TG2 0x80	/* Tag #2 */

unsigned _stack = 8000;


char _months[13][4] = {
	"Eh?",
	"Jan",
	"Feb",
	"Mar",
	"Apr",
	"May",
	"Jun",
	"Jul",
	"Aug",
	"Sep",
	"Oct",
	"Nov",
	"Dec"
};

main(argc,argv)
int argc;
char *argv[];
{
char sw[40],*p,buff[80];
int i;

	drive= 0;				/* 0 == default */
	stopfile= 1;				/* pay attention to stopfile.z's */
	filename[0]= NUL;

	for (i= 1; i < argc; i++) {		/* Process any options, */
		cpyarg(buff,strip_path(buff,argv[i])); /* copy out filename */
		strip_switch(sw,argv[i]);	/* recover switches, */
		for (p= sw; *p; ++p) {
			switch (*p) {
				case 'Z': stopfile= 0; break;
			}
		}
		if (buff[0]) cpyarg(filename,buff); /* possible filename */
	}
	if (! filename[0]) {			/* must be a filespec */
		printf("W <filespec>  /Z            26 Jan 92\r\n");
		printf("\r\n");
		printf("No filename given!\r\n");
		printf("\r\n");
		printf("  Searches all directories for filenames matching <filespec>. If\r\n");
		printf("  a file named \"STOPFILE.Z\" is found within any subdirectory, sub-\r\n");
		printf("  directories below that level are not searched.\r\n");
		printf("\r\n");
		printf("  Some shorthand is allowed for filenames:\r\n");
		printf("\r\n");
		printf("    FILE  is equiv. to FILE*.*            .EXT is equiv. to *.EXT\r\n");
		printf("    FILE. is equiv. to FILE.              FILE*. is equiv. to FILE*.\r\n");
		printf("\r\n");
		printf("Options:\r\n");
		printf("               /Z      Ignore STOPFILE.Z\r\n");
		printf("\r\n");
		printf("  Tom Jennings / World Power Systems / Box 77731 / San Francisco CA 94107 USA\r\n");
		exit(1);
	}
	fixdir(filename);			/* fixup directory names */
	if ((*filename == '.') && (strlen(filename) <= 4)) {
		strcpy(buff,"*");		/* turn extention-only  (.EXE) */
		strcat(buff,filename);		/* into full filename (*.EXE) */
		strcpy(filename,buff);
	}
	for (p= filename; *p; ++p) {		/* if no extention given (FILE) */
		if (*p == '.') break;
	}
	if (*p != '.') strcat(filename,"*.*");	/* make it wild (FILE*.*) */
	dir("\\");				/* start at the root */
	exit(0);
}

/* Recursively find each directory, and execute all the weird options. Returns
the number of bytes tallied. */

dir(s) 
char *s;
{
int i;
struct _xfbuf xfbuf;
char path[80];
char zfound;

	++level;
	strcpy(path,s);					/* build full search path */
	strcat(path,"*.*"); /* filename); */
	i= 0;						/* _find flag, file count */
	zfound= 0;
	xfbuf.s_attrib= 0xff;
	while (_find(path,i++,&xfbuf)) {
		if (xfbuf.f_attrib & VO) continue;	/* ignore volume ID */
		if (*xfbuf.name == '.') continue;	/* ignore . and .. */
		if (fmatch("Stopfile.Z",xfbuf.name)) 	/* if we find a stopfile */
			zfound= stopfile;		/* flag for later */
		if (fmatch(filename,xfbuf.name)) {	/* if matches our pattern */
			fileinfo(s,&xfbuf);		/* display it */
		}
	}

/* Now search for all subdirectories within this directory. */

	strcpy(path,s);					/* start here, */
	strcat(path,"*.*");				/* all subdirs */
	i= 0;						/* _find flag, file count */
	xfbuf.s_attrib= DI;

	if (! zfound) while (_find(path,i++,&xfbuf)) {
		if ((xfbuf.f_attrib & DI) == 0) continue; /* only dirs */
		if (*xfbuf.name == '.') continue;	/* ignore . and .. */

		strcpy(path,s);				/* build full pathname */
		strcat(path,xfbuf.name);
		strcat(path,"\\");
		dir(path);				/* do it, */
	}
	if (level) --level;				/* pop up one level */
}

/* Display stuff for this file. */

fileinfo(path,xfbuf)
char *path;			/* pathname */
struct _xfbuf *xfbuf;		/* file info structure */
{
char buff[80];
int i;
	strcpy(buff,path);				/* build full pathname */
	strcat(buff,xfbuf-> name);
	if (xfbuf-> f_attrib & DI) stoupper(buff);	/* dirs in upper case */
	else stolower(buff);				/* files in lower case */

	printf("%s",buff);				/* output the filename text */
	for (i= strlen(buff); i < 40; i++) {		/* generate leaders */
		printf(i & 1 ? " " : ".");		/* dot or space */
	}
	if (xfbuf-> f_attrib & DI) printf("   <dir>  ");
	else printf("%11,lu ",xfbuf-> fsize);

	printf(" %2u ",xfbuf-> date & 0x1f);			/* day */
	printf("%s ",_months[(xfbuf-> date >> 5) & 0x0f]);	/* month */
	printf("%2u",((xfbuf-> date >> 9) & 0x3f) + 80);	/* year */
	printf("  %2u:%02u",xfbuf-> time >> 11,(xfbuf-> time >> 5) & 0x3f);

	if (xfbuf-> f_attrib & (AR | SY | RO | HI)) {
		printf("    [");
		if (xfbuf-> f_attrib & AR) printf("A");
		if (xfbuf-> f_attrib & SY) printf("S");
		if (xfbuf-> f_attrib & RO) printf("R");
		if (xfbuf-> f_attrib & HI) printf("H");
		printf("]");
	}
	printf("\r\n");
}

