summaryrefslogtreecommitdiff
path: root/which.c
diff options
context:
space:
mode:
authortim <tim>1997-05-14 15:30:41 +0000
committerToby Goodwin <toby@paccrat.org>2015-05-16 21:23:00 +0100
commit53cf1b1c1c3f0c2b5067afccc2976b99a574a089 (patch)
treea31f167c3779362e29ab377d662052b6257253a8 /which.c
parentb87bfedf65c289bf0ee5338c9e10492b70b1e8e0 (diff)
Initial revision
Diffstat (limited to 'which.c')
-rw-r--r--which.c121
1 files changed, 0 insertions, 121 deletions
diff --git a/which.c b/which.c
deleted file mode 100644
index 372cc92..0000000
--- a/which.c
+++ /dev/null
@@ -1,121 +0,0 @@
-/* which.c: check to see if a file is executable.
-
- This function was originally written with Maarten Litmaath's which.c as
- a template, but was changed in order to accomodate the possibility of
- rc's running setuid or the possibility of executing files not in the
- primary group. Much of this file has been re-vamped by Paul Haahr.
- I re-re-vamped the functions that Paul supplied to correct minor bugs
- and to strip out unneeded functionality.
-*/
-
-#include "rc.h"
-#include <errno.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <unistd.h>
-
-#define X_USR 0100
-#define X_GRP 0010
-#define X_OTH 0001
-#define X_ALL (X_USR|X_GRP|X_OTH)
-
-extern int stat(const char *, struct stat *);
-
-static bool initialized = FALSE;
-static uid_t uid;
-static gid_t gid;
-
-#if HAVE_GETGROUPS
-static int ngroups;
-static GETGROUPS_T *gidset;
-
-/* determine whether gid lies in gidset */
-
-static int ingidset(gid_t g) {
- gid_t i;
- for (i = 0; i < ngroups; ++i)
- if (g == gidset[i])
- return 1;
- return 0;
-}
-#endif
-
-/*
- A home-grown access/stat. Does the right thing for group-executable files.
- Returns a bool instead of this -1 nonsense.
-*/
-
-static bool rc_access(char *path, bool verbose) {
- struct stat st;
- int mask;
- if (stat(path, &st) != 0) {
- if (verbose) /* verbose flag only set for absolute pathname */
- uerror(path);
- return FALSE;
- }
- if (uid == 0)
- mask = X_ALL;
- else if (uid == st.st_uid)
- mask = X_USR;
-#if HAVE_GETGROUPS
- else if (gid == st.st_gid || ingidset(st.st_gid))
-#else
- else if (gid == st.st_gid)
-#endif
- mask = X_GRP;
- else
- mask = X_OTH;
- if (((st.st_mode & S_IFMT) == S_IFREG) && (st.st_mode & mask))
- return TRUE;
- errno = EACCES;
- if (verbose)
- uerror(path);
- return FALSE;
-}
-
-/* return a full pathname by searching $path, and by checking the status of the file */
-
-extern char *which(char *name, bool verbose) {
- static char *test = NULL;
- static size_t testlen = 0;
- List *path;
- int len;
- if (name == NULL) /* no filename? can happen with "> foo" as a command */
- return NULL;
- if (!initialized) {
- initialized = TRUE;
- uid = geteuid();
- gid = getegid();
-#if HAVE_GETGROUPS
- ngroups = getgroups(0, (gid_t *)0);
- gidset = malloc(ngroups * sizeof(gid_t));
- if (!gidset)
- uerror("malloc");
- else
- getgroups(ngroups, gidset);
-#endif
- }
- if (isabsolute(name)) /* absolute pathname? */
- return rc_access(name, verbose) ? name : NULL;
- len = strlen(name);
- for (path = varlookup("path"); path != NULL; path = path->n) {
- size_t need = strlen(path->w) + len + 2; /* one for null terminator, one for the '/' */
- if (testlen < need) {
- efree(test);
- test = ealloc(testlen = need);
- }
- if (*path->w == '\0') {
- strcpy(test, name);
- } else {
- strcpy(test, path->w);
- if (!streq(test, "/")) /* "//" is special to POSIX */
- strcat(test, "/");
- strcat(test, name);
- }
- if (rc_access(test, FALSE))
- return test;
- }
- if (verbose)
- fprint(2, "%s not found\n", name);
- return NULL;
-}