int main(int argc, char **argv){ int a = 1, b = 0; size_t l; char *path, *p, *pp; struct stat sbuf; struct dirent *direntp; DIR *dirp; if(argc == 1) return -1; if(!strcmp(argv[a], "-a")){ a++; b++; } if((path = getenv("PATH")) == NULL){ perror("no path defined"); return -1; } l = strlen(p)+1; p = malloc(sizeof(char)*strlen(path)*2); pp = malloc(sizeof(char)*strlen(path)*2); p = strtok(path, ":"); while((p != NULL)){ if((!stat(p, &sbuf)) && (S_ISDIR(sbuf.st_mode))){ if((dirp = opendir(p)) == NULL) return -1; while((direntp = readdir(dirp)) != NULL){ if(strcmp(direntp->d_name, argv[a]) == 0){ if((pp = realloc(pp,sizeof(direntp->d_name)+sizeof(p)*2)) == NULL) return -1; sprintf(pp, "%s/%s",p,direntp->d_name); if(checkexecutable(pp)){ fprintf(stdout, "%s\n",pp); if(b) break; return 0; } } } } p = strtok(NULL, ":"); } return 0; }
/* eval -- evaluate a list, producing a list */ extern List *eval(List *list0, Binding *binding0, int flags) { Closure *volatile cp; List *fn; if (++evaldepth >= maxevaldepth) fail("es:eval", "max-eval-depth exceeded"); Ref(List *, list, list0); Ref(Binding *, binding, binding0); Ref(char *, funcname, NULL); restart: if (list == NULL) { RefPop3(funcname, binding, list); --evaldepth; return true; } assert(list->term != NULL); if ((cp = getclosure(list->term)) != NULL) { switch (cp->tree->kind) { case nPrim: assert(cp->binding == NULL); list = prim(cp->tree->u[0].s, list->next, binding, flags); break; case nThunk: list = walk(cp->tree->u[0].p, cp->binding, flags); break; case nLambda: ExceptionHandler Push p; Ref(Tree *, tree, cp->tree); Ref(Binding *, context, bindargs(tree->u[0].p, list->next, cp->binding)); if (funcname != NULL) varpush(&p, "0", mklist(mkterm(funcname, NULL), NULL)); list = walk(tree->u[1].p, context, flags); if (funcname != NULL) varpop(&p); RefEnd2(context, tree); CatchException (e) if (termeq(e->term, "return")) { list = e->next; goto done; } throw(e); EndExceptionHandler break; case nList: { list = glom(cp->tree, cp->binding, TRUE); list = append(list, list->next); goto restart; } default: panic("eval: bad closure node kind %d", cp->tree->kind); } goto done; } /* the logic here is duplicated in $&whatis */ Ref(char *, name, getstr(list->term)); fn = varlookup2("fn-", name, binding); if (fn != NULL) { funcname = name; list = append(fn, list->next); RefPop(name); goto restart; } if (isabsolute(name)) { char *error = checkexecutable(name); if (error != NULL) fail("$&whatis", "%s: %s", name, error); list = forkexec(name, list, flags & eval_inchild); RefPop(name); goto done; } RefEnd(name); fn = pathsearch(list->term); if (fn != NULL && fn->next == NULL && (cp = getclosure(fn->term)) == NULL) { char *name = getstr(fn->term); list = forkexec(name, list, flags & eval_inchild); goto done; } list = append(fn, list->next); goto restart; done: --evaldepth; if ((flags & eval_exitonfalse) && !istrue(list)) exit(exitstatus(list)); RefEnd2(funcname, binding); RefReturn(list); }