1: /*
2: * From the 4.4-Lite2 CD's csh sources and modified appropriately.
3: */
4:
5: #if !defined(lint) && defined(DOSCCS)
6: static char *sccsid = "@(#)sh.exec2.c 1.0 (2.11BSD) 1996/9/20";
7: #endif
8:
9: #include "sh.h"
10: #include <string.h>
11: #include <sys/file.h>
12: #include <sys/stat.h>
13: #include <sys/dir.h>
14: #include "sh.exec.h"
15:
16: extern char *justabs[]; /* in sh.exec.c */
17:
18: static int
19: iscommand(name)
20: char *name;
21: {
22: register char **pv;
23: register char *sav;
24: register struct varent *v;
25: bool slash = any(name, '/');
26: int hashval = 0, hashval1, i;
27:
28: v = adrof("path");
29: if (v == 0 || v->vec[0] == 0 || slash)
30: pv = justabs;
31: else
32: pv = v->vec;
33: sav = strspl("/", name); /* / command name for postpending */
34: if (havhash)
35: hashval = hashname(name);
36: i = 0;
37: do {
38: if (!slash && pv[0][0] == '/' && havhash) {
39: hashval1 = hash(hashval, i);
40: if (!bit(xhash, hashval1))
41: goto cont;
42: }
43: if (pv[0][0] == 0 || eq(pv[0], ".")) { /* don't make ./xxx */
44: if (executable(NULL, name, 0)) {
45: xfree(sav);
46: return i + 1;
47: }
48: }
49: else {
50: if (executable(*pv, sav, 0)) {
51: xfree(sav);
52: return i + 1;
53: }
54: }
55: cont:
56: pv++;
57: i++;
58: } while (*pv);
59: xfree(sav);
60: return 0;
61: }
62:
63: /* Also by:
64: * Andreas Luik <luik@isaak.isa.de>
65: * I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
66: * Azenberstr. 35
67: * D-7000 Stuttgart 1
68: * West-Germany
69: * is the executable() routine below and changes to iscommand().
70: * Thanks again!!
71: */
72:
73: /*
74: * executable() examines the pathname obtained by concatenating dir and name
75: * (dir may be NULL), and returns 1 either if it is executable by us, or
76: * if dir_ok is set and the pathname refers to a directory.
77: * This is a bit kludgy, but in the name of optimization...
78: */
79: static int
80: executable(dir, name, dir_ok)
81: char *dir, *name;
82: bool dir_ok;
83: {
84: struct stat stbuf;
85: char path[MAXPATHLEN + 1];
86: register char *dp, *sp;
87: char *strname;
88:
89: if (dir && *dir) {
90: for (dp = path, sp = dir; *sp; *dp++ = *sp++)
91: if (dp == &path[MAXPATHLEN + 1]) {
92: *--dp = '\0';
93: break;
94: }
95: for (sp = name; *sp; *dp++ = *sp++)
96: if (dp == &path[MAXPATHLEN + 1]) {
97: *--dp = '\0';
98: break;
99: }
100: *dp = '\0';
101: strname = path;
102: }
103: else
104: strname = name;
105: return (stat(strname, &stbuf) != -1 &&
106: ((S_ISREG(stbuf.st_mode) &&
107: /* save time by not calling access() in the hopeless case */
108: (stbuf.st_mode & (S_IXOTH | S_IXGRP | S_IXUSR)) &&
109: access(strname, X_OK) == 0) ||
110: (dir_ok && S_ISDIR(stbuf.st_mode))));
111: }
112: /* The dowhich() is by:
113: * Andreas Luik <luik@isaak.isa.de>
114: * I S A GmbH - Informationssysteme fuer computerintegrierte Automatisierung
115: * Azenberstr. 35
116: * D-7000 Stuttgart 1
117: * West-Germany
118: * Thanks!!
119: */
120: /*ARGSUSED*/
121: void
122: dowhich(v, c)
123: register char **v;
124: struct command *c;
125: {
126: struct wordent lex[3];
127: struct varent *vp;
128:
129: lex[0].next = &lex[1];
130: lex[1].next = &lex[2];
131: lex[2].next = &lex[0];
132:
133: lex[0].prev = &lex[2];
134: lex[1].prev = &lex[0];
135: lex[2].prev = &lex[1];
136:
137: lex[0].word = "";
138: lex[2].word = "\n";
139:
140: while (*++v) {
141: if ((vp = adrof1(*v, &aliases)) != NULL) {
142: (void) printf("%s: \t aliased to ", *v);
143: blkpr(vp->vec);
144: (void) putchar('\n');
145: }
146: else {
147: lex[1].word = *v;
148: tellmewhat(lex);
149: }
150: }
151: }
152:
153: static void
154: tellmewhat(lex)
155: struct wordent *lex;
156: {
157: int i;
158: struct biltins *bptr;
159: register struct wordent *sp = lex->next;
160: bool aliased = 0;
161: register char *s2;
162: char *s0, *s1, *cmd;
163: char qc;
164:
165: if (adrof1(sp->word, &aliases)) {
166: alias(lex);
167: sp = lex->next;
168: aliased = 1;
169: }
170:
171: s0 = sp->word; /* to get the memory freeing right... */
172:
173: /* handle quoted alias hack */
174: if ((*(sp->word) & (QUOTE | TRIM)) == QUOTE)
175: (sp->word)++;
176:
177: /* do quoting, if it hasn't been done */
178: s1 = s2 = sp->word;
179: while (*s2)
180: switch (*s2) {
181: case '\'':
182: case '"':
183: qc = *s2++;
184: while (*s2 && *s2 != qc)
185: *s1++ = *s2++ | QUOTE;
186: if (*s2)
187: s2++;
188: break;
189: case '\\':
190: if (*++s2)
191: *s1++ = *s2++ | QUOTE;
192: break;
193: default:
194: *s1++ = *s2++;
195: }
196: *s1 = '\0';
197:
198: for (bptr = bfunc; bptr < &bfunc[nbfunc]; bptr++) {
199: if (eq(sp->word, bptr->bname)) {
200: if (aliased)
201: prlex(lex);
202: (void) printf("%s: shell built-in command.\n", sp->word);
203: sp->word = s0; /* we save and then restore this */
204: return;
205: }
206: }
207:
208: sp->word = cmd = globone(sp->word);
209:
210: if ((i = iscommand(strip(sp->word))) != 0) {
211: register char **pv;
212: register struct varent *v;
213: bool slash = any(sp->word, '/');
214:
215: v = adrof("path");
216: if (v == 0 || v->vec[0] == 0 || slash)
217: pv = justabs;
218: else
219: pv = v->vec;
220:
221: while (--i)
222: pv++;
223: if (pv[0][0] == 0 || eq(pv[0], ".")) {
224: if (!slash) {
225: sp->word = strspl("./", sp->word);
226: prlex(lex);
227: xfree(sp->word);
228: }
229: else
230: prlex(lex);
231: sp->word = s0; /* we save and then restore this */
232: xfree(cmd);
233: return;
234: }
235: s1 = strspl(*pv, "/");
236: sp->word = strspl(s1, sp->word);
237: xfree(s1);
238: prlex(lex);
239: xfree(sp->word);
240: }
241: else {
242: if (aliased)
243: prlex(lex);
244: (void) printf("%s: Command not found.\n", sp->word);
245: }
246: sp->word = s0; /* we save and then restore this */
247: xfree(cmd);
248: }
Defined functions
Defined variables
sccsid
defined in line
6;
never used