Date: Sun, 10 Mar 2002 08:51:40 -0700 From: Peter Sanchez <fut0n@linuxforlesbians.org> To: wolfram schneider <wosch@FreeBSD.org>, freebsd-bugs@FreeBSD.org Subject: Re: bin/35719: which(1) ignore empty components of $PATH. Message-ID: <20020310085139.B52034@sushi.linuxforlesbians.org> In-Reply-To: <200203092323.g29NNsl91233@freefall.freebsd.org>; from wosch@FreeBSD.org on Sat, Mar 09, 2002 at 03:23:54PM -0800 References: <200203092323.g29NNsl91233@freefall.freebsd.org>
next in thread | previous in thread | raw e-mail | index | archive | help
I wrote a which(1) replacement in C but the current version in -current
already was committed. My version addressed all the issues you posted
about -current which(1). Here is my code again, maybe the gods will take
another peak at it:
/*
* 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->path = ".";
}
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;
}
On Sat, Mar 09, 2002 at 03:23:54PM -0800, wolfram schneider wrote:
>
> >Number: 35719
> >Category: bin
> >Synopsis: which(1) ignore empty components of $PATH.
> >Confidential: no
> >Severity: non-critical
> >Priority: low
> >Responsible: freebsd-bugs
> >State: open
> >Quarter:
> >Keywords:
> >Date-Required:
> >Class: sw-bug
> >Submitter-Id: current-users
> >Arrival-Date: Sat Mar 09 15:30:00 PST 2002
> >Closed-Date:
> >Last-Modified:
> >Originator: wolfram schneider
> >Release:
> >Organization:
> >Environment:
> >Description:
> The new c version of which(1) command
> ignore empty components of $PATH.
>
> $ cd /bin
> $ env PATH=: which date
> $ echo $?
> 1
>
>
> It should print:
> ./date
> >How-To-Repeat:
>
> >Fix:
>
> >Release-Note:
> >Audit-Trail:
> >Unformatted:
>
> To Unsubscribe: send mail to majordomo@FreeBSD.org
> with "unsubscribe freebsd-bugs" in the body of the message
--
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?20020310085139.B52034>
