|
|
1.1 root 1: #ifndef lint
2: static char sccsid[] = "@(#)service.c 4.8 4/14/90";
3: #endif
4:
5: #
6: /*
7: * UNIX shell
8: *
9: * S. R. Bourne
10: * Bell Telephone Laboratories
11: *
12: */
13:
14: #include "defs.h"
15: #include "errno.h"
16: #include "sys/file.h"
17: #include "pathnames.h"
18:
19:
20: PROC VOID gsort();
21:
22: #define ARGMK 01
23:
24: INT errno;
25: STRING sysmsg[];
26: INT num_sysmsg;
27:
28: /* service routines for `execute' */
29:
30: VOID initio(iop)
31: IOPTR iop;
32: {
33: REG STRING ion;
34: REG INT iof, fd;
35:
36: IF iop
37: THEN iof=iop->iofile;
38: ion=mactrim(iop->ioname);
39: IF *ion ANDF (flags&noexec)==0
40: THEN IF iof&IODOC
41: THEN subst(chkopen(ion),(fd=tmpfil()));
42: close(fd); fd=chkopen(tmpout); unlink(tmpout);
43: ELIF iof&IOMOV
44: THEN IF eq(minus,ion)
45: THEN fd = -1;
46: close(iof&IOUFD);
47: ELIF (fd=stoi(ion))>=USERIO
48: THEN failed(ion,badfile);
49: ELSE fd=dup(fd);
50: FI
51: ELIF (iof&IOPUT)==0
52: THEN fd=chkopen(ion);
53: ELIF flags&rshflg
54: THEN failed(ion,restricted);
55: ELIF (iof&IOAPP)==0 ORF
56: (fd=open(ion,O_WRONLY|O_APPEND))<0
57: THEN fd=create(ion);
58: FI
59: IF fd>=0
60: THEN rename(fd,iof&IOUFD);
61: FI
62: FI
63: initio(iop->ionxt);
64: FI
65: }
66:
67: STRING getpath(s)
68: STRING s;
69: {
70: REG STRING path;
71: IF any('/',s)
72: THEN IF flags&rshflg
73: THEN failed(s, restricted);
74: ELSE return(nullstr);
75: FI
76: ELIF (path = pathnod.namval)==0
77: THEN return(_PATH_DEFPATH);
78: ELSE return(cpystak(path));
79: FI
80: }
81:
82: INT pathopen(path, name)
83: REG STRING path, name;
84: {
85: REG UFD f;
86:
87: REP path=catpath(path,name);
88: PER (f=open(curstak(),0))<0 ANDF path DONE
89: return(f);
90: }
91:
92: STRING catpath(path,name)
93: REG STRING path;
94: STRING name;
95: {
96: /* leaves result on top of stack */
97: REG STRING scanp = path,
98: argp = locstak();
99:
100: WHILE *scanp ANDF *scanp!=COLON DO *argp++ = *scanp++ OD
101: IF scanp!=path THEN *argp++='/' FI
102: IF *scanp==COLON THEN scanp++ FI
103: path=(*scanp ? scanp : 0); scanp=name;
104: WHILE (*argp++ = *scanp++) DONE
105: return(path);
106: }
107:
108: LOCAL STRING xecmsg;
109: LOCAL STRING *xecenv;
110:
111: VOID execa(at)
112: STRING at[];
113: {
114: REG STRING path;
115: REG STRING *t = at;
116:
117: IF (flags&noexec)==0
118: THEN xecmsg=notfound; path=getpath(*t);
119: namscan(exname);
120: xecenv=setenv();
121: WHILE path=execs(path,t) DONE
122: failed(*t,xecmsg);
123: FI
124: }
125:
126: LOCAL STRING execs(ap,t)
127: STRING ap;
128: REG STRING t[];
129: {
130: REG STRING p, prefix;
131:
132: prefix=catpath(ap,t[0]);
133: trim(p=curstak());
134:
135: sigchk();
136: execve(p, &t[0] ,xecenv);
137: SWITCH errno IN
138:
139: case ENOEXEC:
140: flags=0;
141: comdiv=0; ioset=0;
142: clearup(); /* remove open files and for loop junk */
143: IF input THEN close(input) FI
144: close(output); output=2;
145: input=chkopen(p);
146:
147: /* band aid to get csh... 2/26/79 */
148: {
149: char c;
150: if (!isatty(input)) {
151: read(input, &c, 1);
152: if (c == '#')
153: gocsh(t, p, xecenv);
154: lseek(input, (long) 0, 0);
155: }
156: }
157:
158: /* set up new args */
159: setargs(t);
160: longjmp(subshell,1);
161:
162: case ENOMEM:
163: failed(p,toobig);
164:
165: case E2BIG:
166: failed(p,arglist);
167:
168: case ETXTBSY:
169: failed(p,txtbsy);
170:
171: default:
172: xecmsg=badexec;
173: case ENOENT:
174: return(prefix);
175: ENDSW
176: }
177:
178: gocsh(t, cp, xecenv)
179: register char **t, *cp, **xecenv;
180: {
181: char **newt[1000];
182: register char **p;
183: register int i;
184:
185: for (i = 0; t[i]; i++)
186: newt[i+1] = t[i];
187: newt[i+1] = 0;
188: newt[0] = _PATH_CSHELL;
189: newt[1] = cp;
190: execve(_PATH_CSHELL, newt, xecenv);
191: }
192:
193: /* for processes to be waited for */
194: #define MAXP 20
195: LOCAL INT pwlist[MAXP];
196: LOCAL INT pwc;
197:
198: postclr()
199: {
200: REG INT *pw = pwlist;
201:
202: WHILE pw <= &pwlist[pwc]
203: DO *pw++ = 0 OD
204: pwc=0;
205: }
206:
207: VOID post(pcsid)
208: INT pcsid;
209: {
210: REG INT *pw = pwlist;
211:
212: IF pcsid
213: THEN WHILE *pw DO pw++ OD
214: IF pwc >= MAXP-1
215: THEN pw--;
216: ELSE pwc++;
217: FI
218: *pw = pcsid;
219: FI
220: }
221:
222: VOID await(i)
223: INT i;
224: {
225: INT rc=0, wx=0;
226: INT w;
227: INT ipwc = pwc;
228:
229: post(i);
230: WHILE pwc
231: DO REG INT p;
232: REG INT sig;
233: INT w_hi;
234:
235: BEGIN
236: REG INT *pw=pwlist;
237: IF setjmp(INTbuf) == 0
238: THEN trapjmp[INTR] = 1; p=wait(&w);
239: ELSE p = -1;
240: FI
241: trapjmp[INTR] = 0;
242: WHILE pw <= &pwlist[ipwc]
243: DO IF *pw==p
244: THEN *pw=0; pwc--;
245: ELSE pw++;
246: FI
247: OD
248: END
249:
250: IF p == -1 THEN continue FI
251:
252: w_hi = (w>>8)&LOBYTE;
253:
254: IF sig = w&0177
255: THEN IF sig == 0177 /* ptrace! return */
256: THEN prs("ptrace: ");
257: sig = w_hi;
258: FI
259: IF sig < num_sysmsg ANDF sysmsg[sig]
260: THEN IF i!=p ORF (flags&prompt)==0
261: THEN prp(); prn(p); blank()
262: FI
263: prs(sysmsg[sig]);
264: IF w&0200 THEN prs(coredump) FI
265: FI
266: newline();
267: FI
268:
269: IF rc==0
270: THEN rc = (sig ? sig|SIGFLG : w_hi);
271: FI
272: wx |= w;
273: OD
274:
275: IF wx ANDF flags&errflg
276: THEN exitsh(rc);
277: FI
278: exitval=rc; exitset();
279: }
280:
281: BOOL nosubst;
282:
283: trim(at)
284: STRING at;
285: {
286: REG STRING p;
287: REG CHAR c;
288: REG CHAR q=0;
289:
290: IF p=at
291: THEN WHILE c = *p
292: DO *p++=c&STRIP; q |= c OD
293: FI
294: nosubst=q"E;
295: }
296:
297: STRING mactrim(s)
298: STRING s;
299: {
300: REG STRING t=macro(s);
301: trim(t);
302: return(t);
303: }
304:
305: STRING *scan(argn)
306: INT argn;
307: {
308: REG ARGPTR argp = Rcheat(gchain)&~ARGMK;
309: REG STRING *comargn, *comargm;
310:
311: comargn=getstak(BYTESPERWORD*argn+BYTESPERWORD); comargm = comargn += argn; *comargn = ENDARGS;
312:
313: WHILE argp
314: DO *--comargn = argp->argval;
315: IF argp = argp->argnxt
316: THEN trim(*comargn);
317: FI
318: IF argp==0 ORF Rcheat(argp)&ARGMK
319: THEN gsort(comargn,comargm);
320: comargm = comargn;
321: FI
322: /* Lcheat(argp) &= ~ARGMK; */
323: argp = Rcheat(argp)&~ARGMK;
324: OD
325: return(comargn);
326: }
327:
328: LOCAL VOID gsort(from,to)
329: STRING from[], to[];
330: {
331: INT k, m, n;
332: REG INT i, j;
333:
334: IF (n=to-from)<=1 THEN return FI
335:
336: FOR j=1; j<=n; j*=2 DONE
337:
338: FOR m=2*j-1; m/=2;
339: DO k=n-m;
340: FOR j=0; j<k; j++
341: DO FOR i=j; i>=0; i-=m
342: DO REG STRING *fromi; fromi = &from[i];
343: IF cf(fromi[m],fromi[0])>0
344: THEN break;
345: ELSE STRING s; s=fromi[m]; fromi[m]=fromi[0]; fromi[0]=s;
346: FI
347: OD
348: OD
349: OD
350: }
351:
352: /* Argument list generation */
353:
354: INT getarg(ac)
355: COMPTR ac;
356: {
357: REG ARGPTR argp;
358: REG INT count=0;
359: REG COMPTR c;
360:
361: IF c=ac
362: THEN argp=c->comarg;
363: WHILE argp
364: DO count += split(macro(argp->argval));
365: argp=argp->argnxt;
366: OD
367: FI
368: return(count);
369: }
370:
371: LOCAL INT split(s)
372: REG STRING s;
373: {
374: REG STRING argp;
375: REG INT c;
376: INT count=0;
377:
378: LOOP sigchk(); argp=locstak()+BYTESPERWORD;
379: WHILE (c = *s++, !any(c,ifsnod.namval) && c)
380: DO *argp++ = c OD
381: IF argp==staktop+BYTESPERWORD
382: THEN IF c
383: THEN continue;
384: ELSE return(count);
385: FI
386: ELIF c==0
387: THEN s--;
388: FI
389: IF c=expand(((ARGPTR)(argp=endstak(argp)))->argval,0)
390: THEN count += c;
391: ELSE /* assign(&fngnod, argp->argval); */
392: makearg(argp); count++;
393: FI
394: Lcheat(gchain) |= ARGMK;
395: POOL
396: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.