|
|
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), 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, 0);
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:
192: if ((flags & noexec) == 0)
193: {
194: xecmsg = notfound;
195: path = getpath(*t);
196: xecenv = setenv();
197:
198: while (path = execs(path,t))
199: ;
200: failed(*t, xecmsg, 1);
201: }
202: }
203:
204: char *
205: execs(ap, t)
206: char *ap;
207: register char *t[];
208: {
209: register char *p, *prefix;
210:
211: prefix = catpath(ap, t[0]);
212: trim(p = curstak());
213: sigchk();
214:
215: execve(p, &t[0] ,xecenv);
216: switch (errno)
217: {
218: case ENOEXEC: /* could be a shell script */
219: funcnt = 0;
220: flags = 0;
221: *flagadr = 0;
222: comdiv = 0;
223: ioset = 0;
224: clearup(); /* remove open files and for loop junk */
225: if (input)
226: close(input);
227: input = chkopen(p);
228:
229: #ifdef ACCT
230: preacct(p); /* reset accounting */
231: #endif
232:
233: /*
234: * set up new args
235: */
236:
237: setargs(t);
238: longjmp(subshell, 1);
239:
240: case ENOMEM:
241: case E2BIG:
242: case ETXTBSY:
243: failed(p, NIL, 1);
244:
245: default:
246: xecmsg = badexec;
247: case ENOENT:
248: return(prefix);
249: }
250: }
251:
252:
253: /*
254: * for processes to be waited for
255: */
256: #define MAXP 20
257: static int pwlist[MAXP];
258: static int pwc;
259:
260: postclr()
261: {
262: register int *pw = pwlist;
263:
264: while (pw <= &pwlist[pwc])
265: *pw++ = 0;
266: pwc = 0;
267: }
268:
269: post(pcsid)
270: int pcsid;
271: {
272: register int *pw = pwlist;
273:
274: if (pcsid)
275: {
276: while (*pw)
277: pw++;
278: if (pwc >= MAXP - 1)
279: pw--;
280: else
281: pwc++;
282: *pw = pcsid;
283: }
284: }
285:
286: await(i, bckg)
287: int i, bckg;
288: {
289: int rc = 0, wx = 0;
290: int w;
291: int ipwc = pwc;
292:
293: post(i);
294: while (pwc)
295: {
296: register int p;
297: register int sig;
298: int w_hi;
299: int found = 0;
300:
301: {
302: register int *pw = pwlist;
303:
304: p = wait(&w);
305: if (wasintr)
306: {
307: wasintr = 0;
308: if (bckg)
309: {
310: break;
311: }
312: }
313: while (pw <= &pwlist[ipwc])
314: {
315: if (*pw == p)
316: {
317: *pw = 0;
318: pwc--;
319: found++;
320: }
321: else
322: pw++;
323: }
324: }
325: if (p == -1)
326: {
327: if (bckg)
328: {
329: register int *pw = pwlist;
330:
331: while (pw <= &pwlist[ipwc] && i != *pw)
332: pw++;
333: if (i == *pw)
334: {
335: *pw = 0;
336: pwc--;
337: }
338: }
339: continue;
340: }
341: w_hi = (w >> 8) & LOBYTE;
342: if (sig = w & 0177)
343: {
344: if (sig == 0177) /* ptrace! return */
345: {
346: prs("ptrace: ");
347: sig = w_hi;
348: }
349: if (sysmsg[sig])
350: {
351: if (i != p || (flags & prompt) == 0)
352: {
353: prp();
354: prn(p);
355: blank();
356: }
357: prs(sysmsg[sig]);
358: if (w & 0200)
359: prs(coredump);
360: }
361: newline();
362: }
363: if (rc == 0 && found != 0)
364: rc = (sig ? sig | SIGFLG : w_hi);
365: wx |= w;
366: if (p == i)
367: {
368: break;
369: }
370: }
371: if (wx && flags & errflg)
372: exitsh(rc);
373: flags |= eflag;
374: exitval = rc;
375: exitset();
376: }
377:
378: BOOL nosubst;
379:
380: trim(at)
381: char *at;
382: {
383: register char *p;
384: register char *ptr;
385: register char c;
386: register char q = 0;
387:
388: if (p = at)
389: {
390: ptr = p;
391: while (c = *p++)
392: {
393: if (*ptr = c & STRIP)
394: ++ptr;
395: q |= c;
396: }
397:
398: *ptr = 0;
399: }
400: nosubst = q & QUOTE;
401: }
402:
403: char *
404: mactrim(s)
405: char *s;
406: {
407: register char *t = macro(s);
408:
409: trim(t);
410: return(t);
411: }
412:
413: char **
414: scan(argn)
415: int argn;
416: {
417: register struct argnod *argp = (struct argnod *)(Rcheat(gchain) & ~ARGMK);
418: register char **comargn, **comargm;
419:
420: comargn = (char **)getstak(BYTESPERWORD * argn + BYTESPERWORD);
421: comargm = comargn += argn;
422: *comargn = ENDARGS;
423: while (argp)
424: {
425: *--comargn = argp->argval;
426:
427: trim(*comargn);
428: argp = argp->argnxt;
429:
430: if (argp == 0 || Rcheat(argp) & ARGMK)
431: {
432: gsort(comargn, comargm);
433: comargm = comargn;
434: }
435: /* Lcheat(argp) &= ~ARGMK; */
436: argp = (struct argnod *)(Rcheat(argp) & ~ARGMK);
437: }
438: return(comargn);
439: }
440:
441: static int
442: gsort(from, to)
443: char *from[], *to[];
444: {
445: int k, m, n;
446: register int i, j;
447:
448: if ((n = to - from) <= 1)
449: return;
450: for (j = 1; j <= n; j *= 2)
451: ;
452: for (m = 2 * j - 1; m /= 2; )
453: {
454: k = n - m;
455: for (j = 0; j < k; j++)
456: {
457: for (i = j; i >= 0; i -= m)
458: {
459: register char **fromi;
460:
461: fromi = &from[i];
462: if (cf(fromi[m], fromi[0]) > 0)
463: {
464: break;
465: }
466: else
467: {
468: char *s;
469:
470: s = fromi[m];
471: fromi[m] = fromi[0];
472: fromi[0] = s;
473: }
474: }
475: }
476: }
477: }
478:
479: /*
480: * Argument list generation
481: */
482: getarg(ac)
483: struct comnod *ac;
484: {
485: register struct argnod *argp;
486: register int count = 0;
487: register struct comnod *c;
488:
489: if (c = ac)
490: {
491: argp = c->comarg;
492: while (argp)
493: {
494: count += split(macro(argp->argval));
495: argp = argp->argnxt;
496: }
497: }
498: return(count);
499: }
500:
501: static int
502: split(s) /* blank interpretation routine */
503: register char *s;
504: {
505: register char *argp;
506: register int c;
507: int count = 0;
508:
509: for (;;)
510: {
511: sigchk();
512: staktop = argp = locstak() + BYTESPERWORD;
513: while ((c = *s++, !any(c, ifsnod.namval.val) && c))
514: pushstak(c);
515: if (argp == staktop)
516: {
517: if (c)
518: {
519: continue;
520: }
521: else
522: {
523: staktop = stakbot;
524: return(count);
525: }
526: }
527: else if (c == 0)
528: s--;
529: /*
530: * file name generation
531: */
532:
533: argp = fixstak();
534:
535: if ((flags & nofngflg) == 0 &&
536: (c = expand(((struct argnod *)argp)->argval, 0)))
537: count += c;
538: else
539: {
540: makearg((struct argnod *)argp);
541: count++;
542: }
543: gchain = (struct argnod *)((int)gchain | ARGMK);
544: }
545: }
546:
547: #ifdef ACCT
548: #include <sys/types.h>
549: #include "acctdef.h"
550: #include <sys/acct.h>
551: #include <sys/times.h>
552:
553: struct acct sabuf;
554: struct tms buffer;
555: extern long times();
556: static long before;
557: static int shaccton; /* 0 implies do not write record on exit
558: 1 implies write acct record on exit
559: */
560:
561:
562: /*
563: * suspend accounting until turned on by preacct()
564: */
565:
566: suspacct()
567: {
568: shaccton = 0;
569: }
570:
571: preacct(cmdadr)
572: char *cmdadr;
573: {
574: char *simple();
575:
576: if (acctnod.namval.val && *acctnod.namval.val)
577: {
578: sabuf.ac_btime = time((long *)0);
579: before = times(&buffer);
580: sabuf.ac_uid = getuid();
581: sabuf.ac_gid = getgid();
582: movstrn(simple(cmdadr), sabuf.ac_comm, sizeof(sabuf.ac_comm));
583: shaccton = 1;
584: }
585: }
586:
587: #include <fcntl.h>
588:
589: doacct()
590: {
591: int fd;
592: long int after;
593:
594: if (shaccton)
595: {
596: after = times(&buffer);
597: sabuf.ac_utime = compress(buffer.tms_utime + buffer.tms_cutime);
598: sabuf.ac_stime = compress(buffer.tms_stime + buffer.tms_cstime);
599: sabuf.ac_etime = compress(after - before);
600:
601: if ((fd = open(acctnod.namval.val, O_WRONLY | O_APPEND | O_CREAT, 0666)) != -1)
602: {
603: write(fd, &sabuf, sizeof(sabuf));
604: close(fd);
605: }
606: }
607: }
608:
609: /*
610: * Produce a pseudo-floating point representation
611: * with 3 bits base-8 exponent, 13 bits fraction
612: */
613:
614: compress(t)
615: register time_t t;
616: {
617: register exp = 0;
618: register rund = 0;
619:
620: while (t >= 8192)
621: {
622: exp++;
623: rund = t & 04;
624: t >>= 3;
625: }
626:
627: if (rund)
628: {
629: t++;
630: if (t >= 8192)
631: {
632: t >>= 3;
633: exp++;
634: }
635: }
636:
637: return((exp << 13) + t);
638: }
639: #endif
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.