]> git.saurik.com Git - apple/system_cmds.git/blobdiff - sysctl.tproj/sysctl.c
system_cmds-597.90.1.tar.gz
[apple/system_cmds.git] / sysctl.tproj / sysctl.c
index fb0dbb4be12e198cf2c98aed22a2b9de30ca5f38..3b16137a38687189a2fee0cb23266b5c58a054e0 100644 (file)
@@ -1,23 +1,22 @@
-/*
- * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
+ /*
+ * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
  *
  * @APPLE_LICENSE_HEADER_START@
  * 
- * "Portions Copyright (c) 1999 Apple Computer, Inc.  All Rights
- * Reserved.  This file contains Original Code and/or Modifications of
- * Original Code as defined in and that are subject to the Apple Public
- * Source License Version 1.0 (the 'License').  You may not use this file
- * except in compliance with the License.  Please obtain a copy of the
- * License at http://www.apple.com/publicsource and read it before using
- * this file.
+ * This file contains Original Code and/or Modifications of Original Code
+ * as defined in and that are subject to the Apple Public Source License
+ * Version 2.0 (the 'License'). You may not use this file except in
+ * compliance with the License. Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this
+ * file.
  * 
  * The Original Code and all software distributed under the License are
  * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
  * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
  * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT.  Please see the
- * License for the specific language governing rights and limitations
- * under the License."
+ * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
+ * Please see the License for the specific language governing rights and
+ * limitations under the License.
  * 
  * @APPLE_LICENSE_HEADER_END@
  */
  * 2. Redistributions in binary form must reproduce the above copyright
  *    notice, this list of conditions and the following disclaimer in the
  *    documentation and/or other materials provided with the distribution.
- * 3. All advertising materials mentioning features or use of this software
- *    must display the following acknowledgement:
- *     This product includes software developed by the University of
- *     California, Berkeley and its contributors.
  * 4. Neither the name of the University nor the names of its contributors
  *    may be used to endorse or promote products derived from this software
  *    without specific prior written permission.
  setting values where the format is specified as unsigned integer.
  */
  
+#include <sys/cdefs.h>
 #ifndef lint
-static char copyright[] =
+__unused static char copyright[] =
 "@(#) Copyright (c) 1993\n\
        The Regents of the University of California.  All rights reserved.\n";
 #endif /* not lint */
 
 #ifndef lint
-static char sccsid[] = "@(#)sysctl.c   8.5 (Berkeley) 5/9/95";
+__unused static char sccsid[] = "@(#)sysctl.c  8.5 (Berkeley) 5/9/95";
 #endif /* not lint */
 
 #include <sys/param.h>
@@ -110,7 +106,6 @@ static char sccsid[] = "@(#)sysctl.c        8.5 (Berkeley) 5/9/95";
 #else
 #include <vm/vm_param.h>
 #endif /* __APPLE__ */
-#include <machine/cpu.h>
 
 #include <errno.h>
 #include <ctype.h>
@@ -146,7 +141,7 @@ struct list secondlevel[] = {
        { kernname, KERN_MAXID },       /* CTL_KERN */
        { vmname, VM_MAXID },           /* CTL_VM */
        { 0, 0 },                       /* CTL_VFS */
-    { 0, 0 },          /* CTL_NET */
+       { 0, 0 },                       /* CTL_NET */
        { 0, CTL_DEBUG_MAXID },         /* CTL_DEBUG */
        { hwname, HW_MAXID },           /* CTL_HW */
 #ifdef CTL_MACHDEP_NAMES
@@ -157,8 +152,9 @@ struct list secondlevel[] = {
        { username, USER_MAXID },       /* CTL_USER_NAMES */
 };
 
-static int     Aflag, aflag, bflag, nflag, wflag, Xflag;
+static int     Aflag, aflag, bflag, hflag, nflag, wflag, Xflag;
 static int     foundSome = 0;
+static int     invalid_name_used = 0;
 
 void listall(char *prefix, struct list *lp);
 void old_parse(char *string, int flags);
@@ -169,7 +165,7 @@ void usage();
 
 static void    parse(char *string, int flags);
 static int     oidfmt(int *, int, char *, u_int *);
-static int     show_var(int *, int);
+static int     show_var(int *, int, int);
 static int     sysctl_all (int *oid, int len);
 static int     name2oid(char *, int *);
 
@@ -194,6 +190,7 @@ main(argc, argv)
                        case 'A': Aflag = 1; break;
                        case 'a': aflag = 1; break;
                        case 'b': bflag = 1; break;
+                       case 'h': hflag = 1; break;
                        case 'n': nflag = 1; break;
                        case 'w': wflag = 1; break;
                        case 'X': Xflag = Aflag = 1; break;
@@ -212,9 +209,9 @@ main(argc, argv)
        }
        if (argc == 0)
                usage();
