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