/*
 *  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);
}
