+
+#include <sys/limit.h>
+
+struct limits {
+ int limconst;
+ char *limname;
+ int limdiv;
+ char *limscale;
+} limits[] = {
+ LIM_NORAISE, "noraise", 1, "",
+ LIM_CPU, "cputime", 1, "seconds",
+ LIM_FSIZE, "filesize", 1024, "kbytes",
+ LIM_DATA, "datasize", 1024, "kbytes",
+ LIM_STACK, "stacksize", 1024, "kbytes",
+ LIM_CORE, "coredumpsize", 1024, "kbytes",
+ -1, 0,
+};
+
+struct limits *
+findlim(cp)
+ char *cp;
+{
+ register struct limits *lp, *res;
+
+ res = 0;
+ for (lp = limits; lp->limconst >= 0; lp++)
+ if (prefix(cp, lp->limname)) {
+ if (res)
+ bferr("Ambiguous");
+ res = lp;
+ }
+ if (res)
+ return (res);
+ bferr("No such limit");
+}
+
+dolimit(v)
+ register char **v;
+{
+ register struct limits *lp;
+ register int limit;
+
+ v++;
+ if (*v == 0) {
+ for (lp = limits+1; lp->limconst >= 0; lp++)
+ plim(lp);
+ if (vlimit(LIM_NORAISE, -1) && getuid())
+ printf("Limits cannot be raised\n");
+ return;
+ }
+ lp = findlim(v[0]);
+ if (v[1] == 0) {
+ plim(lp);
+ return;
+ }
+ limit = getval(lp, v+1);
+ setlim(lp, limit);
+}
+
+getval(lp, v)
+ register struct limits *lp;
+ char **v;
+{
+ register float f;
+ double atof();
+ char *cp = *v++;
+
+ f = atof(cp);
+ while (digit(*cp) || *cp == '.' || *cp == 'e' || *cp == 'E')
+ cp++;
+ if (*cp == 0) {
+ if (*v == 0)
+ return ((int)(f+0.5) * lp->limdiv);
+ cp = *v;
+ }
+ if (lp->limconst == LIM_NORAISE)
+ goto badscal;
+ switch (*cp) {
+
+ case ':':
+ if (lp->limconst != LIM_CPU)
+ goto badscal;
+ return ((int)(f * 60.0 + atof(cp+1)));
+
+ case 'h':
+ if (lp->limconst != LIM_CPU)
+ goto badscal;
+ limtail(cp, "hours");
+ f *= 3600.;
+ break;
+
+ case 'm':
+ if (lp->limconst == LIM_CPU) {
+ limtail(cp, "minutes");
+ f *= 60.;
+ break;
+ }
+ case 'M':
+ if (lp->limconst == LIM_CPU)
+ goto badscal;
+ *cp = 'm';
+ limtail(cp, "megabytes");
+ f *= 1024.*1024.;
+ break;
+
+ case 's':
+ if (lp->limconst != LIM_CPU)
+ goto badscal;
+ limtail(cp, "seconds");
+ break;
+
+ case 'k':
+ if (lp->limconst == LIM_CPU)
+ goto badscal;
+ limtail(cp, "kbytes");
+ f *= 1024;
+ break;
+
+ case 'u':
+ limtail(cp, "unlimited");
+ return (INFINITY);
+
+ default:
+badscal:
+ bferr("Improper or unknown scale factor");
+ }
+ return ((int)(f+0.5));
+}
+
+limtail(cp, str0)
+ char *cp, *str0;
+{
+ register char *str = str0;
+
+ while (*cp && *cp == *str)
+ cp++, str++;
+ if (*cp)
+ error("Bad scaling; did you mean ``%s''?", str0);
+}
+
+plim(lp)
+ register struct limits *lp;
+{
+ register int lim;
+
+ printf("%s \t", lp->limname);
+ lim = vlimit(lp->limconst, -1);
+ if (lim == INFINITY)
+ printf("unlimited");
+ else if (lp->limconst == LIM_CPU)
+ psecs((long)lim);
+ else
+ printf("%d %s", lim / lp->limdiv, lp->limscale);
+ printf("\n");
+}
+
+dounlimit(v)
+ register char **v;
+{
+ register struct limits *lp;
+
+ v++;
+ if (*v == 0) {
+ for (lp = limits+1; lp->limconst >= 0; lp++)
+ setlim(lp, INFINITY);
+ return;
+ }
+ while (*v) {
+ lp = findlim(*v++);
+ setlim(lp, INFINITY);
+ }
+}
+
+setlim(lp, limit)
+ register struct limits *lp;
+{
+
+ if (vlimit(lp->limconst, limit) < 0)
+ Perror(bname);
+}
+
+dosuspend()
+{
+ int old, ldisc;
+ short ctpgrp;
+
+ if (loginsh)
+ error("Can't suspend a login shell (yet)");
+ untty();
+ old = sigsys(SIGTSTP, SIG_DFL);
+ kill(0, SIGTSTP);
+ /* the shell stops here */
+ sigsys(SIGTSTP, old);
+ if (tpgrp != -1) {
+retry:
+ ioctl(FSHTTY, TIOCGPGRP, &ctpgrp);
+ if (ctpgrp != opgrp) {
+ old = sigsys(SIGTTIN, SIG_DFL);
+ kill(0, SIGTTIN);
+ sigsys(SIGTTIN, old);
+ goto retry;
+ }
+ ioctl(FSHTTY, TIOCSPGRP, &shpgrp);
+ setpgrp(0, shpgrp);
+ }
+ ioctl(FSHTTY, TIOCGETD, &oldisc);
+ if (oldisc != NTTYDISC) {
+ printf("Switching to new tty driver...\n");
+ ldisc = NTTYDISC;
+ ioctl(FSHTTY, TIOCSETD, &ldisc);
+ }
+}
+
+doeval(v)
+ char **v;
+{
+ char **oevalvec = evalvec;
+ char *oevalp = evalp;
+ jmp_buf osetexit;
+ int reenter;
+ char **gv = 0;
+
+ v++;
+ if (*v == 0)
+ return;
+ gflag = 0; rscan(v, tglob);
+ if (gflag) {
+ gv = v = glob(v);
+ gargv = 0;
+ if (v == 0)
+ error("No match");
+ v = copyblk(v);
+ } else
+ scan(v, trim);
+ getexit(osetexit);
+ reenter = 0;
+ setexit();
+ reenter++;
+ if (reenter == 1) {
+ evalvec = v;
+ evalp = 0;
+ process(0);
+ }
+ evalvec = oevalvec;
+ evalp = oevalp;
+ doneinp = 0;
+ if (gv)
+ blkfree(gv);
+ resexit(osetexit);
+ if (reenter >= 2)
+ error(NOSTR);
+}