-       for (; *argv != NULL; ++argv)
+       for (; *argv != NULL; ++argv) 
                parse(*argv, 1);
-       exit(0);
+       exit(invalid_name_used ? 1 : 0);
 }
 
 /*
@@ -346,10 +343,13 @@ old_parse(string, flags)
                break;
 
        case CTL_HW:
+               useUnsignedInt = 1;
                break;
 
-       case CTL_VM:
-               if (mib[1] == VM_LOADAVG) {
+       case CTL_VM: break;
+#if 0 /* XXX Handled by the new sysctl mechanism */
+               switch (mib[1]) {
+               case VM_LOADAVG: {      /* XXX this is bogus */
                        double loads[3];
 
                        getloadavg(loads, 3);
@@ -359,11 +359,39 @@ old_parse(string, flags)
                            loads[0], loads[1], loads[2]);
                        return;
                }
+               case VM_SWAPUSAGE: {
+                       struct xsw_usage        xsu;
+                       int                     saved_errno;
+
+                       size = sizeof (xsu);
+                       if (sysctl(mib, 2, &xsu, &size, NULL, 0) != 0) {
+                               if (flags == 0)
+                                       return;
+                               saved_errno = errno;
+                               if (!nflag)
+                                       fprintf(stderr, "%s: ", string);
+                               fprintf(stderr, "sysctl(VM_SWAPUSAGE): %s\n",
+                                       strerror(saved_errno));
+                               return;
+                       }
+
+                       if (!nflag)
+                               fprintf(stdout, "%s: ", string);
+                       fprintf(stdout,
+                               "total = %.2fM  used = %.2fM  free = %.2fM  %s\n",
+                               ((double) xsu.xsu_total) / (1024.0 * 1024.0),
+                               ((double) xsu.xsu_used) / (1024.0 * 1024.0),
+                               ((double) xsu.xsu_avail) / (1024.0 * 1024.0),
+                               xsu.xsu_encrypted ? "(encrypted)" : "");
+                       return;
+               }
+               }
                if (flags == 0)
                        return;
                fprintf(stderr,
                    "Use vmstat or systat to view %s information\n", string);
                return;
+#endif
         
        case CTL_DEBUG:
                mib[2] = CTL_DEBUG_VALUE;
