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