From owner-freebsd-bugs Thu Dec 13 9:40:21 2001 Delivered-To: freebsd-bugs@hub.freebsd.org Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id E899437B417 for ; Thu, 13 Dec 2001 09:40:00 -0800 (PST) Received: (from gnats@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id fBDHe0T30358; Thu, 13 Dec 2001 09:40:00 -0800 (PST) (envelope-from gnats) Received: from freefall.freebsd.org (freefall.FreeBSD.org [216.136.204.21]) by hub.freebsd.org (Postfix) with ESMTP id 1578137B41C for ; Thu, 13 Dec 2001 09:39:02 -0800 (PST) Received: (from nobody@localhost) by freefall.freebsd.org (8.11.6/8.11.6) id fBDHd2h30268; Thu, 13 Dec 2001 09:39:02 -0800 (PST) (envelope-from nobody) Message-Id: <200112131739.fBDHd2h30268@freefall.freebsd.org> Date: Thu, 13 Dec 2001 09:39:02 -0800 (PST) From: Peter Sanchez To: freebsd-gnats-submit@FreeBSD.org X-Send-Pr-Version: www-1.0 Subject: bin/32807: which utility replacement in C 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 >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 #include #include #include #include #include #include #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