Relay-Version: version B 2.10 5/3/83; site utzoo.UUCP Path: utzoo!mnetor!seismo!lll-crg!mordor!sri-spam!sri-unix!hplabs!tektronix!tekgen!tektools!tonyb From: tonyb@tektools.UUCP (Tony Birnseth) Newsgroups: comp.bugs.4bsd Subject: Builtin 'which' command for csh Message-ID: <1991@tektools.UUCP> Date: Thu, 11-Dec-86 23:36:30 EST Article-I.D.: tektools.1991 Posted: Thu Dec 11 23:36:30 1986 Date-Received: Mon, 15-Dec-86 04:29:06 EST Organization: Tektronix Inc., Beaverton, Or. Lines: 220 Keywords: /usr/ucb/which too slow, builtin which for csh Index: /bin/csh 4.3BSD Description: /usr/ucb/which does not handle builtin csh commands and is slower than a slug! The following is an internal which command for csh. We had a long argument about the functionality of this command. Should it be useful and fast? Or should it be compatible with /usr/ucb/which? Unfortunately, the compatibility argument won out. However it should be easy enough for a site to remove the -u option stuff and get a reasonably fast useful, which command. Fix: Apply the following diffs to sh.func.c and sh.init.c. *** /tmp/,RCSt1027852 Thu Dec 11 17:03:03 1986 --- sh.func.c Thu Dec 11 16:58:59 1986 *************** *** 1149,1151 if (reenter >= 2) error(NOSTR); } --- 1170,1325 ----- if (reenter >= 2) error(NOSTR); } + + + #ifdef TEK_MODS + + /* + * After much disucussion, it was decided to have this fast clean internal + * version of 'which' produce the same ugly output as it slower counterpart + * /usr/ucb/which. A -u (useful) flag was added to allow a user to alias + * which to which -u for a cleaner more useful form of the command. + * tonyb@tek + */ + dowhich(vec) + char **vec; + { + register struct biltins *bp; + register char *word, **pp, *func; + struct varent *vp, *pth; + char dir[MAXPATHLEN+1]; + int cmp, hit, outty, uflag; + + + /* + * Glob it up + */ + uflag = gflag = 0; + tglob(++vec); + if(gflag) { /* has globbing chars */ + vec = glob(vec); /* glob it */ + if(vec == 0) + bferr("No match"); + } else + trim( vec ); + + pth = adrof("path"); + + /* + * Find out if we're writting to a tty. If not, use "command type" + * output, else use "user" type output. + * command type output is used to do things like 'echo `which foobar`' + */ + outty = isatty(1); + + /* + * If no -u, go into useless mode, else provide useable, + * coherent output. + */ + if(eq(*vec,"-u")) { + uflag++; + vec++; + } + + while(word = *vec++) { + + /* + * check aliases first. + */ + vp = adrof1(word, &aliases); + if(vp) { + if(!uflag) { + printf("%s: \t aliased to '", word); + blkpr(vp->vec);printf("'\n"); + } else if(outty) { + printf("alias/%s '", word); + blkpr(vp->vec); printf("'\n"); + } else + printf("%s\n",word); + continue; + } + + /* + * If a hard path, just return it if it is executable, else + * return nothing. + */ + if(index(word, '/') ) { + if(executable(word)) { + printf("%s\n",word); + continue; + } + else if( !uflag ) { + printf("%s not found\n", word); + continue; + } + } + + /* + * Check builtins + * "standard" /usr/ucb/which does not support the concept + * of builtin commands. YUK!!! + */ + if(uflag) { + hit = 0; + for(bp=bfunc; func = bp->bname; bp++) { + cmp = strcmp(func, word); + if(cmp == 0) { + if(outty) + printf("builtin/%s\n",word); + else + printf("%s\n",word); + hit++; + } + else if(cmp > 0) + break; + } + if(hit) + continue; + } + + + /* + * Check the paths + * No need to read 'em, just check if it is executable. + */ + if(pth) { + register char *ep; + + hit = 0; + for(pp = pth->vec; pp && *pp && **pp; pp++) { + ep = strcpy(dir,*pp); + while(*ep) + ep++; + *ep++ = '/'; + strcpy(ep,word); + if(executable(dir)) { + printf("%s\n",dir); + hit++; + break; + } + } + } + + /* + * If not found and in useless mode + */ + if(!hit && !uflag) { + printf("no %s in ", word); + blkpr(pth->vec); + printf("\n"); + } + } /* end while */ + } + + + executable(path) + register char *path; + { + struct stat st; + + if(access(path,1) || stat(path, &st) ) + st.st_mode = 0; + return( (st.st_mode & S_IFMT) == S_IFREG); + } + #endif /* TEK_MODS */ + *** /tmp/,RCSt1027862 Thu Dec 11 17:03:14 1986 --- sh.init.c Thu Dec 11 12:47:00 1986 *************** *** 77,82 extern int dounhash(); extern int unset(); extern int dounsetenv(); #define INF 1000 --- 77,85 ----- extern int dounhash(); extern int unset(); extern int dounsetenv(); + #ifdef TEK_MODS + extern int dowhich(); + #endif /* TEK_MODS */ #define INF 1000 *************** *** 153,158 "unlimit", dounlimit, 0, INF, "unset", unset, 1, INF, "unsetenv", dounsetenv, 1, INF, "wait", dowait, 0, 0, "while", dowhile, 1, INF, }; --- 160,168 ----- "unlimit", dounlimit, 0, INF, "unset", unset, 1, INF, "unsetenv", dounsetenv, 1, INF, + #ifdef TEK_MODS + "which", dowhich, 1, INF, + #endif /* TEK_MODS */ "wait", dowait, 0, 0, "while", dowhile, 1, INF, };