avoid null ptr deref, from glenn@sun
[unix-history] / usr / src / bin / csh / func.c
index 2a647e6..55301d1 100644 (file)
@@ -1,5 +1,11 @@
+/*
+ * Copyright (c) 1980 Regents of the University of California.
+ * All rights reserved.  The Berkeley Software License Agreement
+ * specifies the terms and conditions for redistribution.
+ */
+
 #ifndef lint
 #ifndef lint
-static char *sccsid = "@(#)func.c      4.13 (Berkeley) %G%";
+static char *sccsid = "@(#)func.c      5.3 (Berkeley) %G%";
 #endif
 
 #include "sh.h"
 #endif
 
 #include "sh.h"
@@ -736,7 +742,7 @@ echo(sep, v)
                        bferr("No match");
        } else
                trim(v);
                        bferr("No match");
        } else
                trim(v);
-       if (sep == ' ' && !strcmp(*v, "-n"))
+       if (sep == ' ' && *v && !strcmp(*v, "-n"))
                nonl++, v++;
        while (cp = *v++) {
                register int c;
                nonl++, v++;
        while (cp = *v++) {
                register int c;
@@ -761,10 +767,22 @@ char      **environ;
 dosetenv(v)
        register char **v;
 {
 dosetenv(v)
        register char **v;
 {
-       char *lp = globone(v[2]);
+       char *vp, *lp;
 
 
-       setenv(v[1], lp);
-       if (eq(v[1], "PATH")) {
+       v++;
+       if ((vp = *v++) == 0) {
+               register char **ep;
+
+               if (setintr)
+                       (void) sigsetmask(sigblock(0) & ~ sigmask(SIGINT));
+               for (ep = environ; *ep; ep++)
+                       printf("%s\n", *ep);
+               return;
+       }
+       if ((lp = *v++) == 0)
+               lp = "";
+       setenv(vp, lp = globone(lp));
+       if (eq(vp, "PATH")) {
                importpath(lp);
                dohash();
        }
                importpath(lp);
                dohash();
        }
@@ -888,20 +906,26 @@ dolimit(v)
 {
        register struct limits *lp;
        register int limit;
 {
        register struct limits *lp;
        register int limit;
+       char hard = 0;
 
        v++;
 
        v++;
+       if (*v && eq(*v, "-h")) {
+               hard = 1;
+               v++;
+       }
        if (*v == 0) {
        if (*v == 0) {
-               for (lp = limits+1; lp->limconst >= 0; lp++)
-                       plim(lp);
+               for (lp = limits; lp->limconst >= 0; lp++)
+                       plim(lp, hard);
                return;
        }
        lp = findlim(v[0]);
        if (v[1] == 0) {
                return;
        }
        lp = findlim(v[0]);
        if (v[1] == 0) {
-               plim(lp);
+               plim(lp,  hard);
                return;
        }
        limit = getval(lp, v+1);
                return;
        }
        limit = getval(lp, v+1);
-       setlim(lp, limit);
+       if (setlim(lp, hard, limit) < 0)
+               error(NOSTR);
 }
 
 getval(lp, v)
 }
 
 getval(lp, v)
@@ -983,19 +1007,22 @@ limtail(cp, str0)
                error("Bad scaling; did you mean ``%s''?", str0);
 }
 
                error("Bad scaling; did you mean ``%s''?", str0);
 }
 
-plim(lp)
+plim(lp, hard)
        register struct limits *lp;
        register struct limits *lp;
+       char hard;
 {
        struct rlimit rlim;
 {
        struct rlimit rlim;
+       int limit;
 
        printf("%s \t", lp->limname);
        (void) getrlimit(lp->limconst, &rlim);
 
        printf("%s \t", lp->limname);
        (void) getrlimit(lp->limconst, &rlim);
-       if (rlim.rlim_cur == RLIM_INFINITY)
+       limit = hard ? rlim.rlim_max : rlim.rlim_cur;
+       if (limit == RLIM_INFINITY)
                printf("unlimited");
        else if (lp->limconst == RLIMIT_CPU)
                printf("unlimited");
        else if (lp->limconst == RLIMIT_CPU)
-               psecs((long)rlim.rlim_cur);
+               psecs((long)limit);
        else
        else
-               printf("%d %s", rlim.rlim_cur / lp->limdiv, lp->limscale);
+               printf("%d %s", limit / lp->limdiv, lp->limscale);
        printf("\n");
 }
 
        printf("\n");
 }
 
@@ -1003,31 +1030,49 @@ dounlimit(v)
        register char **v;
 {
        register struct limits *lp;
        register char **v;
 {
        register struct limits *lp;
+       int err = 0;
+       char hard = 0;
 
        v++;
 
        v++;
+       if (*v && eq(*v, "-h")) {
+               hard = 1;
+               v++;
+       }
        if (*v == 0) {
        if (*v == 0) {
-               for (lp = limits+1; lp->limconst >= 0; lp++)
-                       setlim(lp, (int)RLIM_INFINITY);
+               for (lp = limits; lp->limconst >= 0; lp++)
+                       if (setlim(lp, hard, (int)RLIM_INFINITY) < 0)
+                               err++;
+               if (err)
+                       error(NOSTR);
                return;
        }
        while (*v) {
                lp = findlim(*v++);
                return;
        }
        while (*v) {
                lp = findlim(*v++);
-               setlim(lp, (int)RLIM_INFINITY);
+               if (setlim(lp, hard, (int)RLIM_INFINITY) < 0)
+                       error(NOSTR);
        }
 }
 
        }
 }
 
-setlim(lp, limit)
+setlim(lp, hard, limit)
        register struct limits *lp;
        register struct limits *lp;
+       char hard;
 {
        struct rlimit rlim;
 
        (void) getrlimit(lp->limconst, &rlim);
 {
        struct rlimit rlim;
 
        (void) getrlimit(lp->limconst, &rlim);
-       if(limit == RLIM_INFINITY && geteuid() != 0)
+       if (hard)
+               rlim.rlim_max = limit;
+       else if (limit == RLIM_INFINITY && geteuid() != 0)
                rlim.rlim_cur = rlim.rlim_max;
        else
                rlim.rlim_cur = limit;
                rlim.rlim_cur = rlim.rlim_max;
        else
                rlim.rlim_cur = limit;
-       if (setrlimit(lp->limconst, &rlim) < 0)
-               Perror(bname);
+       if (setrlimit(lp->limconst, &rlim) < 0) {
+               printf("%s: %s: Can't %s%s limit\n", bname, lp->limname,
+                   limit == RLIM_INFINITY ? "remove" : "set",
+                   hard ? " hard" : "");
+               return (-1);
+       }
+       return (0);
 }
 
 dosuspend()
 }
 
 dosuspend()