Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 14 Dec 2001 19:22:42 -0700
From:      Peter Sanchez <fut0n@linuxforlesbians.org>
To:        Dag-Erling Smorgrav <des@ofug.org>
Cc:        freebsd-bugs@freebsd.org
Subject:   Re: bin/32807: which utility replacement in C
Message-ID:  <20011214192242.C38914@sushi.linuxforlesbians.org>
In-Reply-To: <xzpzo4lwer4.fsf@flood.ping.uio.no>; from des@ofug.org on Sat, Dec 15, 2001 at 12:42:07AM %2B0100
References:  <200112132100.fBDL01r64612@freefall.freebsd.org> <Pine.NEB.3.96L.1011214061809.83145A-100000@fledge.watson.org> <20011214070038.B38914@sushi.linuxforlesbians.org> <xzpd71hyhfi.fsf@flood.ping.uio.no> <20011214143727.A41700@sushi.linuxforlesbians.org> <xzpzo4lwer4.fsf@flood.ping.uio.no>

next in thread | previous in thread | raw e-mail | index | archive | help

--PNTmBPCT7hxwcZjr
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
Content-Transfer-Encoding: quoted-printable

heh, old habits die hard. Here is the final copy :) *whew* and I thought
this was gonna be easy heh.

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=20
 * 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[] =3D "$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 =3D NULL;
int found =3D 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 =3D stat(file, &info);
        if (check =3D=3D -1)
                return check; /* file doesnt exist */

        return (info.st_mode & S_IFREG && access(file, X_OK) =3D=3D 0) ? ch=
eck : -1;
}

void
losepath(void)
{
        struct pathinfo *tmp;

        while (all !=3D NULL) {
                tmp =3D all->next;
                free(all);
                all =3D tmp;
        }
}

void
findpath(void)
{
        struct pathinfo *cur =3D NULL;
        char *userpath =3D getenv("PATH");
   =20
        if (userpath =3D=3D NULL || strlen(userpath) =3D=3D 0)
                errx(EX_OSERR, "No PATH variable.");

        all =3D (struct pathinfo *)malloc(sizeof(struct pathinfo));
        if (all =3D=3D NULL)
                err(EX_OSERR, (char *)NULL);
                /* NOTREACHED */

        cur =3D all;

        while ((cur->path =3D strsep(&userpath, ":")) !=3D NULL) {
                cur->next =3D (struct pathinfo *)malloc(sizeof(struct pathi=
nfo));
                if (cur->next =3D=3D NULL) {
                        losepath();
                        err(EX_OSERR, (char *)NULL);
                        /* NOTREACHED */
                }

                if (strlen(cur->path) =3D=3D 0)
                        warnx("PATH element of 0 length.");

                cur =3D cur->next;
        }
        cur->next =3D NULL;
        cur =3D all;
}

void
findprog(char *prog, int aflag, int sflag)
{
        struct pathinfo *tmp;
        char *tmpbuf;

        tmp =3D all;
        while (all !=3D NULL) {
                if (all->path =3D=3D NULL)
                        break;
                if (strchr(prog, '/'))
                        tmpbuf =3D strdup(prog);
                else {
                        tmpbuf =3D malloc(sizeof(char) * (strlen(all->path)=
 + strlen(prog) + 1));
                        if (tmpbuf =3D=3D NULL) {
                                losepath();
                                err(EX_OSERR, (char *)NULL);
                                /* NOTREACHED */
                        }
                        sprintf(tmpbuf,"%s/%s",all->path,prog);
                }

                if (file_exists(tmpbuf) =3D=3D 0) {
                        found =3D 0;
                        if (sflag && aflag) ;
                        else if (sflag && !aflag) {
                                all =3D tmp;
                                free(tmpbuf);
                                return;
                        }
                        else if (aflag && !sflag)
                                (void)printf("%s\n", tmpbuf);
                        else {
                                (void)printf("%s\n", tmpbuf);
                                all =3D tmp;
                                free(tmpbuf);
                                return;
                        }
                }
                all =3D all->next;
                free(tmpbuf);
        }
        all =3D tmp;
}

int
main(int argc, char *argv[])
{
        char ch;
        int aflag, sflag, i;

        aflag =3D sflag =3D 0;
        if (argc < 2)
                exit(EX_USAGE);
      =20
        while ((ch =3D getopt(argc, argv, "ash?")) !=3D -1) {
                switch (ch) {
                        case 'a':
                                aflag =3D 1;
                                break;
			case 's':
                                sflag =3D 1;
                                break;
                        case 'h':
                        case '?':
                        default:
                                usage();
                                /* NOTREACHED */
                }
        }
        argc -=3D optind;
        argv +=3D optind;
   =20
        findpath();
        for (i =3D 0; i < argc; i++)
                findprog(argv[i], aflag, sflag);
   =20
        losepath();
        return sflag ? found : 0;
}

On Sat, Dec 15, 2001 at 12:42:07AM +0100, Dag-Erling Smorgrav wrote:
> Peter Sanchez <fut0n@linuxforlesbians.org> writes:
> > Struct rules, but understandable. I like the style(9) format, makes it
> > look much more structured and readable. Here ya go, I hope this is what
> > you had in mind.
>=20
> Yes, much better!  Though the explicit "return" from void functions
> isn't necessary.
>=20
> DES
> --=20
> Dag-Erling Smorgrav - des@ofug.org

--=20
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

--PNTmBPCT7hxwcZjr
Content-Type: application/pgp-signature
Content-Disposition: inline

-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.0.6 (FreeBSD)
Comment: For info see http://www.gnupg.org

iEYEARECAAYFAjwas/IACgkQQ2cuXVjoDlvmHgCghtpFWxAby8UGVfyyYYPBjYXd
XP0An3NQgIWgXBQbfNb76QFoNB++Ycqa
=tMqk
-----END PGP SIGNATURE-----

--PNTmBPCT7hxwcZjr--

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?20011214192242.C38914>