@@ -413,18 +441,33 @@ old_parse(string, flags)
                switch (type) {
                case CTLTYPE_INT:
                        if (useUnsignedInt) {   
-                               uintval = strtoul(newval, 0, 0);
+                               uintval = strtoul(newval, NULL, 0);
+                               if ((uintval == 0) && (errno == EINVAL)) {
+                                       fprintf(stderr, "invalid argument: %s\n",
+                                               (char *)newval);
+                                       return;
+                               }
                                newval = &uintval;
                                newsize = sizeof uintval;
                        } else {
-                       intval = atoi(newval);
-                       newval = &intval;
-                       newsize = sizeof intval;
+                               intval = strtol(newval, NULL,  0);
+                               if ((intval == 0) && (errno == EINVAL)) {
+                                       fprintf(stderr, "invalid argument: %s\n",
+                                               (char *)newval);
+                                       return;
+                               }
+                               newval = &intval;
+                               newsize = sizeof intval;
                        }
                        break;
 
                case CTLTYPE_QUAD:
-                       sscanf(newval, "%qd", &quadval);
+                       quadval = strtoq(newval, NULL, 0);
+                       if ((quadval == 0) && (errno == EINVAL)) {
+                               fprintf(stderr, "invalid argument: %s\n",
+                                       (char *)newval);
+                               return;
+                       }
                        newval = &quadval;
                        newsize = sizeof quadval;
                        break;
@@ -435,7 +478,7 @@ old_parse(string, flags)
                if (flags == 0)
                        return;
                switch (errno) {
-               case EOPNOTSUPP:
+               case ENOTSUP:
                        fprintf(stderr, "%s: value is not available\n", string);
                        return;
                case ENOTDIR:
@@ -446,6 +489,10 @@ old_parse(string, flags)
                        fprintf(stderr, "%s: type is unknown to this program\n",
                            string);
                        return;
+               case ENOENT:
+                       fprintf(stderr, "%s: no such MIB\n",
+                           string);
+                       return;
                default:
                        perror(string);
                        return;
@@ -468,7 +515,7 @@ old_parse(string, flags)
                        fprintf(stdout, "%s = %s\n", string,
                            ctime((time_t *) &btp->tv_sec));
                else
-                       fprintf(stdout, "%d\n", btp->tv_sec);
+                       fprintf(stdout, "%ld\n", btp->tv_sec);
                return;
        }
        if (special & CONSDEV) {
@@ -520,11 +567,11 @@ old_parse(string, flags)
                }
                return;
 
+       case CTLTYPE_NODE:
        case CTLTYPE_STRUCT:
                return;
 
        default:
-       case CTLTYPE_NODE:
                fprintf(stderr, "%s: unknown type returned\n",
                    string);
                return;
@@ -581,7 +628,7 @@ void vfsinit()
        for (loc = lastused, cnt = 0; cnt < maxtypenum; cnt++) {
                mib[3] = cnt;
                if (sysctl(mib, 4, &vfc, &buflen, (void *)0, (size_t)0) < 0) {
-                       if (errno == EOPNOTSUPP)
+                       if (errno == ENOTSUP)
                                continue;
                        perror("vfsinit");
                        free(vfsname);
@@ -612,8 +659,14 @@ findname(string, level, bufp, namelist)
        char *name;
        int i;
 
+       /* Make 'sysctl kern.' style behave the same as 'sysctl kern' 3360872*/
+       if (bufp[0][strlen(*bufp)-1] == '.') 
+               bufp[0][strlen(*bufp)-1]='\0';
        if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
-               fprintf(stderr, "%s: incomplete specification\n", string);
+               if (!foundSome) {
+                       fprintf(stderr, "%s: incomplete specification\n", string);
+                       invalid_name_used = 1;
+               }
                return (-1);
        }
        for (i = 0; i < namelist->size; i++)
@@ -621,8 +674,11 @@ findname(string, level, bufp, namelist)
                    strcmp(name, namelist->list[i].ctl_name) == 0)
                        break;
        if (i == namelist->size) {
-               fprintf(stderr, "%s level name %s in %s is invalid\n",
-                   level, name, string);
+               if (!foundSome) {
+                       fprintf(stderr, "%s level name %s in %s is invalid\n",
+                           level, name, string);
+                       invalid_name_used = 1;
+               }
                return (-1);
        }
        return (i);
@@ -658,6 +714,8 @@ parse(char *string, int flags)
        u_int kind;
 
        bufp = buf;
+       if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ)
+                errx(1, "MIB too long");
        snprintf(buf, BUFSIZ, "%s", string);
        if ((cp = strchr(string, '=')) != NULL) {
                if (!wflag)
@@ -683,8 +741,13 @@ parse(char *string, int flags)
                return;
        }
 
+       /*
+        * An non-zero return here is an OID space containing parameters which
+        * needs to be ignored in the interests of backward compatibility with
+        * pre-newsysctl sysctls.
+        */
        if (oidfmt(mib, len, fmt, &kind))
