1: static  char *sccsid = "@(#)sh.func.c 4.5 81/06/19";
   2: 
   3: #include "sh.h"
   4: #include <sys/ioctl.h>
   5: 
   6: /*
   7:  * C shell
   8:  */
   9: 
  10: struct biltins *
  11: isbfunc(t)
  12:     register struct command *t;
  13: {
  14:     register char *cp = t->t_dcom[0];
  15:     register char *dp;
  16:     register struct biltins *bp;
  17:     int dolabel(), dofg1(), dobg1();
  18:     static struct biltins label = { "", dolabel, 0, 0 };
  19:     static struct biltins foregnd = { "%job", dofg1, 0, 0 };
  20:     static struct biltins backgnd = { "%job &", dobg1, 0, 0 };
  21: 
  22:     if (lastchr(cp) == ':') {
  23:         label.bname = cp;
  24:         return (&label);
  25:     }
  26:     if (*cp == '%') {
  27:         if (t->t_dflg & FAND) {
  28:             t->t_dflg &= ~FAND;
  29:             backgnd.bname = cp;
  30:             return (&backgnd);
  31:         }
  32:         foregnd.bname = cp;
  33:         return (&foregnd);
  34:     }
  35:     for (bp = bfunc; dp = bp->bname; bp++) {
  36:         if (dp[0] == cp[0] && eq(dp, cp))
  37:             return (bp);
  38:         if (dp[0] > cp[0])
  39:             break;
  40:     }
  41:     return (0);
  42: }
  43: 
  44: func(t, bp)
  45:     register struct command *t;
  46:     register struct biltins *bp;
  47: {
  48:     int i;
  49: 
  50:     xechoit(t->t_dcom);
  51:     setname(bp->bname);
  52:     i = blklen(t->t_dcom) - 1;
  53:     if (i < bp->minargs)
  54:         bferr("Too few arguments");
  55:     if (i > bp->maxargs)
  56:         bferr("Too many arguments");
  57:     (*bp->bfunct)(t->t_dcom, t);
  58: }
  59: 
  60: dolabel()
  61: {
  62: 
  63: }
  64: 
  65: doonintr(v)
  66:     char **v;
  67: {
  68:     register char *cp;
  69:     register char *vv = v[1];
  70: 
  71:     if (parintr == SIG_IGN)
  72:         return;
  73:     if (setintr && intty)
  74:         bferr("Can't from terminal");
  75:     cp = gointr, gointr = 0, xfree(cp);
  76:     if (vv == 0) {
  77:         if (setintr)
  78:             sighold(SIGINT);
  79:         else
  80:             sigset(SIGINT, SIG_DFL);
  81:         gointr = 0;
  82:     } else if (eq((vv = strip(vv)), "-")) {
  83:         sigset(SIGINT, SIG_IGN);
  84:         gointr = "-";
  85:     } else {
  86:         gointr = savestr(vv);
  87:         sigset(SIGINT, pintr);
  88:     }
  89: }
  90: 
  91: donohup()
  92: {
  93: 
  94:     if (intty)
  95:         bferr("Can't from terminal");
  96:     if (setintr == 0) {
  97:         signal(SIGHUP, SIG_IGN);
  98: #ifdef CC
  99:         submit(getpid());
 100: #endif
 101:     }
 102: }
 103: 
 104: dozip()
 105: {
 106: 
 107:     ;
 108: }
 109: 
 110: prvars()
 111: {
 112: 
 113:     plist(&shvhed);
 114: }
 115: 
 116: doalias(v)
 117:     register char **v;
 118: {
 119:     register struct varent *vp;
 120:     register char *p;
 121: 
 122:     v++;
 123:     p = *v++;
 124:     if (p == 0)
 125:         plist(&aliases);
 126:     else if (*v == 0) {
 127:         vp = adrof1(strip(p), &aliases);
 128:         if (vp)
 129:             blkpr(vp->vec), printf("\n");
 130:     } else {
 131:         if (eq(p, "alias") || eq(p, "unalias")) {
 132:             setname(p);
 133:             bferr("Too dangerous to alias that");
 134:         }
 135:         set1(strip(p), saveblk(v), &aliases);
 136:     }
 137: }
 138: 
 139: unalias(v)
 140:     char **v;
 141: {
 142: 
 143:     unset1(v, &aliases);
 144: }
 145: 
 146: dologout()
 147: {
 148: 
 149:     islogin();
 150:     goodbye();
 151: }
 152: 
 153: dologin(v)
 154:     char **v;
 155: {
 156: 
 157:     islogin();
 158:     signal(SIGTERM, parterm);
 159:     execl("/bin/login", "login", v[1], 0);
 160:     untty();
 161:     exit(1);
 162: }
 163: 
 164: donewgrp(v)
 165:     char **v;
 166: {
 167: 
 168:     if (chkstop == 0 && setintr)
 169:         panystop(0);
 170:     signal(SIGTERM, parterm);
 171:     execl("/bin/newgrp", "newgrp", v[1], 0);
 172:     execl("/usr/bin/newgrp", "newgrp", v[1], 0);
 173:     untty();
 174:     exit(1);
 175: }
 176: 
 177: islogin()
 178: {
 179: 
 180:     if (chkstop == 0 && setintr)
 181:         panystop(0);
 182:     if (loginsh)
 183:         return;
 184:     error("Not login shell");
 185: }
 186: 
 187: doif(v, kp)
 188:     char **v;
 189:     struct command *kp;
 190: {
 191:     register int i;
 192:     register char **vv;
 193: 
 194:     v++;
 195:     i = exp(&v);
 196:     vv = v;
 197:     if (*vv == NOSTR)
 198:         bferr("Empty if");
 199:     if (eq(*vv, "then")) {
 200:         if (*++vv)
 201:             bferr("Improper then");
 202:         setname("then");
 203:         /*
 204: 		 * If expression was zero, then scan to else,
 205: 		 * otherwise just fall into following code.
 206: 		 */
 207:         if (!i)
 208:             search(ZIF, 0);
 209:         return;
 210:     }
 211:     /*
 212: 	 * Simple command attached to this if.
 213: 	 * Left shift the node in this tree, munging it
 214: 	 * so we can reexecute it.
 215: 	 */
 216:     if (i) {
 217:         lshift(kp->t_dcom, vv - kp->t_dcom);
 218:         reexecute(kp);
 219:         donefds();
 220:     }
 221: }
 222: 
 223: /*
 224:  * Reexecute a command, being careful not
 225:  * to redo i/o redirection, which is already set up.
 226:  */
 227: reexecute(kp)
 228:     register struct command *kp;
 229: {
 230: 
 231:     kp->t_dflg &= FSAVE;
 232:     kp->t_dflg |= FREDO;
 233:     /*
 234: 	 * If tty is still ours to arbitrate, arbitrate it;
 235: 	 * otherwise dont even set pgrp's as the jobs would
 236: 	 * then have no way to get the tty (we can't give it
 237: 	 * to them, and our parent wouldn't know their pgrp, etc.
 238: 	 */
 239:     execute(kp, tpgrp > 0 ? tpgrp : -1);
 240: }
 241: 
 242: doelse()
 243: {
 244: 
 245:     search(ZELSE, 0);
 246: }
 247: 
 248: dogoto(v)
 249:     char **v;
 250: {
 251:     register struct whyle *wp;
 252:     char *lp;
 253: 
 254:     /*
 255: 	 * While we still can, locate any unknown ends of existing loops.
 256: 	 * This obscure code is the WORST result of the fact that we
 257: 	 * don't really parse.
 258: 	 */
 259:     for (wp = whyles; wp; wp = wp->w_next)
 260:         if (wp->w_end == 0) {
 261:             search(ZBREAK, 0);
 262:             wp->w_end = btell();
 263:         } else
 264:             bseek(wp->w_end);
 265:     search(ZGOTO, 0, lp = globone(v[1]));
 266:     xfree(lp);
 267:     /*
 268: 	 * Eliminate loops which were exited.
 269: 	 */
 270:     wfree();
 271: }
 272: 
 273: doswitch(v)
 274:     register char **v;
 275: {
 276:     register char *cp, *lp;
 277: 
 278:     v++;
 279:     if (!*v || *(*v++) != '(')
 280:         goto syntax;
 281:     cp = **v == ')' ? "" : *v++;
 282:     if (*(*v++) != ')')
 283:         v--;
 284:     if (*v)
 285: syntax:
 286:         error("Syntax error");
 287:     search(ZSWITCH, 0, lp = globone(cp));
 288:     xfree(lp);
 289: }
 290: 
 291: dobreak()
 292: {
 293: 
 294:     if (whyles)
 295:         toend();
 296:     else
 297:         bferr("Not in while/foreach");
 298: }
 299: 
 300: doexit(v)
 301:     char **v;
 302: {
 303: 
 304:     if (chkstop == 0)
 305:         panystop(0);
 306:     /*
 307: 	 * Don't DEMAND parentheses here either.
 308: 	 */
 309:     v++;
 310:     if (*v) {
 311:         set("status", putn(exp(&v)));
 312:         if (*v)
 313:             bferr("Expression syntax");
 314:     }
 315:     btoeof();
 316:     if (intty)
 317:         close(SHIN);
 318: }
 319: 
 320: doforeach(v)
 321:     register char **v;
 322: {
 323:     register char *cp;
 324:     register struct whyle *nwp;
 325: 
 326:     v++;
 327:     cp = strip(*v);
 328:     while (*cp && letter(*cp))
 329:         cp++;
 330:     if (*cp || strlen(*v) >= 20)
 331:         bferr("Invalid variable");
 332:     cp = *v++;
 333:     if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')')
 334:         bferr("Words not ()'ed");
 335:     v++;
 336:     gflag = 0, rscan(v, tglob);
 337:     v = glob(v);
 338:     if (v == 0)
 339:         bferr("No match");
 340:     nwp = (struct whyle *) calloc(1, sizeof *nwp);
 341:     nwp->w_fe = nwp->w_fe0 = v; gargv = 0;
 342:     nwp->w_start = btell();
 343:     nwp->w_fename = savestr(cp);
 344:     nwp->w_next = whyles;
 345:     whyles = nwp;
 346:     /*
 347: 	 * Pre-read the loop so as to be more
 348: 	 * comprehensible to a terminal user.
 349: 	 */
 350:     if (intty)
 351:         preread();
 352:     doagain();
 353: }
 354: 
 355: dowhile(v)
 356:     char **v;
 357: {
 358:     register int status;
 359:     register bool again = whyles != 0 && whyles->w_start == lineloc &&
 360:         whyles->w_fename == 0;
 361: 
 362:     v++;
 363:     /*
 364: 	 * Implement prereading here also, taking care not to
 365: 	 * evaluate the expression before the loop has been read up
 366: 	 * from a terminal.
 367: 	 */
 368:     if (intty && !again)
 369:         status = !exp0(&v, 1);
 370:     else
 371:         status = !exp(&v);
 372:     if (*v)
 373:         bferr("Expression syntax");
 374:     if (!again) {
 375:         register struct whyle *nwp = (struct whyle *) calloc(1, sizeof (*nwp));
 376: 
 377:         nwp->w_start = lineloc;
 378:         nwp->w_end = 0;
 379:         nwp->w_next = whyles;
 380:         whyles = nwp;
 381:         if (intty) {
 382:             /*
 383: 			 * The tty preread
 384: 			 */
 385:             preread();
 386:             doagain();
 387:             return;
 388:         }
 389:     }
 390:     if (status)
 391:         /* We ain't gonna loop no more, no more! */
 392:         toend();
 393: }
 394: 
 395: preread()
 396: {
 397: 
 398:     whyles->w_end = -1;
 399:     if (setintr)
 400:         sigrelse(SIGINT);
 401:     search(ZBREAK, 0);
 402:     if (setintr)
 403:         sighold(SIGINT);
 404:     whyles->w_end = btell();
 405: }
 406: 
 407: doend()
 408: {
 409: 
 410:     if (!whyles)
 411:         bferr("Not in while/foreach");
 412:     whyles->w_end = btell();
 413:     doagain();
 414: }
 415: 
 416: docontin()
 417: {
 418: 
 419:     if (!whyles)
 420:         bferr("Not in while/foreach");
 421:     doagain();
 422: }
 423: 
 424: doagain()
 425: {
 426: 
 427:     /* Repeating a while is simple */
 428:     if (whyles->w_fename == 0) {
 429:         bseek(whyles->w_start);
 430:         return;
 431:     }
 432:     /*
 433: 	 * The foreach variable list actually has a spurious word
 434: 	 * ")" at the end of the w_fe list.  Thus we are at the
 435: 	 * of the list if one word beyond this is 0.
 436: 	 */
 437:     if (!whyles->w_fe[1]) {
 438:         dobreak();
 439:         return;
 440:     }
 441:     set(whyles->w_fename, savestr(*whyles->w_fe++));
 442:     bseek(whyles->w_start);
 443: }
 444: 
 445: dorepeat(v, kp)
 446:     char **v;
 447:     struct command *kp;
 448: {
 449:     register int i;
 450: 
 451:     i = getn(v[1]);
 452:     if (setintr)
 453:         sighold(SIGINT);
 454:     lshift(v, 2);
 455:     while (i > 0) {
 456:         if (setintr)
 457:             sigrelse(SIGINT);
 458:         reexecute(kp);
 459:         --i;
 460:     }
 461:     donefds();
 462:     if (setintr)
 463:         sigrelse(SIGINT);
 464: }
 465: 
 466: doswbrk()
 467: {
 468: 
 469:     search(ZBRKSW, 0);
 470: }
 471: 
 472: srchx(cp)
 473:     register char *cp;
 474: {
 475:     register struct srch *sp;
 476: 
 477:     for (sp = srchn; sp->s_name; sp++)
 478:         if (eq(cp, sp->s_name))
 479:             return (sp->s_value);
 480:     return (-1);
 481: }
 482: 
 483: char    Stype;
 484: char    *Sgoal;
 485: 
 486: /*VARARGS2*/
 487: search(type, level, goal)
 488:     int type;
 489:     register int level;
 490:     char *goal;
 491: {
 492:     char wordbuf[BUFSIZ];
 493:     register char *aword = wordbuf;
 494:     register char *cp;
 495: 
 496:     Stype = type; Sgoal = goal;
 497:     if (type == ZGOTO)
 498:         bseek(0l);
 499:     do {
 500:         if (intty && fseekp == feobp)
 501:             printf("? "), flush();
 502:         aword[0] = 0, getword(aword);
 503:         switch (srchx(aword)) {
 504: 
 505:         case ZELSE:
 506:             if (level == 0 && type == ZIF)
 507:                 return;
 508:             break;
 509: 
 510:         case ZIF:
 511:             while (getword(aword))
 512:                 continue;
 513:             if ((type == ZIF || type == ZELSE) && eq(aword, "then"))
 514:                 level++;
 515:             break;
 516: 
 517:         case ZENDIF:
 518:             if (type == ZIF || type == ZELSE)
 519:                 level--;
 520:             break;
 521: 
 522:         case ZFOREACH:
 523:         case ZWHILE:
 524:             if (type == ZBREAK)
 525:                 level++;
 526:             break;
 527: 
 528:         case ZEND:
 529:             if (type == ZBREAK)
 530:                 level--;
 531:             break;
 532: 
 533:         case ZSWITCH:
 534:             if (type == ZSWITCH || type == ZBRKSW)
 535:                 level++;
 536:             break;
 537: 
 538:         case ZENDSW:
 539:             if (type == ZSWITCH || type == ZBRKSW)
 540:                 level--;
 541:             break;
 542: 
 543:         case ZLABEL:
 544:             if (type == ZGOTO && getword(aword) && eq(aword, goal))
 545:                 level = -1;
 546:             break;
 547: 
 548:         default:
 549:             if (type != ZGOTO && (type != ZSWITCH || level != 0))
 550:                 break;
 551:             if (lastchr(aword) != ':')
 552:                 break;
 553:             aword[strlen(aword) - 1] = 0;
 554:             if (type == ZGOTO && eq(aword, goal) || type == ZSWITCH && eq(aword, "default"))
 555:                 level = -1;
 556:             break;
 557: 
 558:         case ZCASE:
 559:             if (type != ZSWITCH || level != 0)
 560:                 break;
 561:             getword(aword);
 562:             if (lastchr(aword) == ':')
 563:                 aword[strlen(aword) - 1] = 0;
 564:             cp = strip(Dfix1(aword));
 565:             if (Gmatch(goal, cp))
 566:                 level = -1;
 567:             xfree(cp);
 568:             break;
 569: 
 570:         case ZDEFAULT:
 571:             if (type == ZSWITCH && level == 0)
 572:                 level = -1;
 573:             break;
 574:         }
 575:         getword(NOSTR);
 576:     } while (level >= 0);
 577: }
 578: 
 579: getword(wp)
 580:     register char *wp;
 581: {
 582:     register int found = 0;
 583:     register int c, d;
 584: 
 585:     c = readc(1);
 586:     d = 0;
 587:     do {
 588:         while (c == ' ' || c == '\t')
 589:             c = readc(1);
 590:         if (c == '#')
 591:             do
 592:                 c = readc(1);
 593:             while (c >= 0 && c != '\n');
 594:         if (c < 0)
 595:             goto past;
 596:         if (c == '\n') {
 597:             if (wp)
 598:                 break;
 599:             return (0);
 600:         }
 601:         unreadc(c);
 602:         found = 1;
 603:         do {
 604:             c = readc(1);
 605:             if (c == '\\' && (c = readc(1)) == '\n')
 606:                 c = ' ';
 607:             if (any(c, "'\""))
 608:                 if (d == 0)
 609:                     d = c;
 610:                 else if (d == c)
 611:                     d = 0;
 612:             if (c < 0)
 613:                 goto past;
 614:             if (wp)
 615:                 *wp++ = c;
 616:         } while ((d || c != ' ' && c != '\t') && c != '\n');
 617:     } while (wp == 0);
 618:     unreadc(c);
 619:     if (found)
 620:         *--wp = 0;
 621:     return (found);
 622: 
 623: past:
 624:     switch (Stype) {
 625: 
 626:     case ZIF:
 627:         bferr("then/endif not found");
 628: 
 629:     case ZELSE:
 630:         bferr("endif not found");
 631: 
 632:     case ZBRKSW:
 633:     case ZSWITCH:
 634:         bferr("endsw not found");
 635: 
 636:     case ZBREAK:
 637:         bferr("end not found");
 638: 
 639:     case ZGOTO:
 640:         setname(Sgoal);
 641:         bferr("label not found");
 642:     }
 643:     /*NOTREACHED*/
 644: }
 645: 
 646: toend()
 647: {
 648: 
 649:     if (whyles->w_end == 0) {
 650:         search(ZBREAK, 0);
 651:         whyles->w_end = btell() - 1;
 652:     } else
 653:         bseek(whyles->w_end);
 654:     wfree();
 655: }
 656: 
 657: wfree()
 658: {
 659:     long o = btell();
 660: 
 661:     while (whyles) {
 662:         register struct whyle *wp = whyles;
 663:         register struct whyle *nwp = wp->w_next;
 664: 
 665:         if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end))
 666:             break;
 667:         if (wp->w_fe0)
 668:             blkfree(wp->w_fe0);
 669:         if (wp->w_fename)
 670:             xfree(wp->w_fename);
 671:         xfree((char *)wp);
 672:         whyles = nwp;
 673:     }
 674: }
 675: 
 676: doecho(v)
 677:     char **v;
 678: {
 679: 
 680:     echo(' ', v);
 681: }
 682: 
 683: doglob(v)
 684:     char **v;
 685: {
 686: 
 687:     echo(0, v);
 688:     flush();
 689: }
 690: 
 691: echo(sep, v)
 692:     char sep;
 693:     register char **v;
 694: {
 695:     register char *cp;
 696:     int nonl = 0;
 697: 
 698:     if (setintr)
 699:         sigrelse(SIGINT);
 700:     v++;
 701:     if (*v == 0)
 702:         return;
 703:     gflag = 0; rscan(v, tglob);
 704:     if (gflag) {
 705:         v = glob(v);
 706:         if (v == 0)
 707:             bferr("No match");
 708:     } else
 709:         scan(v, trim);
 710:     if (sep == ' ' && !strcmp(*v, "-n"))
 711:         nonl++, v++;
 712:     while (cp = *v++) {
 713:         register int c;
 714: 
 715:         while (c = *cp++)
 716:             putchar(c | QUOTE);
 717:         if (*v)
 718:             putchar(sep | QUOTE);
 719:     }
 720:     if (sep && nonl == 0)
 721:         putchar('\n');
 722:     else
 723:         flush();
 724:     if (setintr)
 725:         sighold(SIGINT);
 726:     if (gargv)
 727:         blkfree(gargv), gargv = 0;
 728: }
 729: 
 730: char    **environ;
 731: 
 732: dosetenv(v)
 733:     register char **v;
 734: {
 735:     char *lp = globone(v[2]);
 736: 
 737:     setenv(v[1], lp);
 738:     if (eq(v[1], "PATH")) {
 739:         importpath(lp);
 740:         dohash();
 741:     }
 742:     xfree(lp);
 743: }
 744: 
 745: dounsetenv(v)
 746:     register char **v;
 747: {
 748: 
 749:     v++;
 750:     do
 751:         unsetenv(*v++);
 752:     while (*v);
 753: }
 754: 
 755: setenv(name, value)
 756:     char *name, *value;
 757: {
 758:     register char **ep = environ;
 759:     register char *cp, *dp;
 760:     char *blk[2], **oep = ep;
 761: 
 762:     for (; *ep; ep++) {
 763:         for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
 764:             continue;
 765:         if (*cp != 0 || *dp != '=')
 766:             continue;
 767:         cp = strspl("=", value);
 768:         xfree(*ep);
 769:         *ep = strspl(name, cp);
 770:         xfree(cp);
 771:         scan(ep, trim);
 772:         return;
 773:     }
 774:     blk[0] = strspl(name, "="); blk[1] = 0;
 775:     environ = blkspl(environ, blk);
 776:     xfree((char *)oep);
 777:     setenv(name, value);
 778: }
 779: 
 780: unsetenv(name)
 781:     char *name;
 782: {
 783:     register char **ep = environ;
 784:     register char *cp, *dp;
 785:     char **oep = ep;
 786: 
 787:     for (; *ep; ep++) {
 788:         for (cp = name, dp = *ep; *cp && *cp == *dp; cp++, dp++)
 789:             continue;
 790:         if (*cp != 0 || *dp != '=')
 791:             continue;
 792:         cp = *ep;
 793:         *ep = 0;
 794:         environ = blkspl(environ, ep+1);
 795:         *ep = cp;
 796:         xfree(cp);
 797:         xfree((char *)oep);
 798:         return;
 799:     }
 800: }
 801: 
 802: doumask(v)
 803:     register char **v;
 804: {
 805:     register char *cp = v[1];
 806:     register int i;
 807: 
 808:     if (cp == 0) {
 809:         i = umask(0);
 810:         umask(i);
 811:         printf("%o\n", i);
 812:         return;
 813:     }
 814:     i = 0;
 815:     while (digit(*cp) && *cp != '8' && *cp != '9')
 816:         i = i * 8 + *cp++ - '0';
 817:     if (*cp || i < 0 || i > 0777)
 818:         bferr("Improper mask");
 819:     umask(i);
 820: }
 821: #ifdef LIMITS
 822: #include <sys/vlimit.h>
 823: 
 824: struct limits {
 825:     int limconst;
 826:     char    *limname;
 827:     int limdiv;
 828:     char    *limscale;
 829: } limits[] = {
 830:     LIM_NORAISE,    "noraise",  1,  "",
 831:     LIM_CPU,    "cputime",  1,  "seconds",
 832:     LIM_FSIZE,  "filesize", 1024,   "kbytes",
 833:     LIM_DATA,   "datasize", 1024,   "kbytes",
 834:     LIM_STACK,  "stacksize",    1024,   "kbytes",
 835:     LIM_CORE,   "coredumpsize", 1024,   "kbytes",
 836:     LIM_MAXRSS, "memoryuse",    1024,   "kbytes",
 837:     -1,     0,
 838: };
 839: 
 840: struct limits *
 841: findlim(cp)
 842:     char *cp;
 843: {
 844:     register struct limits *lp, *res;
 845: 
 846:     res = 0;
 847:     for (lp = limits; lp->limconst >= 0; lp++)
 848:         if (prefix(cp, lp->limname)) {
 849:             if (res)
 850:                 bferr("Ambiguous");
 851:             res = lp;
 852:         }
 853:     if (res)
 854:         return (res);
 855:     bferr("No such limit");
 856: }
 857: 
 858: dolimit(v)
 859:     register char **v;
 860: {
 861:     register struct limits *lp;
 862:     register int limit;
 863: 
 864:     v++;
 865:     if (*v == 0) {
 866:         for (lp = limits+1; lp->limconst >= 0; lp++)
 867:             plim(lp);
 868:         if (vlimit(LIM_NORAISE, -1) && getuid())
 869:             printf("Limits cannot be raised\n");
 870:         return;
 871:     }
 872:     lp = findlim(v[0]);
 873:     if (v[1] == 0) {
 874:         plim(lp);
 875:         return;
 876:     }
 877:     limit = getval(lp, v+1);
 878:     setlim(lp, limit);
 879: }
 880: 
 881: getval(lp, v)
 882:     register struct limits *lp;
 883:     char **v;
 884: {
 885:     register float f;
 886:     double atof();
 887:     char *cp = *v++;
 888: 
 889:     f = atof(cp);
 890:     while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E')
 891:         cp++;
 892:     if (*cp == 0) {
 893:         if (*v == 0)
 894:             return ((int)(f+0.5) * lp->limdiv);
 895:         cp = *v;
 896:     }
 897:     if (lp->limconst == LIM_NORAISE)
 898:         goto badscal;
 899:     switch (*cp) {
 900: 
 901:     case ':':
 902:         if (lp->limconst != LIM_CPU)
 903:             goto badscal;
 904:         return ((int)(f * 60.0 + atof(cp+1)));
 905: 
 906:     case 'h':
 907:         if (lp->limconst != LIM_CPU)
 908:             goto badscal;
 909:         limtail(cp, "hours");
 910:         f *= 3600.;
 911:         break;
 912: 
 913:     case 'm':
 914:         if (lp->limconst == LIM_CPU) {
 915:             limtail(cp, "minutes");
 916:             f *= 60.;
 917:             break;
 918:         }
 919:     case 'M':
 920:         if (lp->limconst == LIM_CPU)
 921:             goto badscal;
 922:         *cp = 'm';
 923:         limtail(cp, "megabytes");
 924:         f *= 1024.*1024.;
 925:         break;
 926: 
 927:     case 's':
 928:         if (lp->limconst != LIM_CPU)
 929:             goto badscal;
 930:         limtail(cp, "seconds");
 931:         break;
 932: 
 933:     case 'k':
 934:         if (lp->limconst == LIM_CPU)
 935:             goto badscal;
 936:         limtail(cp, "kbytes");
 937:         f *= 1024;
 938:         break;
 939: 
 940:     case 'u':
 941:         limtail(cp, "unlimited");
 942:         return (INFINITY);
 943: 
 944:     default:
 945: badscal:
 946:         bferr("Improper or unknown scale factor");
 947:     }
 948:     return ((int)(f+0.5));
 949: }
 950: 
 951: limtail(cp, str0)
 952:     char *cp, *str0;
 953: {
 954:     register char *str = str0;
 955: 
 956:     while (*cp && *cp == *str)
 957:         cp++, str++;
 958:     if (*cp)
 959:         error("Bad scaling; did you mean ``%s''?", str0);
 960: }
 961: 
 962: plim(lp)
 963:     register struct limits *lp;
 964: {
 965:     register int lim;
 966: 
 967:     printf("%s \t", lp->limname);
 968:     lim = vlimit(lp->limconst, -1);
 969:     if (lim == INFINITY)
 970:         printf("unlimited");
 971:     else if (lp->limconst == LIM_CPU)
 972:         psecs((long)lim);
 973:     else
 974:         printf("%d %s", lim / lp->limdiv, lp->limscale);
 975:     printf("\n");
 976: }
 977: 
 978: dounlimit(v)
 979:     register char **v;
 980: {
 981:     register struct limits *lp;
 982: 
 983:     v++;
 984:     if (*v == 0) {
 985:         for (lp = limits+1; lp->limconst >= 0; lp++)
 986:             setlim(lp, INFINITY);
 987:         return;
 988:     }
 989:     while (*v) {
 990:         lp = findlim(*v++);
 991:         setlim(lp, INFINITY);
 992:     }
 993: }
 994: 
 995: setlim(lp, limit)
 996:     register struct limits *lp;
 997: {
 998: 
 999:     if (vlimit(lp->limconst, limit) < 0)
1000:         Perror(bname);
1001: }
1002: #endif
1003: 
1004: dosuspend()
1005: {
1006:     int old, ldisc;
1007:     short ctpgrp;
1008: 
1009:     if (loginsh)
1010:         error("Can't suspend a login shell (yet)");
1011:     untty();
1012:     old = sigsys(SIGTSTP, SIG_DFL);
1013:     kill(0, SIGTSTP);
1014:     /* the shell stops here */
1015:     sigsys(SIGTSTP, old);
1016:     if (tpgrp != -1) {
1017: retry:
1018:         ioctl(FSHTTY, TIOCGPGRP, &ctpgrp);
1019:         if (ctpgrp != opgrp) {
1020:             old = sigsys(SIGTTIN, SIG_DFL);
1021:             kill(0, SIGTTIN);
1022:             sigsys(SIGTTIN, old);
1023:             goto retry;
1024:         }
1025:         ioctl(FSHTTY, TIOCSPGRP, &shpgrp);
1026:         setpgrp(0, shpgrp);
1027:     }
1028:     ioctl(FSHTTY, TIOCGETD, &oldisc);
1029:     if (oldisc != NTTYDISC) {
1030:         printf("Switching to new tty driver...\n");
1031:         ldisc = NTTYDISC;
1032:         ioctl(FSHTTY, TIOCSETD, &ldisc);
1033:     }
1034: }
1035: 
1036: doeval(v)
1037:     char **v;
1038: {
1039:     char **oevalvec = evalvec;
1040:     char *oevalp = evalp;
1041:     jmp_buf osetexit;
1042:     int reenter;
1043:     char **gv = 0;
1044: 
1045:     v++;
1046:     if (*v == 0)
1047:         return;
1048:     gflag = 0; rscan(v, tglob);
1049:     if (gflag) {
1050:         gv = v = glob(v);
1051:         gargv = 0;
1052:         if (v == 0)
1053:             error("No match");
1054:         v = copyblk(v);
1055:     } else
1056:         scan(v, trim);
1057:     getexit(osetexit);
1058:     reenter = 0;
1059:     setexit();
1060:     reenter++;
1061:     if (reenter == 1) {
1062:         evalvec = v;
1063:         evalp = 0;
1064:         process(0);
1065:     }
1066:     evalvec = oevalvec;
1067:     evalp = oevalp;
1068:     doneinp = 0;
1069:     if (gv)
1070:         blkfree(gv);
1071:     resexit(osetexit);
1072:     if (reenter >= 2)
1073:         error(NOSTR);
1074: }

