-/*
- * 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>
#else
#include <vm/vm_param.h>
#endif /* __APPLE__ */
-#include <machine/cpu.h>
#include <errno.h>
#include <ctype.h>
{ 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
{ 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);
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 *);
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;
}
if (argc == 0)
usage();
- for (; *argv != NULL; ++argv)
+ for (; *argv != NULL; ++argv)
parse(*argv, 1);
- exit(0);
+ exit(invalid_name_used ? 1 : 0);
}
/*
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);
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;
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;
if (flags == 0)
return;
switch (errno) {
- case EOPNOTSUPP:
+ case ENOTSUP:
fprintf(stderr, "%s: value is not available\n", string);
return;
case ENOTDIR:
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;
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) {
}
return;
+ case CTLTYPE_NODE:
case CTLTYPE_STRUCT:
return;
default:
- case CTLTYPE_NODE:
fprintf(stderr, "%s: unknown type returned\n",
string);
return;
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);
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++)
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);
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)
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) {
foundSome = 1;
old_parse (string, flags);
} else {
- i = show_var(mib, len);
+ i = show_var(mib, len, 1);
if (!i && !bflag)
putchar('\n');
}
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;
}
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,"
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:
printf(" -> ");
i = nflag;
nflag = 1;
- j = show_var(mib, len);
+ j = show_var(mib, len, 1);
if (!j && !bflag)
putchar('\n');
nflag = i;
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);
}
{
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);
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);
}
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 }",
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);
}
/*
*/
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;
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':
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);
printf("...");
break;
}
- return (0);
+ retval = 0;
+ goto RETURN;
}
- return (1);
+
+ retval = 1;
+ RETURN:
+ free(mval);
+ return (retval);
}
static int
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);
if (name2[i] != oid[i])
return 0;
- i = show_var(name2, l2);
+ i = show_var(name2, l2, 0);
if (!i && !bflag)
putchar('\n');