sysctl.c revision 85747
11553Srgrimes/*
21553Srgrimes * Copyright (c) 1993
31553Srgrimes *	The Regents of the University of California.  All rights reserved.
41553Srgrimes *
51553Srgrimes * Redistribution and use in source and binary forms, with or without
61553Srgrimes * modification, are permitted provided that the following conditions
71553Srgrimes * are met:
81553Srgrimes * 1. Redistributions of source code must retain the above copyright
91553Srgrimes *    notice, this list of conditions and the following disclaimer.
101553Srgrimes * 2. Redistributions in binary form must reproduce the above copyright
111553Srgrimes *    notice, this list of conditions and the following disclaimer in the
121553Srgrimes *    documentation and/or other materials provided with the distribution.
131553Srgrimes * 3. All advertising materials mentioning features or use of this software
141553Srgrimes *    must display the following acknowledgement:
151553Srgrimes *	This product includes software developed by the University of
161553Srgrimes *	California, Berkeley and its contributors.
171553Srgrimes * 4. Neither the name of the University nor the names of its contributors
181553Srgrimes *    may be used to endorse or promote products derived from this software
191553Srgrimes *    without specific prior written permission.
201553Srgrimes *
211553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
221553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
231553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
241553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
251553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
261553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
271553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
281553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
291553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
301553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
311553Srgrimes * SUCH DAMAGE.
321553Srgrimes */
331553Srgrimes
341553Srgrimes#ifndef lint
3530602Scharnierstatic const char copyright[] =
361553Srgrimes"@(#) Copyright (c) 1993\n\
371553Srgrimes	The Regents of the University of California.  All rights reserved.\n";
381553Srgrimes#endif /* not lint */
391553Srgrimes
401553Srgrimes#ifndef lint
4130602Scharnier#if 0
4230602Scharnierstatic char sccsid[] = "@(#)from: sysctl.c	8.1 (Berkeley) 6/6/93";
4330602Scharnier#endif
446284Swollmanstatic const char rcsid[] =
4550476Speter  "$FreeBSD: head/sbin/sysctl/sysctl.c 85747 2001-10-30 20:15:32Z tobez $";
461553Srgrimes#endif /* not lint */
471553Srgrimes
4812946Sphk#include <sys/types.h>
491553Srgrimes#include <sys/stat.h>
501553Srgrimes#include <sys/sysctl.h>
5112946Sphk#include <sys/resource.h>
521553Srgrimes
5330602Scharnier#include <ctype.h>
5430602Scharnier#include <err.h>
551553Srgrimes#include <errno.h>
561553Srgrimes#include <stdio.h>
571553Srgrimes#include <stdlib.h>
581553Srgrimes#include <string.h>
5930602Scharnier#include <unistd.h>
601553Srgrimes
6185747Stobezstatic int	aflag, bflag, eflag, Nflag, nflag, oflag, xflag;
621553Srgrimes
6312946Sphkstatic int	oidfmt(int *, int, char *, u_int *);
6412946Sphkstatic void	parse(char *);
6512946Sphkstatic int	show_var(int *, int);
6612946Sphkstatic int	sysctl_all (int *oid, int len);
6712946Sphkstatic int	name2oid(char *, int *);
681553Srgrimes
6912946Sphkstatic void
7012946Sphkusage(void)
7112946Sphk{
721553Srgrimes
7377330Sdes	(void)fprintf(stderr, "%s\n%s\n",
7485747Stobez	    "usage: sysctl [-beNnox] variable[=value] ...",
7585747Stobez	    "       sysctl [-beNnox] -a");
7612946Sphk	exit(1);
7712946Sphk}
781553Srgrimes
791553Srgrimesint
8012946Sphkmain(int argc, char **argv)
811553Srgrimes{
8212946Sphk	int ch;
8312946Sphk	setbuf(stdout,0);
8412946Sphk	setbuf(stderr,0);
851553Srgrimes
8685747Stobez	while ((ch = getopt(argc, argv, "AabeNnowxX")) != -1) {
871553Srgrimes		switch (ch) {
8871034Sdes		case 'A':
8977330Sdes			/* compatibility */
9077330Sdes			aflag = oflag = 1;
9171034Sdes			break;
9271034Sdes		case 'a':
9371034Sdes			aflag = 1;
9471034Sdes			break;
9571034Sdes		case 'b':
9671034Sdes			bflag = 1;
9771034Sdes			break;
9885747Stobez		case 'e':
9985747Stobez			eflag = 1;
10085747Stobez			break;
10171034Sdes		case 'N':
10271034Sdes			Nflag = 1;
10371034Sdes			break;
10471034Sdes		case 'n':
10571034Sdes			nflag = 1;
10671034Sdes			break;
10777330Sdes		case 'o':
10877330Sdes			oflag = 1;
10977330Sdes			break;
11071034Sdes		case 'w':
11177330Sdes			/* compatibility */
11277330Sdes			/* ignored */
11371034Sdes			break;
11471034Sdes		case 'X':
11577330Sdes			/* compatibility */
11677330Sdes			aflag = xflag = 1;
11771034Sdes			break;
11877330Sdes		case 'x':
11977330Sdes			xflag = 1;
12077330Sdes			break;
12171034Sdes		default:
12271034Sdes			usage();
1231553Srgrimes		}
1241553Srgrimes	}
1251553Srgrimes	argc -= optind;
1261553Srgrimes	argv += optind;
1271553Srgrimes
12877330Sdes	if (Nflag && nflag)
12942456Sdes		usage();
13077330Sdes	if (aflag && argc == 0)
13177330Sdes		exit(sysctl_all(0, 0));
1321553Srgrimes	if (argc == 0)
1331553Srgrimes		usage();
1341553Srgrimes	while (argc-- > 0)
13512946Sphk		parse(*argv++);
1361553Srgrimes	exit(0);
1371553Srgrimes}
1381553Srgrimes
1391553Srgrimes/*
1401553Srgrimes * Parse a name into a MIB entry.
1411553Srgrimes * Lookup and print out the MIB entry if it exists.
1421553Srgrimes * Set a new value if requested.
1431553Srgrimes */
14412946Sphkstatic void
14512946Sphkparse(char *string)
1461553Srgrimes{
14712946Sphk	int len, i, j;
1481553Srgrimes	void *newval = 0;
14978434Spirzyk	int intval;
15078434Spirzyk	unsigned int uintval;
15178434Spirzyk	long longval;
15278434Spirzyk	unsigned long ulongval;
15378434Spirzyk	size_t newsize = 0;
1541553Srgrimes	quad_t quadval;
1551553Srgrimes	int mib[CTL_MAXNAME];
15612946Sphk	char *cp, *bufp, buf[BUFSIZ];
15712946Sphk	u_int kind;
1581553Srgrimes
1591553Srgrimes	bufp = buf;
1601553Srgrimes	snprintf(buf, BUFSIZ, "%s", string);
1611553Srgrimes	if ((cp = strchr(string, '=')) != NULL) {
1621553Srgrimes		*strchr(buf, '=') = '\0';
1631553Srgrimes		*cp++ = '\0';
1641553Srgrimes		while (isspace(*cp))
1651553Srgrimes			cp++;
1661553Srgrimes		newval = cp;
1671553Srgrimes		newsize = strlen(cp);
1681553Srgrimes	}
16912946Sphk	len = name2oid(bufp, mib);
1701553Srgrimes
17112946Sphk	if (len < 0)
17230602Scharnier		errx(1, "unknown oid '%s'", bufp);
1731553Srgrimes
17412946Sphk	if (oidfmt(mib, len, 0, &kind))
17530602Scharnier		err(1, "couldn't find format of oid '%s'", bufp);
1761553Srgrimes
17777330Sdes	if (newval == NULL) {
17812946Sphk		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
17912946Sphk			sysctl_all(mib, len);
18012946Sphk		} else {
18112946Sphk			i = show_var(mib, len);
18212946Sphk			if (!i && !bflag)
18312946Sphk				putchar('\n');
1841553Srgrimes		}
18512946Sphk	} else {
18612946Sphk		if ((kind & CTLTYPE) == CTLTYPE_NODE)
18712946Sphk			errx(1, "oid '%s' isn't a leaf node", bufp);
1881553Srgrimes
18912946Sphk		if (!(kind&CTLFLAG_WR))
19012946Sphk			errx(1, "oid '%s' is read only", bufp);
19112946Sphk
19212946Sphk		switch (kind & CTLTYPE) {
19312946Sphk			case CTLTYPE_INT:
19453317Sgrog				intval = (int) strtol(newval, NULL, 0);
19512946Sphk				newval = &intval;
19677928Sdd				newsize = sizeof(intval);
1971553Srgrimes				break;
19878434Spirzyk			case CTLTYPE_UINT:
19978434Spirzyk				uintval = (int) strtoul(newval, NULL, 0);
20078434Spirzyk				newval = &uintval;
20178434Spirzyk				newsize = sizeof uintval;
20212946Sphk				break;
20378434Spirzyk			case CTLTYPE_LONG:
20478434Spirzyk				longval = strtol(newval, NULL, 0);
20578434Spirzyk				newval = &longval;
20678434Spirzyk				newsize = sizeof longval;
20778434Spirzyk				break;
20878434Spirzyk			case CTLTYPE_ULONG:
20978434Spirzyk				ulongval = strtoul(newval, NULL, 0);
21078434Spirzyk				newval = &ulongval;
21178434Spirzyk				newsize = sizeof ulongval;
21278434Spirzyk				break;
21312946Sphk			case CTLTYPE_STRING:
21412946Sphk				break;
21512946Sphk			case CTLTYPE_QUAD:
21612946Sphk				break;
21712946Sphk				sscanf(newval, "%qd", &quadval);
21812946Sphk				newval = &quadval;
21977928Sdd				newsize = sizeof(quadval);
22012946Sphk				break;
22112946Sphk			default:
22212946Sphk				errx(1, "oid '%s' is type %d,"
22331214Sjdp					" cannot set that", bufp,
22431214Sjdp					kind & CTLTYPE);
2251553Srgrimes		}
2261553Srgrimes
22712946Sphk		i = show_var(mib, len);
22812946Sphk		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
22912946Sphk			if (!i && !bflag)
23012946Sphk				putchar('\n');
23112946Sphk			switch (errno) {
23212946Sphk			case EOPNOTSUPP:
23330602Scharnier				errx(1, "%s: value is not available",
23412946Sphk					string);
23512946Sphk			case ENOTDIR:
23630602Scharnier				errx(1, "%s: specification is incomplete",
23712946Sphk					string);
23812946Sphk			case ENOMEM:
23930602Scharnier				errx(1, "%s: type is unknown to this program",
24012946Sphk					string);
24112946Sphk			default:
24230602Scharnier				warn("%s", string);
24312946Sphk				return;
24412946Sphk			}
24512946Sphk		}
24612946Sphk		if (!bflag)
24712946Sphk			printf(" -> ");
24812946Sphk		i = nflag;
24912946Sphk		nflag = 1;
25012946Sphk		j = show_var(mib, len);
25112946Sphk		if (!j && !bflag)
25212946Sphk			putchar('\n');
25312946Sphk		nflag = i;
25412946Sphk	}
25512946Sphk}
2561553Srgrimes
25712946Sphk/* These functions will dump out various interesting structures. */
2581553Srgrimes
25912946Sphkstatic int
26012946SphkS_clockinfo(int l2, void *p)
26112946Sphk{
26212946Sphk	struct clockinfo *ci = (struct clockinfo*)p;
26377928Sdd	if (l2 != sizeof(*ci))
26477928Sdd		err(1, "S_clockinfo %d != %d", l2, sizeof(*ci));
26526899Sjhay	printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
26626899Sjhay		ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
26712946Sphk	return (0);
26812946Sphk}
2691553Srgrimes
27012946Sphkstatic int
27112946SphkS_loadavg(int l2, void *p)
27212946Sphk{
27312946Sphk	struct loadavg *tv = (struct loadavg*)p;
2748857Srgrimes
27577928Sdd	if (l2 != sizeof(*tv))
27677928Sdd		err(1, "S_loadavg %d != %d", l2, sizeof(*tv));
2771553Srgrimes
27812946Sphk	printf("{ %.2f %.2f %.2f }",
27912946Sphk		(double)tv->ldavg[0]/(double)tv->fscale,
28012946Sphk		(double)tv->ldavg[1]/(double)tv->fscale,
28112946Sphk		(double)tv->ldavg[2]/(double)tv->fscale);
28212946Sphk	return (0);
28312946Sphk}
2841553Srgrimes
28512946Sphkstatic int
28612946SphkS_timeval(int l2, void *p)
28712946Sphk{
28812946Sphk	struct timeval *tv = (struct timeval*)p;
28937266Sbde	time_t tv_sec;
29012946Sphk	char *p1, *p2;
2911553Srgrimes
29277928Sdd	if (l2 != sizeof(*tv))
29377928Sdd		err(1, "S_timeval %d != %d", l2, sizeof(*tv));
29412946Sphk	printf("{ sec = %ld, usec = %ld } ",
29512946Sphk		tv->tv_sec, tv->tv_usec);
29637266Sbde	tv_sec = tv->tv_sec;
29737266Sbde	p1 = strdup(ctime(&tv_sec));
29812946Sphk	for (p2=p1; *p2 ; p2++)
29912946Sphk		if (*p2 == '\n')
30012946Sphk			*p2 = '\0';
30112946Sphk	fputs(p1, stdout);
30212946Sphk	return (0);
30312946Sphk}
3041553Srgrimes
30512946Sphkstatic int
30612946SphkT_dev_t(int l2, void *p)
30712946Sphk{
30812946Sphk	dev_t *d = (dev_t *)p;
30977928Sdd	if (l2 != sizeof(*d))
31077928Sdd		err(1, "T_dev_T %d != %d", l2, sizeof(*d));
31161514Sphk	if ((int)(*d) != -1) {
31261514Sphk		if (minor(*d) > 255 || minor(*d) < 0)
31361514Sphk			printf("{ major = %d, minor = 0x%x }",
31461514Sphk				major(*d), minor(*d));
31561514Sphk		else
31661514Sphk			printf("{ major = %d, minor = %d }",
31761514Sphk				major(*d), minor(*d));
31861514Sphk	}
31912946Sphk	return (0);
32012946Sphk}
3211553Srgrimes
32212946Sphk/*
32312946Sphk * These functions uses a presently undocumented interface to the kernel
32412946Sphk * to walk the tree and get the type so it can print the value.
32512946Sphk * This interface is under work and consideration, and should probably
32612946Sphk * be killed with a big axe by the first person who can find the time.
32712946Sphk * (be aware though, that the proper interface isn't as obvious as it
32812946Sphk * may seem, there are various conflicting requirements.
32912946Sphk */
3301553Srgrimes
33112946Sphkstatic int
33212946Sphkname2oid(char *name, int *oidp)
33312946Sphk{
33412946Sphk	int oid[2];
33538533Sdfr	int i;
33638533Sdfr	size_t j;
3371553Srgrimes
33812946Sphk	oid[0] = 0;
33912946Sphk	oid[1] = 3;
3401553Srgrimes
34177928Sdd	j = CTL_MAXNAME * sizeof(int);
34212946Sphk	i = sysctl(oid, 2, oidp, &j, name, strlen(name));
34312946Sphk	if (i < 0)
34412946Sphk		return i;
34577928Sdd	j /= sizeof(int);
34612946Sphk	return (j);
3471553Srgrimes}
3481553Srgrimes
34912946Sphkstatic int
35012946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind)
35112946Sphk{
35212946Sphk	int qoid[CTL_MAXNAME+2];
35312946Sphk	u_char buf[BUFSIZ];
35438533Sdfr	int i;
35538533Sdfr	size_t j;
3561553Srgrimes
35712946Sphk	qoid[0] = 0;
35812946Sphk	qoid[1] = 4;
35912946Sphk	memcpy(qoid + 2, oid, len * sizeof(int));
3601553Srgrimes
36177928Sdd	j = sizeof(buf);
36212946Sphk	i = sysctl(qoid, len + 2, buf, &j, 0, 0);
36312946Sphk	if (i)
36430602Scharnier		err(1, "sysctl fmt %d %d %d", i, j, errno);
3651553Srgrimes
36612946Sphk	if (kind)
36712946Sphk		*kind = *(u_int *)buf;
36812946Sphk
36912946Sphk	if (fmt)
37012946Sphk		strcpy(fmt, (char *)(buf + sizeof(u_int)));
37112946Sphk	return 0;
3721553Srgrimes}
3731553Srgrimes
3741553Srgrimes/*
37512946Sphk * This formats and outputs the value of one variable
37612946Sphk *
37712946Sphk * Returns zero if anything was actually output.
37812946Sphk * Returns one if didn't know what to do with this.
37912946Sphk * Return minus one if we had errors.
3801553Srgrimes */
38112946Sphk
38212946Sphkstatic int
38312946Sphkshow_var(int *oid, int nlen)
3841553Srgrimes{
38512946Sphk	u_char buf[BUFSIZ], *val, *p;
38685747Stobez	char name[BUFSIZ], *fmt, *sep;
38712946Sphk	int qoid[CTL_MAXNAME+2];
38838533Sdfr	int i;
38938533Sdfr	size_t j, len;
39012946Sphk	u_int kind;
39177332Sdes	int (*func)(int, void *);
3921553Srgrimes
39342456Sdes	qoid[0] = 0;
39442456Sdes	memcpy(qoid + 2, oid, nlen * sizeof(int));
39542456Sdes
39642456Sdes	qoid[1] = 1;
39777928Sdd	j = sizeof(name);
39842456Sdes	i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
39942456Sdes	if (i || !j)
40042456Sdes		err(1, "sysctl name %d %d %d", i, j, errno);
40142456Sdes
40271034Sdes	if (Nflag) {
40371034Sdes		printf("%s", name);
40471034Sdes		return (0);
40571034Sdes	}
40671034Sdes
40785747Stobez	if (eflag)
40885747Stobez		sep = "=";
40985747Stobez	else
41085747Stobez		sep = ": ";
41185747Stobez
41212946Sphk	/* find an estimate of how much we need for this var */
41312946Sphk	j = 0;
41412946Sphk	i = sysctl(oid, nlen, 0, &j, 0, 0);
41512946Sphk	j += j; /* we want to be sure :-) */
41612946Sphk
41712946Sphk	val = alloca(j);
41812946Sphk	len = j;
41912946Sphk	i = sysctl(oid, nlen, val, &len, 0, 0);
42012946Sphk	if (i || !len)
42112946Sphk		return (1);
42212946Sphk
42312946Sphk	if (bflag) {
42412946Sphk		fwrite(val, 1, len, stdout);
42512946Sphk		return (0);
4261553Srgrimes	}
42712946Sphk
42812946Sphk	qoid[1] = 4;
42977928Sdd	j = sizeof(buf);
43012946Sphk	i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
43112946Sphk	if (i || !j)
43230602Scharnier		err(1, "sysctl fmt %d %d %d", i, j, errno);
43312946Sphk
43412946Sphk	kind = *(u_int *)buf;
43512946Sphk
43612946Sphk	fmt = (char *)(buf + sizeof(u_int));
43712946Sphk
43812946Sphk	p = val;
43912946Sphk	switch (*fmt) {
44012946Sphk	case 'A':
44112946Sphk		if (!nflag)
44285747Stobez			printf("%s%s", name, sep);
44312946Sphk		printf("%s", p);
44412946Sphk		return (0);
44512946Sphk
44612946Sphk	case 'I':
44712946Sphk		if (!nflag)
44885747Stobez			printf("%s%s", name, sep);
44962622Sjhb		fmt++;
45041019Sphk		val = "";
45141019Sphk		while (len >= sizeof(int)) {
45262622Sjhb			if(*fmt == 'U')
45362622Sjhb				printf("%s%u", val, *(unsigned int *)p);
45462622Sjhb			else
45562622Sjhb				printf("%s%d", val, *(int *)p);
45641019Sphk			val = " ";
45777332Sdes			len -= sizeof(int);
45877332Sdes			p += sizeof(int);
45941019Sphk		}
46012946Sphk		return (0);
46112946Sphk
46238533Sdfr	case 'L':
46338533Sdfr		if (!nflag)
46485747Stobez			printf("%s%s", name, sep);
46562622Sjhb		fmt++;
46662975Sphk		val = "";
46762975Sphk		while (len >= sizeof(long)) {
46862975Sphk			if(*fmt == 'U')
46962975Sphk				printf("%s%lu", val, *(unsigned long *)p);
47062975Sphk			else
47162975Sphk				printf("%s%ld", val, *(long *)p);
47262975Sphk			val = " ";
47377332Sdes			len -= sizeof(long);
47477332Sdes			p += sizeof(long);
47562975Sphk		}
47638533Sdfr		return (0);
47738533Sdfr
47838533Sdfr	case 'P':
47938533Sdfr		if (!nflag)
48085747Stobez			printf("%s%s", name, sep);
48138533Sdfr		printf("%p", *(void **)p);
48238533Sdfr		return (0);
48338533Sdfr
48412946Sphk	case 'T':
48512946Sphk	case 'S':
48612946Sphk		i = 0;
48777332Sdes		if (strcmp(fmt, "S,clockinfo") == 0)
48877332Sdes			func = S_clockinfo;
48977332Sdes		else if (strcmp(fmt, "S,timeval") == 0)
49077332Sdes			func = S_timeval;
49177332Sdes		else if (strcmp(fmt, "S,loadavg") == 0)
49277332Sdes			func = S_loadavg;
49377332Sdes		else if (strcmp(fmt, "T,dev_t") == 0)
49477332Sdes			func = T_dev_t;
49577332Sdes		else
49677332Sdes			func = NULL;
49712946Sphk		if (func) {
49812946Sphk			if (!nflag)
49985747Stobez				printf("%s%s", name, sep);
50012946Sphk			return ((*func)(len, p));
50112946Sphk		}
50212946Sphk		/* FALL THROUGH */
50312946Sphk	default:
50477330Sdes		if (!oflag && !xflag)
50512946Sphk			return (1);
50612946Sphk		if (!nflag)
50785747Stobez			printf("%s%s", name, sep);
50812946Sphk		printf("Format:%s Length:%d Dump:0x", fmt, len);
50977332Sdes		while (len-- && (xflag || p < val + 16))
51012946Sphk			printf("%02x", *p++);
51177332Sdes		if (!xflag && len > 16)
51212946Sphk			printf("...");
51312946Sphk		return (0);
5141553Srgrimes	}
51512946Sphk	return (1);
5161553Srgrimes}
5171553Srgrimes
51812946Sphkstatic int
51912946Sphksysctl_all (int *oid, int len)
5201553Srgrimes{
52112946Sphk	int name1[22], name2[22];
52238533Sdfr	int i, j;
52338533Sdfr	size_t l1, l2;
5241553Srgrimes
52512946Sphk	name1[0] = 0;
52612946Sphk	name1[1] = 2;
52712946Sphk	l1 = 2;
52812946Sphk	if (len) {
52977928Sdd		memcpy(name1+2, oid, len * sizeof(int));
53012946Sphk		l1 += len;
53112946Sphk	} else {
53212946Sphk		name1[2] = 1;
53312946Sphk		l1++;
53412946Sphk	}
53577332Sdes	for (;;) {
53677928Sdd		l2 = sizeof(name2);
53712946Sphk		j = sysctl(name1, l1, name2, &l2, 0, 0);
53848956Sbillf		if (j < 0) {
53912946Sphk			if (errno == ENOENT)
54012946Sphk				return 0;
54112946Sphk			else
54230602Scharnier				err(1, "sysctl(getnext) %d %d", j, l2);
54348956Sbillf		}
54412946Sphk
54577928Sdd		l2 /= sizeof(int);
54612946Sphk
54712946Sphk		if (l2 < len)
54812946Sphk			return 0;
54912946Sphk
55012946Sphk		for (i = 0; i < len; i++)
55112946Sphk			if (name2[i] != oid[i])
55212946Sphk				return 0;
55312946Sphk
55412946Sphk		i = show_var(name2, l2);
55512946Sphk		if (!i && !bflag)
55612946Sphk			putchar('\n');
55712946Sphk
55877928Sdd		memcpy(name1+2, name2, l2 * sizeof(int));
55912946Sphk		l1 = 2 + l2;
56012946Sphk	}
5611553Srgrimes}
562