sysctl.c revision 91217
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 91217 2002-02-25 03:36:06Z bde $";
461553Srgrimes#endif /* not lint */
471553Srgrimes
4891217Sbde#include <sys/param.h>
4991217Sbde#include <sys/time.h>
5091217Sbde#include <sys/resource.h>
511553Srgrimes#include <sys/stat.h>
521553Srgrimes#include <sys/sysctl.h>
531553Srgrimes
5430602Scharnier#include <ctype.h>
5530602Scharnier#include <err.h>
561553Srgrimes#include <errno.h>
571553Srgrimes#include <stdio.h>
581553Srgrimes#include <stdlib.h>
591553Srgrimes#include <string.h>
6030602Scharnier#include <unistd.h>
611553Srgrimes
6288006Sluigistatic int	aflag, bflag, dflag, eflag, Nflag, nflag, oflag, xflag;
631553Srgrimes
6412946Sphkstatic int	oidfmt(int *, int, char *, u_int *);
6512946Sphkstatic void	parse(char *);
6612946Sphkstatic int	show_var(int *, int);
6712946Sphkstatic int	sysctl_all (int *oid, int len);
6812946Sphkstatic int	name2oid(char *, int *);
691553Srgrimes
7088696Sphkstatic void	set_T_dev_t (char *, void **, int *);
7188696Sphk
7212946Sphkstatic void
7312946Sphkusage(void)
7412946Sphk{
751553Srgrimes
7677330Sdes	(void)fprintf(stderr, "%s\n%s\n",
7788006Sluigi	    "usage: sysctl [-bdeNnox] variable[=value] ...",
7888006Sluigi	    "       sysctl [-bdeNnox] -a");
7912946Sphk	exit(1);
8012946Sphk}
811553Srgrimes
821553Srgrimesint
8312946Sphkmain(int argc, char **argv)
841553Srgrimes{
8512946Sphk	int ch;
8612946Sphk	setbuf(stdout,0);
8712946Sphk	setbuf(stderr,0);
881553Srgrimes
8988006Sluigi	while ((ch = getopt(argc, argv, "AabdeNnowxX")) != -1) {
901553Srgrimes		switch (ch) {
9171034Sdes		case 'A':
9277330Sdes			/* compatibility */
9377330Sdes			aflag = oflag = 1;
9471034Sdes			break;
9571034Sdes		case 'a':
9671034Sdes			aflag = 1;
9771034Sdes			break;
9871034Sdes		case 'b':
9971034Sdes			bflag = 1;
10071034Sdes			break;
10188006Sluigi		case 'd':
10288006Sluigi			dflag = 1;
10388006Sluigi			break;
10485747Stobez		case 'e':
10585747Stobez			eflag = 1;
10685747Stobez			break;
10771034Sdes		case 'N':
10871034Sdes			Nflag = 1;
10971034Sdes			break;
11071034Sdes		case 'n':
11171034Sdes			nflag = 1;
11271034Sdes			break;
11377330Sdes		case 'o':
11477330Sdes			oflag = 1;
11577330Sdes			break;
11671034Sdes		case 'w':
11777330Sdes			/* compatibility */
11877330Sdes			/* ignored */
11971034Sdes			break;
12071034Sdes		case 'X':
12177330Sdes			/* compatibility */
12277330Sdes			aflag = xflag = 1;
12371034Sdes			break;
12477330Sdes		case 'x':
12577330Sdes			xflag = 1;
12677330Sdes			break;
12771034Sdes		default:
12871034Sdes			usage();
1291553Srgrimes		}
1301553Srgrimes	}
1311553Srgrimes	argc -= optind;
1321553Srgrimes	argv += optind;
1331553Srgrimes
13477330Sdes	if (Nflag && nflag)
13542456Sdes		usage();
13677330Sdes	if (aflag && argc == 0)
13777330Sdes		exit(sysctl_all(0, 0));
1381553Srgrimes	if (argc == 0)
1391553Srgrimes		usage();
1401553Srgrimes	while (argc-- > 0)
14112946Sphk		parse(*argv++);
1421553Srgrimes	exit(0);
1431553Srgrimes}
1441553Srgrimes
1451553Srgrimes/*
1461553Srgrimes * Parse a name into a MIB entry.
1471553Srgrimes * Lookup and print out the MIB entry if it exists.
1481553Srgrimes * Set a new value if requested.
1491553Srgrimes */
15012946Sphkstatic void
15112946Sphkparse(char *string)
1521553Srgrimes{
15312946Sphk	int len, i, j;
1541553Srgrimes	void *newval = 0;
15578434Spirzyk	int intval;
15678434Spirzyk	unsigned int uintval;
15778434Spirzyk	long longval;
15878434Spirzyk	unsigned long ulongval;
15978434Spirzyk	size_t newsize = 0;
1601553Srgrimes	quad_t quadval;
1611553Srgrimes	int mib[CTL_MAXNAME];
16288696Sphk	char *cp, *bufp, buf[BUFSIZ], fmt[BUFSIZ];
16312946Sphk	u_int kind;
1641553Srgrimes
1651553Srgrimes	bufp = buf;
1661553Srgrimes	snprintf(buf, BUFSIZ, "%s", string);
1671553Srgrimes	if ((cp = strchr(string, '=')) != NULL) {
1681553Srgrimes		*strchr(buf, '=') = '\0';
1691553Srgrimes		*cp++ = '\0';
1701553Srgrimes		while (isspace(*cp))
1711553Srgrimes			cp++;
1721553Srgrimes		newval = cp;
1731553Srgrimes		newsize = strlen(cp);
1741553Srgrimes	}
17512946Sphk	len = name2oid(bufp, mib);
1761553Srgrimes
17712946Sphk	if (len < 0)
17830602Scharnier		errx(1, "unknown oid '%s'", bufp);
1791553Srgrimes
18088696Sphk	if (oidfmt(mib, len, fmt, &kind))
18130602Scharnier		err(1, "couldn't find format of oid '%s'", bufp);
1821553Srgrimes
18377330Sdes	if (newval == NULL) {
18412946Sphk		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
18512946Sphk			sysctl_all(mib, len);
18612946Sphk		} else {
18712946Sphk			i = show_var(mib, len);
18812946Sphk			if (!i && !bflag)
18912946Sphk				putchar('\n');
1901553Srgrimes		}
19112946Sphk	} else {
19212946Sphk		if ((kind & CTLTYPE) == CTLTYPE_NODE)
19312946Sphk			errx(1, "oid '%s' isn't a leaf node", bufp);
1941553Srgrimes
19512946Sphk		if (!(kind&CTLFLAG_WR))
19612946Sphk			errx(1, "oid '%s' is read only", bufp);
19712946Sphk
19812946Sphk		switch (kind & CTLTYPE) {
19912946Sphk			case CTLTYPE_INT:
20053317Sgrog				intval = (int) strtol(newval, NULL, 0);
20112946Sphk				newval = &intval;
20277928Sdd				newsize = sizeof(intval);
2031553Srgrimes				break;
20478434Spirzyk			case CTLTYPE_UINT:
20578434Spirzyk				uintval = (int) strtoul(newval, NULL, 0);
20678434Spirzyk				newval = &uintval;
20778434Spirzyk				newsize = sizeof uintval;
20812946Sphk				break;
20978434Spirzyk			case CTLTYPE_LONG:
21078434Spirzyk				longval = strtol(newval, NULL, 0);
21178434Spirzyk				newval = &longval;
21278434Spirzyk				newsize = sizeof longval;
21378434Spirzyk				break;
21478434Spirzyk			case CTLTYPE_ULONG:
21578434Spirzyk				ulongval = strtoul(newval, NULL, 0);
21678434Spirzyk				newval = &ulongval;
21778434Spirzyk				newsize = sizeof ulongval;
21878434Spirzyk				break;
21912946Sphk			case CTLTYPE_STRING:
22012946Sphk				break;
22112946Sphk			case CTLTYPE_QUAD:
22212946Sphk				sscanf(newval, "%qd", &quadval);
22312946Sphk				newval = &quadval;
22477928Sdd				newsize = sizeof(quadval);
22512946Sphk				break;
22688696Sphk			case CTLTYPE_OPAQUE:
22788696Sphk				if (strcmp(fmt, "T,dev_t") == 0) {
22888696Sphk					set_T_dev_t ((char*)newval, &newval, &newsize);
22988696Sphk					break;
23088696Sphk				}
23188696Sphk				/* FALLTHROUGH */
23212946Sphk			default:
23312946Sphk				errx(1, "oid '%s' is type %d,"
23431214Sjdp					" cannot set that", bufp,
23531214Sjdp					kind & CTLTYPE);
2361553Srgrimes		}
2371553Srgrimes
23812946Sphk		i = show_var(mib, len);
23912946Sphk		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
24012946Sphk			if (!i && !bflag)
24112946Sphk				putchar('\n');
24212946Sphk			switch (errno) {
24312946Sphk			case EOPNOTSUPP:
24430602Scharnier				errx(1, "%s: value is not available",
24512946Sphk					string);
24612946Sphk			case ENOTDIR:
24730602Scharnier				errx(1, "%s: specification is incomplete",
24812946Sphk					string);
24912946Sphk			case ENOMEM:
25030602Scharnier				errx(1, "%s: type is unknown to this program",
25112946Sphk					string);
25212946Sphk			default:
25330602Scharnier				warn("%s", string);
25412946Sphk				return;
25512946Sphk			}
25612946Sphk		}
25712946Sphk		if (!bflag)
25812946Sphk			printf(" -> ");
25912946Sphk		i = nflag;
26012946Sphk		nflag = 1;
26112946Sphk		j = show_var(mib, len);
26212946Sphk		if (!j && !bflag)
26312946Sphk			putchar('\n');
26412946Sphk		nflag = i;
26512946Sphk	}
26612946Sphk}
2671553Srgrimes
26812946Sphk/* These functions will dump out various interesting structures. */
2691553Srgrimes
27012946Sphkstatic int
27112946SphkS_clockinfo(int l2, void *p)
27212946Sphk{
27312946Sphk	struct clockinfo *ci = (struct clockinfo*)p;
27477928Sdd	if (l2 != sizeof(*ci))
27577928Sdd		err(1, "S_clockinfo %d != %d", l2, sizeof(*ci));
27626899Sjhay	printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
27726899Sjhay		ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
27812946Sphk	return (0);
27912946Sphk}
2801553Srgrimes
28112946Sphkstatic int
28212946SphkS_loadavg(int l2, void *p)
28312946Sphk{
28412946Sphk	struct loadavg *tv = (struct loadavg*)p;
2858857Srgrimes
28677928Sdd	if (l2 != sizeof(*tv))
28777928Sdd		err(1, "S_loadavg %d != %d", l2, sizeof(*tv));
2881553Srgrimes
28912946Sphk	printf("{ %.2f %.2f %.2f }",
29012946Sphk		(double)tv->ldavg[0]/(double)tv->fscale,
29112946Sphk		(double)tv->ldavg[1]/(double)tv->fscale,
29212946Sphk		(double)tv->ldavg[2]/(double)tv->fscale);
29312946Sphk	return (0);
29412946Sphk}
2951553Srgrimes
29612946Sphkstatic int
29712946SphkS_timeval(int l2, void *p)
29812946Sphk{
29912946Sphk	struct timeval *tv = (struct timeval*)p;
30037266Sbde	time_t tv_sec;
30112946Sphk	char *p1, *p2;
3021553Srgrimes
30377928Sdd	if (l2 != sizeof(*tv))
30477928Sdd		err(1, "S_timeval %d != %d", l2, sizeof(*tv));
30512946Sphk	printf("{ sec = %ld, usec = %ld } ",
30612946Sphk		tv->tv_sec, tv->tv_usec);
30737266Sbde	tv_sec = tv->tv_sec;
30837266Sbde	p1 = strdup(ctime(&tv_sec));
30912946Sphk	for (p2=p1; *p2 ; p2++)
31012946Sphk		if (*p2 == '\n')
31112946Sphk			*p2 = '\0';
31212946Sphk	fputs(p1, stdout);
31312946Sphk	return (0);
31412946Sphk}
3151553Srgrimes
31612946Sphkstatic int
31712946SphkT_dev_t(int l2, void *p)
31812946Sphk{
31912946Sphk	dev_t *d = (dev_t *)p;
32077928Sdd	if (l2 != sizeof(*d))
32177928Sdd		err(1, "T_dev_T %d != %d", l2, sizeof(*d));
32261514Sphk	if ((int)(*d) != -1) {
32361514Sphk		if (minor(*d) > 255 || minor(*d) < 0)
32461514Sphk			printf("{ major = %d, minor = 0x%x }",
32561514Sphk				major(*d), minor(*d));
32661514Sphk		else
32761514Sphk			printf("{ major = %d, minor = %d }",
32861514Sphk				major(*d), minor(*d));
32961514Sphk	}
33012946Sphk	return (0);
33112946Sphk}
3321553Srgrimes
33388696Sphkstatic void
33488696Sphkset_T_dev_t (char *path, void **val, int *size)
33588696Sphk{
33688696Sphk	static struct stat statb;
33788696Sphk
33888696Sphk	if (strcmp(path, "none") && strcmp(path, "off")) {
33988696Sphk		int rc = stat (path, &statb);
34088696Sphk		if (rc) {
34188696Sphk			err(1, "cannot stat %s", path);
34288696Sphk		}
34388696Sphk
34488696Sphk		if (!S_ISCHR(statb.st_mode)) {
34588696Sphk			errx(1, "must specify a device special file.");
34688696Sphk		}
34788696Sphk	} else {
34888696Sphk		statb.st_rdev = NODEV;
34988696Sphk	}
35088696Sphk	*val = (char*) &statb.st_rdev;
35188696Sphk	*size = sizeof statb.st_rdev;
35288696Sphk}
35388696Sphk
35412946Sphk/*
35512946Sphk * These functions uses a presently undocumented interface to the kernel
35612946Sphk * to walk the tree and get the type so it can print the value.
35712946Sphk * This interface is under work and consideration, and should probably
35812946Sphk * be killed with a big axe by the first person who can find the time.
35912946Sphk * (be aware though, that the proper interface isn't as obvious as it
36012946Sphk * may seem, there are various conflicting requirements.
36112946Sphk */
3621553Srgrimes
36312946Sphkstatic int
36412946Sphkname2oid(char *name, int *oidp)
36512946Sphk{
36612946Sphk	int oid[2];
36738533Sdfr	int i;
36838533Sdfr	size_t j;
3691553Srgrimes
37012946Sphk	oid[0] = 0;
37112946Sphk	oid[1] = 3;
3721553Srgrimes
37377928Sdd	j = CTL_MAXNAME * sizeof(int);
37412946Sphk	i = sysctl(oid, 2, oidp, &j, name, strlen(name));
37512946Sphk	if (i < 0)
37612946Sphk		return i;
37777928Sdd	j /= sizeof(int);
37812946Sphk	return (j);
3791553Srgrimes}
3801553Srgrimes
38112946Sphkstatic int
38212946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind)
38312946Sphk{
38412946Sphk	int qoid[CTL_MAXNAME+2];
38512946Sphk	u_char buf[BUFSIZ];
38638533Sdfr	int i;
38738533Sdfr	size_t j;
3881553Srgrimes
38912946Sphk	qoid[0] = 0;
39012946Sphk	qoid[1] = 4;
39112946Sphk	memcpy(qoid + 2, oid, len * sizeof(int));
3921553Srgrimes
39377928Sdd	j = sizeof(buf);
39412946Sphk	i = sysctl(qoid, len + 2, buf, &j, 0, 0);
39512946Sphk	if (i)
39630602Scharnier		err(1, "sysctl fmt %d %d %d", i, j, errno);
3971553Srgrimes
39812946Sphk	if (kind)
39912946Sphk		*kind = *(u_int *)buf;
40012946Sphk
40112946Sphk	if (fmt)
40212946Sphk		strcpy(fmt, (char *)(buf + sizeof(u_int)));
40312946Sphk	return 0;
4041553Srgrimes}
4051553Srgrimes
4061553Srgrimes/*
40712946Sphk * This formats and outputs the value of one variable
40812946Sphk *
40912946Sphk * Returns zero if anything was actually output.
41012946Sphk * Returns one if didn't know what to do with this.
41112946Sphk * Return minus one if we had errors.
4121553Srgrimes */
41312946Sphk
41412946Sphkstatic int
41512946Sphkshow_var(int *oid, int nlen)
4161553Srgrimes{
41712946Sphk	u_char buf[BUFSIZ], *val, *p;
41885747Stobez	char name[BUFSIZ], *fmt, *sep;
41912946Sphk	int qoid[CTL_MAXNAME+2];
42038533Sdfr	int i;
42138533Sdfr	size_t j, len;
42212946Sphk	u_int kind;
42377332Sdes	int (*func)(int, void *);
4241553Srgrimes
42542456Sdes	qoid[0] = 0;
42642456Sdes	memcpy(qoid + 2, oid, nlen * sizeof(int));
42742456Sdes
42842456Sdes	qoid[1] = 1;
42977928Sdd	j = sizeof(name);
43042456Sdes	i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
43142456Sdes	if (i || !j)
43242456Sdes		err(1, "sysctl name %d %d %d", i, j, errno);
43342456Sdes
43471034Sdes	if (Nflag) {
43571034Sdes		printf("%s", name);
43671034Sdes		return (0);
43771034Sdes	}
43871034Sdes
43985747Stobez	if (eflag)
44085747Stobez		sep = "=";
44185747Stobez	else
44285747Stobez		sep = ": ";
44385747Stobez
44488006Sluigi	if (dflag) {	/* just print description */
44588006Sluigi		qoid[1] = 5;
44688006Sluigi		j = sizeof(buf);
44788006Sluigi		i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
44888006Sluigi		if (!nflag)
44988006Sluigi			printf("%s%s", name, sep);
45088006Sluigi		printf("%s", buf);
45188006Sluigi		return (0);
45288006Sluigi	}
45312946Sphk	/* find an estimate of how much we need for this var */
45412946Sphk	j = 0;
45512946Sphk	i = sysctl(oid, nlen, 0, &j, 0, 0);
45612946Sphk	j += j; /* we want to be sure :-) */
45712946Sphk
45812946Sphk	val = alloca(j);
45912946Sphk	len = j;
46012946Sphk	i = sysctl(oid, nlen, val, &len, 0, 0);
46112946Sphk	if (i || !len)
46212946Sphk		return (1);
46312946Sphk
46412946Sphk	if (bflag) {
46512946Sphk		fwrite(val, 1, len, stdout);
46612946Sphk		return (0);
4671553Srgrimes	}
46812946Sphk
46988696Sphk	fmt = buf;
47088696Sphk	oidfmt(oid, nlen, fmt, &kind);
47112946Sphk	p = val;
47212946Sphk	switch (*fmt) {
47312946Sphk	case 'A':
47412946Sphk		if (!nflag)
47585747Stobez			printf("%s%s", name, sep);
47612946Sphk		printf("%s", p);
47712946Sphk		return (0);
47812946Sphk
47912946Sphk	case 'I':
48012946Sphk		if (!nflag)
48185747Stobez			printf("%s%s", name, sep);
48262622Sjhb		fmt++;
48341019Sphk		val = "";
48441019Sphk		while (len >= sizeof(int)) {
48562622Sjhb			if(*fmt == 'U')
48662622Sjhb				printf("%s%u", val, *(unsigned int *)p);
48762622Sjhb			else
48862622Sjhb				printf("%s%d", val, *(int *)p);
48941019Sphk			val = " ";
49077332Sdes			len -= sizeof(int);
49177332Sdes			p += sizeof(int);
49241019Sphk		}
49312946Sphk		return (0);
49412946Sphk
49538533Sdfr	case 'L':
49638533Sdfr		if (!nflag)
49785747Stobez			printf("%s%s", name, sep);
49862622Sjhb		fmt++;
49962975Sphk		val = "";
50062975Sphk		while (len >= sizeof(long)) {
50162975Sphk			if(*fmt == 'U')
50262975Sphk				printf("%s%lu", val, *(unsigned long *)p);
50362975Sphk			else
50462975Sphk				printf("%s%ld", val, *(long *)p);
50562975Sphk			val = " ";
50677332Sdes			len -= sizeof(long);
50777332Sdes			p += sizeof(long);
50862975Sphk		}
50938533Sdfr		return (0);
51038533Sdfr
51138533Sdfr	case 'P':
51238533Sdfr		if (!nflag)
51385747Stobez			printf("%s%s", name, sep);
51438533Sdfr		printf("%p", *(void **)p);
51538533Sdfr		return (0);
51638533Sdfr
51712946Sphk	case 'T':
51812946Sphk	case 'S':
51912946Sphk		i = 0;
52077332Sdes		if (strcmp(fmt, "S,clockinfo") == 0)
52177332Sdes			func = S_clockinfo;
52277332Sdes		else if (strcmp(fmt, "S,timeval") == 0)
52377332Sdes			func = S_timeval;
52477332Sdes		else if (strcmp(fmt, "S,loadavg") == 0)
52577332Sdes			func = S_loadavg;
52677332Sdes		else if (strcmp(fmt, "T,dev_t") == 0)
52777332Sdes			func = T_dev_t;
52877332Sdes		else
52977332Sdes			func = NULL;
53012946Sphk		if (func) {
53112946Sphk			if (!nflag)
53285747Stobez				printf("%s%s", name, sep);
53312946Sphk			return ((*func)(len, p));
53412946Sphk		}
53512946Sphk		/* FALL THROUGH */
53612946Sphk	default:
53777330Sdes		if (!oflag && !xflag)
53812946Sphk			return (1);
53912946Sphk		if (!nflag)
54085747Stobez			printf("%s%s", name, sep);
54112946Sphk		printf("Format:%s Length:%d Dump:0x", fmt, len);
54277332Sdes		while (len-- && (xflag || p < val + 16))
54312946Sphk			printf("%02x", *p++);
54477332Sdes		if (!xflag && len > 16)
54512946Sphk			printf("...");
54612946Sphk		return (0);
5471553Srgrimes	}
54812946Sphk	return (1);
5491553Srgrimes}
5501553Srgrimes
55112946Sphkstatic int
55212946Sphksysctl_all (int *oid, int len)
5531553Srgrimes{
55412946Sphk	int name1[22], name2[22];
55538533Sdfr	int i, j;
55638533Sdfr	size_t l1, l2;
5571553Srgrimes
55812946Sphk	name1[0] = 0;
55912946Sphk	name1[1] = 2;
56012946Sphk	l1 = 2;
56112946Sphk	if (len) {
56277928Sdd		memcpy(name1+2, oid, len * sizeof(int));
56312946Sphk		l1 += len;
56412946Sphk	} else {
56512946Sphk		name1[2] = 1;
56612946Sphk		l1++;
56712946Sphk	}
56877332Sdes	for (;;) {
56977928Sdd		l2 = sizeof(name2);
57012946Sphk		j = sysctl(name1, l1, name2, &l2, 0, 0);
57148956Sbillf		if (j < 0) {
57212946Sphk			if (errno == ENOENT)
57312946Sphk				return 0;
57412946Sphk			else
57530602Scharnier				err(1, "sysctl(getnext) %d %d", j, l2);
57648956Sbillf		}
57712946Sphk
57877928Sdd		l2 /= sizeof(int);
57912946Sphk
58012946Sphk		if (l2 < len)
58112946Sphk			return 0;
58212946Sphk
58312946Sphk		for (i = 0; i < len; i++)
58412946Sphk			if (name2[i] != oid[i])
58512946Sphk				return 0;
58612946Sphk
58712946Sphk		i = show_var(name2, l2);
58812946Sphk		if (!i && !bflag)
58912946Sphk			putchar('\n');
59012946Sphk
59177928Sdd		memcpy(name1+2, name2, l2 * sizeof(int));
59212946Sphk		l1 = 2 + l2;
59312946Sphk	}
5941553Srgrimes}
595