2.11BSD/src/bin/csh/sh.exec2.c
/*
* From the 4.4-Lite2 CD's csh sources and modified appropriately.
*/
#if !defined(lint) && defined(DOSCCS)
static char *sccsid = "@(#)sh.exec2.c 1.0 (2.11BSD) 1996/9/20";
#endif
#include "sh.h"
#include <string.h>
#include <sys/file.h>
#include <sys/stat.h>
#include <sys/dir.h>
#include "sh.exec.h"
extern char *justabs[]; /* in sh.exec.c */
static int
iscommand(name)
char *name;
{
register char **pv;
register char *sav;
register struct varent *v;
bool slash = any(name, '/');
int hashval = 0, hashval1, i;
v = adrof("path");
if (v == 0 || v->vec[0] == 0 || slash)
pv = justabs;
else
pv = v->vec;
sav = strspl("/", name); /* / command name for postpending */
if (havhash)
hashval = hashname(name);
i = 0;
do {
if (!slash && pv[0][0] == '/' && havhash) {
hashval1 = hash(hashval, i);
if (!bit(xhash, hashval1))
goto cont;
}
if (pv[0][0] == 0 || eq(pv[0], ".")) { /* don't make ./xxx */
if (executable(NULL, name, 0)) {
xfree(sav);
return i + 1;
}
}
else {
if (executable(*pv, sav, 0)) {
xfree(sav);
return i + 1;
}
}
cont:
pv++;
i++;
} while (*pv);
xfree(sav);
return 0;
}
/* Also by:
* Andreas Luik <luik@isaak.isa.de>
* I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
* Azenberstr. 35
* D-7000 Stuttgart 1
* West-Germany
* is the executable() routine below and changes to iscommand().
* Thanks again!!
*/
/*
* executable() examines the pathname obtained by concatenating dir and name
* (dir may be NULL), and returns 1 either if it is executable by us, or
* if dir_ok is set and the pathname refers to a directory.
* This is a bit kludgy, but in the name of optimization...
*/
static int
executable(dir, name, dir_ok)
char *dir, *name;
bool dir_ok;
{
struct stat stbuf;
char path[MAXPATHLEN + 1];
register char *dp, *sp;
char *strname;
if (dir && *dir) {
for (dp = path, sp = dir; *sp; *dp++ = *sp++)
if (dp == &path[MAXPATHLEN + 1]) {
*--dp = '\0';
break;
}
for (sp = name; *sp; *dp++ = *sp++)
if (dp == &path[MAXPATHLEN + 1]) {
*--dp = '\0';
break;
}
*dp = '\0';
strname = path;
}
else
strname = name;
return (stat(strname, &stbuf) != -1 &&
((S_ISREG(stbuf.st_mode) &&
/* save time by not calling access() in the hopeless case */
(stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) &&
access(strname, X_OK) == 0) ||
(dir_ok && S_ISDIR(stbuf.st_mode))));
}
/* The dowhich() is by:
* Andreas Luik <luik@isaak.isa.de>
* I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
* Azenberstr. 35
* D-7000 Stuttgart 1
* West-Germany
* Thanks!!
*/
/*ARGSUSED*/
void
dowhich(v, c)
register char **v;
struct command *c;
{
struct wordent lex[3];
struct varent *vp;
lex[0].next = &lex[1];
lex[1].next = &lex[2];
lex[2].next = &lex[0];
lex[0].prev = &lex[2];
lex[1].prev = &lex[0];
lex[2].prev = &lex[1];
lex[0].word = "";
lex[2].word = "\n";
while (*++v) {
if ((vp = adrof1(*v, &aliases)) != NULL) {
(void) printf("%s: \t aliased to ", *v);
blkpr(vp->vec);
(void) putchar('\n');
}
else {
lex[1].word = *v;
tellmewhat(lex);
}
}
}
static void
tellmewhat(lex)
struct wordent *lex;
{
int i;
struct biltins *bptr;
register struct wordent *sp = lex->next;
bool aliased = 0;
register char *s2;
char *s0, *s1, *cmd;
char qc;
if (adrof1(sp->word, &aliases)) {
alias(lex);
sp = lex->next;
aliased = 1;
}
s0 = sp->word; /* to get the memory freeing right... */
/* handle quoted alias hack */
if ((*(sp->word) & (QUOTE | TRIM)) == QUOTE)
(sp->word)++;
/* do quoting, if it hasn't been done */
s1 = s2 = sp->word;
while (*s2)
switch (*s2) {
case '\'':
case '"':
qc = *s2++;
while (*s2 && *s2 != qc)
*s1++ = *s2++ | QUOTE;
if (*s2)
s2++;
break;
case '\\':
if (*++s2)
*s1++ = *s2++ | QUOTE;
break;
default:
*s1++ = *s2++;
}
*s1 = '\0';
for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) {
if (eq(sp->word, bptr->bname)) {
if (aliased)
prlex(lex);
(void) printf("%s: shell built-in command.\n", sp->word);
sp->word = s0; /* we save and then restore this */
return;
}
}
sp->word = cmd = globone(sp->word);
if ((i = iscommand(strip(sp->word))) != 0) {
register char **pv;
register struct varent *v;
bool slash = any(sp->word, '/');
v = adrof("path");
if (v == 0 || v->vec[0] == 0 || slash)
pv = justabs;
else
pv = v->vec;
while (--i)
pv++;
if (pv[0][0] == 0 || eq(pv[0], ".")) {
if (!slash) {
sp->word = strspl("./", sp->word);
prlex(lex);
xfree(sp->word);
}
else
prlex(lex);
sp->word = s0; /* we save and then restore this */
xfree(cmd);
return;
}
s1 = strspl(*pv, "/");
sp->word = strspl(s1, sp->word);
xfree(s1);
prlex(lex);
xfree(sp->word);
}
else {
if (aliased)
prlex(lex);
(void) printf("%s: Command not found.\n", sp->word);
}
sp->word = s0; /* we save and then restore this */
xfree(cmd);
}