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++; } }