[alt.sources] Path Program

markk@censor.UUCP (Mark Keating) (06/16/89)

   After trying to work on another system I was slightly dissapointed
to find that there was no 'path' program to be found anywhere.
So I wrote one  -- hope you find it useful.

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	path.1
#	path.c
# This archive created: Thu Jun 15 16:04:06 1989
export PATH; PATH=/bin:$PATH
if test -f 'path.1'
then
	echo shar: will not over-write existing file "'path.1'"
else
cat << \SHAR_EOF > 'path.1'
.TH PATH 1
.SH NAME
path \- locate the executable for a command
.SH SYNOPSIS
/usr/local/bin/path [ -options ] command(s)
.I file
.SH DESCRIPTION
.I Path
will report on the location of
.I file,
searching every directory in the path (as defined in the
$PATH variable), much like the operating system does when searching
$PATH to execute a program.  It is handy for finding out where in your path
a command resides. Any options specified are passed with located names to the
.I ls
command.
.PP
.SH CREDITS
This utility was inspired by the
.I findpath
utility posted by Ed Carp,
and re-generated into
.I path
by Mark Keating.
SHAR_EOF
fi # end of overwriting check
if test -f 'path.c'
then
	echo shar: will not over-write existing file "'path.c'"
else
cat << \SHAR_EOF > 'path.c'
/* opt: -O -s -o path
 
 	path [ -options ] command [ command... ] 
 
 		find the path of a command
 		if options specified then they are passed through to `ls'


		path  Version 1.0   created by  Mark Keating - 1989
*/

#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <dirent.h>

	DIR				*d_fp;
	struct dirent	*d_ent;
	char			*d_nam;
	char			*ls_opt, ls_buf[256];
	char			*path,   path_list[512];

	char *getenv();

main(argc, argv)
int  argc;
char 	  *argv[];
{
	register int	i, found;
	register char	*ptr;

	if (argc < 2) {
		fprintf(stderr, "Usage: path [-lsopt] command [...]\n");
		exit(1);
	}

	if ((path=getenv("PATH")) == NULL) {
		fprintf(stderr, "PATH not set!\n");
		exit(1);
	}

	for (i=1; i < argc; i++) {
		if (argv[i][0] == '-') {	/* ls option passed */
			ls_opt = argv[i]; continue;
		}

		strcpy(path_list, ".:");  strcat(path_list, path);
		for (ptr = path_list, found = 0;
				!found && (d_nam=strtok(ptr, ":")) != NULL; ptr = NULL) {
			if ((d_fp=opendir(d_nam)) == (DIR *)NULL) {
				perror(d_nam); continue;
			}
			while ((d_ent=readdir(d_fp)) != (struct dirent *)NULL) {
				if (strcmp(d_ent->d_name, argv[i]) == 0) {
					if (ls_opt == NULL) {
						printf("%s/%s\n", d_nam, argv[i]);
					}
					else {
						sprintf(ls_buf, "ls %s %s/%s\n",
											ls_opt, d_nam, argv[i]);
						system(ls_buf);
					}
					found = 1; break;
				}
			}
			closedir(d_fp);
		}
	}
}
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0

mpl@cbnewsl.ATT.COM (michael.p.lindner) (06/16/89)

In article <702@censor.UUCP>, markk@censor.UUCP (Mark Keating) writes:
>    After trying to work on another system I was slightly dissapointed
> to find that there was no 'path' program to be found anywhere.
> So I wrote one  -- hope you find it useful.

I have a program which does just about the same thing.  It is written in
shell.  The difference is it takes an optional path or paths, so it can also
be used for finding things like "where is this #include file found" or
"where is this source file found (by using MAKEPATH).  Here it is.  Enjoy!

Mike Lindner
attunix!mpl

#! /bin/sh
# This is a shell archive, meaning:
# 1. Remove everything above the #! /bin/sh line.
# 2. Save the resulting text in a file.
# 3. Execute the file with /bin/sh (not csh) to create the files:
#	whf.1
#	whf.sh
# This archive created: Fri Jun 16 09:04:06 1989
export PATH; PATH=/bin:$PATH
if test -f 'whf.1'
then
	echo shar: will not over-write existing file "'whf.1'"
