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