1331722Seadler/*
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 * 4. Neither the name of the University nor the names of its contributors
141553Srgrimes *    may be used to endorse or promote products derived from this software
151553Srgrimes *    without specific prior written permission.
161553Srgrimes *
171553Srgrimes * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
181553Srgrimes * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
191553Srgrimes * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
201553Srgrimes * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
211553Srgrimes * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
221553Srgrimes * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
231553Srgrimes * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
241553Srgrimes * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
251553Srgrimes * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
261553Srgrimes * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
271553Srgrimes * SUCH DAMAGE.
281553Srgrimes */
291553Srgrimes
301553Srgrimes#ifndef lint
3130602Scharnierstatic const char copyright[] =
321553Srgrimes"@(#) Copyright (c) 1993\n\
331553Srgrimes	The Regents of the University of California.  All rights reserved.\n";
341553Srgrimes#endif /* not lint */
351553Srgrimes
361553Srgrimes#ifndef lint
3730602Scharnier#if 0
3830602Scharnierstatic char sccsid[] = "@(#)from: sysctl.c	8.1 (Berkeley) 6/6/93";
3930602Scharnier#endif
406284Swollmanstatic const char rcsid[] =
4150476Speter  "$FreeBSD: stable/11/sbin/sysctl/sysctl.c 344984 2019-03-10 20:58:24Z wulf $";
421553Srgrimes#endif /* not lint */
431553Srgrimes
4491217Sbde#include <sys/param.h>
4591217Sbde#include <sys/time.h>
4691217Sbde#include <sys/resource.h>
471553Srgrimes#include <sys/stat.h>
481553Srgrimes#include <sys/sysctl.h>
49109097Sdillon#include <sys/vmmeter.h>
50344984Swulf#include <dev/evdev/input.h>
511553Srgrimes
52271495Sjhb#ifdef __amd64__
53271495Sjhb#include <sys/efi.h>
54271495Sjhb#include <machine/metadata.h>
55271495Sjhb#endif
56271495Sjhb
57270828Sjhb#if defined(__amd64__) || defined(__i386__)
58270828Sjhb#include <machine/pc/bios.h>
59270828Sjhb#endif
60270828Sjhb
61272154Sdelphij#include <assert.h>
6230602Scharnier#include <ctype.h>
6330602Scharnier#include <err.h>
641553Srgrimes#include <errno.h>
65170287Sdwmalone#include <inttypes.h>
66122233Sdes#include <locale.h>
67331603Sjhb#include <stdbool.h>
681553Srgrimes#include <stdio.h>
691553Srgrimes#include <stdlib.h>
701553Srgrimes#include <string.h>
71244198Sdelphij#include <sysexits.h>
7230602Scharnier#include <unistd.h>
731553Srgrimes
74244198Sdelphijstatic const char *conffile;
75244198Sdelphij
76278654Sjmgstatic int	aflag, bflag, Bflag, dflag, eflag, hflag, iflag;
77292045Saraujostatic int	Nflag, nflag, oflag, qflag, tflag, Tflag, Wflag, xflag;
781553Srgrimes
7912946Sphkstatic int	oidfmt(int *, int, char *, u_int *);
80244198Sdelphijstatic int	parsefile(const char *);
81244198Sdelphijstatic int	parse(const char *, int);
8212946Sphkstatic int	show_var(int *, int);
83170512Sdwmalonestatic int	sysctl_all(int *oid, int len);
84272044Sdelphijstatic int	name2oid(const char *, int *);
851553Srgrimes
86285994Simpstatic int	strIKtoi(const char *, char **, const char *);
8788696Sphk
88272154Sdelphijstatic int ctl_sign[CTLTYPE+1] = {
89272154Sdelphij	[CTLTYPE_INT] = 1,
90272154Sdelphij	[CTLTYPE_LONG] = 1,
91290476Scem	[CTLTYPE_S8] = 1,
92290476Scem	[CTLTYPE_S16] = 1,
93290476Scem	[CTLTYPE_S32] = 1,
94272154Sdelphij	[CTLTYPE_S64] = 1,
95272154Sdelphij};
96272154Sdelphij
97272154Sdelphijstatic int ctl_size[CTLTYPE+1] = {
98272154Sdelphij	[CTLTYPE_INT] = sizeof(int),
99272154Sdelphij	[CTLTYPE_UINT] = sizeof(u_int),
100272154Sdelphij	[CTLTYPE_LONG] = sizeof(long),
101272154Sdelphij	[CTLTYPE_ULONG] = sizeof(u_long),
102290476Scem	[CTLTYPE_S8] = sizeof(int8_t),
103290476Scem	[CTLTYPE_S16] = sizeof(int16_t),
104290476Scem	[CTLTYPE_S32] = sizeof(int32_t),
105272154Sdelphij	[CTLTYPE_S64] = sizeof(int64_t),
106290476Scem	[CTLTYPE_U8] = sizeof(uint8_t),
107290476Scem	[CTLTYPE_U16] = sizeof(uint16_t),
108290476Scem	[CTLTYPE_U32] = sizeof(uint32_t),
109272154Sdelphij	[CTLTYPE_U64] = sizeof(uint64_t),
110272154Sdelphij};
111272154Sdelphij
112272154Sdelphijstatic const char *ctl_typename[CTLTYPE+1] = {
113272154Sdelphij	[CTLTYPE_INT] = "integer",
114272154Sdelphij	[CTLTYPE_UINT] = "unsigned integer",
115272154Sdelphij	[CTLTYPE_LONG] = "long integer",
116272154Sdelphij	[CTLTYPE_ULONG] = "unsigned long",
117290476Scem	[CTLTYPE_U8] = "uint8_t",
118290476Scem	[CTLTYPE_U16] = "uint16_t",
119311689Savos	[CTLTYPE_U32] = "uint32_t",
120290476Scem	[CTLTYPE_U64] = "uint64_t",
121290476Scem	[CTLTYPE_S8] = "int8_t",
122290476Scem	[CTLTYPE_S16] = "int16_t",
123290476Scem	[CTLTYPE_S32] = "int32_t",
124272154Sdelphij	[CTLTYPE_S64] = "int64_t",
125292045Saraujo	[CTLTYPE_NODE] = "node",
126292045Saraujo	[CTLTYPE_STRING] = "string",
127292045Saraujo	[CTLTYPE_OPAQUE] = "opaque",
128272154Sdelphij};
129272154Sdelphij
13012946Sphkstatic void
13112946Sphkusage(void)
13212946Sphk{
1331553Srgrimes
13477330Sdes	(void)fprintf(stderr, "%s\n%s\n",
135292045Saraujo	    "usage: sysctl [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
136292045Saraujo	    "       sysctl [-bdehNnoqTtWx] [ -B <bufsize> ] -a");
13712946Sphk	exit(1);
13812946Sphk}
1391553Srgrimes
1401553Srgrimesint
14112946Sphkmain(int argc, char **argv)
1421553Srgrimes{
14312946Sphk	int ch;
144244198Sdelphij	int warncount = 0;
145122233Sdes
146122233Sdes	setlocale(LC_NUMERIC, "");
14712946Sphk	setbuf(stdout,0);
14812946Sphk	setbuf(stderr,0);
1491553Srgrimes
150292045Saraujo	while ((ch = getopt(argc, argv, "AabB:def:hiNnoqtTwWxX")) != -1) {
1511553Srgrimes		switch (ch) {
15271034Sdes		case 'A':
15377330Sdes			/* compatibility */
15477330Sdes			aflag = oflag = 1;
15571034Sdes			break;
15671034Sdes		case 'a':
15771034Sdes			aflag = 1;
15871034Sdes			break;
15971034Sdes		case 'b':
16071034Sdes			bflag = 1;
16171034Sdes			break;
162278654Sjmg		case 'B':
163278654Sjmg			Bflag = strtol(optarg, NULL, 0);
164278654Sjmg			break;
16588006Sluigi		case 'd':
16688006Sluigi			dflag = 1;
16788006Sluigi			break;
16885747Stobez		case 'e':
16985747Stobez			eflag = 1;
17085747Stobez			break;
171244198Sdelphij		case 'f':
172244198Sdelphij			conffile = optarg;
173244198Sdelphij			break;
174122233Sdes		case 'h':
175122233Sdes			hflag = 1;
176122233Sdes			break;
177203310Sgavin		case 'i':
178203310Sgavin			iflag = 1;
179203310Sgavin			break;
18071034Sdes		case 'N':
18171034Sdes			Nflag = 1;
18271034Sdes			break;
18371034Sdes		case 'n':
18471034Sdes			nflag = 1;
18571034Sdes			break;
18677330Sdes		case 'o':
18777330Sdes			oflag = 1;
18877330Sdes			break;
189150167Srwatson		case 'q':
190150167Srwatson			qflag = 1;
191150167Srwatson			break;
192292045Saraujo		case 't':
193292045Saraujo			tflag = 1;
194292045Saraujo			break;
195244106Salfred		case 'T':
196244106Salfred			Tflag = 1;
197244106Salfred			break;
19871034Sdes		case 'w':
19977330Sdes			/* compatibility */
20077330Sdes			/* ignored */
20171034Sdes			break;
202244106Salfred		case 'W':
203244106Salfred			Wflag = 1;
204244106Salfred			break;
20571034Sdes		case 'X':
20677330Sdes			/* compatibility */
20777330Sdes			aflag = xflag = 1;
20871034Sdes			break;
20977330Sdes		case 'x':
21077330Sdes			xflag = 1;
21177330Sdes			break;
21271034Sdes		default:
21371034Sdes			usage();
2141553Srgrimes		}
2151553Srgrimes	}
2161553Srgrimes	argc -= optind;
2171553Srgrimes	argv += optind;
2181553Srgrimes
21977330Sdes	if (Nflag && nflag)
22042456Sdes		usage();
22177330Sdes	if (aflag && argc == 0)
22277330Sdes		exit(sysctl_all(0, 0));
223244198Sdelphij	if (argc == 0 && conffile == NULL)
2241553Srgrimes		usage();
225179965Smtm
226179965Smtm	warncount = 0;
227244198Sdelphij	if (conffile != NULL)
228244198Sdelphij		warncount += parsefile(conffile);
229244198Sdelphij
2301553Srgrimes	while (argc-- > 0)
231244198Sdelphij		warncount += parse(*argv++, 0);
232244198Sdelphij
233244198Sdelphij	return (warncount);
2341553Srgrimes}
2351553Srgrimes
2361553Srgrimes/*
237331603Sjhb * Parse a single numeric value, append it to 'newbuf', and update
238331603Sjhb * 'newsize'.  Returns true if the value was parsed and false if the
239331603Sjhb * value was invalid.  Non-numeric types (strings) are handled
240331603Sjhb * directly in parse().
2411553Srgrimes */
242331603Sjhbstatic bool
243331603Sjhbparse_numeric(const char *newvalstr, const char *fmt, u_int kind,
244331603Sjhb    void **newbufp, size_t *newsizep)
2451553Srgrimes{
246331603Sjhb	void *newbuf;
247272154Sdelphij	const void *newval;
248290476Scem	int8_t i8val;
249289773Scem	uint8_t u8val;
250290476Scem	int16_t i16val;
251289773Scem	uint16_t u16val;
252290476Scem	int32_t i32val;
253290476Scem	uint32_t u32val;
25478434Spirzyk	int intval;
25578434Spirzyk	unsigned int uintval;
25678434Spirzyk	long longval;
25778434Spirzyk	unsigned long ulongval;
258217616Smdf	int64_t i64val;
259217616Smdf	uint64_t u64val;
260331603Sjhb	size_t valsize;
261331603Sjhb	char *endptr = NULL;
262331603Sjhb
263331603Sjhb	errno = 0;
264331603Sjhb
265331603Sjhb	switch (kind & CTLTYPE) {
266331603Sjhb	case CTLTYPE_INT:
267331603Sjhb		if (strncmp(fmt, "IK", 2) == 0)
268331603Sjhb			intval = strIKtoi(newvalstr, &endptr, fmt);
269331603Sjhb		else
270331603Sjhb			intval = (int)strtol(newvalstr, &endptr, 0);
271331603Sjhb		newval = &intval;
272331603Sjhb		valsize = sizeof(intval);
273331603Sjhb		break;
274331603Sjhb	case CTLTYPE_UINT:
275331603Sjhb		uintval = (int) strtoul(newvalstr, &endptr, 0);
276331603Sjhb		newval = &uintval;
277331603Sjhb		valsize = sizeof(uintval);
278331603Sjhb		break;
279331603Sjhb	case CTLTYPE_LONG:
280331603Sjhb		longval = strtol(newvalstr, &endptr, 0);
281331603Sjhb		newval = &longval;
282331603Sjhb		valsize = sizeof(longval);
283331603Sjhb		break;
284331603Sjhb	case CTLTYPE_ULONG:
285331603Sjhb		ulongval = strtoul(newvalstr, &endptr, 0);
286331603Sjhb		newval = &ulongval;
287331603Sjhb		valsize = sizeof(ulongval);
288331603Sjhb		break;
289331603Sjhb	case CTLTYPE_S8:
290331603Sjhb		i8val = (int8_t)strtol(newvalstr, &endptr, 0);
291331603Sjhb		newval = &i8val;
292331603Sjhb		valsize = sizeof(i8val);
293331603Sjhb		break;
294331603Sjhb	case CTLTYPE_S16:
295331603Sjhb		i16val = (int16_t)strtol(newvalstr, &endptr, 0);
296331603Sjhb		newval = &i16val;
297331603Sjhb		valsize = sizeof(i16val);
298331603Sjhb		break;
299331603Sjhb	case CTLTYPE_S32:
300331603Sjhb		i32val = (int32_t)strtol(newvalstr, &endptr, 0);
301331603Sjhb		newval = &i32val;
302331603Sjhb		valsize = sizeof(i32val);
303331603Sjhb		break;
304331603Sjhb	case CTLTYPE_S64:
305331603Sjhb		i64val = strtoimax(newvalstr, &endptr, 0);
306331603Sjhb		newval = &i64val;
307331603Sjhb		valsize = sizeof(i64val);
308331603Sjhb		break;
309331603Sjhb	case CTLTYPE_U8:
310331603Sjhb		u8val = (uint8_t)strtoul(newvalstr, &endptr, 0);
311331603Sjhb		newval = &u8val;
312331603Sjhb		valsize = sizeof(u8val);
313331603Sjhb		break;
314331603Sjhb	case CTLTYPE_U16:
315331603Sjhb		u16val = (uint16_t)strtoul(newvalstr, &endptr, 0);
316331603Sjhb		newval = &u16val;
317331603Sjhb		valsize = sizeof(u16val);
318331603Sjhb		break;
319331603Sjhb	case CTLTYPE_U32:
320331603Sjhb		u32val = (uint32_t)strtoul(newvalstr, &endptr, 0);
321331603Sjhb		newval = &u32val;
322331603Sjhb		valsize = sizeof(u32val);
323331603Sjhb		break;
324331603Sjhb	case CTLTYPE_U64:
325331603Sjhb		u64val = strtoumax(newvalstr, &endptr, 0);
326331603Sjhb		newval = &u64val;
327331603Sjhb		valsize = sizeof(u64val);
328331603Sjhb		break;
329331603Sjhb	default:
330331603Sjhb		/* NOTREACHED */
331331603Sjhb		abort();
332331603Sjhb	}
333331603Sjhb
334331603Sjhb	if (errno != 0 || endptr == newvalstr ||
335331603Sjhb	    (endptr != NULL && *endptr != '\0'))
336331603Sjhb		return (false);
337331603Sjhb
338331603Sjhb	newbuf = realloc(*newbufp, *newsizep + valsize);
339331603Sjhb	if (newbuf == NULL)
340331603Sjhb		err(1, "out of memory");
341331603Sjhb	memcpy((char *)newbuf + *newsizep, newval, valsize);
342331603Sjhb	*newbufp = newbuf;
343331603Sjhb	*newsizep += valsize;
344331603Sjhb
345331603Sjhb	return (true);
346331603Sjhb}
347331603Sjhb
348331603Sjhb/*
349331603Sjhb * Parse a name into a MIB entry.
350331603Sjhb * Lookup and print out the MIB entry if it exists.
351331603Sjhb * Set a new value if requested.
352331603Sjhb */
353331603Sjhbstatic int
354331603Sjhbparse(const char *string, int lineno)
355331603Sjhb{
356331603Sjhb	int len, i, j;
357331603Sjhb	const void *newval;
358331603Sjhb	char *newvalstr = NULL;
359331603Sjhb	void *newbuf;
360331603Sjhb	size_t newsize = Bflag;
3611553Srgrimes	int mib[CTL_MAXNAME];
362331603Sjhb	char *cp, *bufp, buf[BUFSIZ], fmt[BUFSIZ], line[BUFSIZ];
36312946Sphk	u_int kind;
3641553Srgrimes
365244198Sdelphij	if (lineno)
366244198Sdelphij		snprintf(line, sizeof(line), " at line %d", lineno);
367244198Sdelphij	else
368244198Sdelphij		line[0] = '\0';
369244198Sdelphij
370244104Sdelphij	cp = buf;
371244198Sdelphij	if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) {
372258659Strasz		warnx("oid too long: '%s'%s", string, line);
373244198Sdelphij		return (1);
374244198Sdelphij	}
375244198Sdelphij	bufp = strsep(&cp, "=:");
376244104Sdelphij	if (cp != NULL) {
377244106Salfred		/* Tflag just lists tunables, do not allow assignment */
378244106Salfred		if (Tflag || Wflag) {
379244106Salfred			warnx("Can't set variables when using -T or -W");
380244106Salfred			usage();
381244106Salfred		}
3821553Srgrimes		while (isspace(*cp))
3831553Srgrimes			cp++;
384244198Sdelphij		/* Strip a pair of " or ' if any. */
385244198Sdelphij		switch (*cp) {
386244198Sdelphij		case '\"':
387244198Sdelphij		case '\'':
388244198Sdelphij			if (cp[strlen(cp) - 1] == *cp)
389244198Sdelphij				cp[strlen(cp) - 1] = '\0';
390244198Sdelphij			cp++;
391244198Sdelphij		}
392272154Sdelphij		newvalstr = cp;
3931553Srgrimes		newsize = strlen(cp);
3941553Srgrimes	}
395288981Sbapt	/* Trim spaces */
396288981Sbapt	cp = bufp + strlen(bufp) - 1;
397288981Sbapt	while (cp >= bufp && isspace((int)*cp)) {
398288981Sbapt		*cp = '\0';
399288981Sbapt		cp--;
400288981Sbapt	}
40112946Sphk	len = name2oid(bufp, mib);
4021553Srgrimes
403150167Srwatson	if (len < 0) {
404203310Sgavin		if (iflag)
405244198Sdelphij			return (0);
406150167Srwatson		if (qflag)
407244198Sdelphij			return (1);
408244198Sdelphij		else {
409288984Sbapt			if (errno == ENOENT) {
410288984Sbapt				warnx("unknown oid '%s'%s", bufp, line);
411288984Sbapt			} else {
412288984Sbapt				warn("unknown oid '%s'%s", bufp, line);
413288984Sbapt			}
414244198Sdelphij			return (1);
415244198Sdelphij		}
416244198Sdelphij	}
417244198Sdelphij
418244198Sdelphij	if (oidfmt(mib, len, fmt, &kind)) {
419244198Sdelphij		warn("couldn't find format of oid '%s'%s", bufp, line);
420244198Sdelphij		if (iflag)
421244198Sdelphij			return (1);
422244198Sdelphij		else
423150167Srwatson			exit(1);
424150167Srwatson	}
4251553Srgrimes
426272154Sdelphij	if (newvalstr == NULL || dflag) {
42712946Sphk		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
428144998Smdodd			if (dflag) {
429144998Smdodd				i = show_var(mib, len);
430144998Smdodd				if (!i && !bflag)
431144998Smdodd					putchar('\n');
432144998Smdodd			}
43312946Sphk			sysctl_all(mib, len);
43412946Sphk		} else {
43512946Sphk			i = show_var(mib, len);
43612946Sphk			if (!i && !bflag)
43712946Sphk				putchar('\n');
4381553Srgrimes		}
43912946Sphk	} else {
440244198Sdelphij		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
441258659Strasz			warnx("oid '%s' isn't a leaf node%s", bufp, line);
442244198Sdelphij			return (1);
443244198Sdelphij		}
4441553Srgrimes
445121849Ssilby		if (!(kind & CTLFLAG_WR)) {
446121306Ssilby			if (kind & CTLFLAG_TUN) {
447245361Sdelphij				warnx("oid '%s' is a read only tunable%s", bufp, line);
448244198Sdelphij				warnx("Tunable values are set in /boot/loader.conf");
449244198Sdelphij			} else
450244198Sdelphij				warnx("oid '%s' is read only%s", bufp, line);
451244198Sdelphij			return (1);
452121306Ssilby		}
453116383Srwatson
454272154Sdelphij		switch (kind & CTLTYPE) {
455272154Sdelphij		case CTLTYPE_INT:
456272154Sdelphij		case CTLTYPE_UINT:
457272154Sdelphij		case CTLTYPE_LONG:
458272154Sdelphij		case CTLTYPE_ULONG:
459290476Scem		case CTLTYPE_S8:
460290476Scem		case CTLTYPE_S16:
461290476Scem		case CTLTYPE_S32:
462272154Sdelphij		case CTLTYPE_S64:
463290476Scem		case CTLTYPE_U8:
464290476Scem		case CTLTYPE_U16:
465290476Scem		case CTLTYPE_U32:
466272154Sdelphij		case CTLTYPE_U64:
467272154Sdelphij			if (strlen(newvalstr) == 0) {
468244198Sdelphij				warnx("empty numeric value");
469244198Sdelphij				return (1);
470244198Sdelphij			}
471272154Sdelphij			/* FALLTHROUGH */
472272154Sdelphij		case CTLTYPE_STRING:
473272154Sdelphij			break;
474272154Sdelphij		default:
475272154Sdelphij			warnx("oid '%s' is type %d,"
476272154Sdelphij				" cannot set that%s", bufp,
477272154Sdelphij				kind & CTLTYPE, line);
478272154Sdelphij			return (1);
479116383Srwatson		}
480122234Sdes
481331603Sjhb		newbuf = NULL;
482272145Sdelphij
48312946Sphk		switch (kind & CTLTYPE) {
484331603Sjhb		case CTLTYPE_STRING:
485331603Sjhb			newval = newvalstr;
486331603Sjhb			break;
487331603Sjhb		default:
488331603Sjhb			newsize = 0;
489331603Sjhb			while ((cp = strsep(&newvalstr, " ,")) != NULL) {
490331603Sjhb				if (*cp == '\0')
491331603Sjhb					continue;
492331603Sjhb				if (!parse_numeric(cp, fmt, kind, &newbuf,
493331603Sjhb				    &newsize)) {
494331603Sjhb					warnx("invalid %s '%s'%s",
495331603Sjhb					    ctl_typename[kind & CTLTYPE],
496331603Sjhb					    cp, line);
497331603Sjhb					free(newbuf);
498331603Sjhb					return (1);
499331603Sjhb				}
500331603Sjhb			}
501331603Sjhb			newval = newbuf;
502331603Sjhb			break;
5031553Srgrimes		}
5041553Srgrimes
50512946Sphk		i = show_var(mib, len);
50612946Sphk		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
507331603Sjhb			free(newbuf);
50812946Sphk			if (!i && !bflag)
50912946Sphk				putchar('\n');
51012946Sphk			switch (errno) {
51112946Sphk			case EOPNOTSUPP:
512244198Sdelphij				warnx("%s: value is not available%s",
513244198Sdelphij					string, line);
514244198Sdelphij				return (1);
51512946Sphk			case ENOTDIR:
516244198Sdelphij				warnx("%s: specification is incomplete%s",
517244198Sdelphij					string, line);
518244198Sdelphij				return (1);
51912946Sphk			case ENOMEM:
520244198Sdelphij				warnx("%s: type is unknown to this program%s",
521244198Sdelphij					string, line);
522244198Sdelphij				return (1);
52312946Sphk			default:
524244198Sdelphij				warn("%s%s", string, line);
525244198Sdelphij				return (1);
52612946Sphk			}
52712946Sphk		}
528331603Sjhb		free(newbuf);
52912946Sphk		if (!bflag)
53012946Sphk			printf(" -> ");
53112946Sphk		i = nflag;
53212946Sphk		nflag = 1;
53312946Sphk		j = show_var(mib, len);
53412946Sphk		if (!j && !bflag)
53512946Sphk			putchar('\n');
53612946Sphk		nflag = i;
53712946Sphk	}
538244198Sdelphij
539244198Sdelphij	return (0);
54012946Sphk}
5411553Srgrimes
542244198Sdelphijstatic int
543244198Sdelphijparsefile(const char *filename)
544244198Sdelphij{
545244198Sdelphij	FILE *file;
546244198Sdelphij	char line[BUFSIZ], *p, *pq, *pdq;
547244198Sdelphij	int warncount = 0, lineno = 0;
548244198Sdelphij
549244198Sdelphij	file = fopen(filename, "r");
550244198Sdelphij	if (file == NULL)
551244198Sdelphij		err(EX_NOINPUT, "%s", filename);
552244198Sdelphij	while (fgets(line, sizeof(line), file) != NULL) {
553244198Sdelphij		lineno++;
554244198Sdelphij		p = line;
555244198Sdelphij		pq = strchr(line, '\'');
556244198Sdelphij		pdq = strchr(line, '\"');
557244198Sdelphij		/* Replace the first # with \0. */
558244198Sdelphij		while((p = strchr(p, '#')) != NULL) {
559244198Sdelphij			if (pq != NULL && p > pq) {
560244198Sdelphij				if ((p = strchr(pq+1, '\'')) != NULL)
561244198Sdelphij					*(++p) = '\0';
562244198Sdelphij				break;
563244198Sdelphij			} else if (pdq != NULL && p > pdq) {
564244198Sdelphij				if ((p = strchr(pdq+1, '\"')) != NULL)
565244198Sdelphij					*(++p) = '\0';
566244198Sdelphij				break;
567244198Sdelphij			} else if (p == line || *(p-1) != '\\') {
568244198Sdelphij				*p = '\0';
569244198Sdelphij				break;
570244198Sdelphij			}
571244198Sdelphij			p++;
572244198Sdelphij		}
573244198Sdelphij		/* Trim spaces */
574244198Sdelphij		p = line + strlen(line) - 1;
575244198Sdelphij		while (p >= line && isspace((int)*p)) {
576244198Sdelphij			*p = '\0';
577244198Sdelphij			p--;
578244198Sdelphij		}
579244198Sdelphij		p = line;
580244198Sdelphij		while (isspace((int)*p))
581244198Sdelphij			p++;
582244198Sdelphij		if (*p == '\0')
583244198Sdelphij			continue;
584244198Sdelphij		else
585244198Sdelphij			warncount += parse(p, lineno);
586244198Sdelphij	}
587244198Sdelphij	fclose(file);
588244198Sdelphij
589244198Sdelphij	return (warncount);
590244198Sdelphij}
591244198Sdelphij
59212946Sphk/* These functions will dump out various interesting structures. */
5931553Srgrimes
59412946Sphkstatic int
595271487SjhbS_clockinfo(size_t l2, void *p)
59612946Sphk{
59712946Sphk	struct clockinfo *ci = (struct clockinfo*)p;
598170512Sdwmalone
59997232Salfred	if (l2 != sizeof(*ci)) {
600271487Sjhb		warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci));
601170558Sbde		return (1);
60297232Salfred	}
603122233Sdes	printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
604122233Sdes		"{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
60594752Sphk		ci->hz, ci->tick, ci->profhz, ci->stathz);
60612946Sphk	return (0);
60712946Sphk}
6081553Srgrimes
60912946Sphkstatic int
610271487SjhbS_loadavg(size_t l2, void *p)
61112946Sphk{
61212946Sphk	struct loadavg *tv = (struct loadavg*)p;
6138857Srgrimes
61497232Salfred	if (l2 != sizeof(*tv)) {
615271487Sjhb		warnx("S_loadavg %zu != %zu", l2, sizeof(*tv));
616170558Sbde		return (1);
61797232Salfred	}
618122233Sdes	printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
61912946Sphk		(double)tv->ldavg[0]/(double)tv->fscale,
62012946Sphk		(double)tv->ldavg[1]/(double)tv->fscale,
62112946Sphk		(double)tv->ldavg[2]/(double)tv->fscale);
62212946Sphk	return (0);
62312946Sphk}
6241553Srgrimes
62512946Sphkstatic int
626271487SjhbS_timeval(size_t l2, void *p)
62712946Sphk{
62812946Sphk	struct timeval *tv = (struct timeval*)p;
62937266Sbde	time_t tv_sec;
63012946Sphk	char *p1, *p2;
6311553Srgrimes
63297232Salfred	if (l2 != sizeof(*tv)) {
633271487Sjhb		warnx("S_timeval %zu != %zu", l2, sizeof(*tv));
634170558Sbde		return (1);
63597232Salfred	}
636194684Sjhay	printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
637194684Sjhay		"{ sec = %jd, usec = %ld } ",
638194684Sjhay		(intmax_t)tv->tv_sec, tv->tv_usec);
63937266Sbde	tv_sec = tv->tv_sec;
64037266Sbde	p1 = strdup(ctime(&tv_sec));
64112946Sphk	for (p2=p1; *p2 ; p2++)
64212946Sphk		if (*p2 == '\n')
64312946Sphk			*p2 = '\0';
64412946Sphk	fputs(p1, stdout);
645205118Sbrucec	free(p1);
64612946Sphk	return (0);
64712946Sphk}
6481553Srgrimes
64912946Sphkstatic int
650271487SjhbS_vmtotal(size_t l2, void *p)
651109097Sdillon{
652109097Sdillon	struct vmtotal *v = (struct vmtotal *)p;
653109113Sdillon	int pageKilo = getpagesize() / 1024;
654109097Sdillon
655109097Sdillon	if (l2 != sizeof(*v)) {
656271487Sjhb		warnx("S_vmtotal %zu != %zu", l2, sizeof(*v));
657170558Sbde		return (1);
658109097Sdillon	}
659109097Sdillon
660109113Sdillon	printf(
661109113Sdillon	    "\nSystem wide totals computed every five seconds:"
662109113Sdillon	    " (values in kilobytes)\n");
663109097Sdillon	printf("===============================================\n");
664109113Sdillon	printf(
665164718Sru	    "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
666164718Sru	    "%hd Sleep: %hd)\n",
667109113Sdillon	    v->t_rq, v->t_dw, v->t_pw, v->t_sl);
668109113Sdillon	printf(
669302174Sasomers	    "Virtual Memory:\t\t(Total: %jdK Active: %jdK)\n",
670302174Sasomers	    (intmax_t)v->t_vm * pageKilo, (intmax_t)v->t_avm * pageKilo);
671302174Sasomers	printf("Real Memory:\t\t(Total: %jdK Active: %jdK)\n",
672302174Sasomers	    (intmax_t)v->t_rm * pageKilo, (intmax_t)v->t_arm * pageKilo);
673302174Sasomers	printf("Shared Virtual Memory:\t(Total: %jdK Active: %jdK)\n",
674302174Sasomers	    (intmax_t)v->t_vmshr * pageKilo, (intmax_t)v->t_avmshr * pageKilo);
675302174Sasomers	printf("Shared Real Memory:\t(Total: %jdK Active: %jdK)\n",
676302174Sasomers	    (intmax_t)v->t_rmshr * pageKilo, (intmax_t)v->t_armshr * pageKilo);
677302174Sasomers	printf("Free Memory:\t%jdK", (intmax_t)v->t_free * pageKilo);
678122234Sdes
679109097Sdillon	return (0);
680109097Sdillon}
681109097Sdillon
682344984Swulfstatic int
683344984SwulfS_input_id(size_t l2, void *p)
684344984Swulf{
685344984Swulf	struct input_id *id = p;
686344984Swulf
687344984Swulf	if (l2 != sizeof(*id)) {
688344984Swulf		warnx("S_input_id %zu != %zu", l2, sizeof(*id));
689344984Swulf		return (1);
690344984Swulf	}
691344984Swulf
692344984Swulf	printf("{ bustype = 0x%04x, vendor = 0x%04x, "
693344984Swulf	    "product = 0x%04x, version = 0x%04x }",
694344984Swulf	    id->bustype, id->vendor, id->product, id->version);
695344984Swulf	return (0);
696344984Swulf}
697344984Swulf
698271495Sjhb#ifdef __amd64__
699271495Sjhbstatic int
700271495SjhbS_efi_map(size_t l2, void *p)
701271495Sjhb{
702271495Sjhb	struct efi_map_header *efihdr;
703271495Sjhb	struct efi_md *map;
704271495Sjhb	const char *type;
705271495Sjhb	size_t efisz;
706271495Sjhb	int ndesc, i;
707271495Sjhb
708338680Skib	static const char * const types[] = {
709338680Skib		[EFI_MD_TYPE_NULL] =	"Reserved",
710338680Skib		[EFI_MD_TYPE_CODE] =	"LoaderCode",
711338680Skib		[EFI_MD_TYPE_DATA] =	"LoaderData",
712338680Skib		[EFI_MD_TYPE_BS_CODE] =	"BootServicesCode",
713338680Skib		[EFI_MD_TYPE_BS_DATA] =	"BootServicesData",
714338680Skib		[EFI_MD_TYPE_RT_CODE] =	"RuntimeServicesCode",
715338680Skib		[EFI_MD_TYPE_RT_DATA] =	"RuntimeServicesData",
716338680Skib		[EFI_MD_TYPE_FREE] =	"ConventionalMemory",
717338680Skib		[EFI_MD_TYPE_BAD] =	"UnusableMemory",
718338680Skib		[EFI_MD_TYPE_RECLAIM] =	"ACPIReclaimMemory",
719338680Skib		[EFI_MD_TYPE_FIRMWARE] = "ACPIMemoryNVS",
720338680Skib		[EFI_MD_TYPE_IOMEM] =	"MemoryMappedIO",
721338680Skib		[EFI_MD_TYPE_IOPORT] =	"MemoryMappedIOPortSpace",
722338680Skib		[EFI_MD_TYPE_PALCODE] =	"PalCode",
723338680Skib		[EFI_MD_TYPE_PERSISTENT] = "PersistentMemory",
724271495Sjhb	};
725271495Sjhb
726271495Sjhb	/*
727271495Sjhb	 * Memory map data provided by UEFI via the GetMemoryMap
728271495Sjhb	 * Boot Services API.
729271495Sjhb	 */
730271495Sjhb	if (l2 < sizeof(*efihdr)) {
731271495Sjhb		warnx("S_efi_map length less than header");
732271495Sjhb		return (1);
733271495Sjhb	}
734271495Sjhb	efihdr = p;
735271495Sjhb	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
736338680Skib	map = (struct efi_md *)((uint8_t *)efihdr + efisz);
737271495Sjhb
738271495Sjhb	if (efihdr->descriptor_size == 0)
739271495Sjhb		return (0);
740271495Sjhb	if (l2 != efisz + efihdr->memory_size) {
741271495Sjhb		warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz +
742271495Sjhb		    efihdr->memory_size);
743271495Sjhb		return (1);
744338680Skib	}
745271495Sjhb	ndesc = efihdr->memory_size / efihdr->descriptor_size;
746271495Sjhb
747271495Sjhb	printf("\n%23s %12s %12s %8s %4s",
748271495Sjhb	    "Type", "Physical", "Virtual", "#Pages", "Attr");
749271495Sjhb
750271495Sjhb	for (i = 0; i < ndesc; i++,
751271495Sjhb	    map = efi_next_descriptor(map, efihdr->descriptor_size)) {
752338680Skib		type = NULL;
753338680Skib		if (map->md_type < nitems(types))
754271495Sjhb			type = types[map->md_type];
755338680Skib		if (type == NULL)
756271495Sjhb			type = "<INVALID>";
757271495Sjhb		printf("\n%23s %012lx %12p %08lx ", type, map->md_phys,
758271495Sjhb		    map->md_virt, map->md_pages);
759271495Sjhb		if (map->md_attr & EFI_MD_ATTR_UC)
760271495Sjhb			printf("UC ");
761271495Sjhb		if (map->md_attr & EFI_MD_ATTR_WC)
762271495Sjhb			printf("WC ");
763271495Sjhb		if (map->md_attr & EFI_MD_ATTR_WT)
764271495Sjhb			printf("WT ");
765271495Sjhb		if (map->md_attr & EFI_MD_ATTR_WB)
766271495Sjhb			printf("WB ");
767271495Sjhb		if (map->md_attr & EFI_MD_ATTR_UCE)
768271495Sjhb			printf("UCE ");
769271495Sjhb		if (map->md_attr & EFI_MD_ATTR_WP)
770271495Sjhb			printf("WP ");
771271495Sjhb		if (map->md_attr & EFI_MD_ATTR_RP)
772271495Sjhb			printf("RP ");
773271495Sjhb		if (map->md_attr & EFI_MD_ATTR_XP)
774271495Sjhb			printf("XP ");
775271495Sjhb		if (map->md_attr & EFI_MD_ATTR_RT)
776271495Sjhb			printf("RUNTIME");
777271495Sjhb	}
778271495Sjhb	return (0);
779271495Sjhb}
780271495Sjhb#endif
781271495Sjhb
782270828Sjhb#if defined(__amd64__) || defined(__i386__)
783109097Sdillonstatic int
784271487SjhbS_bios_smap_xattr(size_t l2, void *p)
785270828Sjhb{
786270828Sjhb	struct bios_smap_xattr *smap, *end;
787270828Sjhb
788270828Sjhb	if (l2 % sizeof(*smap) != 0) {
789271487Sjhb		warnx("S_bios_smap_xattr %zu is not a multiple of %zu", l2,
790270828Sjhb		    sizeof(*smap));
791270828Sjhb		return (1);
792270828Sjhb	}
793270828Sjhb
794270828Sjhb	end = (struct bios_smap_xattr *)((char *)p + l2);
795270828Sjhb	for (smap = p; smap < end; smap++)
796270828Sjhb		printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx",
797270828Sjhb		    smap->type, smap->xattr, (uintmax_t)smap->base,
798270828Sjhb		    (uintmax_t)smap->length);
799270828Sjhb	return (0);
800270828Sjhb}
801270828Sjhb#endif
802270828Sjhb
803270828Sjhbstatic int
804285994SimpstrIKtoi(const char *str, char **endptrp, const char *fmt)
805161951Sume{
806272154Sdelphij	int kelv;
807161951Sume	float temp;
808272154Sdelphij	size_t len;
809198340Sed	const char *p;
810285994Simp	int prec, i;
811161951Sume
812272154Sdelphij	assert(errno == 0);
813272154Sdelphij
814272154Sdelphij	len = strlen(str);
815272154Sdelphij	/* caller already checked this */
816272154Sdelphij	assert(len > 0);
817272154Sdelphij
818285994Simp	/*
819285994Simp	 * A format of "IK" is in deciKelvin. A format of "IK3" is in
820285994Simp	 * milliKelvin. The single digit following IK is log10 of the
821285994Simp	 * multiplying factor to convert Kelvin into the untis of this sysctl,
822285994Simp	 * or the dividing factor to convert the sysctl value to Kelvin. Numbers
823285994Simp	 * larger than 6 will run into precision issues with 32-bit integers.
824285994Simp	 * Characters that aren't ASCII digits after the 'K' are ignored. No
825285994Simp	 * localization is present because this is an interface from the kernel
826285994Simp	 * to this program (eg not an end-user interface), so isdigit() isn't
827285994Simp	 * used here.
828285994Simp	 */
829285994Simp	if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9')
830285994Simp		prec = fmt[2] - '0';
831285994Simp	else
832285994Simp		prec = 1;
833161951Sume	p = &str[len - 1];
834285994Simp	if (*p == 'C' || *p == 'F' || *p == 'K') {
835272154Sdelphij		temp = strtof(str, endptrp);
836275377Sdelphij		if (*endptrp != str && *endptrp == p && errno == 0) {
837272154Sdelphij			if (*p == 'F')
838272154Sdelphij				temp = (temp - 32) * 5 / 9;
839275377Sdelphij			*endptrp = NULL;
840285994Simp			if (*p != 'K')
841285994Simp				temp += 273.15;
842285994Simp			for (i = 0; i < prec; i++)
843285994Simp				temp *= 10.0;
844285994Simp			return ((int)(temp + 0.5));
845272154Sdelphij		}
846161951Sume	} else {
847285994Simp		/* No unit specified -> treat it as a raw number */
848272154Sdelphij		kelv = (int)strtol(str, endptrp, 10);
849275377Sdelphij		if (*endptrp != str && *endptrp == p && errno == 0) {
850275377Sdelphij			*endptrp = NULL;
851272154Sdelphij			return (kelv);
852275377Sdelphij		}
853161951Sume	}
854272154Sdelphij
855272154Sdelphij	errno = ERANGE;
856272154Sdelphij	return (0);
857161951Sume}
858161951Sume
85912946Sphk/*
86012946Sphk * These functions uses a presently undocumented interface to the kernel
86112946Sphk * to walk the tree and get the type so it can print the value.
86212946Sphk * This interface is under work and consideration, and should probably
86312946Sphk * be killed with a big axe by the first person who can find the time.
86412946Sphk * (be aware though, that the proper interface isn't as obvious as it
86512946Sphk * may seem, there are various conflicting requirements.
86612946Sphk */
8671553Srgrimes
86812946Sphkstatic int
869272044Sdelphijname2oid(const char *name, int *oidp)
87012946Sphk{
87112946Sphk	int oid[2];
87238533Sdfr	int i;
87338533Sdfr	size_t j;
8741553Srgrimes
87512946Sphk	oid[0] = 0;
87612946Sphk	oid[1] = 3;
8771553Srgrimes
87877928Sdd	j = CTL_MAXNAME * sizeof(int);
87912946Sphk	i = sysctl(oid, 2, oidp, &j, name, strlen(name));
880122234Sdes	if (i < 0)
881170512Sdwmalone		return (i);
88277928Sdd	j /= sizeof(int);
88312946Sphk	return (j);
8841553Srgrimes}
8851553Srgrimes
88612946Sphkstatic int
88712946Sphkoidfmt(int *oid, int len, char *fmt, u_int *kind)
88812946Sphk{
88912946Sphk	int qoid[CTL_MAXNAME+2];
89012946Sphk	u_char buf[BUFSIZ];
89138533Sdfr	int i;
89238533Sdfr	size_t j;
8931553Srgrimes
89412946Sphk	qoid[0] = 0;
89512946Sphk	qoid[1] = 4;
89612946Sphk	memcpy(qoid + 2, oid, len * sizeof(int));
8971553Srgrimes
89877928Sdd	j = sizeof(buf);
89912946Sphk	i = sysctl(qoid, len + 2, buf, &j, 0, 0);
90012946Sphk	if (i)
901203917Suqs		err(1, "sysctl fmt %d %zu %d", i, j, errno);
9021553Srgrimes
90312946Sphk	if (kind)
90412946Sphk		*kind = *(u_int *)buf;
90512946Sphk
90612946Sphk	if (fmt)
90712946Sphk		strcpy(fmt, (char *)(buf + sizeof(u_int)));
908170512Sdwmalone	return (0);
9091553Srgrimes}
9101553Srgrimes
9111553Srgrimes/*
91212946Sphk * This formats and outputs the value of one variable
91312946Sphk *
91412946Sphk * Returns zero if anything was actually output.
91512946Sphk * Returns one if didn't know what to do with this.
91612946Sphk * Return minus one if we had errors.
9171553Srgrimes */
91812946Sphkstatic int
91912946Sphkshow_var(int *oid, int nlen)
9201553Srgrimes{
921162073Sru	u_char buf[BUFSIZ], *val, *oval, *p;
922244133Salfred	char name[BUFSIZ], fmt[BUFSIZ];
923292045Saraujo	const char *sep, *sep1, *prntype;
92412946Sphk	int qoid[CTL_MAXNAME+2];
925170512Sdwmalone	uintmax_t umv;
926170512Sdwmalone	intmax_t mv;
927217586Smdf	int i, hexlen, sign, ctltype;
928170287Sdwmalone	size_t intlen;
92938533Sdfr	size_t j, len;
93012946Sphk	u_int kind;
931285994Simp	float base;
932271487Sjhb	int (*func)(size_t, void *);
933285994Simp	int prec;
9341553Srgrimes
935203917Suqs	/* Silence GCC. */
936203917Suqs	umv = mv = intlen = 0;
937203917Suqs
938144997Smdodd	bzero(buf, BUFSIZ);
939244133Salfred	bzero(fmt, BUFSIZ);
940144997Smdodd	bzero(name, BUFSIZ);
94142456Sdes	qoid[0] = 0;
94242456Sdes	memcpy(qoid + 2, oid, nlen * sizeof(int));
94342456Sdes
94442456Sdes	qoid[1] = 1;
94577928Sdd	j = sizeof(name);
94642456Sdes	i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
94742456Sdes	if (i || !j)
948203917Suqs		err(1, "sysctl name %d %zu %d", i, j, errno);
94942456Sdes
950244133Salfred	oidfmt(oid, nlen, fmt, &kind);
951244133Salfred	/* if Wflag then only list sysctls that are writeable and not stats. */
952244133Salfred	if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0))
953244133Salfred		return 1;
954244133Salfred
955244133Salfred	/* if Tflag then only list sysctls that are tuneables. */
956244133Salfred	if (Tflag && (kind & CTLFLAG_TUN) == 0)
957244133Salfred		return 1;
958244133Salfred
95971034Sdes	if (Nflag) {
96071034Sdes		printf("%s", name);
96171034Sdes		return (0);
96271034Sdes	}
96371034Sdes
96485747Stobez	if (eflag)
96585747Stobez		sep = "=";
96685747Stobez	else
96785747Stobez		sep = ": ";
96885747Stobez
969292045Saraujo	ctltype = (kind & CTLTYPE);
970292045Saraujo	if (tflag || dflag) {
971292045Saraujo		if (!nflag)
972292045Saraujo			printf("%s%s", name, sep);
973292045Saraujo        	if (ctl_typename[ctltype] != NULL)
974292045Saraujo            		prntype = ctl_typename[ctltype];
975292045Saraujo        	else
976292045Saraujo            		prntype = "unknown";
977292045Saraujo		if (tflag && dflag)
978292045Saraujo			printf("%s%s", prntype, sep);
979292045Saraujo		else if (tflag) {
980292045Saraujo			printf("%s", prntype);
981292045Saraujo			return (0);
982292045Saraujo		}
98388006Sluigi		qoid[1] = 5;
98488006Sluigi		j = sizeof(buf);
98588006Sluigi		i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
98688006Sluigi		printf("%s", buf);
98788006Sluigi		return (0);
98888006Sluigi	}
98912946Sphk	/* find an estimate of how much we need for this var */
990278654Sjmg	if (Bflag)
991278654Sjmg		j = Bflag;
992278654Sjmg	else {
993278654Sjmg		j = 0;
994278654Sjmg		i = sysctl(oid, nlen, 0, &j, 0, 0);
995278654Sjmg		j += j; /* we want to be sure :-) */
996278654Sjmg	}
99712946Sphk
998162073Sru	val = oval = malloc(j + 1);
999162073Sru	if (val == NULL) {
1000162073Sru		warnx("malloc failed");
1001170558Sbde		return (1);
1002162073Sru	}
100312946Sphk	len = j;
100412946Sphk	i = sysctl(oid, nlen, val, &len, 0, 0);
1005267960Shselasky	if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) {
1006162073Sru		free(oval);
100712946Sphk		return (1);
1008162073Sru	}
100912946Sphk
101012946Sphk	if (bflag) {
101112946Sphk		fwrite(val, 1, len, stdout);
1012162073Sru		free(oval);
101312946Sphk		return (0);
10141553Srgrimes	}
101596234Sache	val[len] = '\0';
101612946Sphk	p = val;
1017217616Smdf	sign = ctl_sign[ctltype];
1018217616Smdf	intlen = ctl_size[ctltype];
1019217616Smdf
1020217586Smdf	switch (ctltype) {
1021217586Smdf	case CTLTYPE_STRING:
102212946Sphk		if (!nflag)
102385747Stobez			printf("%s%s", name, sep);
1024203917Suqs		printf("%.*s", (int)len, p);
1025162073Sru		free(oval);
102612946Sphk		return (0);
1027122234Sdes
1028217586Smdf	case CTLTYPE_INT:
1029217586Smdf	case CTLTYPE_UINT:
1030217586Smdf	case CTLTYPE_LONG:
1031217586Smdf	case CTLTYPE_ULONG:
1032290476Scem	case CTLTYPE_S8:
1033290476Scem	case CTLTYPE_S16:
1034290476Scem	case CTLTYPE_S32:
1035217616Smdf	case CTLTYPE_S64:
1036290476Scem	case CTLTYPE_U8:
1037290476Scem	case CTLTYPE_U16:
1038290476Scem	case CTLTYPE_U32:
1039217616Smdf	case CTLTYPE_U64:
104012946Sphk		if (!nflag)
104185747Stobez			printf("%s%s", name, sep);
1042170514Sdwmalone		hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
1043170513Sdwmalone		sep1 = "";
1044170287Sdwmalone		while (len >= intlen) {
1045217586Smdf			switch (kind & CTLTYPE) {
1046217586Smdf			case CTLTYPE_INT:
1047217586Smdf			case CTLTYPE_UINT:
1048170514Sdwmalone				umv = *(u_int *)p;
1049170514Sdwmalone				mv = *(int *)p;
1050170287Sdwmalone				break;
1051217586Smdf			case CTLTYPE_LONG:
1052217586Smdf			case CTLTYPE_ULONG:
1053170514Sdwmalone				umv = *(u_long *)p;
1054170514Sdwmalone				mv = *(long *)p;
1055170287Sdwmalone				break;
1056290476Scem			case CTLTYPE_S8:
1057290476Scem			case CTLTYPE_U8:
1058290476Scem				umv = *(uint8_t *)p;
1059290476Scem				mv = *(int8_t *)p;
1060290476Scem				break;
1061290476Scem			case CTLTYPE_S16:
1062290476Scem			case CTLTYPE_U16:
1063290476Scem				umv = *(uint16_t *)p;
1064290476Scem				mv = *(int16_t *)p;
1065290476Scem				break;
1066290476Scem			case CTLTYPE_S32:
1067290476Scem			case CTLTYPE_U32:
1068290476Scem				umv = *(uint32_t *)p;
1069290476Scem				mv = *(int32_t *)p;
1070290476Scem				break;
1071217616Smdf			case CTLTYPE_S64:
1072217616Smdf			case CTLTYPE_U64:
1073217616Smdf				umv = *(uint64_t *)p;
1074217616Smdf				mv = *(int64_t *)p;
1075170287Sdwmalone				break;
1076170287Sdwmalone			}
1077170513Sdwmalone			fputs(sep1, stdout);
1078217586Smdf			if (xflag)
1079217586Smdf				printf("%#0*jx", hexlen, umv);
1080217586Smdf			else if (!sign)
1081170512Sdwmalone				printf(hflag ? "%'ju" : "%ju", umv);
1082170287Sdwmalone			else if (fmt[1] == 'K') {
1083170514Sdwmalone				if (mv < 0)
1084170512Sdwmalone					printf("%jd", mv);
1085285994Simp				else {
1086285994Simp					/*
1087285994Simp					 * See strIKtoi for details on fmt.
1088285994Simp					 */
1089285994Simp					prec = 1;
1090285994Simp					if (fmt[2] != '\0')
1091285994Simp						prec = fmt[2] - '0';
1092285994Simp					base = 1.0;
1093285994Simp					for (int i = 0; i < prec; i++)
1094285994Simp						base *= 10.0;
1095285994Simp					printf("%.*fC", prec,
1096285994Simp					    (float)mv / base - 273.15);
1097285994Simp				}
1098134541Speter			} else
1099170513Sdwmalone				printf(hflag ? "%'jd" : "%jd", mv);
1100170513Sdwmalone			sep1 = " ";
1101170287Sdwmalone			len -= intlen;
1102170287Sdwmalone			p += intlen;
110341019Sphk		}
1104162073Sru		free(oval);
110512946Sphk		return (0);
110612946Sphk
1107217586Smdf	case CTLTYPE_OPAQUE:
110812946Sphk		i = 0;
110977332Sdes		if (strcmp(fmt, "S,clockinfo") == 0)
111077332Sdes			func = S_clockinfo;
111177332Sdes		else if (strcmp(fmt, "S,timeval") == 0)
111277332Sdes			func = S_timeval;
111377332Sdes		else if (strcmp(fmt, "S,loadavg") == 0)
111477332Sdes			func = S_loadavg;
1115109097Sdillon		else if (strcmp(fmt, "S,vmtotal") == 0)
1116109097Sdillon			func = S_vmtotal;
1117344984Swulf		else if (strcmp(fmt, "S,input_id") == 0)
1118344984Swulf			func = S_input_id;
1119271495Sjhb#ifdef __amd64__
1120271495Sjhb		else if (strcmp(fmt, "S,efi_map_header") == 0)
1121271495Sjhb			func = S_efi_map;
1122271495Sjhb#endif
1123270828Sjhb#if defined(__amd64__) || defined(__i386__)
1124270828Sjhb		else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
1125270828Sjhb			func = S_bios_smap_xattr;
1126270828Sjhb#endif
112777332Sdes		else
112877332Sdes			func = NULL;
112912946Sphk		if (func) {
113012946Sphk			if (!nflag)
113185747Stobez				printf("%s%s", name, sep);
1132163275Sharti			i = (*func)(len, p);
1133162073Sru			free(oval);
1134163275Sharti			return (i);
113512946Sphk		}
1136102411Scharnier		/* FALLTHROUGH */
113712946Sphk	default:
1138162073Sru		if (!oflag && !xflag) {
1139162073Sru			free(oval);
114012946Sphk			return (1);
1141162073Sru		}
114212946Sphk		if (!nflag)
114385747Stobez			printf("%s%s", name, sep);
1144203917Suqs		printf("Format:%s Length:%zu Dump:0x", fmt, len);
114577332Sdes		while (len-- && (xflag || p < val + 16))
114612946Sphk			printf("%02x", *p++);
114777332Sdes		if (!xflag && len > 16)
114812946Sphk			printf("...");
1149162073Sru		free(oval);
115012946Sphk		return (0);
11511553Srgrimes	}
1152162073Sru	free(oval);
115312946Sphk	return (1);
11541553Srgrimes}
11551553Srgrimes
115612946Sphkstatic int
1157170512Sdwmalonesysctl_all(int *oid, int len)
11581553Srgrimes{
115912946Sphk	int name1[22], name2[22];
116038533Sdfr	int i, j;
116138533Sdfr	size_t l1, l2;
11621553Srgrimes
116312946Sphk	name1[0] = 0;
116412946Sphk	name1[1] = 2;
116512946Sphk	l1 = 2;
116612946Sphk	if (len) {
116777928Sdd		memcpy(name1+2, oid, len * sizeof(int));
116812946Sphk		l1 += len;
116912946Sphk	} else {
117012946Sphk		name1[2] = 1;
117112946Sphk		l1++;
117212946Sphk	}
117377332Sdes	for (;;) {
117477928Sdd		l2 = sizeof(name2);
117512946Sphk		j = sysctl(name1, l1, name2, &l2, 0, 0);
117648956Sbillf		if (j < 0) {
117712946Sphk			if (errno == ENOENT)
1178170512Sdwmalone				return (0);
117912946Sphk			else
1180203917Suqs				err(1, "sysctl(getnext) %d %zu", j, l2);
118148956Sbillf		}
118212946Sphk
118377928Sdd		l2 /= sizeof(int);
118412946Sphk
1185170513Sdwmalone		if (len < 0 || l2 < (unsigned int)len)
1186170512Sdwmalone			return (0);
118712946Sphk
118812946Sphk		for (i = 0; i < len; i++)
118912946Sphk			if (name2[i] != oid[i])
1190170512Sdwmalone				return (0);
119112946Sphk
119212946Sphk		i = show_var(name2, l2);
119312946Sphk		if (!i && !bflag)
119412946Sphk			putchar('\n');
119512946Sphk
119677928Sdd		memcpy(name1+2, name2, l2 * sizeof(int));
119712946Sphk		l1 = 2 + l2;
119812946Sphk	}
11991553Srgrimes}
1200