Date: Thu, 13 Dec 2001 09:39:02 -0800 (PST) From: Peter Sanchez <fut0n@linuxforlesbians.org> To: freebsd-gnats-submit@FreeBSD.org Subject: bin/32807: which utility replacement in C Message-ID: <200112131739.fBDHd2h30268@freefall.freebsd.org>
next in thread | raw e-mail | index | archive | help
>Number: 32807
>Category: bin
>Synopsis: which utility replacement in C
>Confidential: no
>Severity: non-critical
>Priority: low
>Responsible: freebsd-bugs
>State: open
>Quarter:
>Keywords:
>Date-Required:
>Class: change-request
>Submitter-Id: current-users
>Arrival-Date: Thu Dec 13 09:40:00 PST 2001
>Closed-Date:
>Last-Modified:
>Originator: Peter Sanchez
>Release: 4.4-STABLE
>Organization:
>Environment:
FreeBSD char.linuxforlesbians.org 4.4-STABLE FreeBSD 4.4-STABLE #0: Thu Nov 22 14:19:15 MST 2001 root@char.linuxforlesbians.org:/usr/src/sys/compile/CHAR i386
>Description:
Just a simple C program to replace the perl which utility that comes
default at /usr/bin/which (/usr/src/usr.bin/which). Its slighly faster
than the perl version.
>How-To-Repeat:
N/A
>Fix:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <pwd.h>
#define NGROUPS 15
struct pathinfo
{
char path[1024];
struct pathinfo *next;
};
struct pathinfo *all = NULL;
struct passwd *pw;
uid_t uid;
int found = 1, gfail = 0;
int groups[NGROUPS + 1], ngroups = (NGROUPS + 1);
void
printusage(bin)
char *bin;
{
fprintf(stderr,"usage: %s [-a] [-s] program ...\n",bin);
return;
}
int
file_exists(file)
char *file;
{
struct stat info;
int check, i;
check = stat(file,&info);
if(check == -1)
return check; /* file doesnt exist */
if(S_ISDIR(info.st_mode))
return -1; /* file is a directory */
/*
* I did not use access() here cause of man page warnings that
* it is a potential security risk and shoule NEVER be used. Not
* quit sure on how it can be a security risk, but I worked around
* it anyways.
*/
if(info.st_uid == uid && info.st_mode & S_IFREG && info.st_mode & S_IXUSR)
return check; /* user executable */
if(gfail)
{
if(info.st_gid == pw->pw_gid && info.st_mode & S_IFREG &&
info.st_mode & S_IXGRP)
return check; /* group executable */
}
else
{
for(i = 0; i < ngroups; i++)
{
if(info.st_gid == groups[i] && info.st_mode & S_IFREG &&
info.st_mode & S_IXGRP)
return check; /* group executable */
}
}
if(info.st_mode & S_IFREG && info.st_mode & S_IXOTH)
return check; /* other executable */
else
return -1;
}
void
losepath(void)
{
struct pathinfo *tmp;
while(all != NULL)
{
tmp = all->next;
free(all);
all = tmp;
}
return;
}
void
findpath(void)
{
struct pathinfo *cur = NULL;
char *userpath = getenv("PATH");
int i, x;
if(userpath == NULL)
exit(1);
all = (struct pathinfo *)malloc((unsigned)sizeof(struct pathinfo));
if(all == NULL)
{
fprintf(stderr,"Out of memory, malloc() failed!\n");
exit(1);
}
cur = all;
for(i = 0, x = 0; i < strlen(userpath); i++)
{
if(userpath[i] == ':')
{
cur->path[x] = '\0';
x = 0;
cur->next = (struct pathinfo *)malloc((unsigned)sizeof(struct pathinfo));
if(cur->next == NULL)
{
losepath();
fprintf(stderr,"Out of memory, malloc() failed!\n");
exit(1);
}
cur = cur->next;
}
else
cur->path[x++] = userpath[i];
}
cur->path[x] = '\0';
cur->next = NULL;
cur = all;
return;
}
void
findprog(prog, aflag, sflag)
char *prog;
int aflag;
int sflag;
{
struct pathinfo *tmp;
char tmpbuf[2048];
tmp = all;
while(all != NULL)
{
if(strchr(prog,'/'))
strncpy(tmpbuf,prog,2048);
else
snprintf(tmpbuf,2048,"%s/%s",all->path,prog);
if(!file_exists(tmpbuf))
{
found = 0;
if(sflag && aflag) ;
else if(sflag && !aflag)
{
all = tmp;
return;
}
else if(aflag && !sflag)
printf("%s\n",tmpbuf);
else
{
printf("%s\n",tmpbuf);
all = tmp;
return;
}
}
all = all->next;
}
all = tmp;
return;
}
int
main(argc, argv)
int argc;
char *argv[];
{
char buf[1024];
int aflag, sflag, pass, i;
aflag = sflag = pass = 0;
if(argc < 2)
return 1;
if(!strncmp(argv[1],"-h",2) || !strncmp(argv[1],"--h",3) ||
!strcmp(argv[1],"?"))
{
printusage(argv[0]);
return 1;
}
uid = getuid();
pw = getpwuid(uid);
if(getgrouplist(pw->pw_name,pw->pw_gid,groups,&ngroups) == -1)
gfail = 1;
findpath();
for(i = 1; i < argc; i++)
{
if(!pass && *argv[i] == '-')
{
if(!strcmp(argv[i],"-a"))
aflag = 1;
else if(!strcmp(argv[i],"-s"))
sflag = 1;
else
{
printusage(argv[0]);
return 1;
}
continue;
}
pass = 1;
strncpy(buf,argv[i],1024);
findprog(buf,aflag,sflag);
}
losepath();
return sflag ? found : 0;
}
>Release-Note:
>Audit-Trail:
>Unformatted:
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?200112131739.fBDHd2h30268>
