Builtin 'which' command for csh
Tony Birnseth
tonyb at tektools.UUCP
Fri Dec 12 14:36:30 AEST 1986
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 at 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,
};
More information about the Comp.bugs.4bsd.ucb-fixes
mailing list