
/*
 *  FINDIT()
 *
 *  FINDIT [-ddir] <programname> <programname> ...
 *
 *  Search specified directories (those specified in FINDITVOLS if none
 *  spcified on the command line) for the specified program names.  Wildcards
 *  are acceptable
 *
 *  Format for FINDITVOLS:	dir,dir,dir ...
 */

#include <local/typedefs.h>
#include <local/xmisc.h>
#include <stdio.h>

#define ENVVAR	"FINDITVOLS"

MLIST	DList;
MLIST	FList;
char *ErrorString = "unable to open dres.library";
char *EnvStr;
char Path[1024];

extern int Enable_Abort;

main(ac,av)
char *av[];
{
    NewList(&DList);
    NewList(&FList);

    Enable_Abort = 0;
    {
	register short i;
	for (i = 1; i < ac; ++i) {
	    register char *str = av[i];
	    if (*str != '-') {
		register NODE *node = malloc(sizeof(NODE));
		node->ln_Name = str;
		AddTail(&FList, node);
		continue;
	    }
	    for (++str; *str; ++str) {
		switch(*str) {
		case 'd':
		    {
			register NODE *node = malloc(sizeof(NODE));
			node->ln_Name = str + 1;
			AddTail(&DList, node);
		    }
		    str = "\0";
		    break;
		default:
		    printf("Unknown option: -%c\n", *str);
		    exit(1);
		}
	    }
	}
    }
    if (openlibs(DRES_LIB) == 0) {
	puts(ErrorString);
	exit(1);
    }
    mountrequest(0);
    if (!GetHead(&DList)) {         /*  scan enviroment variable for dirs */
	char *str;
	register char *ptr;
	register NODE *node;
	register char c;

	str = EnvStr = GetDEnv(ENVVAR);
	if (!str) {
	    printf("Env. Var %s not found, format:  dir,dir,dir...\n", ENVVAR);
	    goto fail;
	}
	for (c = 1; c; str = ptr + 1) {
	    for (ptr = str; *ptr && *ptr != ','; ++ptr);
	    c = *ptr;
	    *ptr = 0;
	    node = malloc(sizeof(NODE));
	    node->ln_Name = str;
	    AddTail(&DList, node);
	}
    }
    {
	register NODE *node;
	register FIB *fib = malloc(sizeof(FIB));
	while (node = RemHead(&DList)) {
	    long lock;

	    if (lock = Lock(node->ln_Name, SHARED_LOCK)) {
		strcpy(Path, node->ln_Name);
		if (Examine(lock, fib))
		    SearchTree(lock, fib, strlen(Path));
		UnLock(lock);
	    }
	    free(node);
	    if (checkbreak())
		break;
	}
	free(fib);
	puts("");
    }
fail:
    if (checkbreak())
	puts("^C");
    {
	register NODE *node;
	while (node = RemHead(&DList))
	    free(node);
	while (node = RemHead(&FList))
	    free(node);
    }
    if (EnvStr)
	free(EnvStr);
    mountrequest(1);
    closelibs(-1);
}

/*
 *  Search the specified directory for the wildcarded names in FList.
 */

SearchTree(dirlock, dirfib, idx)
long dirlock;
FIB *dirfib;
{
    long oldlock;
    long lock;
    register FIB *fib = malloc(sizeof(FIB));

    oldlock = CurrentDir(dirlock);
    while (ExNext(dirlock, dirfib)) {
	if (idx && Path[idx-1] != ':' && Path[idx-1] != '/') {
	    Path[idx] = '/';
	    strcpy(Path+idx+1, dirfib->fib_FileName);
	} else {
	    strcpy(Path+idx, dirfib->fib_FileName);
	}
	if (dirfib->fib_DirEntryType > 0) {
	    if (lock = Lock(dirfib->fib_FileName, SHARED_LOCK)) {
		if (Examine(lock, fib))
		    SearchTree(lock, fib, idx + strlen(Path+idx));
		UnLock(lock);
		if (checkbreak())
		    break;
	    }
	} else {
	    register NODE *node;
	    for (node = GetHead(&FList); node; node = GetSucc(node)) {
		if (WildCmp(node->ln_Name, dirfib->fib_FileName)) {
		    printf("%s ", Path);
		    fflush(stdout);
		}
	    }
	}
    }
    CurrentDir(oldlock);
    free(fib);
}

