[net.sources] Source for findp

sra@hocda.UUCP (S.ABBOT) (09/23/83)

Following is the source for a utility "findp" which I wrote.  It will
go through your PATH looking for the executable programs given as its
arguments and print the full path of anything that matches.  Regular
expressions may also be used in the names.  For example, "findp ed*"
will find anything in your path that starts with "ed".  This utility
is very useful when trying to locate a program or optimizing your PATH.

It should be compiled as:
	cc -s -O -lPW findp.c -o findp

					Scott Abbot
					Bell Labs, Merrimack Valley
					hocda!sra or mvuxb!sa

(These lines should be removed before attempting to compile this)


/************************************************************************
 *
 * file: findp.c
 *
 * written by: S. R. Abbot, BTL-MV
 *
 * date: 3/14/83
 *
 * purpose: locate a process within a path
 *
 *   *** must be compiled with the -lPW option ***
 ************************************************************************/

#include <stdio.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/dir.h>
#define FALSE 0
#define TRUE 1
#define MAXBUF 512
char Buf1[MAXBUF];
char Buf2[MAXBUF];
char *Regexp;

main(argc,argv)
	int argc;
	char **argv;
{
	char path[256],directory[100];
	char proc[256],procpath[256];
	char *getenv();
	extern curdir();
	struct direct dirbuf;
	struct stat statbuf;

	int i,j,nflag,found,fd;

	if (argc < 2)
	{
		fprintf(stderr,"usage: findp command ...\n");
		exit(1);
	}


	/* get PATH from environment */
	strcpy(path,getenv("PATH"));
	if (path[0] == '\0')
	{
		fprintf(stderr,"ERROR: No PATH\n");
		exit(1);
	}

	while (--argc > 0)
	{
		if ((*++argv)[0] == '\0')
			exit(0);
		found = 0;
		strcpy(proc,*argv);
		nflag = 0;
		j = 0;

		for (i = 0; nflag == 0; i++)
		{
		    if (path[i] == ':' || path[i] == '\0')
		    {
			directory[j] = '\0';
			if (directory[0] == '\0')
			    curdir(directory);

			    if (stat(directory,&statbuf) == -1)
			    {
				fprintf(stderr,"ERROR: cannot find %s\n",directory);
				exit(1);
			    }
			    if ((fd = open(directory,0)) == -1)
			    {
				fprintf(stderr,"ERROR: cannot open %s\n",directory);
				exit(1);
			    }
			    while(read(fd,(char *)&dirbuf,sizeof(dirbuf)) > 0)
			    {
				if (dirbuf.d_ino == 0)
				    continue;
				if (strcmp(dirbuf.d_name,".") == 0 ||
				    strcmp(dirbuf.d_name,"..") == 0)
				    continue;
				if (wildcard(proc,dirbuf.d_name) == 0)
				{
				    sprintf(procpath,"%s/%s",directory,dirbuf.d_name);
				    /* check status of proc */
				    if (stat(procpath,&statbuf) != -1)
				    {
					if ((statbuf.st_mode & S_IFMT) == S_IFDIR)
					    /* this is a directory */
					    continue;
					if (access(procpath,01) == 0)
					    /* proc exists and is executable */
					{
					    fprintf(stdout,"%s\n",procpath);
					    found = 1;
					}
				    }
				}
			    }
			    if (path[i] == '\0')
				nflag = 1;

			    for (j = 0; j < 100; j++)
				directory[j] = '\0';
			    j = 0;
			}
			else
			{
				directory[j] = path[i];
				j++;
			}
		}
		if (found == 0)
			fprintf(stderr,"%s not found\n",proc);
	}
}

wildcard(word,base)
char *word, *base;
{
	char *bufptr;
	extern char *regex();	/* finction of libPW.a */
	extern void kludge();
	int retval;

	bufptr = Buf1;
	*bufptr++ = '~';	/* stuff "~" at the beginning of string */

	if (!(retval = regexpchk(word)))
	{
		/* no regular expressions in the word,
		   just call strcmp() to see if they are equal */
		return(strcmp(word,base));
	}
	else if (retval > 0)
	{
		strcpy(bufptr,base);
		kludge(bufptr);
		if (regex(Regexp,Buf1,Buf2))
			return(0);	/* match */
		free(Regexp);
	}
	else
	{
		return(-1);
	}
	return(1);
}

regexpchk(token)
char *token;
{
	char *bufptr;
	extern char *regcmp();
	int exp;

	exp = FALSE;
	bufptr = Buf2;
	*bufptr++ = '(';
	*bufptr++ = '~';
	while (*token)
		switch(*token)
		{
			case '*':
				/* convert "*" to ".*" */
				exp = TRUE;
				*bufptr++ = '.';
				*bufptr++ = '*';
				token++;
				break;
			case '?':
				/* convert "?" to "." */
				exp = TRUE;
				*bufptr++ = '.';
				token++;
				break;
			default:
				*bufptr++ = *token++;
		}
	if (!exp)
		return(0);
	*bufptr = NULL;
	strcat(Buf2,"~)$0");
	if ((Regexp = regcmp(Buf2,0)) == NULL)
	{
		return(-1);
	}
	return(1);
}

void
kludge(str)
char *str;
{
	for (;;)
		switch(*str)
		{
			case '\0':
				*str++ = '~';
				*str = '\0';
				return;
			case ' ':
				*str = '~';
				return;
			default:
				str++;
		}
}