/* * 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 #include #include #include #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 * 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 * 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); }