else
cat << \SHAR_EOF > 'whf.1'
.TH WHF 1
.SH NAME
whf \- locate a file using a path
.SH SYNOPSIS
whf file [path ...]
.SH DESCRIPTION
.I Whf
will print the location of file by searching each directory in the
given path(s).
If no path is specified, $PATH is used.
If one or more paths are given, each should be a list of
colon separated directories, and are searched left-to-right.
.PP
.SH CREDITS
This utility is functionally an extension of the
.I whf
command I had on my home machine at AT&T Bell Labs.
The source is my own invention, and is not based on anything.
SHAR_EOF
fi # end of overwriting check
if test -f 'whf.sh'
then
	echo shar: will not over-write existing file "'whf.sh'"
else
cat << \SHAR_EOF > 'whf.sh'
# whf - find a file somewhere
# by Michael Lindner
IFS=":$IFS"
case "$#" in
0)
        echo >&2 "usage: $0 file [path ... ]"
        exit 1
        ;;
1)
        file="$1"
        shift
        for d in $PATH
        do
                if [ -s $d/$file ]
                then
                        echo $d/$file
                        exit 0
                fi
        done
        ;;
*)
        file="$1"
        shift
        for d in $*
        do
                if [ -s $d/$file ]
                then
                        echo $d/$file
                        exit 0
                fi
        done
        ;;
esac
echo >&2 "$0: $file not found"
exit 1
SHAR_EOF
fi # end of overwriting check
#	End of shell archive
exit 0

rustcat@csli.Stanford.EDU (Vallury Prabhakar) (06/17/89)

In article <702@censor.UUCP> markk@censor.UUCP (Mark Keating) writes:
% 
% path \- locate the executable for a command

[...]

% will report on the location of
% .I file,
% searching every directory in the path (as defined in the
% $PATH variable), much like the operating system does when searching
% $PATH to execute a program.  It is handy for finding out where in your path
% a command resides. 

[...Source code deleted...]


Is this in any way better or different from the `which' command on BSD 
systems?  Just curious. 

markk@censor.UUCP (Mark Keating) (06/19/89)

I've received several cards 'n letters from some of the folks
out there in netland, about my recent path posting, and no I
don't know how it differs, if at all to the BSC which program,
any clarification here would be appreciated, although I don't
think it's a SYSV thing, I know we don't have it (which) here.

I also recieved a script, and one was posted as well to do the
same thing with the exception that path entries located are
not conditionally passed through `ls', which I find very useful

 ie:		`path path -l path -x path'
 will produce 

	/usr/bin/path
	-rwxr-xr-x   1 root   root    11896 Jun  17 1989 /usr/bin/path
	/usr/bin/path

all the options are passed through 'ls' so more extravagent combinations
could be produced, most useful is 'path -l name', but you probably get
the idea. And yes I know that "ls -l `path path`" would work as well,
just not as convienently or allow changing options along the line.

The thing I liked about the one script was to specify the path, BUT since
everything that is an option, is blindly passed to ls for simplicity,
anybody have a good suggestion on the best way to handle this ??

  Hope I haven't started wars here, or put us on a which path.


				Appreciate the Response.

				Mark Keating  -  markk@censor

mpl@cbnewsl.ATT.COM (michael.p.lindner) (06/20/89)

In article <720@censor.UUCP>, markk@censor.UUCP (Mark Keating) writes:
> 
> I also recieved a script, and one was posted as well to do the
> same thing with the exception that path entries located are
> not conditionally passed through `ls', which I find very useful
> 
> The thing I liked about the one script was to specify the path, BUT since
> everything that is an option, is blindly passed to ls for simplicity,
> anybody have a good suggestion on the best way to handle this ??

simple!  Here's the revised script:

options=
while [ "$#" -gt 0 ]
do
	case "$1" in
	--)
		shift
		break
		;;
	-*)
		options="$options $1"
		shift
		;;
	*)
		break
		;;
	esac
done
IFS=":$IFS"
case "$#" in
0)
        echo >&2 "usage: $0 file [path ... ]"
        exit 1
        ;;
1)
        file="$1"
        shift
        for d in $PATH
        do
                if [ -s $d/$file ]
                then
                        /bin/ls$options $d/$file
                        exit 0
                fi
        done
        ;;
*)
        file="$1"
        shift
        for d in $*
        do
                if [ -s $d/$file ]
                then
                        /bin/ls$options $d/$file
                        exit 0
                fi
        done
        ;;
esac
echo >&2 "$0: $file not found"
exit 1