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