-               err(1, "couldn't find format of oid '%s'", bufp);
+               return;
 
        if (!wflag) {
                if ((kind & CTLTYPE) == CTLTYPE_NODE) {
@@ -692,7 +755,7 @@ parse(char *string, int flags)
                        foundSome = 1;
                        old_parse (string, flags);
                } else {
-                       i = show_var(mib, len);
+                       i = show_var(mib, len, 1);
                        if (!i && !bflag)
                                putchar('\n');
                }
@@ -707,10 +770,22 @@ parse(char *string, int flags)
                        case CTLTYPE_INT:
                                if ((*fmt == 'I') && (*(fmt + 1) == 'U')) {
                                        uintval = (unsigned int) strtoul (newval, NULL, 0);
+                                       if ((uintval == 0) &&
+                                           (errno == EINVAL)) {
+                                               errx(1, "invalid argument: %s",
+                                                       (char *)newval);
+                                               return;
+                                       }
                                        newval = &uintval;
                                        newsize = sizeof uintval;
                                } else {
                                        intval = (int) strtol(newval, NULL, 0);
+                                       if ((intval == 0) &&
+                                           (errno == EINVAL)) {
+                                               errx(1, "invalid argument: %s",
+                                                       (char *)newval);
+                                               return;
+                                       }
                                        newval = &intval;
                                        newsize = sizeof intval;
                                }
@@ -718,10 +793,13 @@ parse(char *string, int flags)
                        case CTLTYPE_STRING:
                                break;
                        case CTLTYPE_QUAD:
-                               break;
-                               sscanf(newval, "%qd", &quadval);
+                               quadval = strtoq(newval, NULL, 0);
+                               if ((quadval == 0) && (errno == EINVAL)) {
+                                       errx(1, "invalid argument %s", (char *)newval);
+                                       return;
+                               }
                                newval = &quadval;
-                               newsize = sizeof quadval;
+                               newsize = sizeof(quadval);
                                break;
                        default:
                                errx(1, "oid '%s' is type %d,"
@@ -729,12 +807,12 @@ parse(char *string, int flags)
                                        kind & CTLTYPE);
                }
 
