home *** CD-ROM | disk | FTP | other *** search
- From decwrl!labrea!rutgers!ukma!cwjcc!hal!ncoast!allbery Sun Oct 30 15:06:39 PST 1988
- Article 693 of comp.sources.misc:
- Path: granite!decwrl!labrea!rutgers!ukma!cwjcc!hal!ncoast!allbery
- From: maart@cs.vu.nl.UUCP (Maarten Litmaath)
- Newsgroups: comp.sources.misc
- Subject: v05i016: which2 version 2 (includes bug-fix)
- Message-ID: <8810261300.aa18153@star.cs.vu.nl>
- Date: 28 Oct 88 02:50:24 GMT
- Sender: allbery@ncoast.UUCP
- Reply-To: maart@cs.vu.nl.UUCP (Maarten Litmaath)
- Lines: 338
- Approved: allbery@ncoast.UUCP
-
- Posting-number: Volume 5, Issue 16
- Submitted-by: "Maarten Litmaath" <maart@cs.vu.nl.UUCP>
- Archive-name: which2-v2
-
- Dear moderator, included below is the new and enhanced version of `which2'.
- I think the comments in the source header and the manual describe the
- changes clearly. This version is to supersede the previous one.
- Special thanks to Emile LeBlanc for catching the bug and testing the fix.
- Thanks for your attention.
- Regards & enjoy!
- Maarten Litmaath @ VU Amsterdam:
- maart@cs.vu.nl, mcvax!botter!maart
-
- : This is a shar archive. Extract with sh, not csh.
- : This archive ends with exit, so do not worry about trailing junk.
- : --------------------------- cut here --------------------------
- PATH=/bin:/usr/bin:/usr/ucb
- echo Extracting 'which.c'
- sed 's/^X//' > 'which.c' << '+ END-OF-FILE ''which.c'
- X/*
- X * [alias <command> |] which [-i] [-a] [<command>]
- X * alias which alias !\$ \| /usr/local/bin/which -i !\*
- X * alias which eval alias '\$$# |' /usr/local/bin/which -i $\*
- X *
- X * author: Maarten Litmaath @ Free U Amsterdam (maart@cs.vu.nl)
- X * first change:
- X * Emile LeBlanc (leblanc%math.Berkeley.EDU@ucbvax.berkeley.edu) notes
- X * the access() system call considering everything executable for
- X * root (!), so we give root a special treatment
- X * 'which', 'which -i' and 'which -a' with no further arguments now
- X * return the PATH environment variable, split up into its components
- X * the aliases defined above are slightly different from the previous
- X * version - now it's the shell who's doing the alias checking
- X */
- X
- X#include <sys/types.h>
- X#include <sys/stat.h>
- X#include <stdio.h>
- X
- X#define BUF_SIZE 512
- X
- Xchar E_usage[] = "Usage: [alias <command> |] %s [-i] [-a] [<command>]\n",
- X E_read[] = "%s - read error in ",
- X E_path[] = "no PATH in environment!\n",
- X E_dir[] = "%s found in unreadable directory %s!\n",
- X E_notfound[] = "%s not found in\n%s\n",
- X *prog;
- Xint uid;
- X
- X
- Xmain(argc, argv)
- Xint argc;
- Xregister char **argv;
- X{
- X register char *path, *s;
- X char *save, *strcpy(), *getenv(), *gets(), buf[BUF_SIZE];
- X int all = 0, inter = 0, found = 0;
- X struct stat st;
- X void usage(), convert();
- X
- X
- X prog = *argv++;
- X
- X if (argc > 4)
- X usage();
- X
- X while (--argc > 1) {
- X s = *argv++;
- X if (*s++ != '-')
- X usage();
- X while (*s)
- X switch (*s++) {
- X case 'a':
- X all = 1;
- X break;
- X case 'i':
- X inter = 1;
- X break;
- X default:
- X usage();
- X }
- X }
- X
- X if (inter) {
- X if (gets(buf) && *buf != '\n') {
- X printf("%s\t%s\n", *argv, buf);
- X if (!all)
- X exit(0);
- X found = 1;
- X }
- X if (ferror(stdin)) {
- X fprintf(stderr, E_read, prog);
- X perror("stdin");
- X exit(1);
- X }
- X }
- X
- X if (!(save = path = getenv("PATH"))) {
- X fprintf(stderr, E_path);
- X exit(1);
- X }
- X
- X if (!*path)
- X save = path = ".";
- X
- X if (argc == 0) {
- X convert(path, buf);
- X puts(buf);
- X exit(0);
- X }
- X
- X if (**argv == '-' && (*argv)[1] && !(*argv)[2])
- X switch ((*argv)[1]) {
- X case 'i':
- X case 'a':
- X convert(path, buf);
- X puts(buf);
- X exit(0);
- X }
- X
- X uid = getuid();
- X
- X while (*path) {
- X s = buf;
- X while ((*s++ = *path) && *path++ != ':')
- X ;
- X if (*buf == ':') {
- X /*
- X * to deal with the dubious convention that a spurious
- X * colon is equivalent to a dot...
- X */
- X *buf = '.';
- X ++s;
- X }
- X (void) strcpy(s, *argv);
- X *--s = '/';
- X if (stat(buf, &st) != 0 || (st.st_mode & S_IFMT) != S_IFREG)
- X continue;
- X
- X /* file exists and is regular */
- X
- X if (uid == 0 ? !(st.st_mode & 0111) : access(buf, 1) != 0)
- X continue;
- X
- X /* file is executable */
- X
- X *s = 0;
- X if (uid == 0 && stat(buf, &st) != 0) {
- X perror(buf);
- X continue;
- X }
- X
- X if (uid == 0 ? !(st.st_mode & 0444) : access(buf, 4) != 0) {
- X fprintf(stderr, E_dir, *argv, buf);
- X continue;
- X }
- X
- X /* directory is readable */
- X
- X *s = '/';
- X puts(buf);
- X if (!all)
- X exit(0);
- X found = 1;
- X }
- X
- X if (found)
- X exit(0);
- X
- X convert(save, buf);
- X fprintf(stderr, E_notfound, *argv, buf);
- X exit(1);
- X}
- X
- X
- Xvoid usage()
- X{
- X fprintf(stderr, E_usage, prog);
- X exit(1);
- X}
- X
- X
- Xvoid convert(path, buf)
- Xregister char *path, *buf;
- X{
- X for (;;) {
- X while ((*buf++ = *path) && *path++ != ':')
- X ;
- X if (!*path)
- X break;
- X *buf++ = '\n';
- X }
- X *buf = '\0'; /* to cope with a PATH ending in ':' */
- X}
- + END-OF-FILE which.c
- chmod 'u=rw,g=r,o=r' 'which.c'
- set `wc -c 'which.c'`
- count=$1
- case $count in
- 3306) :;;
- *) echo 'Bad character count in ''which.c' >&2
- echo 'Count should be 3306' >&2
- esac
- echo Extracting 'which.1'
- sed 's/^X//' > 'which.1' << '+ END-OF-FILE ''which.1'
- X.TH WHICH 1 Oct\ 3\ 1988
- X.SH NAME
- Xwhich \- give alias or path expansion of command
- X.SH SYNOPSIS
- X.B which
- X[
- X.B \-i
- X] [
- X.B \-a
- X] [
- X.I command
- X]
- X.SH DESCRIPTION
- X.B Which
- Xprovides the user with the full expansion of the
- X.I command
- Xargument, be it either an
- X.I alias
- Xor an executable file (default). To enable search for
- X.I aliases
- Xthe user should supply the
- X.B \-i
- X(= interactive) flag. In that case
- X.B which
- Xexpects as standard input the output of an
- X.I alias
- Xcommand. This demand is easily met by setting an
- X.I alias
- Xlike the following:
- X.br
- X
- X.br
- X.RS
- X.B alias \t which \t \\\\
- X.RS
- X.B
- Xalias !\\$ \\| /usr/local/bin/which \-i !\\*
- X.RE
- X.RE
- X.br
- X
- X.br
- Xin
- X.I csh,
- Xor
- X.br
- X
- X.br
- X.RS
- X.B alias \t which \t \\\\
- X.RS
- X.B
- Xeval alias '\\$$# |' /usr/local/bin/which \-i $\\*
- X.RE
- X.RE
- X.br
- X
- X.br
- Xin shells which are supersets of
- X.I sh.
- X.sp
- XIf the
- X.B \-i
- Xflag is not supplied, only the user's
- X.I PATH
- Xis searched for the
- X.I command.
- XIf the
- X.B \-a
- X(= all) flag is given,
- X.B which
- Xwill not stop after the first 'match', but search for all occurrences of
- X.I command
- Xin the user's
- X.I PATH.
- X.B Which [-i | -a]
- Xwithout further argument prints the user's
- X.I PATH
- Xbroken up into its components,
- Xone per line.
- X.PP
- XThis new version of the
- X.I which
- Xcommand is not a
- X.I csh
- Xscript.
- XBeing an executable it is much faster, and not sourcing
- X.I .cshrc
- Xit gives a true picture of one's
- X.I aliases
- Xand can be used safely between backquotes, like:
- X.sp
- X.RS
- X.B
- X$ file `which which`
- X.br
- X.B /usr/local/bin/which: pure executable
- X.br
- X.B $
- X.RE
- X.SH EXAMPLE
- X.B % alias
- X.br
- X.B which \t alias !$ | /usr/local/bin/which
- X.B \-i !*
- X.br
- X.B % which which
- X.br
- X.B which \t alias !$ | /usr/local/bin/which
- X.B \-i !*
- X.br
- X.B % which \-a which
- X.br
- X.B which \t alias !$ | /usr/local/bin/which
- X.B \-i !*
- X.br
- X.B /usr/local/bin/which
- X.br
- X.B /usr/ucb/which
- X.br
- X.B %
- X.SH AUTHOR
- XMaarten Litmaath @ Free University Amsterdam
- + END-OF-FILE which.1
- chmod 'u=rw,g=r,o=r' 'which.1'
- set `wc -c 'which.1'`
- count=$1
- case $count in
- 1852) :;;
- *) echo 'Bad character count in ''which.1' >&2
- echo 'Count should be 1852' >&2
- esac
- exit 0
-
-
-