Date: Sun, 30 Dec 2001 08:21:50 -0700 From: Peter Sanchez <fut0n@linuxforlesbians.org> To: Sheldon Hearn <sheldonh@starjuice.net> Cc: freebsd-bugs@freebsd.org Subject: Re: bin/32807: which utility replacement in C Message-ID: <20011230082150.C17916@sushi.linuxforlesbians.org> In-Reply-To: <89022.1009717138@axl.seasidesoftware.co.za>; from sheldonh@starjuice.net on Sun, Dec 30, 2001 at 02:58:58PM %2B0200 References: <xzpzo4lwer4.fsf@flood.ping.uio.no> <89022.1009717138@axl.seasidesoftware.co.za>
next in thread | previous in thread | raw e-mail | index | archive | help
> On 15 Dec 2001 00:42:07 +0100, Dag-Erling Smorgrav wrote:
>
> Since you've been driving the review process, will you don an asbestos
> suit and use this one to kill the existing perl script? :-)
LOL. Im the one being killed over here ;)
> Note that there's a malloc() that isn't tested for failure, but it's
> hidden in a strdup(). This is in findprog().
>
> Ciao,
> Sheldon.
Here ya go...
Peter
/*
* which - a which utility for Unix
*
* SYNOPSIS: For FreeBSD-4.x and later
*
* DESCRIPTION:
* Utility to get the full system path of an executable in the
* users PATH environment variable.
*
* Works for:
* FreeBSD 4.x and probably most earlier versions
*
* AUTHOR: Peter Sanchez <psanchez@packet-addiction.org>
*/
#ifndef lint
static const char rcsid[] = "$FreeBSD$";
#endif /* not lint */
#include <sys/types.h>
#include <sys/stat.h>
#include <err.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <pwd.h>
#include <sysexits.h>
#define NGROUPS 15
struct pathinfo {
struct pathinfo *next;
char *path;
};
struct pathinfo *all = NULL;
int found = 1;
void
usage(void)
{
(void)fprintf(stderr, "usage: which [-a] [-s] program ...\n");
exit(EX_USAGE);
}
int
file_exists(char *file)
{
struct stat info;
int check;
check = stat(file, &info);
if (check == -1)
return check; /* file doesnt exist */
return (info.st_mode & S_IFREG && access(file, X_OK) == 0) ? check : -1;
}
void
losepath(void)
{
struct pathinfo *tmp;
while (all != NULL) {
tmp = all->next;
free(all);
all = tmp;
}
}
void
findpath(void)
{
struct pathinfo *cur = NULL;
char *userpath = getenv("PATH");
if (userpath == NULL || strlen(userpath) == 0)
errx(EX_OSERR, "No PATH variable.");
all = (struct pathinfo *)malloc(sizeof(struct pathinfo));
if (all == NULL)
err(EX_OSERR, (char *)NULL);
/* NOTREACHED */
cur = all;
while ((cur->path = strsep(&userpath, ":")) != NULL) {
cur->next = (struct pathinfo *)malloc(sizeof(struct pathinfo));
if (cur->next == NULL) {
losepath();
err(EX_OSERR, (char *)NULL);
/* NOTREACHED */
}
if (strlen(cur->path) == 0)
warnx("PATH element of 0 length.");
cur = cur->next;
}
cur->next = NULL;
cur = all;
}
void
findprog(char *prog, int aflag, int sflag)
{
struct pathinfo *tmp;
char *tmpbuf;
tmp = all;
while (all != NULL) {
if (all->path == NULL)
break;
if (strchr(prog, '/')) {
tmpbuf = strdup(prog);
if (tmpbuf == NULL) {
losepath();
err(EX_OSERR, (char *)NULL);
/* NOTREACHED */
}
}
else {
tmpbuf = malloc(strlen(all->path) + (strlen(prog) + 1));
if (tmpbuf == NULL) {
losepath();
err(EX_OSERR, (char *)NULL);
/* NOTREACHED */
}
sprintf(tmpbuf, "%s/%s", all->path, prog);
}
if (file_exists(tmpbuf) == 0) {
found = 0;
if (sflag && aflag) ;
else if (sflag && !aflag) {
all = tmp;
free(tmpbuf);
return;
}
else if (aflag && !sflag)
(void)printf("%s\n", tmpbuf);
else {
(void)printf("%s\n", tmpbuf);
all = tmp;
free(tmpbuf);
return;
}
}
all = all->next;
free(tmpbuf);
}
all = tmp;
}
int
main(int argc, char *argv[])
{
char ch;
int aflag, sflag, i;
aflag = sflag = 0;
if (argc < 2)
exit(EX_USAGE);
while ((ch = getopt(argc, argv, "ash?")) != -1) {
switch (ch) {
case 'a':
aflag = 1;
break;
case 's':
sflag = 1;
break;
case 'h':
case '?':
default:
usage();
/* NOTREACHED */
}
}
argc -= optind;
argv += optind;
findpath();
for (i = 0; i < argc; i++)
findprog(argv[i], aflag, sflag);
losepath();
return sflag ? found : 0;
}
--
Peter Sanchez, aka fut0n | "The ability to read is what
- fut0n@linuxforlesbians.org | distinguishes Unix users from
- www.linuxforlesbians.org | those of more popular platforms."
- FreeBSD or DIE | - John Lasser
To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20011230082150.C17916>
