|
|
1.1 root 1: /* @(#)service.c 1.11 */
2: /*
3: * UNIX shell
4: *
5: * Bell Telephone Laboratories
6: *
7: */
8:
9: #include "defs.h"
10: #include <errno.h>
11:
12: #define ARGMK 01
13:
14: extern int gsort();
15: extern char *sysmsg[];
16: extern short topfd;
17:
18:
19:
20: /*
21: * service routines for `execute'
22: */
23: initio(iop, save)
24: struct ionod *iop;
25: int save;
26: {
27: register char *ion;
28: register int iof, fd;
29: int ioufd;
30: short lastfd;
31:
32: lastfd = topfd;
33: while (iop)
34: {
35: iof = iop->iofile;
36: ion = mactrim(iop->ioname);
37: ioufd = iof & IOUFD;
38:
39: if (*ion && (flags&noexec) == 0)
40: {
41: if (save)
42: {
43: fdmap[topfd].org_fd = ioufd;
44: fdmap[topfd++].dup_fd = savefd(ioufd);
45: }
46:
47: if (iof & IODOC)
48: {
49: struct tempblk tb;
50:
51: subst(chkopen(ion), (fd = tmpfil(&tb)));
52:
53: poptemp(); /* pushed in tmpfil() --
54: bug fix for problem with
55: in-line scripts
56: */
57:
58: fd = chkopen(tmpout);
59: unlink(tmpout);
60: }
61: else if (iof & IOMOV)
62: {
63: if (eq(minus, ion))
64: {
65: fd = -1;
66: close(ioufd);
67: }
68: else if ((fd = stoi(ion)) >= USERIO)
69: failed(ion, badfile);
70: else
71: fd = dup(fd);
72: }
73: else if ((iof & IOPUT) == 0)
74: fd = chkopen(ion);
75: else if (iof & IOAPP && (fd = open(ion, 1)) >= 0)
76: lseek(fd, 0L, 2);
77: else
78: fd = create(ion);
79: if (fd >= 0)
80: rename(fd, ioufd);
81: }
82:
83: iop = iop->ionxt;
84: }
85: if (histfd > 0) {
86: close (histfd);
87: histfd = 0;
88: }
89: return(lastfd);
90: }
91:
92: char *
93: simple(s)
94: char *s;
95: {
96: char *sname;
97:
98: sname = s;
99: while (1)
100: {
101: if (any('/', sname))
102: while (*sname++ != '/')
103: ;
104: else
105: return(sname);
106: }
107: }
108:
109: char *
110: getpath(s)
111: char *s;
112: {
113: register char *path;
114:
115: if (any('/', s) || any(('/' | QUOTE), s))
116: {
117: return(nullstr);
118: }
119: else if ((path = pathnod.namval.val) == 0)
120: return(defpath);
121: else
122: return(cpystak(path));
123: }
124:
125: pathopen(path, name)
126: register char *path, *name;
127: {
128: register int f;
129:
130: do
131: {
132: path = catpath(path, name);
133: } while ((f = open(curstak(), 0)) < 0 && path);
134: return(f);
135: }
136:
137: char *
138: catpath(path, name)
139: register char *path;
140: char *name;
141: {
142: /*
143: * leaves result on top of stack
144: */
145: register char *scanp = path;
146: register char *argp = locstak();
147:
148: while (*scanp && *scanp != COLON)
149: *argp++ = *scanp++;
150: if (scanp != path)
151: *argp++ = '/';
152: if (*scanp == COLON)
153: scanp++;
154: path = (*scanp ? scanp : 0);
155: scanp = name;
156: while ((*argp++ = *scanp++))
157: ;
158: return(path);
159: }
160:
161: char *
162: nextpath(path)
163: register char *path;
164: {
165: register char *scanp = path;
166:
167: while (*scanp && *scanp != COLON)
168: scanp++;
169:
170: if (*scanp == COLON)
171: scanp++;
172:
173: return(*scanp ? scanp : 0);
174: }
175:
176: static char *xecmsg;
177: static char **xecenv;
178:
179: int execa(at)
180: char *at[];
181: {
182: register char *path;
183: register char **t = at;
184: int cnt;
185:
186: if ((flags & noexec) == 0)
187: {
188: xecmsg = notfound;
189: path = getpath(*t);
190: xecenv = setenv();
191:
192: while (path = execs(path,t))
193: ;
194: failed(*t, xecmsg);
195: }
196: }
197:
198: static char *
199: execs(ap, t)
200: char *ap;
201: register char *t[];
202: {
203: register char *p, *prefix;
204:
205: prefix = catpath(ap, t[0]);
206: trim(p = curstak());
207: sigchk();
208:
209: execve(p, &t[0] ,xecenv);
210: switch (errno)
211: {
212: case ENOEXEC: /* could be a shell script */
213: funcnt = 0;
214: flags = 0;
215: *flagadr = 0;
216: comdiv = 0;
217: ioset = 0;
218: clearup(); /* remove open files and for loop junk */
219: if (input)
220: close(input);
221: input = chkopen(p);
222:
223: #ifdef ACCT
224: preacct(p); /* reset accounting */
225: #endif
226:
227: /*
228: * set up new args
229: */
230:
231: setargs(t);
232: longjmp(subshell, 1);
233:
234: case ENOMEM:
235: failed(p, toobig);
236:
237: case E2BIG:
238: failed(p, arglist);
239:
240: case ETXTBSY:
241: failed(p, txtbsy);
242:
243: default:
244: xecmsg = badexec;
245: case ENOENT:
246: return(prefix);
247: }
248: }
249:
250:
251: /*
252: * for processes to be waited for
253: */
254: #define MAXP 20
255: static int pwlist[MAXP];
256: static int pwc;
257:
258: postclr()
259: {
260: register int *pw = pwlist;
261:
262: while (pw <= &pwlist[pwc])
263: *pw++ = 0;
264: pwc = 0;
265: }
266:
267: post(pcsid)
268: int pcsid;
269: {
270: register int *pw = pwlist;
271:
272: if (pcsid)
273: {
274: while (*pw)
275: pw++;
276: if (pwc >= MAXP - 1)
277: pw--;
278: else
279: pwc++;
280: *pw = pcsid;
281: }
282: }
283:
284: await(i, bckg)
285: int i, bckg;
286: {
287: int rc = 0, wx = 0;
288: int w;
289: int ipwc = pwc;
290:
291: post(i);
292: while (pwc)
293: {
294: register int p;
295: register int sig;
296: int w_hi;
297: int found = 0;
298:
299: {
300: register int *pw = pwlist;
301:
302: p = wait(&w);
303: if (wasintr)
304: {
305: wasintr = 0;
306: if (bckg)
307: {
308: break;
309: }
310: }
311: while (pw <= &pwlist[ipwc])
312: {
313: if (*pw == p)
314: {
315: *pw = 0;
316: pwc--;
317: found++;
318: }
319: else
320: pw++;
321: }
322: }
323: if (p == -1)
324: {
325: if (bckg)
326: {
327: register int *pw = pwlist;
328:
329: while (pw <= &pwlist[ipwc] && i != *pw)
330: pw++;
331: if (i == *pw)
332: {
333: *pw = 0;
334: pwc--;
335: }
336: }
337: continue;
338: }
339: w_hi = (w >> 8) & LOBYTE;
340: if (sig = w & 0177)
341: {
342: if (sig == 0177) /* ptrace! return */
343: {
344: prs("ptrace: ");
345: sig = w_hi;
346: }
347: if (sysmsg[sig])
348: {
349: if (i != p || (flags & prompt) == 0)
350: {
351: prp();
352: prn(p);
353: blank();
354: }
355: prs(sysmsg[sig]);
356: if (w & 0200)
357: prs(coredump);
358: }
359: newline();
360: }
361: if (rc == 0 && found != 0)
362: rc = (sig ? sig | SIGFLG : w_hi);
363: wx |= w;
364: if (p == i)
365: {
366: break;
367: }
368: }
369: if (wx && flags & errflg)
370: exitsh(rc);
371: flags |= eflag;
372: exitval = rc;
373: exitset();
374: }
375:
376: BOOL nosubst;
377:
378: trim(at)
379: char *at;
380: {
381: register char *p;
382: register char *ptr;
383: register char c;
384: register char q = 0;
385:
386: if (p = at)
387: {
388: ptr = p;
389: while (c = *p++)
390: {
391: if (*ptr = c & STRIP)
392: ++ptr;
393: q |= c;
394: }
395:
396: *ptr = 0;
397: }
398: nosubst = q & QUOTE;
399: }
400:
401: char *
402: mactrim(s)
403: char *s;
404: {
405: register char *t = macro(s);
406:
407: trim(t);
408: return(t);
409: }
410:
411: char **
412: scan(argn)
413: int argn;
414: {
415: register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);
416: register char **comargn, **comargm;
417:
418: comargn = (char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
419: comargm = comargn += argn;
420: *comargn = ENDARGS;
421: while (argp)
422: {
423: *--comargn = argp->argval;
424:
425: trim(*comargn);
426: argp = argp->argnxt;
427:
428: if (argp == 0 || Rcheat(argp) & ARGMK)
429: {
430: gsort(comargn, comargm);
431: comargm = comargn;
432: }
433: /* Lcheat(argp) &= ~ARGMK; */
434: argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
435: }
436: return(comargn);
437: }
438:
439: static int
440: gsort(from, to)
441: char *from[], *to[];
442: {
443: int k, m, n;
444: register int i, j;
445:
446: if ((n = to - from) <= 1)
447: return;
448: for (j = 1; j <= n; j *= 2)
449: ;
450: for (m = 2 * j - 1; m /= 2; )
451: {
452: k = n - m;
453: for (j = 0; j < k; j++)
454: {
455: for (i = j; i >= 0; i -= m)
456: {
457: register char **fromi;
458:
459: fromi = &from[i];
460: if (cf(fromi[m], fromi[0]) > 0)
461: {
462: break;
463: }
464: else
465: {
466: char *s;
467:
468: s = fromi[m];
469: fromi[m] = fromi[0];
470: fromi[0] = s;
471: }
472: }
473: }
474: }
475: }
476:
477: /*
478: * Argument list generation
479: */
480: getarg(ac)
481: struct comnod *ac;
482: {
483: register struct argnod *argp;
484: register int count = 0;
485: register struct comnod *c;
486:
487: if (c = ac)
488: {
489: argp = c->comarg;
490: while (argp)
491: {
492: count += split(macro(argp->argval));
493: argp = argp->argnxt;
494: }
495: }
496: return(count);
497: }
498:
499: static int
500: split(s) /* blank interpretation routine */
501: register char *s;
502: {
503: register char *argp;
504: register int c;
505: int count = 0;
506:
507: for (;;)
508: {
509: sigchk();
510: argp = locstak() + BYTESPERWORD;
511: while ((c = *s++, !any(c, ifsnod.namval.val) && c))
512: *argp++ = c;
513: if (argp == staktop + BYTESPERWORD)
514: {
515: if (c)
516: {
517: continue;
518: }
519: else
520: {
521: return(count);
522: }
523: }
524: else if (c == 0)
525: s--;
526: /*
527: * file name generation
528: */
529:
530: argp = endstak(argp);
531:
532: if ((flags & nofngflg) == 0 &&
533: (c = expand(((struct argnod *)argp)->argval, 0)))
534: count += c;
535: else
536: {
537: makearg(argp);
538: count++;
539: }
540: gchain = (struct argnod *)((int)gchain | ARGMK);
541: }
542: }
543:
544: #ifdef ACCT
545: #include <sys/types.h>
546: #include "acctdef.h"
547: #include <sys/acct.h>
548: #include <sys/times.h>
549:
550: struct acct sabuf;
551: struct tms buffer;
552: extern long times();
553: static long before;
554: static int shaccton; /* 0 implies do not write record on exit
555: 1 implies write acct record on exit
556: */
557:
558:
559: /*
560: * suspend accounting until turned on by preacct()
561: */
562:
563: suspacct()
564: {
565: shaccton = 0;
566: }
567:
568: preacct(cmdadr)
569: char *cmdadr;
570: {
571: char *simple();
572:
573: if (acctnod.namval.val && *acctnod.namval.val)
574: {
575: sabuf.ac_btime = time((long *)0);
576: before = times(&buffer);
577: sabuf.ac_uid = getuid();
578: sabuf.ac_gid = getgid();
579: movstrn(simple(cmdadr), sabuf.ac_comm, sizeof(sabuf.ac_comm));
580: shaccton = 1;
581: }
582: }
583:
584: #include <fcntl.h>
585:
586: doacct()
587: {
588: int fd;
589: long int after;
590:
591: if (shaccton)
592: {
593: after = times(&buffer);
594: sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
595: sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
596: sabuf.ac_etime = compress(after - before);
597:
598: if ((fd = open(acctnod.namval.val, O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)
599: {
600: write(fd, &sabuf, sizeof(sabuf));
601: close(fd);
602: }
603: }
604: }
605:
606: /*
607: * Produce a pseudo-floating point representation
608: * with 3 bits base-8 exponent, 13 bits fraction
609: */
610:
611: compress(t)
612: register time_t t;
613: {
614: register exp = 0;
615: register rund = 0;
616:
617: while (t >= 8192)
618: {
619: exp++;
620: rund = t & 04;
621: t >>= 3;
622: }
623:
624: if (rund)
625: {
626: t++;
627: if (t >= 8192)
628: {
629: t >>= 3;
630: exp++;
631: }
632: }
633:
634: return((exp << 13) + t);
635: }
636: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.