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