mjr@welchsun2.UUCP (Marcus J. Ranum) (05/25/88)
comp.sources.misc: Volume 3, Issue 24 Submitted-By: "Marcus J. Ranum" <mjr@welchsun2.UUCP> Archive-Name: which A really quickie version of the 'which(ucb)' command. No excuses for the looks, but it runs and is (as far as I can tell) "compatible" and a lot faster than having to invoke the C-shell. For SYSV compile it with -DSYSV - I think it should work. uunet!mimsy!aplcen!osiris!welchvax!mjr mjr@jhuigf.BITNET -------cut------cut--------cut--------cut--------cut--------cut------- #ifndef lint static char *RCSid="$Header: which.c,v 1.2 88/05/24 19:29:53 mjr Exp $"; #endif /* * Marcus Ranum, December 10, 1987 - a really fast and dirty hack- * VERY tired of waiting for that idiot C shell script. * actually this code is hacked from several of my other programs, * hence the incoherence. */ #include <stdio.h> #include <sys/types.h> #include <sys/stat.h> #include <sys/param.h> char *path = 0; static void prpath(str) char *str; { char *cp = str; while(cp && *cp) { if(*cp == ':') putchar(' '); else putchar(*cp); cp++; } putchar('\n'); } main(ac,av) int ac; char *av[]; { int ret; extern char *getenv(); if((path = getenv("PATH")) == NULL) { (void)fprintf(stderr,"no PATH in environment\n"); exit(1); } for(ret =1; ret < ac; ret++){ char *todo, *xpath(); if(!(todo = xpath(av[ret]))) { (void)printf("no \"%s\" in ",av[ret]); prpath(path); } else { puts(todo); } } exit(0); } static char * xpath(exe) char *exe; { char *ptr, *doxpath(); #ifndef SYSV extern char *index(); #else extern char *strchr(); #endif /* read the path and search for the first thing that matches */ /* the name of the program */ /* first check if absolute or relative path */ #ifndef SYSV if(exe[0] == '/' || index(exe, '/')) #else if(exe[0] == '/' || strchr(exe, '/')) #endif return(doxpath(exe)); ptr = path; /* somewhat gnarly */ while(*ptr) { char pbuf[MAXPATHLEN]; /* thing to build path in */ char *p = pbuf, *p2 = exe; while(*ptr && *ptr != ':') *p++ = *ptr++; *p++ = '/'; while(*p2) *p++ = *p2++; *p++ = '\0'; if (p2 = doxpath(pbuf)) return(p2); if(*ptr == ':') ptr++; } return((char *)NULL); } static char * doxpath(path) char *path; { struct stat sbuf; if (!stat(path, &sbuf)) if ((sbuf.st_mode & S_IFMT) == S_IFREG && (sbuf.st_mode & ~S_IFMT & S_IEXEC)) return(path); return((char *) 0); }