From owner-freebsd-bugs Sun Mar 10 7:46:25 2002 Delivered-To: freebsd-bugs@freebsd.org Received: from sushi.linuxforlesbians.org (bgp01357202bgs.albqrq01.nm.comcast.net [68.35.149.200]) by hub.freebsd.org (Postfix) with ESMTP id C734137B41A; Sun, 10 Mar 2002 07:46:15 -0800 (PST) Received: by sushi.linuxforlesbians.org (Postfix, from userid 1001) id 2705719BA; Sun, 10 Mar 2002 08:51:40 -0700 (MST) Date: Sun, 10 Mar 2002 08:51:40 -0700 From: Peter Sanchez To: wolfram schneider , freebsd-bugs@FreeBSD.org Subject: Re: bin/35719: which(1) ignore empty components of $PATH. Message-ID: <20020310085139.B52034@sushi.linuxforlesbians.org> References: <200203092323.g29NNsl91233@freefall.freebsd.org> Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i In-Reply-To: <200203092323.g29NNsl91233@freefall.freebsd.org>; from wosch@FreeBSD.org on Sat, Mar 09, 2002 at 03:23:54PM -0800 Sender: owner-freebsd-bugs@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.org 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 */ #ifndef lint static const char rcsid[] = "$FreeBSD$"; #endif /* not lint */ #include #include #include #include #include #include #include #include #include #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