17c478bd9Sstevel@tonic-gate /*
270a587ddSchin * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
37c478bd9Sstevel@tonic-gate * Use is subject to license terms.
47c478bd9Sstevel@tonic-gate */
57c478bd9Sstevel@tonic-gate
67c478bd9Sstevel@tonic-gate /* Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
77c478bd9Sstevel@tonic-gate /* All Rights Reserved */
87c478bd9Sstevel@tonic-gate
97c478bd9Sstevel@tonic-gate /*
107c478bd9Sstevel@tonic-gate * Copyright (c) 1980 Regents of the University of California.
117c478bd9Sstevel@tonic-gate * All rights reserved. The Berkeley Software License Agreement
127c478bd9Sstevel@tonic-gate * specifies the terms and conditions for redistribution.
137c478bd9Sstevel@tonic-gate */
147c478bd9Sstevel@tonic-gate
157c478bd9Sstevel@tonic-gate #include "sh.h"
167c478bd9Sstevel@tonic-gate #include <locale.h> /* For LC_ALL */
177c478bd9Sstevel@tonic-gate #include "sh.tconst.h"
187c478bd9Sstevel@tonic-gate #include <sys/types.h>
197c478bd9Sstevel@tonic-gate #include <stdlib.h>
207c478bd9Sstevel@tonic-gate
217c478bd9Sstevel@tonic-gate /*
227c478bd9Sstevel@tonic-gate * N.B.: Some of the limits change from SunOS 4.x to SunOS 5.0. In
237c478bd9Sstevel@tonic-gate * particular, RLIMIT_RSS is gone and RLIMIT_VMEM is new. Beware of consusing
247c478bd9Sstevel@tonic-gate * the keywords that the command prints for these two. The old one was
257c478bd9Sstevel@tonic-gate * "memoryuse" and the new one is "memorysize". Note also that a given limit
267c478bd9Sstevel@tonic-gate * doesn't necessarily appear in the same position in the two releases.
277c478bd9Sstevel@tonic-gate */
287c478bd9Sstevel@tonic-gate struct limits {
297c478bd9Sstevel@tonic-gate int limconst;
307c478bd9Sstevel@tonic-gate tchar *limname;
317c478bd9Sstevel@tonic-gate int limdiv;
327c478bd9Sstevel@tonic-gate tchar *limscale;
337c478bd9Sstevel@tonic-gate } limits[] = {
347c478bd9Sstevel@tonic-gate RLIMIT_CPU, S_cputime, /* "cputime" */
357c478bd9Sstevel@tonic-gate 1, S_seconds, /* "seconds" */
367c478bd9Sstevel@tonic-gate RLIMIT_FSIZE, S_filesize, /* "filesize" */
377c478bd9Sstevel@tonic-gate 1024, S_kbytes, /* "kbytes" */
387c478bd9Sstevel@tonic-gate RLIMIT_DATA, S_datasize, /* "datasize" */
397c478bd9Sstevel@tonic-gate 1024, S_kbytes, /* "kbytes" */
407c478bd9Sstevel@tonic-gate RLIMIT_STACK, S_stacksize, /* "stacksize" */
417c478bd9Sstevel@tonic-gate 1024, S_kbytes, /* "kbytes" */
427c478bd9Sstevel@tonic-gate RLIMIT_CORE, S_coredumpsize, /* "coredumpsize" */
437c478bd9Sstevel@tonic-gate 1024, S_kbytes, /* "kbytes" */
447c478bd9Sstevel@tonic-gate RLIMIT_NOFILE, S_descriptors, /* "descriptors" */
457c478bd9Sstevel@tonic-gate 1, S_, /* "" */
467c478bd9Sstevel@tonic-gate RLIMIT_VMEM, S_memorysize, /* "memorysize" */
477c478bd9Sstevel@tonic-gate 1024, S_kbytes, /* "kbytes" */
487c478bd9Sstevel@tonic-gate -1, 0,
497c478bd9Sstevel@tonic-gate };
507c478bd9Sstevel@tonic-gate
51*258f91c6SToomas Soome struct Bin B;
52*258f91c6SToomas Soome struct whyle *whyles;
53*258f91c6SToomas Soome bool chkstop;
54*258f91c6SToomas Soome bool doneinp;
55*258f91c6SToomas Soome bool intty;
56*258f91c6SToomas Soome bool setintr;
57*258f91c6SToomas Soome int shpgrp;
58*258f91c6SToomas Soome int opgrp;
59*258f91c6SToomas Soome off_t lineloc;
60*258f91c6SToomas Soome tchar *evalp;
61*258f91c6SToomas Soome tchar **evalvec;
62*258f91c6SToomas Soome tchar *gointr;
63*258f91c6SToomas Soome
646c02b4a4Smuffin
657c478bd9Sstevel@tonic-gate static int getval(struct limits *lp, tchar **v, rlim_t *);
666c02b4a4Smuffin void islogin(void);
676c02b4a4Smuffin int dolabel(void);
687c478bd9Sstevel@tonic-gate void reexecute(struct command *kp);
696c02b4a4Smuffin void preread_(void);
706c02b4a4Smuffin void doagain(void);
716c02b4a4Smuffin void toend(void);
726c02b4a4Smuffin void wfree(void);
737c478bd9Sstevel@tonic-gate void echo(tchar sep, tchar **v);
747c478bd9Sstevel@tonic-gate void local_setenv(tchar *name, tchar *val);
757c478bd9Sstevel@tonic-gate void local_unsetenv(tchar *name);
767c478bd9Sstevel@tonic-gate void limtail(tchar *cp, tchar *str0);
777c478bd9Sstevel@tonic-gate void plim(struct limits *lp, tchar hard);
787c478bd9Sstevel@tonic-gate void search();
797c478bd9Sstevel@tonic-gate
807c478bd9Sstevel@tonic-gate #define BUFSZ 1028
817c478bd9Sstevel@tonic-gate
827c478bd9Sstevel@tonic-gate /*
837c478bd9Sstevel@tonic-gate * C shell
847c478bd9Sstevel@tonic-gate */
857c478bd9Sstevel@tonic-gate
866c02b4a4Smuffin struct biltins *
isbfunc(struct command * t)877c478bd9Sstevel@tonic-gate isbfunc(struct command *t)
887c478bd9Sstevel@tonic-gate {
897c478bd9Sstevel@tonic-gate tchar *cp = t->t_dcom[0];
907c478bd9Sstevel@tonic-gate struct biltins *bp, *bp1, *bp2;
917c478bd9Sstevel@tonic-gate int dofg1(), dobg1();
927c478bd9Sstevel@tonic-gate
937c478bd9Sstevel@tonic-gate static struct biltins label = { S_, dolabel, 0, 0 };
947c478bd9Sstevel@tonic-gate static struct biltins foregnd = { S_Pjob, dofg1, 0, 0 };
957c478bd9Sstevel@tonic-gate static struct biltins backgnd = { S_PjobAND, dobg1, 0, 0 };
967c478bd9Sstevel@tonic-gate #ifdef TRACE
977c478bd9Sstevel@tonic-gate tprintf("TRACE- isbfunc()\n");
987c478bd9Sstevel@tonic-gate #endif
997c478bd9Sstevel@tonic-gate if (lastchr(cp) == ':') {
1007c478bd9Sstevel@tonic-gate label.bname = cp;
1017c478bd9Sstevel@tonic-gate return (&label);
1027c478bd9Sstevel@tonic-gate }
1037c478bd9Sstevel@tonic-gate if (*cp == '%') {
1047c478bd9Sstevel@tonic-gate if (t->t_dflg & FAND) {
1057c478bd9Sstevel@tonic-gate t->t_dflg &= ~FAND;
1067c478bd9Sstevel@tonic-gate backgnd.bname = cp;
1077c478bd9Sstevel@tonic-gate return (&backgnd);
1087c478bd9Sstevel@tonic-gate }
1097c478bd9Sstevel@tonic-gate foregnd.bname = cp;
1107c478bd9Sstevel@tonic-gate return (&foregnd);
1117c478bd9Sstevel@tonic-gate }
1127c478bd9Sstevel@tonic-gate /*
1137c478bd9Sstevel@tonic-gate * Binary search
1147c478bd9Sstevel@tonic-gate * Bp1 is the beginning of the current search range.
1157c478bd9Sstevel@tonic-gate * Bp2 is one past the end.
1167c478bd9Sstevel@tonic-gate */
1177c478bd9Sstevel@tonic-gate for (bp1 = bfunc, bp2 = bfunc + nbfunc; bp1 < bp2; ) {
1187c478bd9Sstevel@tonic-gate int i;
1197c478bd9Sstevel@tonic-gate
1207c478bd9Sstevel@tonic-gate bp = bp1 + (bp2 - bp1 >> 1);
1217c478bd9Sstevel@tonic-gate if ((i = *cp - *bp->bname) == 0 &&
1227c478bd9Sstevel@tonic-gate (i = strcmp_(cp, bp->bname)) == 0) {
1237c478bd9Sstevel@tonic-gate return (bp);
1247c478bd9Sstevel@tonic-gate }
1257c478bd9Sstevel@tonic-gate if (i < 0) {
1267c478bd9Sstevel@tonic-gate bp2 = bp;
1277c478bd9Sstevel@tonic-gate } else {
1287c478bd9Sstevel@tonic-gate bp1 = bp + 1;
1297c478bd9Sstevel@tonic-gate }
1307c478bd9Sstevel@tonic-gate }
1317c478bd9Sstevel@tonic-gate return (0);
1327c478bd9Sstevel@tonic-gate }
1337c478bd9Sstevel@tonic-gate
1347c478bd9Sstevel@tonic-gate void
func(struct command * t,struct biltins * bp)1357c478bd9Sstevel@tonic-gate func(struct command *t, struct biltins *bp)
1367c478bd9Sstevel@tonic-gate {
1377c478bd9Sstevel@tonic-gate int i;
1387c478bd9Sstevel@tonic-gate
1397c478bd9Sstevel@tonic-gate #ifdef TRACE
1407c478bd9Sstevel@tonic-gate tprintf("TRACE- func()\n");
1417c478bd9Sstevel@tonic-gate #endif
1427c478bd9Sstevel@tonic-gate xechoit(t->t_dcom);
1437c478bd9Sstevel@tonic-gate setname(bp->bname);
1447c478bd9Sstevel@tonic-gate i = blklen(t->t_dcom) - 1;
1457c478bd9Sstevel@tonic-gate if (i < bp->minargs) {
1467c478bd9Sstevel@tonic-gate bferr("Too few arguments");
1477c478bd9Sstevel@tonic-gate }
1487c478bd9Sstevel@tonic-gate if (i > bp->maxargs) {
1497c478bd9Sstevel@tonic-gate bferr("Too many arguments");
1507c478bd9Sstevel@tonic-gate }
1517c478bd9Sstevel@tonic-gate (*bp->bfunct)(t->t_dcom, t);
1527c478bd9Sstevel@tonic-gate }
1537c478bd9Sstevel@tonic-gate
1547c478bd9Sstevel@tonic-gate int
dolabel(void)1556c02b4a4Smuffin dolabel(void)
1567c478bd9Sstevel@tonic-gate {
1577c478bd9Sstevel@tonic-gate #ifdef TRACE
1587c478bd9Sstevel@tonic-gate tprintf("TRACE- dolabel()\n");
1597c478bd9Sstevel@tonic-gate #endif
1606c02b4a4Smuffin return (0);
1617c478bd9Sstevel@tonic-gate }
1627c478bd9Sstevel@tonic-gate
1637c478bd9Sstevel@tonic-gate void
doonintr(tchar ** v)1647c478bd9Sstevel@tonic-gate doonintr(tchar **v)
1657c478bd9Sstevel@tonic-gate {
1667c478bd9Sstevel@tonic-gate tchar *cp;
1677c478bd9Sstevel@tonic-gate tchar *vv = v[1];
1687c478bd9Sstevel@tonic-gate
1697c478bd9Sstevel@tonic-gate #ifdef TRACE
1707c478bd9Sstevel@tonic-gate tprintf("TRACE- doonintr()\n");
1717c478bd9Sstevel@tonic-gate #endif
1727c478bd9Sstevel@tonic-gate if (parintr == SIG_IGN) {
1737c478bd9Sstevel@tonic-gate return;
1747c478bd9Sstevel@tonic-gate }
1757c478bd9Sstevel@tonic-gate if (setintr && intty) {
1767c478bd9Sstevel@tonic-gate bferr("Can't from terminal");
1777c478bd9Sstevel@tonic-gate }
1787c478bd9Sstevel@tonic-gate cp = gointr, gointr = 0, xfree(cp);
1797c478bd9Sstevel@tonic-gate if (vv == 0) {
1807c478bd9Sstevel@tonic-gate if (setintr) {
1817c478bd9Sstevel@tonic-gate (void) sigblock(sigmask(SIGINT));
1827c478bd9Sstevel@tonic-gate } else {
1837c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_DFL);
1847c478bd9Sstevel@tonic-gate }
1857c478bd9Sstevel@tonic-gate gointr = 0;
1867c478bd9Sstevel@tonic-gate } else if (eq((vv = strip(vv)), S_MINUS)) {
1877c478bd9Sstevel@tonic-gate (void) signal(SIGINT, SIG_IGN);
1887c478bd9Sstevel@tonic-gate gointr = S_MINUS;
1897c478bd9Sstevel@tonic-gate } else {
1907c478bd9Sstevel@tonic-gate gointr = savestr(vv);
1917c478bd9Sstevel@tonic-gate (void) signal(SIGINT, pintr);
1927c478bd9Sstevel@tonic-gate }
1937c478bd9Sstevel@tonic-gate }
1947c478bd9Sstevel@tonic-gate
1957c478bd9Sstevel@tonic-gate void
donohup(void)1966c02b4a4Smuffin donohup(void)
1977c478bd9Sstevel@tonic-gate {
1987c478bd9Sstevel@tonic-gate
1997c478bd9Sstevel@tonic-gate #ifdef TRACE
2007c478bd9Sstevel@tonic-gate tprintf("TRACE- donohup()\n");
2017c478bd9Sstevel@tonic-gate #endif
2027c478bd9Sstevel@tonic-gate if (intty) {
2037c478bd9Sstevel@tonic-gate bferr("Can't from terminal");
2047c478bd9Sstevel@tonic-gate }
2057c478bd9Sstevel@tonic-gate if (setintr == 0) {
2067c478bd9Sstevel@tonic-gate (void) signal(SIGHUP, SIG_IGN);
2077c478bd9Sstevel@tonic-gate #ifdef CC
2087c478bd9Sstevel@tonic-gate submit(getpid());
2097c478bd9Sstevel@tonic-gate #endif
2107c478bd9Sstevel@tonic-gate }
2117c478bd9Sstevel@tonic-gate }
2127c478bd9Sstevel@tonic-gate
2137c478bd9Sstevel@tonic-gate void
dozip(void)2146c02b4a4Smuffin dozip(void)
2157c478bd9Sstevel@tonic-gate {
2167c478bd9Sstevel@tonic-gate ;
2177c478bd9Sstevel@tonic-gate }
2187c478bd9Sstevel@tonic-gate
2197c478bd9Sstevel@tonic-gate void
prvars(void)2206c02b4a4Smuffin prvars(void)
2217c478bd9Sstevel@tonic-gate {
2227c478bd9Sstevel@tonic-gate #ifdef TRACE
2237c478bd9Sstevel@tonic-gate tprintf("TRACE- prvars()\n");
2247c478bd9Sstevel@tonic-gate #endif
2257c478bd9Sstevel@tonic-gate
2267c478bd9Sstevel@tonic-gate plist(&shvhed);
2277c478bd9Sstevel@tonic-gate }
2287c478bd9Sstevel@tonic-gate
2297c478bd9Sstevel@tonic-gate void
doalias(tchar ** v)2307c478bd9Sstevel@tonic-gate doalias(tchar **v)
2317c478bd9Sstevel@tonic-gate {
2327c478bd9Sstevel@tonic-gate struct varent *vp;
2337c478bd9Sstevel@tonic-gate tchar *p;
2347c478bd9Sstevel@tonic-gate
2357c478bd9Sstevel@tonic-gate #ifdef TRACE
2367c478bd9Sstevel@tonic-gate tprintf("TRACE- doalias()\n");
2377c478bd9Sstevel@tonic-gate #endif
2387c478bd9Sstevel@tonic-gate v++;
2397c478bd9Sstevel@tonic-gate p = *v++;
2407c478bd9Sstevel@tonic-gate if (p == 0) {
2417c478bd9Sstevel@tonic-gate plist(&aliases);
2427c478bd9Sstevel@tonic-gate } else if (*v == 0) {
2437c478bd9Sstevel@tonic-gate vp = adrof1(strip(p), &aliases);
2447c478bd9Sstevel@tonic-gate if (vp) {
2457c478bd9Sstevel@tonic-gate blkpr(vp->vec), printf("\n");
2467c478bd9Sstevel@tonic-gate }
2477c478bd9Sstevel@tonic-gate } else {
2487c478bd9Sstevel@tonic-gate if (eq(p, S_alias) ||
2497c478bd9Sstevel@tonic-gate eq(p, S_unalias)) {
2507c478bd9Sstevel@tonic-gate setname(p);
2517c478bd9Sstevel@tonic-gate bferr("Too dangerous to alias that");
2527c478bd9Sstevel@tonic-gate }
2537c478bd9Sstevel@tonic-gate set1(strip(p), saveblk(v), &aliases);
2547c478bd9Sstevel@tonic-gate }
2557c478bd9Sstevel@tonic-gate }
2567c478bd9Sstevel@tonic-gate
2577c478bd9Sstevel@tonic-gate void
unalias(tchar ** v)2587c478bd9Sstevel@tonic-gate unalias(tchar **v)
2597c478bd9Sstevel@tonic-gate {
2607c478bd9Sstevel@tonic-gate
2617c478bd9Sstevel@tonic-gate #ifdef TRACE
2627c478bd9Sstevel@tonic-gate tprintf("TRACE- unalias()\n");
2637c478bd9Sstevel@tonic-gate #endif
2647c478bd9Sstevel@tonic-gate unset1(v, &aliases);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate
2677c478bd9Sstevel@tonic-gate void
dologout(void)2686c02b4a4Smuffin dologout(void)
2697c478bd9Sstevel@tonic-gate {
2707c478bd9Sstevel@tonic-gate
2717c478bd9Sstevel@tonic-gate #ifdef TRACE
2727c478bd9Sstevel@tonic-gate tprintf("TRACE- dologout()\n");
2737c478bd9Sstevel@tonic-gate #endif
2747c478bd9Sstevel@tonic-gate islogin();
2757c478bd9Sstevel@tonic-gate goodbye();
2767c478bd9Sstevel@tonic-gate }
2777c478bd9Sstevel@tonic-gate
2787c478bd9Sstevel@tonic-gate void
dologin(tchar ** v)2797c478bd9Sstevel@tonic-gate dologin(tchar **v)
2807c478bd9Sstevel@tonic-gate {
2817c478bd9Sstevel@tonic-gate
2827c478bd9Sstevel@tonic-gate char *v_; /* work */
2837c478bd9Sstevel@tonic-gate #ifdef TRACE
2847c478bd9Sstevel@tonic-gate tprintf("TRACE- dologin()\n");
2857c478bd9Sstevel@tonic-gate #endif
2867c478bd9Sstevel@tonic-gate islogin();
2877c478bd9Sstevel@tonic-gate rechist();
2887c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, parterm);
2897c478bd9Sstevel@tonic-gate if (v[1] != NULL) {
2907c478bd9Sstevel@tonic-gate v_ = tstostr(NULL, v[1]); /* No need to free */
2917c478bd9Sstevel@tonic-gate } else {
2927c478bd9Sstevel@tonic-gate v_ = 0;
2937c478bd9Sstevel@tonic-gate }
2947c478bd9Sstevel@tonic-gate execl("/bin/login", "login", v_, 0);
2957c478bd9Sstevel@tonic-gate untty();
2967c478bd9Sstevel@tonic-gate exit(1);
2977c478bd9Sstevel@tonic-gate }
2987c478bd9Sstevel@tonic-gate
2997c478bd9Sstevel@tonic-gate #ifdef NEWGRP
3007c478bd9Sstevel@tonic-gate void
donewgrp(tchar ** v)3017c478bd9Sstevel@tonic-gate donewgrp(tchar **v)
3027c478bd9Sstevel@tonic-gate {
3037c478bd9Sstevel@tonic-gate
3047c478bd9Sstevel@tonic-gate char *v_; /* work */
3057c478bd9Sstevel@tonic-gate #ifdef TRACE
3067c478bd9Sstevel@tonic-gate tprintf("TRACE- donewgrp()\n");
3077c478bd9Sstevel@tonic-gate #endif
3087c478bd9Sstevel@tonic-gate if (chkstop == 0 && setintr) {
3097c478bd9Sstevel@tonic-gate panystop(0);
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate (void) signal(SIGTERM, parterm);
3127c478bd9Sstevel@tonic-gate
3137c478bd9Sstevel@tonic-gate if (v[1] != NULL) {
3147c478bd9Sstevel@tonic-gate v_ = tstostr(NOSTR, v[1]); /* No need to free */
3157c478bd9Sstevel@tonic-gate } else {
3167c478bd9Sstevel@tonic-gate v_ = 0;
3177c478bd9Sstevel@tonic-gate }
3187c478bd9Sstevel@tonic-gate execl("/bin/newgrp", "newgrp", v_, 0);
3197c478bd9Sstevel@tonic-gate execl("/usr/bin/newgrp", "newgrp", v_, 0);
3207c478bd9Sstevel@tonic-gate untty();
3217c478bd9Sstevel@tonic-gate exit(1);
3227c478bd9Sstevel@tonic-gate }
3237c478bd9Sstevel@tonic-gate #endif
3247c478bd9Sstevel@tonic-gate
3257c478bd9Sstevel@tonic-gate void
islogin(void)3266c02b4a4Smuffin islogin(void)
3277c478bd9Sstevel@tonic-gate {
3287c478bd9Sstevel@tonic-gate
3297c478bd9Sstevel@tonic-gate #ifdef TRACE
3307c478bd9Sstevel@tonic-gate tprintf("TRACE- islogin()\n");
3317c478bd9Sstevel@tonic-gate #endif
3327c478bd9Sstevel@tonic-gate if (chkstop == 0 && setintr) {
3337c478bd9Sstevel@tonic-gate panystop(0);
3347c478bd9Sstevel@tonic-gate }
3357c478bd9Sstevel@tonic-gate if (loginsh) {
3367c478bd9Sstevel@tonic-gate return;
3377c478bd9Sstevel@tonic-gate }
3387c478bd9Sstevel@tonic-gate error("Not login shell");
3397c478bd9Sstevel@tonic-gate }
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate void
doif(tchar ** v,struct command * kp)3427c478bd9Sstevel@tonic-gate doif(tchar **v, struct command *kp)
3437c478bd9Sstevel@tonic-gate {
3447c478bd9Sstevel@tonic-gate int i;
3457c478bd9Sstevel@tonic-gate tchar **vv;
3467c478bd9Sstevel@tonic-gate
3477c478bd9Sstevel@tonic-gate #ifdef TRACE
3487c478bd9Sstevel@tonic-gate tprintf("TRACE- doif()\n");
3497c478bd9Sstevel@tonic-gate #endif
3507c478bd9Sstevel@tonic-gate v++;
3517c478bd9Sstevel@tonic-gate i = exp(&v);
3527c478bd9Sstevel@tonic-gate vv = v;
3537c478bd9Sstevel@tonic-gate if (*vv == NOSTR) {
3547c478bd9Sstevel@tonic-gate bferr("Empty if");
3557c478bd9Sstevel@tonic-gate }
3567c478bd9Sstevel@tonic-gate if (eq(*vv, S_then)) {
3577c478bd9Sstevel@tonic-gate if (*++vv) {
3587c478bd9Sstevel@tonic-gate bferr("Improper then");
3597c478bd9Sstevel@tonic-gate }
3607c478bd9Sstevel@tonic-gate setname(S_then);
3617c478bd9Sstevel@tonic-gate /*
3627c478bd9Sstevel@tonic-gate * If expression was zero, then scan to else,
3637c478bd9Sstevel@tonic-gate * otherwise just fall into following code.
3647c478bd9Sstevel@tonic-gate */
3657c478bd9Sstevel@tonic-gate if (!i) {
3667c478bd9Sstevel@tonic-gate search(ZIF, 0);
3677c478bd9Sstevel@tonic-gate }
3687c478bd9Sstevel@tonic-gate return;
3697c478bd9Sstevel@tonic-gate }
3707c478bd9Sstevel@tonic-gate /*
3717c478bd9Sstevel@tonic-gate * Simple command attached to this if.
3727c478bd9Sstevel@tonic-gate * Left shift the node in this tree, munging it
3737c478bd9Sstevel@tonic-gate * so we can reexecute it.
3747c478bd9Sstevel@tonic-gate */
3757c478bd9Sstevel@tonic-gate if (i) {
3767c478bd9Sstevel@tonic-gate lshift(kp->t_dcom, vv - kp->t_dcom);
3777c478bd9Sstevel@tonic-gate reexecute(kp);
3787c478bd9Sstevel@tonic-gate donefds();
3797c478bd9Sstevel@tonic-gate }
3807c478bd9Sstevel@tonic-gate }
3817c478bd9Sstevel@tonic-gate
3827c478bd9Sstevel@tonic-gate /*
3837c478bd9Sstevel@tonic-gate * Reexecute a command, being careful not
3847c478bd9Sstevel@tonic-gate * to redo i/o redirection, which is already set up.
3857c478bd9Sstevel@tonic-gate */
3867c478bd9Sstevel@tonic-gate void
reexecute(struct command * kp)3877c478bd9Sstevel@tonic-gate reexecute(struct command *kp)
3887c478bd9Sstevel@tonic-gate {
3897c478bd9Sstevel@tonic-gate
3907c478bd9Sstevel@tonic-gate #ifdef TRACE
3917c478bd9Sstevel@tonic-gate tprintf("TRACE- reexecute()\n");
3927c478bd9Sstevel@tonic-gate #endif
3937c478bd9Sstevel@tonic-gate kp->t_dflg &= FSAVE;
3947c478bd9Sstevel@tonic-gate kp->t_dflg |= FREDO;
3957c478bd9Sstevel@tonic-gate /*
3967c478bd9Sstevel@tonic-gate * If tty is still ours to arbitrate, arbitrate it;
3977c478bd9Sstevel@tonic-gate * otherwise dont even set pgrp's as the jobs would
3987c478bd9Sstevel@tonic-gate * then have no way to get the tty (we can't give it
3997c478bd9Sstevel@tonic-gate * to them, and our parent wouldn't know their pgrp, etc.
4007c478bd9Sstevel@tonic-gate */
4017c478bd9Sstevel@tonic-gate execute(kp, tpgrp > 0 ? tpgrp : -1);
4027c478bd9Sstevel@tonic-gate }
4037c478bd9Sstevel@tonic-gate
4047c478bd9Sstevel@tonic-gate void
doelse(void)4056c02b4a4Smuffin doelse(void)
4067c478bd9Sstevel@tonic-gate {
4077c478bd9Sstevel@tonic-gate
4087c478bd9Sstevel@tonic-gate #ifdef TRACE
4097c478bd9Sstevel@tonic-gate tprintf("TRACE- doelse()\n");
4107c478bd9Sstevel@tonic-gate #endif
4117c478bd9Sstevel@tonic-gate search(ZELSE, 0);
4127c478bd9Sstevel@tonic-gate }
4137c478bd9Sstevel@tonic-gate
4147c478bd9Sstevel@tonic-gate void
dogoto(tchar ** v)4157c478bd9Sstevel@tonic-gate dogoto(tchar **v)
4167c478bd9Sstevel@tonic-gate {
4177c478bd9Sstevel@tonic-gate struct whyle *wp;
4187c478bd9Sstevel@tonic-gate tchar *lp;
4197c478bd9Sstevel@tonic-gate #ifdef TRACE
4207c478bd9Sstevel@tonic-gate tprintf("TRACE- dogoto()\n");
4217c478bd9Sstevel@tonic-gate #endif
4227c478bd9Sstevel@tonic-gate
4237c478bd9Sstevel@tonic-gate /*
4247c478bd9Sstevel@tonic-gate * While we still can, locate any unknown ends of existing loops.
4257c478bd9Sstevel@tonic-gate * This obscure code is the WORST result of the fact that we
4267c478bd9Sstevel@tonic-gate * don't really parse.
4277c478bd9Sstevel@tonic-gate */
4287c478bd9Sstevel@tonic-gate for (wp = whyles; wp; wp = wp->w_next) {
4297c478bd9Sstevel@tonic-gate if (wp->w_end == 0) {
4307c478bd9Sstevel@tonic-gate search(ZBREAK, 0);
4317c478bd9Sstevel@tonic-gate wp->w_end = btell();
4327c478bd9Sstevel@tonic-gate } else {
4337c478bd9Sstevel@tonic-gate bseek(wp->w_end);
4347c478bd9Sstevel@tonic-gate }
4357c478bd9Sstevel@tonic-gate }
4367c478bd9Sstevel@tonic-gate search(ZGOTO, 0, lp = globone(v[1]));
4377c478bd9Sstevel@tonic-gate xfree(lp);
4387c478bd9Sstevel@tonic-gate /*
4397c478bd9Sstevel@tonic-gate * Eliminate loops which were exited.
4407c478bd9Sstevel@tonic-gate */
4417c478bd9Sstevel@tonic-gate wfree();
4427c478bd9Sstevel@tonic-gate }
4437c478bd9Sstevel@tonic-gate
4447c478bd9Sstevel@tonic-gate void
doswitch(tchar ** v)4457c478bd9Sstevel@tonic-gate doswitch(tchar **v)
4467c478bd9Sstevel@tonic-gate {
4477c478bd9Sstevel@tonic-gate tchar *cp, *lp;
4487c478bd9Sstevel@tonic-gate
4497c478bd9Sstevel@tonic-gate #ifdef TRACE
4507c478bd9Sstevel@tonic-gate tprintf("TRACE- doswitch()\n");
4517c478bd9Sstevel@tonic-gate #endif
4527c478bd9Sstevel@tonic-gate v++;
4537c478bd9Sstevel@tonic-gate if (!*v || *(*v++) != '(') {
4547c478bd9Sstevel@tonic-gate goto syntax;
4557c478bd9Sstevel@tonic-gate }
4567c478bd9Sstevel@tonic-gate cp = **v == ')' ? S_ : *v++;
4577c478bd9Sstevel@tonic-gate if (*(*v++) != ')') {
4587c478bd9Sstevel@tonic-gate v--;
4597c478bd9Sstevel@tonic-gate }
4607c478bd9Sstevel@tonic-gate if (*v) {
4617c478bd9Sstevel@tonic-gate syntax:
4627c478bd9Sstevel@tonic-gate error("Syntax error");
4637c478bd9Sstevel@tonic-gate }
4647c478bd9Sstevel@tonic-gate search(ZSWITCH, 0, lp = globone(cp));
4657c478bd9Sstevel@tonic-gate xfree(lp);
4667c478bd9Sstevel@tonic-gate }
4677c478bd9Sstevel@tonic-gate
4687c478bd9Sstevel@tonic-gate void
dobreak(void)4696c02b4a4Smuffin dobreak(void)
4707c478bd9Sstevel@tonic-gate {
4717c478bd9Sstevel@tonic-gate
4727c478bd9Sstevel@tonic-gate #ifdef TRACE
4737c478bd9Sstevel@tonic-gate tprintf("TRACE- dobreak()\n");
4747c478bd9Sstevel@tonic-gate #endif
4757c478bd9Sstevel@tonic-gate if (whyles) {
4767c478bd9Sstevel@tonic-gate toend();
4777c478bd9Sstevel@tonic-gate } else {
4787c478bd9Sstevel@tonic-gate bferr("Not in while/foreach");
4797c478bd9Sstevel@tonic-gate }
4807c478bd9Sstevel@tonic-gate }
4817c478bd9Sstevel@tonic-gate
4827c478bd9Sstevel@tonic-gate void
doexit(tchar ** v)4837c478bd9Sstevel@tonic-gate doexit(tchar **v)
4847c478bd9Sstevel@tonic-gate {
4857c478bd9Sstevel@tonic-gate
4867c478bd9Sstevel@tonic-gate #ifdef TRACE
4877c478bd9Sstevel@tonic-gate tprintf("TRACE- doexit()\n");
4887c478bd9Sstevel@tonic-gate #endif
4897c478bd9Sstevel@tonic-gate if (chkstop == 0) {
4907c478bd9Sstevel@tonic-gate panystop(0);
4917c478bd9Sstevel@tonic-gate }
4927c478bd9Sstevel@tonic-gate /*
4937c478bd9Sstevel@tonic-gate * Don't DEMAND parentheses here either.
4947c478bd9Sstevel@tonic-gate */
4957c478bd9Sstevel@tonic-gate v++;
4967c478bd9Sstevel@tonic-gate if (*v) {
4977c478bd9Sstevel@tonic-gate set(S_status, putn(exp(&v)));
4987c478bd9Sstevel@tonic-gate if (*v) {
4997c478bd9Sstevel@tonic-gate bferr("Expression syntax");
5007c478bd9Sstevel@tonic-gate }
5017c478bd9Sstevel@tonic-gate }
5027c478bd9Sstevel@tonic-gate btoeof();
5037c478bd9Sstevel@tonic-gate if (intty) {
5047c478bd9Sstevel@tonic-gate (void) close(SHIN);
5057c478bd9Sstevel@tonic-gate unsetfd(SHIN);
5067c478bd9Sstevel@tonic-gate }
5077c478bd9Sstevel@tonic-gate }
5087c478bd9Sstevel@tonic-gate
5097c478bd9Sstevel@tonic-gate void
doforeach(tchar ** v)5107c478bd9Sstevel@tonic-gate doforeach(tchar **v)
5117c478bd9Sstevel@tonic-gate {
5127c478bd9Sstevel@tonic-gate tchar *cp;
5137c478bd9Sstevel@tonic-gate struct whyle *nwp;
5147c478bd9Sstevel@tonic-gate
5157c478bd9Sstevel@tonic-gate #ifdef TRACE
5167c478bd9Sstevel@tonic-gate tprintf("TRACE- doforeach()\n");
5177c478bd9Sstevel@tonic-gate #endif
5187c478bd9Sstevel@tonic-gate v++;
5197c478bd9Sstevel@tonic-gate cp = strip(*v);
5207c478bd9Sstevel@tonic-gate while (*cp && alnum(*cp)) {
5217c478bd9Sstevel@tonic-gate cp++;
5227c478bd9Sstevel@tonic-gate }
52370a587ddSchin if (*cp || strlen_(*v) >= MAX_VAR_LEN || !letter(**v)) {
5247c478bd9Sstevel@tonic-gate bferr("Invalid variable");
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate cp = *v++;
5277c478bd9Sstevel@tonic-gate if (v[0][0] != '(' || v[blklen(v) - 1][0] != ')') {
5287c478bd9Sstevel@tonic-gate bferr("Words not ()'ed");
5297c478bd9Sstevel@tonic-gate }
5307c478bd9Sstevel@tonic-gate v++;
5317c478bd9Sstevel@tonic-gate gflag = 0, tglob(v);
5327c478bd9Sstevel@tonic-gate v = glob(v);
5337c478bd9Sstevel@tonic-gate if (v == 0) {
5347c478bd9Sstevel@tonic-gate bferr("No match");
5357c478bd9Sstevel@tonic-gate }
53665b0c20eSnakanon nwp = (struct whyle *)xcalloc(1, sizeof (*nwp));
5377c478bd9Sstevel@tonic-gate nwp->w_fe = nwp->w_fe0 = v; gargv = 0;
5387c478bd9Sstevel@tonic-gate nwp->w_start = btell();
5397c478bd9Sstevel@tonic-gate nwp->w_fename = savestr(cp);
5407c478bd9Sstevel@tonic-gate nwp->w_next = whyles;
5417c478bd9Sstevel@tonic-gate whyles = nwp;
5427c478bd9Sstevel@tonic-gate /*
5437c478bd9Sstevel@tonic-gate * Pre-read the loop so as to be more
5447c478bd9Sstevel@tonic-gate * comprehensible to a terminal user.
5457c478bd9Sstevel@tonic-gate */
5467c478bd9Sstevel@tonic-gate if (intty) {
5477c478bd9Sstevel@tonic-gate preread_();
5487c478bd9Sstevel@tonic-gate }
5497c478bd9Sstevel@tonic-gate doagain();
5507c478bd9Sstevel@tonic-gate }
5517c478bd9Sstevel@tonic-gate
5527c478bd9Sstevel@tonic-gate void
dowhile(tchar ** v)5537c478bd9Sstevel@tonic-gate dowhile(tchar **v)
5547c478bd9Sstevel@tonic-gate {
5557c478bd9Sstevel@tonic-gate int status;
5567c478bd9Sstevel@tonic-gate bool again = whyles != 0 && whyles->w_start == lineloc &&
5577c478bd9Sstevel@tonic-gate whyles->w_fename == 0;
5587c478bd9Sstevel@tonic-gate
5597c478bd9Sstevel@tonic-gate #ifdef TRACE
5607c478bd9Sstevel@tonic-gate tprintf("TRACE- dowhile()\n");
5617c478bd9Sstevel@tonic-gate #endif
5627c478bd9Sstevel@tonic-gate v++;
5637c478bd9Sstevel@tonic-gate /*
5647c478bd9Sstevel@tonic-gate * Implement prereading here also, taking care not to
5657c478bd9Sstevel@tonic-gate * evaluate the expression before the loop has been read up
5667c478bd9Sstevel@tonic-gate * from a terminal.
5677c478bd9Sstevel@tonic-gate */
5687c478bd9Sstevel@tonic-gate if (intty && !again) {
5697c478bd9Sstevel@tonic-gate status = !exp0(&v, 1);
5707c478bd9Sstevel@tonic-gate } else {
5717c478bd9Sstevel@tonic-gate status = !exp(&v);
5727c478bd9Sstevel@tonic-gate }
5737c478bd9Sstevel@tonic-gate if (*v) {
5747c478bd9Sstevel@tonic-gate bferr("Expression syntax");
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate if (!again) {
57765b0c20eSnakanon struct whyle *nwp = (struct whyle *)xcalloc(1, sizeof (*nwp));
5787c478bd9Sstevel@tonic-gate
5797c478bd9Sstevel@tonic-gate nwp->w_start = lineloc;
5807c478bd9Sstevel@tonic-gate nwp->w_end = 0;
5817c478bd9Sstevel@tonic-gate nwp->w_next = whyles;
5827c478bd9Sstevel@tonic-gate whyles = nwp;
5837c478bd9Sstevel@tonic-gate if (intty) {
5847c478bd9Sstevel@tonic-gate /*
5857c478bd9Sstevel@tonic-gate * The tty preread
5867c478bd9Sstevel@tonic-gate */
5877c478bd9Sstevel@tonic-gate preread_();
5887c478bd9Sstevel@tonic-gate doagain();
5897c478bd9Sstevel@tonic-gate return;
5907c478bd9Sstevel@tonic-gate }
5917c478bd9Sstevel@tonic-gate }
5927c478bd9Sstevel@tonic-gate if (status) {
5937c478bd9Sstevel@tonic-gate /* We ain't gonna loop no more, no more! */
5947c478bd9Sstevel@tonic-gate toend();
5957c478bd9Sstevel@tonic-gate }
5967c478bd9Sstevel@tonic-gate }
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate void
preread_(void)5996c02b4a4Smuffin preread_(void)
6007c478bd9Sstevel@tonic-gate {
6017c478bd9Sstevel@tonic-gate #ifdef TRACE
6027c478bd9Sstevel@tonic-gate tprintf("TRACE- preread()\n");
6037c478bd9Sstevel@tonic-gate #endif
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate whyles->w_end = -1;
6067c478bd9Sstevel@tonic-gate if (setintr) {
6077c478bd9Sstevel@tonic-gate (void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
6087c478bd9Sstevel@tonic-gate }
6097c478bd9Sstevel@tonic-gate search(ZBREAK, 0);
6107c478bd9Sstevel@tonic-gate if (setintr) {
6117c478bd9Sstevel@tonic-gate (void) sigblock(sigmask(SIGINT));
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate whyles->w_end = btell();
6147c478bd9Sstevel@tonic-gate }
6157c478bd9Sstevel@tonic-gate
6167c478bd9Sstevel@tonic-gate void
doend(void)6176c02b4a4Smuffin doend(void)
6187c478bd9Sstevel@tonic-gate {
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate #ifdef TRACE
6217c478bd9Sstevel@tonic-gate tprintf("TRACE- doend()\n");
6227c478bd9Sstevel@tonic-gate #endif
6237c478bd9Sstevel@tonic-gate if (!whyles) {
6247c478bd9Sstevel@tonic-gate bferr("Not in while/foreach");
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate whyles->w_end = btell();
6277c478bd9Sstevel@tonic-gate doagain();
6287c478bd9Sstevel@tonic-gate }
6297c478bd9Sstevel@tonic-gate
6307c478bd9Sstevel@tonic-gate void
docontin(void)6316c02b4a4Smuffin docontin(void)
6327c478bd9Sstevel@tonic-gate {
6337c478bd9Sstevel@tonic-gate #ifdef TRACE
6347c478bd9Sstevel@tonic-gate tprintf("TRACE- docontin()\n");
6357c478bd9Sstevel@tonic-gate #endif
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate if (!whyles) {
6387c478bd9Sstevel@tonic-gate bferr("Not in while/foreach");
6397c478bd9Sstevel@tonic-gate }
6407c478bd9Sstevel@tonic-gate doagain();
6417c478bd9Sstevel@tonic-gate }
6427c478bd9Sstevel@tonic-gate
6437c478bd9Sstevel@tonic-gate void
doagain(void)6446c02b4a4Smuffin doagain(void)
6457c478bd9Sstevel@tonic-gate {
6467c478bd9Sstevel@tonic-gate
6477c478bd9Sstevel@tonic-gate #ifdef TRACE
6487c478bd9Sstevel@tonic-gate tprintf("TRACE- doagain()\n");
6497c478bd9Sstevel@tonic-gate #endif
6507c478bd9Sstevel@tonic-gate /* Repeating a while is simple */
6517c478bd9Sstevel@tonic-gate if (whyles->w_fename == 0) {
6527c478bd9Sstevel@tonic-gate bseek(whyles->w_start);
6537c478bd9Sstevel@tonic-gate return;
6547c478bd9Sstevel@tonic-gate }
6557c478bd9Sstevel@tonic-gate /*
6567c478bd9Sstevel@tonic-gate * The foreach variable list actually has a spurious word
6577c478bd9Sstevel@tonic-gate * ")" at the end of the w_fe list. Thus we are at the
6587c478bd9Sstevel@tonic-gate * of the list if one word beyond this is 0.
6597c478bd9Sstevel@tonic-gate */
6607c478bd9Sstevel@tonic-gate if (!whyles->w_fe[1]) {
6617c478bd9Sstevel@tonic-gate dobreak();
6627c478bd9Sstevel@tonic-gate return;
6637c478bd9Sstevel@tonic-gate }
6647c478bd9Sstevel@tonic-gate set(whyles->w_fename, savestr(*whyles->w_fe++));
6657c478bd9Sstevel@tonic-gate bseek(whyles->w_start);
6667c478bd9Sstevel@tonic-gate }
6677c478bd9Sstevel@tonic-gate
6687c478bd9Sstevel@tonic-gate void
dorepeat(tchar ** v,struct command * kp)6697c478bd9Sstevel@tonic-gate dorepeat(tchar **v, struct command *kp)
6707c478bd9Sstevel@tonic-gate {
6717c478bd9Sstevel@tonic-gate int i, omask;
6727c478bd9Sstevel@tonic-gate
6737c478bd9Sstevel@tonic-gate #ifdef TRACE
6747c478bd9Sstevel@tonic-gate tprintf("TRACE- dorepeat()\n");
6757c478bd9Sstevel@tonic-gate #endif
6767c478bd9Sstevel@tonic-gate i = getn(v[1]);
6777c478bd9Sstevel@tonic-gate if (setintr) {
6787c478bd9Sstevel@tonic-gate omask = sigblock(sigmask(SIGINT)) & ~sigmask(SIGINT);
6797c478bd9Sstevel@tonic-gate }
6807c478bd9Sstevel@tonic-gate lshift(v, 2);
6817c478bd9Sstevel@tonic-gate while (i > 0) {
6827c478bd9Sstevel@tonic-gate if (setintr) {
6837c478bd9Sstevel@tonic-gate (void) sigsetmask(omask);
6847c478bd9Sstevel@tonic-gate }
6857c478bd9Sstevel@tonic-gate reexecute(kp);
6867c478bd9Sstevel@tonic-gate --i;
6877c478bd9Sstevel@tonic-gate }
6887c478bd9Sstevel@tonic-gate donefds();
6897c478bd9Sstevel@tonic-gate if (setintr) {
6907c478bd9Sstevel@tonic-gate (void) sigsetmask(omask);
6917c478bd9Sstevel@tonic-gate }
6927c478bd9Sstevel@tonic-gate }
6937c478bd9Sstevel@tonic-gate
6947c478bd9Sstevel@tonic-gate void
doswbrk(void)6956c02b4a4Smuffin doswbrk(void)
6967c478bd9Sstevel@tonic-gate {
6977c478bd9Sstevel@tonic-gate
6987c478bd9Sstevel@tonic-gate #ifdef TRACE
6997c478bd9Sstevel@tonic-gate tprintf("TRACE- doswbrk()\n");
7007c478bd9Sstevel@tonic-gate #endif
7017c478bd9Sstevel@tonic-gate search(ZBRKSW, 0);
7027c478bd9Sstevel@tonic-gate }
7037c478bd9Sstevel@tonic-gate
7047c478bd9Sstevel@tonic-gate int
srchx(tchar * cp)7057c478bd9Sstevel@tonic-gate srchx(tchar *cp)
7067c478bd9Sstevel@tonic-gate {
7077c478bd9Sstevel@tonic-gate struct srch *sp, *sp1, *sp2;
7087c478bd9Sstevel@tonic-gate int i;
7097c478bd9Sstevel@tonic-gate
7107c478bd9Sstevel@tonic-gate #ifdef TRACE
7117c478bd9Sstevel@tonic-gate tprintf("TRACE- srchx()\n");
7127c478bd9Sstevel@tonic-gate #endif
7137c478bd9Sstevel@tonic-gate /*
7147c478bd9Sstevel@tonic-gate * Binary search
7157c478bd9Sstevel@tonic-gate * Sp1 is the beginning of the current search range.
7167c478bd9Sstevel@tonic-gate * Sp2 is one past the end.
7177c478bd9Sstevel@tonic-gate */
7187c478bd9Sstevel@tonic-gate for (sp1 = srchn, sp2 = srchn + nsrchn; sp1 < sp2; ) {
7197c478bd9Sstevel@tonic-gate sp = sp1 + (sp2 - sp1 >> 1);
7207c478bd9Sstevel@tonic-gate if ((i = *cp - *sp->s_name) == 0 &&
7217c478bd9Sstevel@tonic-gate (i = strcmp_(cp, sp->s_name)) == 0) {
7227c478bd9Sstevel@tonic-gate return (sp->s_value);
7237c478bd9Sstevel@tonic-gate }
7247c478bd9Sstevel@tonic-gate if (i < 0) {
7257c478bd9Sstevel@tonic-gate sp2 = sp;
7267c478bd9Sstevel@tonic-gate } else {
7277c478bd9Sstevel@tonic-gate sp1 = sp + 1;
7287c478bd9Sstevel@tonic-gate }
7297c478bd9Sstevel@tonic-gate }
7307c478bd9Sstevel@tonic-gate return (-1);
7317c478bd9Sstevel@tonic-gate }
7327c478bd9Sstevel@tonic-gate
7337c478bd9Sstevel@tonic-gate tchar Stype;
7347c478bd9Sstevel@tonic-gate tchar *Sgoal;
7357c478bd9Sstevel@tonic-gate
7367c478bd9Sstevel@tonic-gate /*VARARGS2*/
7377c478bd9Sstevel@tonic-gate void
search(type,level,goal)7387c478bd9Sstevel@tonic-gate search(type, level, goal)
7397c478bd9Sstevel@tonic-gate int type; int level; tchar *goal;
7407c478bd9Sstevel@tonic-gate {
7417c478bd9Sstevel@tonic-gate tchar wordbuf[BUFSIZ];
7427c478bd9Sstevel@tonic-gate tchar *aword = wordbuf;
7437c478bd9Sstevel@tonic-gate tchar *cp;
7447c478bd9Sstevel@tonic-gate
7457c478bd9Sstevel@tonic-gate #ifdef TRACE
7467c478bd9Sstevel@tonic-gate tprintf("TRACE- search()\n");
7477c478bd9Sstevel@tonic-gate #endif
7487c478bd9Sstevel@tonic-gate Stype = type; Sgoal = goal;
7497c478bd9Sstevel@tonic-gate if (type == ZGOTO) {
7507c478bd9Sstevel@tonic-gate bseek((off_t)0);
7517c478bd9Sstevel@tonic-gate }
7527c478bd9Sstevel@tonic-gate do {
7537c478bd9Sstevel@tonic-gate if (intty && fseekp == feobp) {
7547c478bd9Sstevel@tonic-gate printf("? "), flush();
7557c478bd9Sstevel@tonic-gate }
7567c478bd9Sstevel@tonic-gate aword[0] = 0;
7577c478bd9Sstevel@tonic-gate (void) getword(aword);
7587c478bd9Sstevel@tonic-gate
7597c478bd9Sstevel@tonic-gate switch (srchx(aword)) {
7607c478bd9Sstevel@tonic-gate
7617c478bd9Sstevel@tonic-gate case ZELSE:
7627c478bd9Sstevel@tonic-gate if (level == 0 && type == ZIF) {
7637c478bd9Sstevel@tonic-gate return;
7647c478bd9Sstevel@tonic-gate }
7657c478bd9Sstevel@tonic-gate break;
7667c478bd9Sstevel@tonic-gate
7677c478bd9Sstevel@tonic-gate case ZIF:
7687c478bd9Sstevel@tonic-gate while (getword(aword)) {
7697c478bd9Sstevel@tonic-gate continue;
7707c478bd9Sstevel@tonic-gate }
7717c478bd9Sstevel@tonic-gate if ((type == ZIF || type == ZELSE) &&
7727c478bd9Sstevel@tonic-gate eq(aword, S_then)) {
7737c478bd9Sstevel@tonic-gate level++;
7747c478bd9Sstevel@tonic-gate }
7757c478bd9Sstevel@tonic-gate break;
7767c478bd9Sstevel@tonic-gate
7777c478bd9Sstevel@tonic-gate case ZENDIF:
7787c478bd9Sstevel@tonic-gate if (type == ZIF || type == ZELSE) {
7797c478bd9Sstevel@tonic-gate level--;
7807c478bd9Sstevel@tonic-gate }
7817c478bd9Sstevel@tonic-gate break;
7827c478bd9Sstevel@tonic-gate
7837c478bd9Sstevel@tonic-gate case ZFOREACH:
7847c478bd9Sstevel@tonic-gate case ZWHILE:
7857c478bd9Sstevel@tonic-gate if (type == ZBREAK) {
7867c478bd9Sstevel@tonic-gate level++;
7877c478bd9Sstevel@tonic-gate }
7887c478bd9Sstevel@tonic-gate break;
7897c478bd9Sstevel@tonic-gate
7907c478bd9Sstevel@tonic-gate case ZEND:
7917c478bd9Sstevel@tonic-gate if (type == ZBREAK) {
7927c478bd9Sstevel@tonic-gate level--;
7937c478bd9Sstevel@tonic-gate }
7947c478bd9Sstevel@tonic-gate break;
7957c478bd9Sstevel@tonic-gate
7967c478bd9Sstevel@tonic-gate case ZSWITCH:
7977c478bd9Sstevel@tonic-gate if (type == ZSWITCH || type == ZBRKSW) {
7987c478bd9Sstevel@tonic-gate level++;
7997c478bd9Sstevel@tonic-gate }
8007c478bd9Sstevel@tonic-gate break;
8017c478bd9Sstevel@tonic-gate
8027c478bd9Sstevel@tonic-gate case ZENDSW:
8037c478bd9Sstevel@tonic-gate if (type == ZSWITCH || type == ZBRKSW) {
8047c478bd9Sstevel@tonic-gate level--;
8057c478bd9Sstevel@tonic-gate }
8067c478bd9Sstevel@tonic-gate break;
8077c478bd9Sstevel@tonic-gate
8087c478bd9Sstevel@tonic-gate case ZLABEL:
8097c478bd9Sstevel@tonic-gate if (type == ZGOTO && getword(aword) &&
8107c478bd9Sstevel@tonic-gate eq(aword, goal)) {
8117c478bd9Sstevel@tonic-gate level = -1;
8127c478bd9Sstevel@tonic-gate }
8137c478bd9Sstevel@tonic-gate break;
8147c478bd9Sstevel@tonic-gate
8157c478bd9Sstevel@tonic-gate default:
8167c478bd9Sstevel@tonic-gate if (type != ZGOTO && (type != ZSWITCH || level != 0)) {
8177c478bd9Sstevel@tonic-gate break;
8187c478bd9Sstevel@tonic-gate }
8197c478bd9Sstevel@tonic-gate if (lastchr(aword) != ':') {
8207c478bd9Sstevel@tonic-gate break;
8217c478bd9Sstevel@tonic-gate }
8227c478bd9Sstevel@tonic-gate aword[strlen_(aword) - 1] = 0;
8237c478bd9Sstevel@tonic-gate if (type == ZGOTO && eq(aword, goal) ||
8247c478bd9Sstevel@tonic-gate type == ZSWITCH && eq(aword, S_default)) {
8257c478bd9Sstevel@tonic-gate level = -1;
8267c478bd9Sstevel@tonic-gate }
8277c478bd9Sstevel@tonic-gate break;
8287c478bd9Sstevel@tonic-gate
8297c478bd9Sstevel@tonic-gate case ZCASE:
8307c478bd9Sstevel@tonic-gate if (type != ZSWITCH || level != 0) {
8317c478bd9Sstevel@tonic-gate break;
8327c478bd9Sstevel@tonic-gate }
8337c478bd9Sstevel@tonic-gate (void) getword(aword);
8347c478bd9Sstevel@tonic-gate if (lastchr(aword) == ':') {
8357c478bd9Sstevel@tonic-gate aword[strlen_(aword) - 1] = 0;
8367c478bd9Sstevel@tonic-gate }
8377c478bd9Sstevel@tonic-gate cp = strip(Dfix1(aword));
8387c478bd9Sstevel@tonic-gate if (Gmatch(goal, cp)) {
8397c478bd9Sstevel@tonic-gate level = -1;
8407c478bd9Sstevel@tonic-gate }
8417c478bd9Sstevel@tonic-gate xfree(cp);
8427c478bd9Sstevel@tonic-gate break;
8437c478bd9Sstevel@tonic-gate
8447c478bd9Sstevel@tonic-gate case ZDEFAULT:
8457c478bd9Sstevel@tonic-gate if (type == ZSWITCH && level == 0) {
8467c478bd9Sstevel@tonic-gate level = -1;
8477c478bd9Sstevel@tonic-gate }
8487c478bd9Sstevel@tonic-gate break;
8497c478bd9Sstevel@tonic-gate }
8507c478bd9Sstevel@tonic-gate (void) getword(NOSTR);
8517c478bd9Sstevel@tonic-gate } while (level >= 0);
8527c478bd9Sstevel@tonic-gate }
8537c478bd9Sstevel@tonic-gate
8547c478bd9Sstevel@tonic-gate int
getword(tchar * wp)8557c478bd9Sstevel@tonic-gate getword(tchar *wp)
8567c478bd9Sstevel@tonic-gate {
8577c478bd9Sstevel@tonic-gate int found = 0;
8587c478bd9Sstevel@tonic-gate int c, d;
8597c478bd9Sstevel@tonic-gate #ifdef TRACE
8607c478bd9Sstevel@tonic-gate tprintf("TRACE- getword()\n");
8617c478bd9Sstevel@tonic-gate #endif
8627c478bd9Sstevel@tonic-gate
8637c478bd9Sstevel@tonic-gate c = readc(1);
8647c478bd9Sstevel@tonic-gate d = 0;
8657c478bd9Sstevel@tonic-gate do {
8667c478bd9Sstevel@tonic-gate while (issp(c)) {
8677c478bd9Sstevel@tonic-gate c = readc(1);
8687c478bd9Sstevel@tonic-gate }
8697c478bd9Sstevel@tonic-gate if (c == '#') {
8707c478bd9Sstevel@tonic-gate do {
8717c478bd9Sstevel@tonic-gate c = readc(1);
8727c478bd9Sstevel@tonic-gate } while (c >= 0 && c != '\n');
8737c478bd9Sstevel@tonic-gate }
8747c478bd9Sstevel@tonic-gate if (c < 0) {
8757c478bd9Sstevel@tonic-gate goto past;
8767c478bd9Sstevel@tonic-gate }
8777c478bd9Sstevel@tonic-gate if (c == '\n') {
8787c478bd9Sstevel@tonic-gate if (wp) {
8797c478bd9Sstevel@tonic-gate break;
8807c478bd9Sstevel@tonic-gate }
8817c478bd9Sstevel@tonic-gate return (0);
8827c478bd9Sstevel@tonic-gate }
8837c478bd9Sstevel@tonic-gate
8847c478bd9Sstevel@tonic-gate /* ( and ) form separate words */
8857c478bd9Sstevel@tonic-gate if (c == '(' || c == ')') {
8867c478bd9Sstevel@tonic-gate return (1);
8877c478bd9Sstevel@tonic-gate }
8887c478bd9Sstevel@tonic-gate
8897c478bd9Sstevel@tonic-gate unreadc(c);
8907c478bd9Sstevel@tonic-gate found = 1;
8917c478bd9Sstevel@tonic-gate do {
8927c478bd9Sstevel@tonic-gate c = readc(1);
8937c478bd9Sstevel@tonic-gate if (c == '\\' && (c = readc(1)) == '\n') {
8947c478bd9Sstevel@tonic-gate c = ' ';
8957c478bd9Sstevel@tonic-gate }
8967c478bd9Sstevel@tonic-gate if (c == '\'' || c == '"') {
8977c478bd9Sstevel@tonic-gate if (d == 0) {
8987c478bd9Sstevel@tonic-gate d = c;
8997c478bd9Sstevel@tonic-gate } else if (d == c) {
9007c478bd9Sstevel@tonic-gate d = 0;
9017c478bd9Sstevel@tonic-gate }
9027c478bd9Sstevel@tonic-gate }
9037c478bd9Sstevel@tonic-gate if (c < 0) {
9047c478bd9Sstevel@tonic-gate goto past;
9057c478bd9Sstevel@tonic-gate }
9067c478bd9Sstevel@tonic-gate if (wp) {
9077c478bd9Sstevel@tonic-gate *wp++ = c;
9087c478bd9Sstevel@tonic-gate }
9097c478bd9Sstevel@tonic-gate } while ((d || !issp(c) && c != '(' && c != ')') && c != '\n');
9107c478bd9Sstevel@tonic-gate } while (wp == 0);
9117c478bd9Sstevel@tonic-gate unreadc(c);
9127c478bd9Sstevel@tonic-gate if (found) {
9137c478bd9Sstevel@tonic-gate *--wp = 0;
9147c478bd9Sstevel@tonic-gate }
9157c478bd9Sstevel@tonic-gate return (found);
9167c478bd9Sstevel@tonic-gate
9177c478bd9Sstevel@tonic-gate past:
9187c478bd9Sstevel@tonic-gate switch (Stype) {
9197c478bd9Sstevel@tonic-gate
9207c478bd9Sstevel@tonic-gate case ZIF:
9217c478bd9Sstevel@tonic-gate bferr("then/endif not found");
9227c478bd9Sstevel@tonic-gate
9237c478bd9Sstevel@tonic-gate case ZELSE:
9247c478bd9Sstevel@tonic-gate bferr("endif not found");
9257c478bd9Sstevel@tonic-gate
9267c478bd9Sstevel@tonic-gate case ZBRKSW:
9277c478bd9Sstevel@tonic-gate case ZSWITCH:
9287c478bd9Sstevel@tonic-gate bferr("endsw not found");
9297c478bd9Sstevel@tonic-gate
9307c478bd9Sstevel@tonic-gate case ZBREAK:
9317c478bd9Sstevel@tonic-gate bferr("end not found");
9327c478bd9Sstevel@tonic-gate
9337c478bd9Sstevel@tonic-gate case ZGOTO:
9347c478bd9Sstevel@tonic-gate setname(Sgoal);
9357c478bd9Sstevel@tonic-gate bferr("label not found");
9367c478bd9Sstevel@tonic-gate }
9377c478bd9Sstevel@tonic-gate /*NOTREACHED*/
9386c02b4a4Smuffin
9396c02b4a4Smuffin return (0);
9407c478bd9Sstevel@tonic-gate }
9417c478bd9Sstevel@tonic-gate
9427c478bd9Sstevel@tonic-gate void
toend(void)9436c02b4a4Smuffin toend(void)
9447c478bd9Sstevel@tonic-gate {
9457c478bd9Sstevel@tonic-gate
9467c478bd9Sstevel@tonic-gate #ifdef TRACE
9477c478bd9Sstevel@tonic-gate tprintf("TRACE- toend()\n");
9487c478bd9Sstevel@tonic-gate #endif
9497c478bd9Sstevel@tonic-gate if (whyles->w_end == 0) {
9507c478bd9Sstevel@tonic-gate search(ZBREAK, 0);
9517c478bd9Sstevel@tonic-gate whyles->w_end = btell() - 1;
9527c478bd9Sstevel@tonic-gate } else {
9537c478bd9Sstevel@tonic-gate bseek(whyles->w_end);
9547c478bd9Sstevel@tonic-gate }
9557c478bd9Sstevel@tonic-gate wfree();
9567c478bd9Sstevel@tonic-gate }
9577c478bd9Sstevel@tonic-gate
9587c478bd9Sstevel@tonic-gate void
wfree(void)9596c02b4a4Smuffin wfree(void)
9607c478bd9Sstevel@tonic-gate {
9617c478bd9Sstevel@tonic-gate long o = btell();
9627c478bd9Sstevel@tonic-gate
9637c478bd9Sstevel@tonic-gate #ifdef TRACE
9647c478bd9Sstevel@tonic-gate tprintf("TRACE- wfree()\n");
9657c478bd9Sstevel@tonic-gate #endif
9667c478bd9Sstevel@tonic-gate while (whyles) {
9677c478bd9Sstevel@tonic-gate struct whyle *wp = whyles;
9687c478bd9Sstevel@tonic-gate struct whyle *nwp = wp->w_next;
9697c478bd9Sstevel@tonic-gate
9707c478bd9Sstevel@tonic-gate if (o >= wp->w_start && (wp->w_end == 0 || o < wp->w_end)) {
9717c478bd9Sstevel@tonic-gate break;
9727c478bd9Sstevel@tonic-gate }
9737c478bd9Sstevel@tonic-gate if (wp->w_fe0) {
9747c478bd9Sstevel@tonic-gate blkfree(wp->w_fe0);
9757c478bd9Sstevel@tonic-gate }
9767c478bd9Sstevel@tonic-gate if (wp->w_fename) {
9777c478bd9Sstevel@tonic-gate xfree(wp->w_fename);
9787c478bd9Sstevel@tonic-gate }
9797c478bd9Sstevel@tonic-gate xfree((char *)wp);
9807c478bd9Sstevel@tonic-gate whyles = nwp;
9817c478bd9Sstevel@tonic-gate }
9827c478bd9Sstevel@tonic-gate }
9837c478bd9Sstevel@tonic-gate
9847c478bd9Sstevel@tonic-gate void
doecho(tchar ** v)9857c478bd9Sstevel@tonic-gate doecho(tchar **v)
9867c478bd9Sstevel@tonic-gate {
9877c478bd9Sstevel@tonic-gate
9887c478bd9Sstevel@tonic-gate #ifdef TRACE
9897c478bd9Sstevel@tonic-gate tprintf("TRACE- doecho()\n");
9907c478bd9Sstevel@tonic-gate #endif
9917c478bd9Sstevel@tonic-gate echo(' ', v);
9927c478bd9Sstevel@tonic-gate }
9937c478bd9Sstevel@tonic-gate
9947c478bd9Sstevel@tonic-gate void
doglob(tchar ** v)9957c478bd9Sstevel@tonic-gate doglob(tchar **v)
9967c478bd9Sstevel@tonic-gate {
9977c478bd9Sstevel@tonic-gate
9987c478bd9Sstevel@tonic-gate #ifdef TRACE
9997c478bd9Sstevel@tonic-gate tprintf("TRACE- doglob()\n");
10007c478bd9Sstevel@tonic-gate #endif
10017c478bd9Sstevel@tonic-gate echo(0, v);
10027c478bd9Sstevel@tonic-gate flush();
10037c478bd9Sstevel@tonic-gate }
10047c478bd9Sstevel@tonic-gate
10057c478bd9Sstevel@tonic-gate void
echo(tchar sep,tchar ** v)10067c478bd9Sstevel@tonic-gate echo(tchar sep, tchar **v)
10077c478bd9Sstevel@tonic-gate {
10087c478bd9Sstevel@tonic-gate tchar *cp;
10097c478bd9Sstevel@tonic-gate int nonl = 0;
10107c478bd9Sstevel@tonic-gate
10117c478bd9Sstevel@tonic-gate #ifdef TRACE
10127c478bd9Sstevel@tonic-gate tprintf("TRACE- echo()\n");
10137c478bd9Sstevel@tonic-gate #endif
10147c478bd9Sstevel@tonic-gate if (setintr) {
10157c478bd9Sstevel@tonic-gate (void) sigsetmask(sigblock(0) & ~sigmask(SIGINT));
10167c478bd9Sstevel@tonic-gate }
10177c478bd9Sstevel@tonic-gate v++;
10187c478bd9Sstevel@tonic-gate if (*v == 0) {
10197c478bd9Sstevel@tonic-gate /*
10207c478bd9Sstevel@tonic-gate * echo command needs to have newline when there are no
10217c478bd9Sstevel@tonic-gate * flags or arguments. glob should have no newline. If
10227c478bd9Sstevel@tonic-gate * the separator is a blank, we are doing an echo. If the
10237c478bd9Sstevel@tonic-gate * separator is zero, we are globbing.
10247c478bd9Sstevel@tonic-gate */
10257c478bd9Sstevel@tonic-gate if (sep == (tchar)' ')
10267c478bd9Sstevel@tonic-gate Putchar('\n');
10277c478bd9Sstevel@tonic-gate return;
10287c478bd9Sstevel@tonic-gate }
10297c478bd9Sstevel@tonic-gate gflag = 0, tglob(v);
10307c478bd9Sstevel@tonic-gate if (gflag) {
10317c478bd9Sstevel@tonic-gate v = glob(v);
10327c478bd9Sstevel@tonic-gate if (v == 0) {
10337c478bd9Sstevel@tonic-gate bferr("No match");
10347c478bd9Sstevel@tonic-gate }
10357c478bd9Sstevel@tonic-gate }
10367c478bd9Sstevel@tonic-gate /* check for -n arg, NOTE: it might be quoted */
10377c478bd9Sstevel@tonic-gate if (sep == ' ' && *v && strlen_(*v) == 2 &&
10387c478bd9Sstevel@tonic-gate ((**v&TRIM) == '-' && (*(*v + 1) & TRIM) == 'n' &&
10397c478bd9Sstevel@tonic-gate (*(*v+2)&TRIM) == 0)) {
10407c478bd9Sstevel@tonic-gate nonl++, v++;
10417c478bd9Sstevel@tonic-gate }
10427c478bd9Sstevel@tonic-gate while (cp = *v++) {
10437c478bd9Sstevel@tonic-gate int c;
10447c478bd9Sstevel@tonic-gate
10457c478bd9Sstevel@tonic-gate while (c = *cp++) {
10467c478bd9Sstevel@tonic-gate Putchar(c | QUOTE);
10477c478bd9Sstevel@tonic-gate }
10487c478bd9Sstevel@tonic-gate if (*v) {
10497c478bd9Sstevel@tonic-gate Putchar(sep | QUOTE);
10507c478bd9Sstevel@tonic-gate }
10517c478bd9Sstevel@tonic-gate }
10527c478bd9Sstevel@tonic-gate if (sep && nonl == 0) {
10537c478bd9Sstevel@tonic-gate Putchar('\n');
10547c478bd9Sstevel@tonic-gate } else {
10557c478bd9Sstevel@tonic-gate flush();
10567c478bd9Sstevel@tonic-gate }
10577c478bd9Sstevel@tonic-gate if (setintr) {
10587c478bd9Sstevel@tonic-gate (void) sigblock(sigmask(SIGINT));
10597c478bd9Sstevel@tonic-gate }
10607c478bd9Sstevel@tonic-gate if (gargv) {
10617c478bd9Sstevel@tonic-gate blkfree(gargv), gargv = 0;
10627c478bd9Sstevel@tonic-gate }
10637c478bd9Sstevel@tonic-gate }
10647c478bd9Sstevel@tonic-gate
10657c478bd9Sstevel@tonic-gate extern char **environ;
10667c478bd9Sstevel@tonic-gate
10677c478bd9Sstevel@tonic-gate /*
10687c478bd9Sstevel@tonic-gate * Check if the environment variable vp affects this csh's behavior
10697c478bd9Sstevel@tonic-gate * and therefore we should call setlocale() or not.
10707c478bd9Sstevel@tonic-gate * This function has two side effects when it returns 1:
10717c478bd9Sstevel@tonic-gate * variable islocalevar_catnum is set to the LC_xxx value.
10727c478bd9Sstevel@tonic-gate * variable islocalevar_catname is set to the string "LC_xxx"
10737c478bd9Sstevel@tonic-gate */
10747c478bd9Sstevel@tonic-gate static int islocalevar_catnum;
10757c478bd9Sstevel@tonic-gate static char *islocalevar_catname;
10767c478bd9Sstevel@tonic-gate
10777c478bd9Sstevel@tonic-gate static
10787c478bd9Sstevel@tonic-gate bool
islocalevar(tchar * vp)10797c478bd9Sstevel@tonic-gate islocalevar(tchar *vp)
10807c478bd9Sstevel@tonic-gate {
10817c478bd9Sstevel@tonic-gate static struct lcinfo {
10827c478bd9Sstevel@tonic-gate tchar * evname; /* The name of the env. var. */
10837c478bd9Sstevel@tonic-gate } categories_we_care[] = {
10847c478bd9Sstevel@tonic-gate S_LANG, S_LC_ALL, S_LC_CTYPE, S_LC_MESSAGES,
10857c478bd9Sstevel@tonic-gate NOSTR /* assumption: LC_xxx >= 0 */
10867c478bd9Sstevel@tonic-gate };
10877c478bd9Sstevel@tonic-gate struct lcinfo *p = categories_we_care;
10887c478bd9Sstevel@tonic-gate
10897c478bd9Sstevel@tonic-gate do {
10907c478bd9Sstevel@tonic-gate if (strcmp_(vp, p->evname) == 0) {
10917c478bd9Sstevel@tonic-gate return (1);
10927c478bd9Sstevel@tonic-gate }
10937c478bd9Sstevel@tonic-gate } while (((++p)->evname) != NOSTR);
10947c478bd9Sstevel@tonic-gate return (0);
10957c478bd9Sstevel@tonic-gate }
10967c478bd9Sstevel@tonic-gate
10977c478bd9Sstevel@tonic-gate void
dosetenv(tchar ** v)10987c478bd9Sstevel@tonic-gate dosetenv(tchar **v)
10997c478bd9Sstevel@tonic-gate {
11007c478bd9Sstevel@tonic-gate tchar *vp, *lp;
11017c478bd9Sstevel@tonic-gate
11027c478bd9Sstevel@tonic-gate #ifdef TRACE
11037c478bd9Sstevel@tonic-gate tprintf("TRACE- dosetenv()\n");
11047c478bd9Sstevel@tonic-gate #endif
11057c478bd9Sstevel@tonic-gate v++;
11067c478bd9Sstevel@tonic-gate if ((vp = *v++) == 0) {
11077c478bd9Sstevel@tonic-gate char **ep;
11087c478bd9Sstevel@tonic-gate
11097c478bd9Sstevel@tonic-gate if (setintr) {
11107c478bd9Sstevel@tonic-gate (void) sigsetmask(sigblock(0) & ~ sigmask(SIGINT));
11117c478bd9Sstevel@tonic-gate }
11127c478bd9Sstevel@tonic-gate for (ep = environ; *ep; ep++) {
11137c478bd9Sstevel@tonic-gate printf("%s\n", *ep);
11147c478bd9Sstevel@tonic-gate }
11157c478bd9Sstevel@tonic-gate return;
11167c478bd9Sstevel@tonic-gate }
11177c478bd9Sstevel@tonic-gate
11187c478bd9Sstevel@tonic-gate if ((lp = *v++) == 0) {
11197c478bd9Sstevel@tonic-gate lp = S_; /* "" */
11207c478bd9Sstevel@tonic-gate }
11217c478bd9Sstevel@tonic-gate local_setenv(vp, lp = globone(lp));
11227c478bd9Sstevel@tonic-gate if (eq(vp, S_PATH)) {
11237c478bd9Sstevel@tonic-gate importpath(lp);
11247c478bd9Sstevel@tonic-gate dohash(xhash);
11257c478bd9Sstevel@tonic-gate } else if (islocalevar(vp)) {
11267c478bd9Sstevel@tonic-gate if (!setlocale(LC_ALL, "")) {
11277c478bd9Sstevel@tonic-gate error("Locale could not be set properly");
11287c478bd9Sstevel@tonic-gate }
11297c478bd9Sstevel@tonic-gate }
11307c478bd9Sstevel@tonic-gate
11317c478bd9Sstevel@tonic-gate xfree(lp);
11327c478bd9Sstevel@tonic-gate }
11337c478bd9Sstevel@tonic-gate
11347c478bd9Sstevel@tonic-gate void
dounsetenv(tchar ** v)11357c478bd9Sstevel@tonic-gate dounsetenv(tchar **v)
11367c478bd9Sstevel@tonic-gate {
11377c478bd9Sstevel@tonic-gate #ifdef TRACE
11387c478bd9Sstevel@tonic-gate tprintf("TRACE- dounsetenv()\n");
11397c478bd9Sstevel@tonic-gate #endif
11407c478bd9Sstevel@tonic-gate v++;
11417c478bd9Sstevel@tonic-gate do {
11427c478bd9Sstevel@tonic-gate local_unsetenv(*v);
11437c478bd9Sstevel@tonic-gate if (islocalevar(*v++)) {
11447c478bd9Sstevel@tonic-gate setlocale(LC_ALL, ""); /* Hope no error! */
11457c478bd9Sstevel@tonic-gate }
11467c478bd9Sstevel@tonic-gate } while (*v);
11477c478bd9Sstevel@tonic-gate }
11487c478bd9Sstevel@tonic-gate
11497c478bd9Sstevel@tonic-gate void
local_setenv(tchar * name,tchar * val)11507c478bd9Sstevel@tonic-gate local_setenv(tchar *name, tchar *val)
11517c478bd9Sstevel@tonic-gate {
11527c478bd9Sstevel@tonic-gate char **ep = environ;
11537c478bd9Sstevel@tonic-gate tchar *cp;
11547c478bd9Sstevel@tonic-gate char *dp;
11557c478bd9Sstevel@tonic-gate tchar *ep_; /* temporary */
11567c478bd9Sstevel@tonic-gate char *blk[2], **oep = ep;
11577c478bd9Sstevel@tonic-gate
11587c478bd9Sstevel@tonic-gate #ifdef TRACE
11597c478bd9Sstevel@tonic-gate /* tprintf("TRACE- local_setenv(%t, %t)\n", name, val); */
11607c478bd9Sstevel@tonic-gate /* printf("IN local_setenv args = (%t)\n", val); */
11617c478bd9Sstevel@tonic-gate #endif
11627c478bd9Sstevel@tonic-gate for (; *ep; ep++) {
11637c478bd9Sstevel@tonic-gate #ifdef MBCHAR
11647c478bd9Sstevel@tonic-gate for (cp = name, dp = *ep; *cp && *dp; cp++) {
11657c478bd9Sstevel@tonic-gate /*
11667c478bd9Sstevel@tonic-gate * This loop compares two chars in different
11677c478bd9Sstevel@tonic-gate * representations, EUC (as char *) and wchar_t
11687c478bd9Sstevel@tonic-gate * (in tchar), and ends when they are different.
11697c478bd9Sstevel@tonic-gate */
11707c478bd9Sstevel@tonic-gate wchar_t dwc;
11717c478bd9Sstevel@tonic-gate int n;
11727c478bd9Sstevel@tonic-gate
11737c478bd9Sstevel@tonic-gate n = mbtowc(&dwc, dp, MB_CUR_MAX);
11747c478bd9Sstevel@tonic-gate if (n <= 0) {
11757c478bd9Sstevel@tonic-gate break; /* Illegal multibyte. */
11767c478bd9Sstevel@tonic-gate }
11777c478bd9Sstevel@tonic-gate dp += n; /* Advance to next multibyte char. */
11787c478bd9Sstevel@tonic-gate if (dwc == (wchar_t)(*cp & TRIM)) {
11797c478bd9Sstevel@tonic-gate continue;
11807c478bd9Sstevel@tonic-gate } else {
11817c478bd9Sstevel@tonic-gate break;
11827c478bd9Sstevel@tonic-gate }
11837c478bd9Sstevel@tonic-gate }
11847c478bd9Sstevel@tonic-gate #else /* !MBCHAR */
11857c478bd9Sstevel@tonic-gate for (cp = name, dp = *ep; *cp && (char)*cp == *dp; cp++, dp++) {
11867c478bd9Sstevel@tonic-gate continue;
11877c478bd9Sstevel@tonic-gate }
11887c478bd9Sstevel@tonic-gate #endif /* !MBCHAR */
11897c478bd9Sstevel@tonic-gate if (*cp != 0 || *dp != '=') {
11907c478bd9Sstevel@tonic-gate continue;
11917c478bd9Sstevel@tonic-gate }
11927c478bd9Sstevel@tonic-gate cp = strspl(S_EQ, val);
11937c478bd9Sstevel@tonic-gate xfree(*ep);
11947c478bd9Sstevel@tonic-gate ep_ = strspl(name, cp); /* ep_ is xalloc'ed */
11957c478bd9Sstevel@tonic-gate xfree(cp);
11967c478bd9Sstevel@tonic-gate /*
11977c478bd9Sstevel@tonic-gate * Trimming is not needed here.
11987c478bd9Sstevel@tonic-gate * trim();
11997c478bd9Sstevel@tonic-gate */
12007c478bd9Sstevel@tonic-gate *ep = tstostr(NULL, ep_);
12017c478bd9Sstevel@tonic-gate xfree(ep_); /* because temp. use */
12027c478bd9Sstevel@tonic-gate return;
12037c478bd9Sstevel@tonic-gate }
12047c478bd9Sstevel@tonic-gate ep_ = strspl(name, S_EQ); /* ep_ is xalloc'ed */
12057c478bd9Sstevel@tonic-gate blk[0] = tstostr(NULL, ep_);
12067c478bd9Sstevel@tonic-gate blk[1] = 0;
12077c478bd9Sstevel@tonic-gate xfree(ep_);
12086c02b4a4Smuffin environ = (char **)blkspl_((char **)environ, blk);
12097c478bd9Sstevel@tonic-gate xfree((void *)oep);
12107c478bd9Sstevel@tonic-gate local_setenv(name, val);
12117c478bd9Sstevel@tonic-gate }
12127c478bd9Sstevel@tonic-gate
12137c478bd9Sstevel@tonic-gate void
local_unsetenv(tchar * name)12147c478bd9Sstevel@tonic-gate local_unsetenv(tchar *name)
12157c478bd9Sstevel@tonic-gate {
12167c478bd9Sstevel@tonic-gate char **ep = environ;
12177c478bd9Sstevel@tonic-gate tchar *cp;
12187c478bd9Sstevel@tonic-gate char *dp;
12197c478bd9Sstevel@tonic-gate char **oep = ep;
12207c478bd9Sstevel@tonic-gate char *cp_; /* tmp use */
12216c02b4a4Smuffin static int cnt = 0; /* delete counter */
12227c478bd9Sstevel@tonic-gate
12237c478bd9Sstevel@tonic-gate #ifdef TRACE
12247c478bd9Sstevel@tonic-gate tprintf("TRACE- local_unsetenv()\n");
12257c478bd9Sstevel@tonic-gate #endif
12267c478bd9Sstevel@tonic-gate for (; *ep; ep++) {
12277c478bd9Sstevel@tonic-gate #ifdef MBCHAR
12287c478bd9Sstevel@tonic-gate for (cp = name, dp = *ep; *cp && *dp; cp++) {
12297c478bd9Sstevel@tonic-gate /*
12307c478bd9Sstevel@tonic-gate * This loop compares two chars in different
12317c478bd9Sstevel@tonic-gate * representations, EUC (as char *) and wchar_t
12327c478bd9Sstevel@tonic-gate * (in tchar), and ends when they are different.
12337c478bd9Sstevel@tonic-gate */
12347c478bd9Sstevel@tonic-gate wchar_t dwc;
12357c478bd9Sstevel@tonic-gate int n;
12367c478bd9Sstevel@tonic-gate
12377c478bd9Sstevel@tonic-gate n = mbtowc(&dwc, dp, MB_CUR_MAX);
12387c478bd9Sstevel@tonic-gate if (n <= 0) {
12397c478bd9Sstevel@tonic-gate break; /* Illegal multibyte. */
12407c478bd9Sstevel@tonic-gate }
12417c478bd9Sstevel@tonic-gate dp += n; /* Advance to next multibyte char. */
12427c478bd9Sstevel@tonic-gate if (dwc == (wchar_t)(*cp & TRIM)) {
12437c478bd9Sstevel@tonic-gate continue;
12447c478bd9Sstevel@tonic-gate } else {
12457c478bd9Sstevel@tonic-gate break;
12467c478bd9Sstevel@tonic-gate }
12477c478bd9Sstevel@tonic-gate }
12487c478bd9Sstevel@tonic-gate #else /* !MBCHAR */
12497c478bd9Sstevel@tonic-gate for (cp = name, dp = *ep; *cp && (char)*cp == *dp; cp++, dp++) {
12507c478bd9Sstevel@tonic-gate continue;
12517c478bd9Sstevel@tonic-gate }
12527c478bd9Sstevel@tonic-gate #endif /* !MBCHAR */
12537c478bd9Sstevel@tonic-gate if (*cp != 0 || *dp != '=') {
12547c478bd9Sstevel@tonic-gate continue;
12557c478bd9Sstevel@tonic-gate }
12567c478bd9Sstevel@tonic-gate cp_ = *ep;
12577c478bd9Sstevel@tonic-gate *ep = 0;
12586c02b4a4Smuffin environ = (char **)blkspl_((char **)environ, ep+1);
12597c478bd9Sstevel@tonic-gate *ep = cp_;
12607c478bd9Sstevel@tonic-gate xfree(cp_);
12617c478bd9Sstevel@tonic-gate xfree((void *)oep);
12627c478bd9Sstevel@tonic-gate return;
12637c478bd9Sstevel@tonic-gate }
12647c478bd9Sstevel@tonic-gate }
12657c478bd9Sstevel@tonic-gate
12667c478bd9Sstevel@tonic-gate void
doumask(tchar ** v)12677c478bd9Sstevel@tonic-gate doumask(tchar **v)
12687c478bd9Sstevel@tonic-gate {
12697c478bd9Sstevel@tonic-gate tchar *cp = v[1];
12707c478bd9Sstevel@tonic-gate int i;
12717c478bd9Sstevel@tonic-gate
12727c478bd9Sstevel@tonic-gate #ifdef TRACE
12737c478bd9Sstevel@tonic-gate tprintf("TRACE- dounmask()\n");
12747c478bd9Sstevel@tonic-gate #endif
12757c478bd9Sstevel@tonic-gate if (cp == 0) {
12767c478bd9Sstevel@tonic-gate i = umask(0);
12777c478bd9Sstevel@tonic-gate (void) umask(i);
12787c478bd9Sstevel@tonic-gate printf("%o\n", i);
12797c478bd9Sstevel@tonic-gate return;
12807c478bd9Sstevel@tonic-gate }
12817c478bd9Sstevel@tonic-gate i = 0;
12827c478bd9Sstevel@tonic-gate while (digit(*cp) && *cp != '8' && *cp != '9') {
12837c478bd9Sstevel@tonic-gate i = i * 8 + *cp++ - '0';
12847c478bd9Sstevel@tonic-gate }
12857c478bd9Sstevel@tonic-gate if (*cp || i < 0 || i > 0777) {
12867c478bd9Sstevel@tonic-gate bferr("Improper mask");
12877c478bd9Sstevel@tonic-gate }
12887c478bd9Sstevel@tonic-gate (void) umask(i);
12897c478bd9Sstevel@tonic-gate }
12907c478bd9Sstevel@tonic-gate
12917c478bd9Sstevel@tonic-gate
12927c478bd9Sstevel@tonic-gate struct limits *
findlim(tchar * cp)12937c478bd9Sstevel@tonic-gate findlim(tchar *cp)
12947c478bd9Sstevel@tonic-gate {
12957c478bd9Sstevel@tonic-gate struct limits *lp, *res;
12967c478bd9Sstevel@tonic-gate
12977c478bd9Sstevel@tonic-gate #ifdef TRACE
12987c478bd9Sstevel@tonic-gate tprintf("TRACE- findlim()\n");
12997c478bd9Sstevel@tonic-gate #endif
13007c478bd9Sstevel@tonic-gate res = 0;
13017c478bd9Sstevel@tonic-gate for (lp = limits; lp->limconst >= 0; lp++) {
13027c478bd9Sstevel@tonic-gate if (prefix(cp, lp->limname)) {
13037c478bd9Sstevel@tonic-gate if (res) {
13047c478bd9Sstevel@tonic-gate bferr("Ambiguous");
13057c478bd9Sstevel@tonic-gate }
13067c478bd9Sstevel@tonic-gate res = lp;
13077c478bd9Sstevel@tonic-gate }
13087c478bd9Sstevel@tonic-gate }
13097c478bd9Sstevel@tonic-gate if (res) {
13107c478bd9Sstevel@tonic-gate return (res);
13117c478bd9Sstevel@tonic-gate }
13127c478bd9Sstevel@tonic-gate bferr("No such limit");
13137c478bd9Sstevel@tonic-gate /*NOTREACHED*/
13147c478bd9Sstevel@tonic-gate }
13157c478bd9Sstevel@tonic-gate
13167c478bd9Sstevel@tonic-gate void
dolimit(tchar ** v)13177c478bd9Sstevel@tonic-gate dolimit(tchar **v)
13187c478bd9Sstevel@tonic-gate {
13197c478bd9Sstevel@tonic-gate struct limits *lp;
13207c478bd9Sstevel@tonic-gate rlim_t limit;
13217c478bd9Sstevel@tonic-gate tchar hard = 0;
13227c478bd9Sstevel@tonic-gate
13237c478bd9Sstevel@tonic-gate #ifdef TRACE
13247c478bd9Sstevel@tonic-gate tprintf("TRACE- dolimit()\n");
13257c478bd9Sstevel@tonic-gate #endif
13267c478bd9Sstevel@tonic-gate v++;
13277c478bd9Sstevel@tonic-gate if (*v && eq(*v, S_h)) {
13287c478bd9Sstevel@tonic-gate hard = 1;
13297c478bd9Sstevel@tonic-gate v++;
13307c478bd9Sstevel@tonic-gate }
13317c478bd9Sstevel@tonic-gate if (*v == 0) {
13327c478bd9Sstevel@tonic-gate for (lp = limits; lp->limconst >= 0; lp++) {
13337c478bd9Sstevel@tonic-gate plim(lp, hard);
13347c478bd9Sstevel@tonic-gate }
13357c478bd9Sstevel@tonic-gate return;
13367c478bd9Sstevel@tonic-gate }
13377c478bd9Sstevel@tonic-gate lp = findlim(v[0]);
13387c478bd9Sstevel@tonic-gate if (v[1] == 0) {
13397c478bd9Sstevel@tonic-gate plim(lp, hard);
13407c478bd9Sstevel@tonic-gate return;
13417c478bd9Sstevel@tonic-gate }
13427c478bd9Sstevel@tonic-gate switch (getval(lp, v+1, &limit)) {
13437c478bd9Sstevel@tonic-gate case 0:
13447c478bd9Sstevel@tonic-gate error("Value specified for limit is too large");
13457c478bd9Sstevel@tonic-gate return;
13467c478bd9Sstevel@tonic-gate case (-1):
13477c478bd9Sstevel@tonic-gate error("Numeric conversion failed");
13487c478bd9Sstevel@tonic-gate return;
13497c478bd9Sstevel@tonic-gate default:
13507c478bd9Sstevel@tonic-gate if (setlim(lp, hard, limit) < 0) {
13517c478bd9Sstevel@tonic-gate error(NOSTR);
13527c478bd9Sstevel@tonic-gate }
13537c478bd9Sstevel@tonic-gate }
13547c478bd9Sstevel@tonic-gate }
13557c478bd9Sstevel@tonic-gate
13567c478bd9Sstevel@tonic-gate static int
getval(struct limits * lp,tchar ** v,rlim_t * retval)13577c478bd9Sstevel@tonic-gate getval(struct limits *lp, tchar **v, rlim_t *retval)
13587c478bd9Sstevel@tonic-gate {
13597c478bd9Sstevel@tonic-gate rlim_t value, tmp, tmp2;
13607c478bd9Sstevel@tonic-gate tchar *cp = *v++;
13617c478bd9Sstevel@tonic-gate char chbuf[BUFSIZ * MB_LEN_MAX];
13627c478bd9Sstevel@tonic-gate
13637c478bd9Sstevel@tonic-gate #ifdef TRACE
13647c478bd9Sstevel@tonic-gate tprintf("TRACE- getval()\n");
13657c478bd9Sstevel@tonic-gate #endif
13667c478bd9Sstevel@tonic-gate
13677c478bd9Sstevel@tonic-gate tstostr(chbuf, cp);
13687c478bd9Sstevel@tonic-gate errno = 0;
13697c478bd9Sstevel@tonic-gate value = strtoull(chbuf, NULL, 0);
13707c478bd9Sstevel@tonic-gate /*
13717c478bd9Sstevel@tonic-gate * we must accept zero, but the conversion can fail and give us
13727c478bd9Sstevel@tonic-gate * zero as well...try to deal with it as gracefully as possible
13737c478bd9Sstevel@tonic-gate * by checking for EINVAL
13747c478bd9Sstevel@tonic-gate */
13757c478bd9Sstevel@tonic-gate if (value == 0 && errno == EINVAL)
13767c478bd9Sstevel@tonic-gate return (-1);
13777c478bd9Sstevel@tonic-gate
13787c478bd9Sstevel@tonic-gate while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E') {
13797c478bd9Sstevel@tonic-gate cp++;
13807c478bd9Sstevel@tonic-gate }
13817c478bd9Sstevel@tonic-gate if (*cp == 0) {
13827c478bd9Sstevel@tonic-gate if (*v == 0) {
13837c478bd9Sstevel@tonic-gate tmp = value * (rlim_t)lp->limdiv;
13847c478bd9Sstevel@tonic-gate /* Check for overflow */
13857c478bd9Sstevel@tonic-gate if (tmp >= value) {
13867c478bd9Sstevel@tonic-gate *retval = tmp;
13877c478bd9Sstevel@tonic-gate return (1);
13887c478bd9Sstevel@tonic-gate } else {
13897c478bd9Sstevel@tonic-gate return (0);
13907c478bd9Sstevel@tonic-gate }
13917c478bd9Sstevel@tonic-gate }
13927c478bd9Sstevel@tonic-gate cp = *v;
13937c478bd9Sstevel@tonic-gate }
13947c478bd9Sstevel@tonic-gate switch (*cp) {
13957c478bd9Sstevel@tonic-gate
13967c478bd9Sstevel@tonic-gate case ':':
13977c478bd9Sstevel@tonic-gate if (lp->limconst != RLIMIT_CPU) {
13987c478bd9Sstevel@tonic-gate goto badscal;
13997c478bd9Sstevel@tonic-gate }
14007c478bd9Sstevel@tonic-gate tstostr(chbuf, cp + 1);
14017c478bd9Sstevel@tonic-gate tmp = strtoull(chbuf, NULL, 0);
14027c478bd9Sstevel@tonic-gate tmp2 = value * 60 + tmp;
14037c478bd9Sstevel@tonic-gate if (tmp2 >= value) {
14047c478bd9Sstevel@tonic-gate *retval = tmp2;
14057c478bd9Sstevel@tonic-gate return (1);
14067c478bd9Sstevel@tonic-gate } else {
14077c478bd9Sstevel@tonic-gate return (0);
14087c478bd9Sstevel@tonic-gate }
14097c478bd9Sstevel@tonic-gate
14107c478bd9Sstevel@tonic-gate case 'h':
14117c478bd9Sstevel@tonic-gate if (lp->limconst != RLIMIT_CPU) {
14127c478bd9Sstevel@tonic-gate goto badscal;
14137c478bd9Sstevel@tonic-gate }
14147c478bd9Sstevel@tonic-gate limtail(cp, S_hours);
14157c478bd9Sstevel@tonic-gate tmp = value * 3600;
14167c478bd9Sstevel@tonic-gate if (tmp < value) {
14177c478bd9Sstevel@tonic-gate return (0);
14187c478bd9Sstevel@tonic-gate }
14197c478bd9Sstevel@tonic-gate value = tmp;
14207c478bd9Sstevel@tonic-gate break;
14217c478bd9Sstevel@tonic-gate
14227c478bd9Sstevel@tonic-gate case 'm':
14237c478bd9Sstevel@tonic-gate if (lp->limconst == RLIMIT_CPU) {
14247c478bd9Sstevel@tonic-gate limtail(cp, S_minutes);
14257c478bd9Sstevel@tonic-gate tmp = value * 60;
14267c478bd9Sstevel@tonic-gate if (tmp < value) {
14277c478bd9Sstevel@tonic-gate return (0);
14287c478bd9Sstevel@tonic-gate }
14297c478bd9Sstevel@tonic-gate value = tmp;
14307c478bd9Sstevel@tonic-gate break;
14317c478bd9Sstevel@tonic-gate }
14327c478bd9Sstevel@tonic-gate case 'M':
14337c478bd9Sstevel@tonic-gate if (lp->limconst == RLIMIT_CPU) {
14347c478bd9Sstevel@tonic-gate goto badscal;
14357c478bd9Sstevel@tonic-gate }
14367c478bd9Sstevel@tonic-gate *cp = 'm';
14377c478bd9Sstevel@tonic-gate limtail(cp, S_megabytes);
14387c478bd9Sstevel@tonic-gate tmp = value * 1024 * 1024;
14397c478bd9Sstevel@tonic-gate if (tmp < value) {
14407c478bd9Sstevel@tonic-gate return (0);
14417c478bd9Sstevel@tonic-gate }
14427c478bd9Sstevel@tonic-gate value = tmp;
14437c478bd9Sstevel@tonic-gate break;
14447c478bd9Sstevel@tonic-gate
14457c478bd9Sstevel@tonic-gate case 's':
14467c478bd9Sstevel@tonic-gate if (lp->limconst != RLIMIT_CPU) {
14477c478bd9Sstevel@tonic-gate goto badscal;
14487c478bd9Sstevel@tonic-gate }
14497c478bd9Sstevel@tonic-gate limtail(cp, S_seconds);
14507c478bd9Sstevel@tonic-gate break;
14517c478bd9Sstevel@tonic-gate
14527c478bd9Sstevel@tonic-gate case 'k':
14537c478bd9Sstevel@tonic-gate if (lp->limconst == RLIMIT_CPU) {
14547c478bd9Sstevel@tonic-gate goto badscal;
14557c478bd9Sstevel@tonic-gate }
14567c478bd9Sstevel@tonic-gate limtail(cp, S_kbytes);
14577c478bd9Sstevel@tonic-gate tmp = value * 1024;
14587c478bd9Sstevel@tonic-gate if (tmp < value) {
14597c478bd9Sstevel@tonic-gate return (0);
14607c478bd9Sstevel@tonic-gate }
14617c478bd9Sstevel@tonic-gate value = tmp;
14627c478bd9Sstevel@tonic-gate break;
14637c478bd9Sstevel@tonic-gate
14647c478bd9Sstevel@tonic-gate case 'u':
14657c478bd9Sstevel@tonic-gate limtail(cp, S_unlimited);
14667c478bd9Sstevel@tonic-gate *retval = RLIM_INFINITY;
14677c478bd9Sstevel@tonic-gate return (1);
14687c478bd9Sstevel@tonic-gate
14697c478bd9Sstevel@tonic-gate default:
14707c478bd9Sstevel@tonic-gate badscal:
14717c478bd9Sstevel@tonic-gate bferr("Improper or unknown scale factor");
14727c478bd9Sstevel@tonic-gate }
14737c478bd9Sstevel@tonic-gate *retval = value;
14747c478bd9Sstevel@tonic-gate return (1);
14757c478bd9Sstevel@tonic-gate }
14767c478bd9Sstevel@tonic-gate
14777c478bd9Sstevel@tonic-gate void
limtail(tchar * cp,tchar * str0)14787c478bd9Sstevel@tonic-gate limtail(tchar *cp, tchar *str0)
14797c478bd9Sstevel@tonic-gate {
14807c478bd9Sstevel@tonic-gate tchar *str = str0;
14817c478bd9Sstevel@tonic-gate #ifdef TRACE
14827c478bd9Sstevel@tonic-gate tprintf("TRACE- limtail()\n");
14837c478bd9Sstevel@tonic-gate #endif
14847c478bd9Sstevel@tonic-gate
14857c478bd9Sstevel@tonic-gate while (*cp && *cp == *str) {
14867c478bd9Sstevel@tonic-gate cp++, str++;
14877c478bd9Sstevel@tonic-gate }
14887c478bd9Sstevel@tonic-gate if (*cp) {
14897c478bd9Sstevel@tonic-gate error("Bad scaling; did you mean ``%t''?", str0);
14907c478bd9Sstevel@tonic-gate }
14917c478bd9Sstevel@tonic-gate }
14927c478bd9Sstevel@tonic-gate
14937c478bd9Sstevel@tonic-gate void
plim(struct limits * lp,tchar hard)14947c478bd9Sstevel@tonic-gate plim(struct limits *lp, tchar hard)
14957c478bd9Sstevel@tonic-gate {
14967c478bd9Sstevel@tonic-gate struct rlimit rlim;
14977c478bd9Sstevel@tonic-gate char buf[BUFSZ];
14987c478bd9Sstevel@tonic-gate char *pbuf;
14997c478bd9Sstevel@tonic-gate rlim_t limit;
15007c478bd9Sstevel@tonic-gate
15017c478bd9Sstevel@tonic-gate #ifdef TRACE
15027c478bd9Sstevel@tonic-gate tprintf("TRACE- plim()\n");
15037c478bd9Sstevel@tonic-gate #endif
15047c478bd9Sstevel@tonic-gate printf("%t \t", lp->limname);
15057c478bd9Sstevel@tonic-gate (void) getrlimit(lp->limconst, &rlim);
15067c478bd9Sstevel@tonic-gate limit = hard ? rlim.rlim_max : rlim.rlim_cur;
15077c478bd9Sstevel@tonic-gate if (limit == RLIM_INFINITY) {
15087c478bd9Sstevel@tonic-gate printf("unlimited");
15097c478bd9Sstevel@tonic-gate } else if (lp->limconst == RLIMIT_CPU) {
15107c478bd9Sstevel@tonic-gate psecs_ull(limit);
15117c478bd9Sstevel@tonic-gate } else {
15127c478bd9Sstevel@tonic-gate buf[BUFSZ - 1] = '\0';
15137c478bd9Sstevel@tonic-gate pbuf = ulltostr((limit / lp->limdiv), &buf[BUFSZ - 1]);
15147c478bd9Sstevel@tonic-gate printf("%s %t", pbuf, lp->limscale);
15157c478bd9Sstevel@tonic-gate }
15167c478bd9Sstevel@tonic-gate printf("\n");
15177c478bd9Sstevel@tonic-gate }
15187c478bd9Sstevel@tonic-gate
15197c478bd9Sstevel@tonic-gate void
dounlimit(tchar ** v)15207c478bd9Sstevel@tonic-gate dounlimit(tchar **v)
15217c478bd9Sstevel@tonic-gate {
15227c478bd9Sstevel@tonic-gate struct limits *lp;
15237c478bd9Sstevel@tonic-gate int err = 0;
15247c478bd9Sstevel@tonic-gate tchar hard = 0;
15257c478bd9Sstevel@tonic-gate #ifdef TRACE
15267c478bd9Sstevel@tonic-gate tprintf("TRACE- dounlimit()\n");
15277c478bd9Sstevel@tonic-gate #endif
15287c478bd9Sstevel@tonic-gate
15297c478bd9Sstevel@tonic-gate v++;
15307c478bd9Sstevel@tonic-gate if (*v && eq(*v, S_h)) {
15317c478bd9Sstevel@tonic-gate hard = 1;
15327c478bd9Sstevel@tonic-gate v++;
15337c478bd9Sstevel@tonic-gate }
15347c478bd9Sstevel@tonic-gate if (*v == 0) {
15357c478bd9Sstevel@tonic-gate for (lp = limits; lp->limconst >= 0; lp++) {
15367c478bd9Sstevel@tonic-gate if (setlim(lp, hard, RLIM_INFINITY) < 0) {
15377c478bd9Sstevel@tonic-gate err++;
15387c478bd9Sstevel@tonic-gate }
15397c478bd9Sstevel@tonic-gate }
15407c478bd9Sstevel@tonic-gate if (err) {
15417c478bd9Sstevel@tonic-gate error(NULL);
15427c478bd9Sstevel@tonic-gate }
15437c478bd9Sstevel@tonic-gate return;
15447c478bd9Sstevel@tonic-gate }
15457c478bd9Sstevel@tonic-gate while (*v) {
15467c478bd9Sstevel@tonic-gate lp = findlim(*v++);
15477c478bd9Sstevel@tonic-gate if (setlim(lp, hard, RLIM_INFINITY) < 0) {
15487c478bd9Sstevel@tonic-gate error(NULL);
15497c478bd9Sstevel@tonic-gate }
15507c478bd9Sstevel@tonic-gate }
15517c478bd9Sstevel@tonic-gate }
15527c478bd9Sstevel@tonic-gate
15537c478bd9Sstevel@tonic-gate int
setlim(struct limits * lp,tchar hard,rlim_t limit)15547c478bd9Sstevel@tonic-gate setlim(struct limits *lp, tchar hard, rlim_t limit)
15557c478bd9Sstevel@tonic-gate {
15567c478bd9Sstevel@tonic-gate struct rlimit rlim;
15577c478bd9Sstevel@tonic-gate
15587c478bd9Sstevel@tonic-gate #ifdef TRACE
15597c478bd9Sstevel@tonic-gate tprintf("TRACE- setlim()\n");
15607c478bd9Sstevel@tonic-gate #endif
15617c478bd9Sstevel@tonic-gate (void) getrlimit(lp->limconst, &rlim);
15627c478bd9Sstevel@tonic-gate if (hard) {
15637c478bd9Sstevel@tonic-gate rlim.rlim_max = limit;
15647c478bd9Sstevel@tonic-gate } else if (limit == RLIM_INFINITY && geteuid() != 0) {
15657c478bd9Sstevel@tonic-gate rlim.rlim_cur = rlim.rlim_max;
15667c478bd9Sstevel@tonic-gate } else {
15677c478bd9Sstevel@tonic-gate rlim.rlim_cur = limit;
15687c478bd9Sstevel@tonic-gate }
15697c478bd9Sstevel@tonic-gate if (setrlimit(lp->limconst, &rlim) < 0) {
15707c478bd9Sstevel@tonic-gate printf("%t: %t: Can't %s%s limit\n", bname, lp->limname,
15717c478bd9Sstevel@tonic-gate limit == RLIM_INFINITY ? "remove" : "set",
15727c478bd9Sstevel@tonic-gate hard ? " hard" : "");
15737c478bd9Sstevel@tonic-gate return (-1);
15747c478bd9Sstevel@tonic-gate }
15757c478bd9Sstevel@tonic-gate return (0);
15767c478bd9Sstevel@tonic-gate }
15777c478bd9Sstevel@tonic-gate
15787c478bd9Sstevel@tonic-gate void
dosuspend()15797c478bd9Sstevel@tonic-gate dosuspend()
15807c478bd9Sstevel@tonic-gate {
15817c478bd9Sstevel@tonic-gate int ctpgrp;
15827c478bd9Sstevel@tonic-gate void (*old)();
15837c478bd9Sstevel@tonic-gate
15847c478bd9Sstevel@tonic-gate #ifdef TRACE
15857c478bd9Sstevel@tonic-gate tprintf("TRACE- dosuspend()\n");
15867c478bd9Sstevel@tonic-gate #endif
15877c478bd9Sstevel@tonic-gate if (loginsh) {
15887c478bd9Sstevel@tonic-gate error("Can't suspend a login shell (yet)");
15897c478bd9Sstevel@tonic-gate }
15907c478bd9Sstevel@tonic-gate if (getpid() == getsid(0)) {
15917c478bd9Sstevel@tonic-gate error("Can't suspend this shell");
15927c478bd9Sstevel@tonic-gate }
15937c478bd9Sstevel@tonic-gate untty();
15947c478bd9Sstevel@tonic-gate old = (void (*)())signal(SIGTSTP, SIG_DFL);
15957c478bd9Sstevel@tonic-gate (void) kill(0, SIGTSTP);
15967c478bd9Sstevel@tonic-gate /* the shell stops here */
15977c478bd9Sstevel@tonic-gate (void) signal(SIGTSTP, old);
15987c478bd9Sstevel@tonic-gate if (tpgrp != -1) {
15997c478bd9Sstevel@tonic-gate retry:
16007c478bd9Sstevel@tonic-gate (void) ioctl(FSHTTY, TIOCGPGRP, (char *)&ctpgrp);
16017c478bd9Sstevel@tonic-gate if (ctpgrp != opgrp) {
16027c478bd9Sstevel@tonic-gate old = (void (*)())signal(SIGTTIN, SIG_DFL);
16037c478bd9Sstevel@tonic-gate (void) kill(0, SIGTTIN);
16047c478bd9Sstevel@tonic-gate (void) signal(SIGTTIN, old);
16057c478bd9Sstevel@tonic-gate goto retry;
16067c478bd9Sstevel@tonic-gate }
16077c478bd9Sstevel@tonic-gate (void) setpgid(0, shpgrp);
16087c478bd9Sstevel@tonic-gate (void) ioctl(FSHTTY, TIOCSPGRP, (char *)&shpgrp);
16097c478bd9Sstevel@tonic-gate }
16107c478bd9Sstevel@tonic-gate }
16117c478bd9Sstevel@tonic-gate
16127c478bd9Sstevel@tonic-gate void
doeval(tchar ** v)16137c478bd9Sstevel@tonic-gate doeval(tchar **v)
16147c478bd9Sstevel@tonic-gate {
16157c478bd9Sstevel@tonic-gate tchar **oevalvec = evalvec;
16167c478bd9Sstevel@tonic-gate tchar *oevalp = evalp;
16177c478bd9Sstevel@tonic-gate jmp_buf osetexit;
16187c478bd9Sstevel@tonic-gate int reenter;
16197c478bd9Sstevel@tonic-gate tchar **gv = 0;
16207c478bd9Sstevel@tonic-gate
16217c478bd9Sstevel@tonic-gate #ifdef TRACE
16227c478bd9Sstevel@tonic-gate tprintf("TRACE- doeval()\n");
16237c478bd9Sstevel@tonic-gate #endif
16247c478bd9Sstevel@tonic-gate v++;
16257c478bd9Sstevel@tonic-gate if (*v == 0) {
16267c478bd9Sstevel@tonic-gate return;
16277c478bd9Sstevel@tonic-gate }
16287c478bd9Sstevel@tonic-gate gflag = 0, tglob(v);
16297c478bd9Sstevel@tonic-gate if (gflag) {
16307c478bd9Sstevel@tonic-gate gv = v = glob(v);
16317c478bd9Sstevel@tonic-gate gargv = 0;
16327c478bd9Sstevel@tonic-gate if (v == 0) {
16337c478bd9Sstevel@tonic-gate error("No match");
16347c478bd9Sstevel@tonic-gate }
16357c478bd9Sstevel@tonic-gate v = copyblk(v);
16367c478bd9Sstevel@tonic-gate } else {
16377c478bd9Sstevel@tonic-gate trim(v);
16387c478bd9Sstevel@tonic-gate }
16397c478bd9Sstevel@tonic-gate getexit(osetexit);
16407c478bd9Sstevel@tonic-gate reenter = 0;
16417c478bd9Sstevel@tonic-gate setexit();
16427c478bd9Sstevel@tonic-gate reenter++;
16437c478bd9Sstevel@tonic-gate if (reenter == 1) {
16447c478bd9Sstevel@tonic-gate evalvec = v;
16457c478bd9Sstevel@tonic-gate evalp = 0;
16467c478bd9Sstevel@tonic-gate process(0);
16477c478bd9Sstevel@tonic-gate }
16487c478bd9Sstevel@tonic-gate evalvec = oevalvec;
16497c478bd9Sstevel@tonic-gate evalp = oevalp;
16507c478bd9Sstevel@tonic-gate doneinp = 0;
16517c478bd9Sstevel@tonic-gate if (gv) {
16527c478bd9Sstevel@tonic-gate blkfree(gv);
16537c478bd9Sstevel@tonic-gate }
16547c478bd9Sstevel@tonic-gate resexit(osetexit);
16557c478bd9Sstevel@tonic-gate if (reenter >= 2) {
16567c478bd9Sstevel@tonic-gate error(NULL);
16577c478bd9Sstevel@tonic-gate }
16587c478bd9Sstevel@tonic-gate }
1659