summaryrefslogtreecommitdiff
path: root/src/lib/libast/path/pathshell.c
diff options
context:
space:
mode:
authorIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
committerIgor Pashev <pashev.igor@gmail.com>2012-06-24 22:28:35 +0000
commit3950ffe2a485479f6561c27364d3d7df5a21d124 (patch)
tree468c6e14449d1b1e279222ec32f676b0311917d2 /src/lib/libast/path/pathshell.c
downloadksh-upstream.tar.gz
Imported Upstream version 93u+upstream
Diffstat (limited to 'src/lib/libast/path/pathshell.c')
-rw-r--r--src/lib/libast/path/pathshell.c112
1 files changed, 112 insertions, 0 deletions
diff --git a/src/lib/libast/path/pathshell.c b/src/lib/libast/path/pathshell.c
new file mode 100644
index 0000000..f4b2557
--- /dev/null
+++ b/src/lib/libast/path/pathshell.c
@@ -0,0 +1,112 @@
+/***********************************************************************
+* *
+* This software is part of the ast package *
+* Copyright (c) 1985-2011 AT&T Intellectual Property *
+* and is licensed under the *
+* Eclipse Public License, Version 1.0 *
+* by AT&T Intellectual Property *
+* *
+* A copy of the License is available at *
+* http://www.eclipse.org/org/documents/epl-v10.html *
+* (with md5 checksum b35adb5213ca9657e911e9befb180842) *
+* *
+* Information and Software Systems Research *
+* AT&T Research *
+* Florham Park NJ *
+* *
+* Glenn Fowler <gsf@research.att.com> *
+* David Korn <dgk@research.att.com> *
+* Phong Vo <kpv@research.att.com> *
+* *
+***********************************************************************/
+#pragma prototyped
+/*
+ * G. S. Fowler
+ * D. G. Korn
+ * AT&T Bell Laboratories
+ *
+ * shell library support
+ */
+
+#include <ast.h>
+#include <sys/stat.h>
+
+/*
+ * return pointer to the full path name of the shell
+ *
+ * SHELL is read from the environment and must start with /
+ *
+ * if set-uid or set-gid then the executable and its containing
+ * directory must not be owned by the real user/group
+ *
+ * root/administrator has its own test
+ *
+ * astconf("SH",NiL,NiL) is returned by default
+ *
+ * NOTE: csh is rejected because the bsh/csh differentiation is
+ * not done for `csh script arg ...'
+ */
+
+char*
+pathshell(void)
+{
+ register char* sh;
+ int ru;
+ int eu;
+ int rg;
+ int eg;
+ struct stat st;
+
+ static char* val;
+
+ if ((sh = getenv("SHELL")) && *sh == '/' && strmatch(sh, "*/(sh|*[!cC]sh)*([[:digit:]])?(-+([.[:alnum:]]))?(.exe)"))
+ {
+ if (!(ru = getuid()) || !eaccess("/bin", W_OK))
+ {
+ if (stat(sh, &st))
+ goto defshell;
+ if (ru != st.st_uid && !strmatch(sh, "?(/usr)?(/local)/?([ls])bin/?([[:lower:]])sh?(.exe)"))
+ goto defshell;
+ }
+ else
+ {
+ eu = geteuid();
+ rg = getgid();
+ eg = getegid();
+ if (ru != eu || rg != eg)
+ {
+ char* s;
+ char dir[PATH_MAX];
+
+ s = sh;
+ for (;;)
+ {
+ if (stat(s, &st))
+ goto defshell;
+ if (ru != eu && st.st_uid == ru)
+ goto defshell;
+ if (rg != eg && st.st_gid == rg)
+ goto defshell;
+ if (s != sh)
+ break;
+ if (strlen(s) >= sizeof(dir))
+ goto defshell;
+ strcpy(dir, s);
+ if (!(s = strrchr(dir, '/')))
+ break;
+ *s = 0;
+ s = dir;
+ }
+ }
+ }
+ return sh;
+ }
+ defshell:
+ if (!(sh = val))
+ {
+ if (!*(sh = astconf("SH", NiL, NiL)) || *sh != '/' || eaccess(sh, X_OK) || !(sh = strdup(sh)))
+ sh = "/bin/sh";
+ val = sh;
+ }
+ return sh;
+}