-               i = show_var(mib, len);
+               i = show_var(mib, len, 1);
                if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
                        if (!i && !bflag)
                                putchar('\n');
                        switch (errno) {
-                       case EOPNOTSUPP:
+                       case ENOTSUP:
                                errx(1, "%s: value is not available", 
                                        string);
                        case ENOTDIR:
@@ -752,7 +830,7 @@ parse(char *string, int flags)
                        printf(" -> ");
                i = nflag;
                nflag = 1;
-               j = show_var(mib, len);
+               j = show_var(mib, len, 1);
                if (!j && !bflag)
                        putchar('\n');
                nflag = i;
@@ -765,9 +843,13 @@ static int
 S_clockinfo(int l2, void *p)
 {
        struct clockinfo *ci = (struct clockinfo*)p;
-       if (l2 != sizeof *ci)
-               err(1, "S_clockinfo %d != %d", l2, sizeof *ci);
-       printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
+
+       if (l2 != sizeof(*ci)) {
+               warnx("S_clockinfo %d != %ld", l2, sizeof(*ci));
+               return (1);
+       }
+       printf(hflag ? "{ hz = %'d, tick = %'d, tickadj = %'d, profhz = %'d, stathz = %'d }" :
+               "{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
                ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
        return (0);
 }
@@ -777,10 +859,11 @@ S_loadavg(int l2, void *p)
 {
        struct loadavg *tv = (struct loadavg*)p;
 
-       if (l2 != sizeof *tv)
-               err(1, "S_loadavg %d != %d", l2, sizeof *tv);
-
-       printf("{ %.2f %.2f %.2f }",
+       if (l2 != sizeof(*tv)) {
+               warnx("S_loadavg %d != %ld", l2, sizeof(*tv));
+               return (1);
+       }
+       printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
                (double)tv->ldavg[0]/(double)tv->fscale,
                (double)tv->ldavg[1]/(double)tv->fscale,
                (double)tv->ldavg[2]/(double)tv->fscale);
@@ -794,16 +877,38 @@ S_timeval(int l2, void *p)
        time_t tv_sec;
        char *p1, *p2;
 
-       if (l2 != sizeof *tv)
-               err(1, "S_timeval %d != %d", l2, sizeof *tv);
-       printf("{ sec = %ld, usec = %ld } ",
-               (long) tv->tv_sec, (long) tv->tv_usec);
+       if (l2 != sizeof(*tv)) {
+               warnx("S_timeval %d != %ld", l2, sizeof(*tv));
+               return (1);
+       }
+       printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
+               "{ sec = %jd, usec = %ld } ",
+               (intmax_t)tv->tv_sec, (long)tv->tv_usec);
        tv_sec = tv->tv_sec;
        p1 = strdup(ctime(&tv_sec));
        for (p2=p1; *p2 ; p2++)
                if (*p2 == '\n')
                        *p2 = '\0';
        fputs(p1, stdout);
+       free(p1);
+       return (0);
+}
+
+static int
+S_xswusage(int l2, void *p)
+{
+        struct xsw_usage *xsu = (struct xsw_usage *)p;
+  
+       if (l2 != sizeof(*xsu)) {
+               warnx("S_xswusage %d != %ld", l2, sizeof(*xsu));
+               return (1);
+       }
+       fprintf(stdout,
+               "total = %.2fM  used = %.2fM  free = %.2fM  %s",
+               ((double)xsu->xsu_total) / (1024.0 * 1024.0),
+               ((double)xsu->xsu_used) / (1024.0 * 1024.0),
+               ((double)xsu->xsu_avail) / (1024.0 * 1024.0),
+               xsu->xsu_encrypted ? "(encrypted)" : "");
        return (0);
 }
 
@@ -811,8 +916,11 @@ static int
 T_dev_t(int l2, void *p)
 {
        dev_t *d = (dev_t *)p;
-       if (l2 != sizeof *d)
-               err(1, "T_dev_T %d != %d", l2, sizeof *d);
+
+       if (l2 != sizeof(*d)) {
+               warnx("T_dev_T %d != %ld", l2, sizeof(*d));
+               return (1);
+       }
        if ((int)(*d) != -1) {
                if (minor(*d) > 255 || minor(*d) < 0)
                        printf("{ major = %d, minor = 0x%x }",
@@ -863,17 +971,27 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
        qoid[1] = 4;
        memcpy(qoid + 2, oid, len * sizeof(int));
 
-       j = sizeof buf;
+       j = sizeof(buf);
        i = sysctl(qoid, len + 2, buf, &j, 0, 0);
-       if (i)
-               err(1, "sysctl fmt %d %d %d", i, j, errno);
+       if (i) {
+               /*
+                * An ENOENT error return indicates that the OID in question
+                * is a node OID followed not by additional OID elements, but
+                * by integer parameters.  We really do not want to support
+                * this type of thing going forward, but we alow it here for
+                * historical compatibility.  Eventually, this will go away.
+                */
+               if (errno == ENOENT)
+                       return ENOENT;
+               err(1, "sysctl fmt %d %ld %d", i, j, errno);
+       }
 
        if (kind)
                *kind = *(u_int *)buf;
 
        if (fmt)
                strcpy(fmt, (char *)(buf + sizeof(u_int)));
-       return 0;
+       return (0);
 }
 
 /*
@@ -885,12 +1003,13 @@ oidfmt(int *oid, int len, char *fmt, u_int *kind)
  */
 
 static int
-show_var(int *oid, int nlen)
+show_var(int *oid, int nlen, int show_masked)
 {
-       u_char buf[BUFSIZ], *val, *p;
+       u_char buf[BUFSIZ], *val, *mval, *p;
        char name[BUFSIZ], /* descr[BUFSIZ], */ *fmt;
        int qoid[CTL_MAXNAME+2];
        int i;
+       int retval;
        size_t j, len;
        u_int kind;
        int (*func)(int, void *) = 0;
@@ -902,79 +1021,126 @@ show_var(int *oid, int nlen)
        j = sizeof name;
        i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
        if (i || !j)
-               err(1, "sysctl name %d %d %d", i, j, errno);
+               err(1, "sysctl name %d %ld %d", i, j, errno);
 
        /* find an estimate of how much we need for this var */
        j = 0;
        i = sysctl(oid, nlen, 0, &j, 0, 0);
        j += j; /* we want to be sure :-) */
 
-       val = alloca(j);
+       val = mval = malloc(j);
        len = j;
        i = sysctl(oid, nlen, val, &len, 0, 0);
-       if (i || !len)
-               return (1);
+       if (i || !len) {
+               retval = 1;
+               goto RETURN;
+       }
 
        if (bflag) {
                fwrite(val, 1, len, stdout);
-               return (0);
+               retval = 0;
+               goto RETURN;
        }
 
        qoid[1] = 4;
        j = sizeof buf;
        i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
+       /*
+        * An ENOENT error return indicates that the OID in question
+        * is a node OID followed not by additional OID elements, but
+        * by integer parameters.  We really do not want to support
+        * this type of thing going forward, but we alow it here for
+        * historical compatibility.  Eventially, this will go away.
+        */
+       if (i && errno == ENOENT) {
+               retval = 1;
+               goto RETURN;
+       }
+               
        if (i || !j)
-               err(1, "sysctl fmt %d %d %d", i, j, errno);
+               err(1, "sysctl fmt %d %ld %d", i, j, errno);
 
        kind = *(u_int *)buf;
+       if (!show_masked && (kind & CTLFLAG_MASKED)) {
+               retval = 1;
+               goto RETURN;
+       }
 
        fmt = (char *)(buf + sizeof(u_int));
 
        p = val;
        switch (*fmt) {
+       case '-':
+               /* deprecated, do not print */
+               retval = 0;
+               goto RETURN;
+               
+
        case 'A':
                if (!nflag)
                        printf("%s: ", name);
                printf("%s", p);
-               return (0);
+               retval = 0;
+               goto RETURN;
                
        case 'I':
                if (!nflag)
                        printf("%s: ", name);
                fmt++;
-               val = "";
+               val = (unsigned char *)"";
                while (len >= sizeof(int)) {
                        if(*fmt == 'U')
                                printf("%s%u", val, *(unsigned int *)p);
                        else
                                printf("%s%d", val, *(int *)p);
-                       val = " ";
+                       val = (unsigned char *)" ";
                        len -= sizeof (int);
                        p += sizeof (int);
                }
-               return (0);
+               retval = 0;
+               goto RETURN;
 
        case 'L':
                if (!nflag)
                        printf("%s: ", name);
                fmt++;
-               val = "";
+               val = (unsigned char *)"";
                while (len >= sizeof(long)) {
                        if(*fmt == 'U')
                                printf("%s%lu", val, *(unsigned long *)p);
                        else
                                printf("%s%ld", val, *(long *)p);
-                       val = " ";
+                       val = (unsigned char *)" ";
                        len -= sizeof (long);
                        p += sizeof (long);
                }
-               return (0);
+               retval = 0;
+               goto RETURN;
 
        case 'P':
                if (!nflag)
                        printf("%s: ", name);
                printf("%p", *(void **)p);
-               return (0);
+               retval = 0;
+               goto RETURN;
+
+       case 'Q':
+               if (!nflag)
+                       printf("%s: ", name);
+               fmt++;
+               val = (unsigned char *)"";
+               while (len >= sizeof(long long)) {
+                       if(*fmt == 'U')
+                               printf("%s%llu", val, *(unsigned long long *)p);
+                       else
+                               printf("%s%lld", val, *(long long *)p);
+                       val = (unsigned char *)" ";
+                       len -= sizeof (long long);
+                       p += sizeof (long long);
+               }
+               retval = 0;
+               goto RETURN;
+
 
        case 'T':
        case 'S':
@@ -982,16 +1148,20 @@ show_var(int *oid, int nlen)
                if (!strcmp(fmt, "S,clockinfo"))        func = S_clockinfo;
                else if (!strcmp(fmt, "S,timeval"))     func = S_timeval;
                else if (!strcmp(fmt, "S,loadavg"))     func = S_loadavg;
+               else if (!strcmp(fmt, "S,xsw_usage"))   func = S_xswusage;
                else if (!strcmp(fmt, "T,dev_t"))       func = T_dev_t;
                if (func) {
                        if (!nflag)
                                printf("%s: ", name);
-                       return ((*func)(len, p));
+                       retval = (*func)(len, p);
+                       goto RETURN;
                }
                /* FALL THROUGH */
        default:
-               if (!Aflag)
-                       return (1);
+               if (!Aflag) {
+                       retval = 1;
+                       goto RETURN;
+               }
                if (!nflag)
                        printf("%s: ", name);
                printf("Format:%s Length:%ld Dump:0x", fmt, len);
@@ -1002,9 +1172,14 @@ show_var(int *oid, int nlen)
                        printf("...");
                        break;
                }
-               return (0);
+               retval = 0;
+               goto RETURN;
        }
-       return (1);
+
+       retval = 1;
+       RETURN:
+       free(mval);
+       return (retval);
 }
 
 static int
@@ -1031,7 +1206,7 @@ sysctl_all (int *oid, int len)
                        if (errno == ENOENT)
                                return 0;
                        else
-                               err(1, "sysctl(getnext) %d %d", j, l2);
+                               err(1, "sysctl(getnext) %d %ld", j, l2);
                }
 
                l2 /= sizeof (int);
@@ -1043,7 +1218,7 @@ sysctl_all (int *oid, int len)
                        if (name2[i] != oid[i])
                                return 0;
 
-               i = show_var(name2, l2);
+               i = show_var(name2, l2, 0);
                if (!i && !bflag)
                        putchar('\n');