|
|
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.