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