Defined functions

doagain defined in line 424; used 4 times
doalias defined in line 116; used 2 times
dobreak defined in line 291; used 3 times
docontin defined in line 416; used 2 times
doecho defined in line 676; used 2 times
doelse defined in line 242; used 2 times
doend defined in line 407; used 2 times
doeval defined in line 1036; used 2 times
doexit defined in line 300; used 2 times
doforeach defined in line 320; used 2 times
doglob defined in line 683; used 2 times
dogoto defined in line 248; used 2 times
doif defined in line 187; used 2 times
dolabel defined in line 60; used 2 times
dolimit defined in line 858; used 2 times
dologin defined in line 153; used 2 times
dologout defined in line 146; used 2 times
donewgrp defined in line 164; used 2 times
donohup defined in line 91; used 2 times
doonintr defined in line 65; used 2 times
dorepeat defined in line 445; used 2 times
dosetenv defined in line 732; used 2 times
dosuspend defined in line 1004; used 2 times
doswbrk defined in line 466; used 2 times
doswitch defined in line 273; used 2 times
doumask defined in line 802; used 2 times
dounlimit defined in line 978; used 2 times
dounsetenv defined in line 745; used 2 times
dowhile defined in line 355; used 2 times
dozip defined in line 104; used 5 times
echo defined in line 691; used 2 times
findlim defined in line 840; used 2 times
func defined in line 44; used 1 times
getval defined in line 881; used 1 times
getword defined in line 579; used 5 times
isbfunc defined in line 10; used 2 times
islogin defined in line 177; used 2 times
limtail defined in line 951; used 6 times
plim defined in line 962; used 2 times
preread defined in line 395; used 2 times
prvars defined in line 110; used 2 times
reexecute defined in line 227; used 2 times
search defined in line 487; used 9 times
setenv defined in line 755; used 6 times
setlim defined in line 995; used 3 times
srchx defined in line 472; used 2 times
toend defined in line 646; used 2 times
unalias defined in line 139; used 2 times
unsetenv defined in line 780; used 1 times
wfree defined in line 657; used 3 times

Defined variables

Sgoal defined in line 484; used 2 times
Stype defined in line 483; used 2 times
environ defined in line 730; used 6 times
limits defined in line 829; used 3 times
sccsid defined in line 1; never used

Defined struct's

limits defined in line 824; used 14 times
Last modified: 1981-11-29
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 2661
Valid CSS Valid XHTML 1.0 Strict