xref: /freebsd/sbin/sysctl/sysctl.c (revision 758200053184b5103cc88de0dbc5ee7a3ddd7369)
1dea673e9SRodney W. Grimes /*
2dea673e9SRodney W. Grimes  * Copyright (c) 1993
3dea673e9SRodney W. Grimes  *	The Regents of the University of California.  All rights reserved.
4dea673e9SRodney W. Grimes  *
5dea673e9SRodney W. Grimes  * Redistribution and use in source and binary forms, with or without
6dea673e9SRodney W. Grimes  * modification, are permitted provided that the following conditions
7dea673e9SRodney W. Grimes  * are met:
8dea673e9SRodney W. Grimes  * 1. Redistributions of source code must retain the above copyright
9dea673e9SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer.
10dea673e9SRodney W. Grimes  * 2. Redistributions in binary form must reproduce the above copyright
11dea673e9SRodney W. Grimes  *    notice, this list of conditions and the following disclaimer in the
12dea673e9SRodney W. Grimes  *    documentation and/or other materials provided with the distribution.
13dea673e9SRodney W. Grimes  * 4. Neither the name of the University nor the names of its contributors
14dea673e9SRodney W. Grimes  *    may be used to endorse or promote products derived from this software
15dea673e9SRodney W. Grimes  *    without specific prior written permission.
16dea673e9SRodney W. Grimes  *
17dea673e9SRodney W. Grimes  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18dea673e9SRodney W. Grimes  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19dea673e9SRodney W. Grimes  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20dea673e9SRodney W. Grimes  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21dea673e9SRodney W. Grimes  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22dea673e9SRodney W. Grimes  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23dea673e9SRodney W. Grimes  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24dea673e9SRodney W. Grimes  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25dea673e9SRodney W. Grimes  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26dea673e9SRodney W. Grimes  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27dea673e9SRodney W. Grimes  * SUCH DAMAGE.
28dea673e9SRodney W. Grimes  */
29dea673e9SRodney W. Grimes 
30dea673e9SRodney W. Grimes #ifndef lint
31d9b1bc77SPhilippe Charnier static const char copyright[] =
32dea673e9SRodney W. Grimes "@(#) Copyright (c) 1993\n\
33dea673e9SRodney W. Grimes 	The Regents of the University of California.  All rights reserved.\n";
34dea673e9SRodney W. Grimes #endif /* not lint */
35dea673e9SRodney W. Grimes 
36dea673e9SRodney W. Grimes #ifndef lint
37d9b1bc77SPhilippe Charnier #if 0
38d9b1bc77SPhilippe Charnier static char sccsid[] = "@(#)from: sysctl.c	8.1 (Berkeley) 6/6/93";
39d9b1bc77SPhilippe Charnier #endif
4035c13fa0SGarrett Wollman static const char rcsid[] =
417f3dea24SPeter Wemm   "$FreeBSD$";
42dea673e9SRodney W. Grimes #endif /* not lint */
43dea673e9SRodney W. Grimes 
44ce685842SBruce Evans #include <sys/param.h>
45ce685842SBruce Evans #include <sys/time.h>
46ce685842SBruce Evans #include <sys/resource.h>
47dea673e9SRodney W. Grimes #include <sys/stat.h>
48dea673e9SRodney W. Grimes #include <sys/sysctl.h>
49f7550ecfSMatthew Dillon #include <sys/vmmeter.h>
50dea673e9SRodney W. Grimes 
517d8312ccSJohn Baldwin #ifdef __amd64__
527d8312ccSJohn Baldwin #include <sys/efi.h>
537d8312ccSJohn Baldwin #include <machine/metadata.h>
547d8312ccSJohn Baldwin #endif
557d8312ccSJohn Baldwin 
5689871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
5789871cdeSJohn Baldwin #include <machine/pc/bios.h>
5889871cdeSJohn Baldwin #endif
5989871cdeSJohn Baldwin 
60e267e00eSXin LI #include <assert.h>
61d9b1bc77SPhilippe Charnier #include <ctype.h>
62d9b1bc77SPhilippe Charnier #include <err.h>
63dea673e9SRodney W. Grimes #include <errno.h>
6441e419cbSDavid Malone #include <inttypes.h>
6545817aaaSDag-Erling Smørgrav #include <locale.h>
66dea673e9SRodney W. Grimes #include <stdio.h>
67dea673e9SRodney W. Grimes #include <stdlib.h>
68dea673e9SRodney W. Grimes #include <string.h>
69da178c77SXin LI #include <sysexits.h>
70d9b1bc77SPhilippe Charnier #include <unistd.h>
71dea673e9SRodney W. Grimes 
72da178c77SXin LI static const char *conffile;
73da178c77SXin LI 
74*75820005SJohn-Mark Gurney static int	aflag, bflag, Bflag, dflag, eflag, hflag, iflag;
75da178c77SXin LI static int	Nflag, nflag, oflag, qflag, Tflag, Wflag, xflag;
76dea673e9SRodney W. Grimes 
771d86b91cSPoul-Henning Kamp static int	oidfmt(int *, int, char *, u_int *);
78da178c77SXin LI static int	parsefile(const char *);
79da178c77SXin LI static int	parse(const char *, int);
801d86b91cSPoul-Henning Kamp static int	show_var(int *, int);
811d86b91cSPoul-Henning Kamp static int	sysctl_all(int *oid, int len);
82c58f8df6SXin LI static int	name2oid(const char *, int *);
83dea673e9SRodney W. Grimes 
84e267e00eSXin LI static int	strIKtoi(const char *, char **);
85e267e00eSXin LI 
86e267e00eSXin LI static int ctl_sign[CTLTYPE+1] = {
87e267e00eSXin LI 	[CTLTYPE_INT] = 1,
88e267e00eSXin LI 	[CTLTYPE_LONG] = 1,
89e267e00eSXin LI 	[CTLTYPE_S64] = 1,
90e267e00eSXin LI };
91e267e00eSXin LI 
92e267e00eSXin LI static int ctl_size[CTLTYPE+1] = {
93e267e00eSXin LI 	[CTLTYPE_INT] = sizeof(int),
94e267e00eSXin LI 	[CTLTYPE_UINT] = sizeof(u_int),
95e267e00eSXin LI 	[CTLTYPE_LONG] = sizeof(long),
96e267e00eSXin LI 	[CTLTYPE_ULONG] = sizeof(u_long),
97e267e00eSXin LI 	[CTLTYPE_S64] = sizeof(int64_t),
98e267e00eSXin LI 	[CTLTYPE_U64] = sizeof(uint64_t),
99e267e00eSXin LI };
100e267e00eSXin LI 
101e267e00eSXin LI static const char *ctl_typename[CTLTYPE+1] = {
102e267e00eSXin LI 	[CTLTYPE_INT] = "integer",
103e267e00eSXin LI 	[CTLTYPE_UINT] = "unsigned integer",
104e267e00eSXin LI 	[CTLTYPE_LONG] = "long integer",
105e267e00eSXin LI 	[CTLTYPE_ULONG] = "unsigned long",
106e267e00eSXin LI 	[CTLTYPE_S64] = "int64_t",
107e267e00eSXin LI 	[CTLTYPE_U64] = "uint64_t",
108e267e00eSXin LI };
109d58f0054SPoul-Henning Kamp 
1101d86b91cSPoul-Henning Kamp static void
1111d86b91cSPoul-Henning Kamp usage(void)
1121d86b91cSPoul-Henning Kamp {
113dea673e9SRodney W. Grimes 
1149a2402bcSDag-Erling Smørgrav 	(void)fprintf(stderr, "%s\n%s\n",
115*75820005SJohn-Mark Gurney 	    "usage: sysctl [-bdehiNnoqTWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
116*75820005SJohn-Mark Gurney 	    "       sysctl [-bdehNnoqTWx] [ -B <bufsize> ] -a");
1171d86b91cSPoul-Henning Kamp 	exit(1);
1181d86b91cSPoul-Henning Kamp }
119dea673e9SRodney W. Grimes 
120dea673e9SRodney W. Grimes int
1211d86b91cSPoul-Henning Kamp main(int argc, char **argv)
122dea673e9SRodney W. Grimes {
1231d86b91cSPoul-Henning Kamp 	int ch;
124da178c77SXin LI 	int warncount = 0;
12545817aaaSDag-Erling Smørgrav 
12645817aaaSDag-Erling Smørgrav 	setlocale(LC_NUMERIC, "");
1271d86b91cSPoul-Henning Kamp 	setbuf(stdout,0);
1281d86b91cSPoul-Henning Kamp 	setbuf(stderr,0);
129dea673e9SRodney W. Grimes 
130*75820005SJohn-Mark Gurney 	while ((ch = getopt(argc, argv, "AabB:def:hiNnoqTwWxX")) != -1) {
131dea673e9SRodney W. Grimes 		switch (ch) {
132ca5fac55SDag-Erling Smørgrav 		case 'A':
1339a2402bcSDag-Erling Smørgrav 			/* compatibility */
1349a2402bcSDag-Erling Smørgrav 			aflag = oflag = 1;
135ca5fac55SDag-Erling Smørgrav 			break;
136ca5fac55SDag-Erling Smørgrav 		case 'a':
137ca5fac55SDag-Erling Smørgrav 			aflag = 1;
138ca5fac55SDag-Erling Smørgrav 			break;
139ca5fac55SDag-Erling Smørgrav 		case 'b':
140ca5fac55SDag-Erling Smørgrav 			bflag = 1;
141ca5fac55SDag-Erling Smørgrav 			break;
142*75820005SJohn-Mark Gurney 		case 'B':
143*75820005SJohn-Mark Gurney 			Bflag = strtol(optarg, NULL, 0);
144*75820005SJohn-Mark Gurney 			break;
1456105f815SLuigi Rizzo 		case 'd':
1466105f815SLuigi Rizzo 			dflag = 1;
1476105f815SLuigi Rizzo 			break;
148d0b8aabbSAnton Berezin 		case 'e':
149d0b8aabbSAnton Berezin 			eflag = 1;
150d0b8aabbSAnton Berezin 			break;
151da178c77SXin LI 		case 'f':
152da178c77SXin LI 			conffile = optarg;
153da178c77SXin LI 			break;
15445817aaaSDag-Erling Smørgrav 		case 'h':
15545817aaaSDag-Erling Smørgrav 			hflag = 1;
15645817aaaSDag-Erling Smørgrav 			break;
15724b2aa32SGavin Atkinson 		case 'i':
15824b2aa32SGavin Atkinson 			iflag = 1;
15924b2aa32SGavin Atkinson 			break;
160ca5fac55SDag-Erling Smørgrav 		case 'N':
161ca5fac55SDag-Erling Smørgrav 			Nflag = 1;
162ca5fac55SDag-Erling Smørgrav 			break;
163ca5fac55SDag-Erling Smørgrav 		case 'n':
164ca5fac55SDag-Erling Smørgrav 			nflag = 1;
165ca5fac55SDag-Erling Smørgrav 			break;
1669a2402bcSDag-Erling Smørgrav 		case 'o':
1679a2402bcSDag-Erling Smørgrav 			oflag = 1;
1689a2402bcSDag-Erling Smørgrav 			break;
169f93d36fdSRobert Watson 		case 'q':
170f93d36fdSRobert Watson 			qflag = 1;
171f93d36fdSRobert Watson 			break;
1729ecd2e32SAlfred Perlstein 		case 'T':
1739ecd2e32SAlfred Perlstein 			Tflag = 1;
1749ecd2e32SAlfred Perlstein 			break;
175ca5fac55SDag-Erling Smørgrav 		case 'w':
1769a2402bcSDag-Erling Smørgrav 			/* compatibility */
1779a2402bcSDag-Erling Smørgrav 			/* ignored */
178ca5fac55SDag-Erling Smørgrav 			break;
1799ecd2e32SAlfred Perlstein 		case 'W':
1809ecd2e32SAlfred Perlstein 			Wflag = 1;
1819ecd2e32SAlfred Perlstein 			break;
182ca5fac55SDag-Erling Smørgrav 		case 'X':
1839a2402bcSDag-Erling Smørgrav 			/* compatibility */
1849a2402bcSDag-Erling Smørgrav 			aflag = xflag = 1;
1859a2402bcSDag-Erling Smørgrav 			break;
1869a2402bcSDag-Erling Smørgrav 		case 'x':
1879a2402bcSDag-Erling Smørgrav 			xflag = 1;
188ca5fac55SDag-Erling Smørgrav 			break;
189ca5fac55SDag-Erling Smørgrav 		default:
190ca5fac55SDag-Erling Smørgrav 			usage();
191dea673e9SRodney W. Grimes 		}
192dea673e9SRodney W. Grimes 	}
193dea673e9SRodney W. Grimes 	argc -= optind;
194dea673e9SRodney W. Grimes 	argv += optind;
195dea673e9SRodney W. Grimes 
1969a2402bcSDag-Erling Smørgrav 	if (Nflag && nflag)
19781e7454aSDag-Erling Smørgrav 		usage();
1989a2402bcSDag-Erling Smørgrav 	if (aflag && argc == 0)
1991d86b91cSPoul-Henning Kamp 		exit(sysctl_all(0, 0));
200da178c77SXin LI 	if (argc == 0 && conffile == NULL)
201dea673e9SRodney W. Grimes 		usage();
202d9fcd86cSMike Makonnen 
203d9fcd86cSMike Makonnen 	warncount = 0;
204da178c77SXin LI 	if (conffile != NULL)
205da178c77SXin LI 		warncount += parsefile(conffile);
206da178c77SXin LI 
207dea673e9SRodney W. Grimes 	while (argc-- > 0)
208da178c77SXin LI 		warncount += parse(*argv++, 0);
209da178c77SXin LI 
210da178c77SXin LI 	return (warncount);
211dea673e9SRodney W. Grimes }
212dea673e9SRodney W. Grimes 
213dea673e9SRodney W. Grimes /*
214dea673e9SRodney W. Grimes  * Parse a name into a MIB entry.
215dea673e9SRodney W. Grimes  * Lookup and print out the MIB entry if it exists.
216dea673e9SRodney W. Grimes  * Set a new value if requested.
217dea673e9SRodney W. Grimes  */
218da178c77SXin LI static int
219da178c77SXin LI parse(const char *string, int lineno)
220dea673e9SRodney W. Grimes {
2211d86b91cSPoul-Henning Kamp 	int len, i, j;
222e267e00eSXin LI 	const void *newval;
223e267e00eSXin LI 	const char *newvalstr = NULL;
2241ce1a53dSJim Pirzyk 	int intval;
2251ce1a53dSJim Pirzyk 	unsigned int uintval;
2261ce1a53dSJim Pirzyk 	long longval;
2271ce1a53dSJim Pirzyk 	unsigned long ulongval;
228*75820005SJohn-Mark Gurney 	size_t newsize = Bflag;
229cbc134adSMatthew D Fleming 	int64_t i64val;
230cbc134adSMatthew D Fleming 	uint64_t u64val;
231dea673e9SRodney W. Grimes 	int mib[CTL_MAXNAME];
232e267e00eSXin LI 	char *cp, *bufp, buf[BUFSIZ], *endptr = NULL, fmt[BUFSIZ], line[BUFSIZ];
2331d86b91cSPoul-Henning Kamp 	u_int kind;
234dea673e9SRodney W. Grimes 
235da178c77SXin LI 	if (lineno)
236da178c77SXin LI 		snprintf(line, sizeof(line), " at line %d", lineno);
237da178c77SXin LI 	else
238da178c77SXin LI 		line[0] = '\0';
239da178c77SXin LI 
240aae75101SXin LI 	cp = buf;
241da178c77SXin LI 	if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) {
242c6919e7fSEdward Tomasz Napierala 		warnx("oid too long: '%s'%s", string, line);
243da178c77SXin LI 		return (1);
244da178c77SXin LI 	}
245da178c77SXin LI 	bufp = strsep(&cp, "=:");
246aae75101SXin LI 	if (cp != NULL) {
2479ecd2e32SAlfred Perlstein 		/* Tflag just lists tunables, do not allow assignment */
2489ecd2e32SAlfred Perlstein 		if (Tflag || Wflag) {
2499ecd2e32SAlfred Perlstein 			warnx("Can't set variables when using -T or -W");
2509ecd2e32SAlfred Perlstein 			usage();
2519ecd2e32SAlfred Perlstein 		}
252dea673e9SRodney W. Grimes 		while (isspace(*cp))
253dea673e9SRodney W. Grimes 			cp++;
254da178c77SXin LI 		/* Strip a pair of " or ' if any. */
255da178c77SXin LI 		switch (*cp) {
256da178c77SXin LI 		case '\"':
257da178c77SXin LI 		case '\'':
258da178c77SXin LI 			if (cp[strlen(cp) - 1] == *cp)
259da178c77SXin LI 				cp[strlen(cp) - 1] = '\0';
260da178c77SXin LI 			cp++;
261da178c77SXin LI 		}
262e267e00eSXin LI 		newvalstr = cp;
263dea673e9SRodney W. Grimes 		newsize = strlen(cp);
264dea673e9SRodney W. Grimes 	}
2651d86b91cSPoul-Henning Kamp 	len = name2oid(bufp, mib);
2661d86b91cSPoul-Henning Kamp 
267f93d36fdSRobert Watson 	if (len < 0) {
26824b2aa32SGavin Atkinson 		if (iflag)
269da178c77SXin LI 			return (0);
270f93d36fdSRobert Watson 		if (qflag)
271da178c77SXin LI 			return (1);
272da178c77SXin LI 		else {
273da178c77SXin LI 			warn("unknown oid '%s'%s", bufp, line);
274da178c77SXin LI 			return (1);
275da178c77SXin LI 		}
276f93d36fdSRobert Watson 	}
2771d86b91cSPoul-Henning Kamp 
278da178c77SXin LI 	if (oidfmt(mib, len, fmt, &kind)) {
279da178c77SXin LI 		warn("couldn't find format of oid '%s'%s", bufp, line);
280da178c77SXin LI 		if (iflag)
281da178c77SXin LI 			return (1);
282da178c77SXin LI 		else
283da178c77SXin LI 			exit(1);
284da178c77SXin LI 	}
2851d86b91cSPoul-Henning Kamp 
286e267e00eSXin LI 	if (newvalstr == NULL || dflag) {
2871d86b91cSPoul-Henning Kamp 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
288b2680e20SMatthew N. Dodd 			if (dflag) {
289b2680e20SMatthew N. Dodd 				i = show_var(mib, len);
290b2680e20SMatthew N. Dodd 				if (!i && !bflag)
291b2680e20SMatthew N. Dodd 					putchar('\n');
292b2680e20SMatthew N. Dodd 			}
2931d86b91cSPoul-Henning Kamp 			sysctl_all(mib, len);
2941d86b91cSPoul-Henning Kamp 		} else {
2951d86b91cSPoul-Henning Kamp 			i = show_var(mib, len);
2961d86b91cSPoul-Henning Kamp 			if (!i && !bflag)
2971d86b91cSPoul-Henning Kamp 				putchar('\n');
298dea673e9SRodney W. Grimes 		}
2991d86b91cSPoul-Henning Kamp 	} else {
300da178c77SXin LI 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
301c6919e7fSEdward Tomasz Napierala 			warnx("oid '%s' isn't a leaf node%s", bufp, line);
302da178c77SXin LI 			return (1);
303da178c77SXin LI 		}
304dea673e9SRodney W. Grimes 
305ac8711d2SMike Silbersack 		if (!(kind & CTLFLAG_WR)) {
3069b4b73b7SMike Silbersack 			if (kind & CTLFLAG_TUN) {
3076f361351SXin LI 				warnx("oid '%s' is a read only tunable%s", bufp, line);
308da178c77SXin LI 				warnx("Tunable values are set in /boot/loader.conf");
309da178c77SXin LI 			} else
310da178c77SXin LI 				warnx("oid '%s' is read only%s", bufp, line);
311da178c77SXin LI 			return (1);
312ac8711d2SMike Silbersack 		}
313dea673e9SRodney W. Grimes 
314e267e00eSXin LI 		switch (kind & CTLTYPE) {
315e267e00eSXin LI 		case CTLTYPE_INT:
316e267e00eSXin LI 		case CTLTYPE_UINT:
317e267e00eSXin LI 		case CTLTYPE_LONG:
318e267e00eSXin LI 		case CTLTYPE_ULONG:
319e267e00eSXin LI 		case CTLTYPE_S64:
320e267e00eSXin LI 		case CTLTYPE_U64:
321e267e00eSXin LI 			if (strlen(newvalstr) == 0) {
322da178c77SXin LI 				warnx("empty numeric value");
323da178c77SXin LI 				return (1);
324da178c77SXin LI 			}
325e267e00eSXin LI 			/* FALLTHROUGH */
326e267e00eSXin LI 		case CTLTYPE_STRING:
327e267e00eSXin LI 			break;
328e267e00eSXin LI 		default:
329e267e00eSXin LI 			warnx("oid '%s' is type %d,"
330e267e00eSXin LI 				" cannot set that%s", bufp,
331e267e00eSXin LI 				kind & CTLTYPE, line);
332e267e00eSXin LI 			return (1);
333a78d3eafSRobert Watson 		}
334a78d3eafSRobert Watson 
3354b8740cdSXin LI 		errno = 0;
3364b8740cdSXin LI 
3371d86b91cSPoul-Henning Kamp 		switch (kind & CTLTYPE) {
338dea673e9SRodney W. Grimes 			case CTLTYPE_INT:
339e267e00eSXin LI 				if (strcmp(fmt, "IK") == 0)
340e267e00eSXin LI 					intval = strIKtoi(newvalstr, &endptr);
341e267e00eSXin LI 				else
342e267e00eSXin LI 					intval = (int)strtol(newvalstr, &endptr,
343d45564dcSHajimu UMEMOTO 					    0);
344dea673e9SRodney W. Grimes 				newval = &intval;
34531fb4661SDima Dorfman 				newsize = sizeof(intval);
346dea673e9SRodney W. Grimes 				break;
3471ce1a53dSJim Pirzyk 			case CTLTYPE_UINT:
348e267e00eSXin LI 				uintval = (int) strtoul(newvalstr, &endptr, 0);
3491ce1a53dSJim Pirzyk 				newval = &uintval;
35021e1f596SDavid Malone 				newsize = sizeof(uintval);
3511ce1a53dSJim Pirzyk 				break;
3521ce1a53dSJim Pirzyk 			case CTLTYPE_LONG:
353e267e00eSXin LI 				longval = strtol(newvalstr, &endptr, 0);
3541ce1a53dSJim Pirzyk 				newval = &longval;
35521e1f596SDavid Malone 				newsize = sizeof(longval);
3561ce1a53dSJim Pirzyk 				break;
3571ce1a53dSJim Pirzyk 			case CTLTYPE_ULONG:
358e267e00eSXin LI 				ulongval = strtoul(newvalstr, &endptr, 0);
3591ce1a53dSJim Pirzyk 				newval = &ulongval;
36021e1f596SDavid Malone 				newsize = sizeof(ulongval);
3611d86b91cSPoul-Henning Kamp 				break;
3621d86b91cSPoul-Henning Kamp 			case CTLTYPE_STRING:
363e267e00eSXin LI 				newval = newvalstr;
3641d86b91cSPoul-Henning Kamp 				break;
365cbc134adSMatthew D Fleming 			case CTLTYPE_S64:
366e267e00eSXin LI 				i64val = strtoimax(newvalstr, &endptr, 0);
367cbc134adSMatthew D Fleming 				newval = &i64val;
368cbc134adSMatthew D Fleming 				newsize = sizeof(i64val);
369cbc134adSMatthew D Fleming 				break;
370cbc134adSMatthew D Fleming 			case CTLTYPE_U64:
371e267e00eSXin LI 				u64val = strtoumax(newvalstr, &endptr, 0);
372cbc134adSMatthew D Fleming 				newval = &u64val;
373cbc134adSMatthew D Fleming 				newsize = sizeof(u64val);
374dea673e9SRodney W. Grimes 				break;
3751d86b91cSPoul-Henning Kamp 			default:
376e267e00eSXin LI 				/* NOTREACHED */
377e267e00eSXin LI 				abort();
378e267e00eSXin LI 		}
379e267e00eSXin LI 
380e267e00eSXin LI 		if (errno != 0 || endptr == newvalstr ||
381e267e00eSXin LI 		    (endptr != NULL && *endptr != '\0')) {
382e267e00eSXin LI 			warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE],
383e267e00eSXin LI 			    newvalstr, line);
384da178c77SXin LI 			return (1);
385dea673e9SRodney W. Grimes 		}
3861d86b91cSPoul-Henning Kamp 
3871d86b91cSPoul-Henning Kamp 		i = show_var(mib, len);
3881d86b91cSPoul-Henning Kamp 		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
3891d86b91cSPoul-Henning Kamp 			if (!i && !bflag)
3901d86b91cSPoul-Henning Kamp 				putchar('\n');
391dea673e9SRodney W. Grimes 			switch (errno) {
392dea673e9SRodney W. Grimes 			case EOPNOTSUPP:
393da178c77SXin LI 				warnx("%s: value is not available%s",
394da178c77SXin LI 					string, line);
395da178c77SXin LI 				return (1);
396dea673e9SRodney W. Grimes 			case ENOTDIR:
397da178c77SXin LI 				warnx("%s: specification is incomplete%s",
398da178c77SXin LI 					string, line);
399da178c77SXin LI 				return (1);
400dea673e9SRodney W. Grimes 			case ENOMEM:
401da178c77SXin LI 				warnx("%s: type is unknown to this program%s",
402da178c77SXin LI 					string, line);
403da178c77SXin LI 				return (1);
404dea673e9SRodney W. Grimes 			default:
405da178c77SXin LI 				warn("%s%s", string, line);
406da178c77SXin LI 				return (1);
407dea673e9SRodney W. Grimes 			}
408dea673e9SRodney W. Grimes 		}
4091d86b91cSPoul-Henning Kamp 		if (!bflag)
4101d86b91cSPoul-Henning Kamp 			printf(" -> ");
4111d86b91cSPoul-Henning Kamp 		i = nflag;
4121d86b91cSPoul-Henning Kamp 		nflag = 1;
4131d86b91cSPoul-Henning Kamp 		j = show_var(mib, len);
4141d86b91cSPoul-Henning Kamp 		if (!j && !bflag)
4151d86b91cSPoul-Henning Kamp 			putchar('\n');
4161d86b91cSPoul-Henning Kamp 		nflag = i;
417dea673e9SRodney W. Grimes 	}
418da178c77SXin LI 
419da178c77SXin LI 	return (0);
420da178c77SXin LI }
421da178c77SXin LI 
422da178c77SXin LI static int
423da178c77SXin LI parsefile(const char *filename)
424da178c77SXin LI {
425da178c77SXin LI 	FILE *file;
426da178c77SXin LI 	char line[BUFSIZ], *p, *pq, *pdq;
427da178c77SXin LI 	int warncount = 0, lineno = 0;
428da178c77SXin LI 
429da178c77SXin LI 	file = fopen(filename, "r");
430da178c77SXin LI 	if (file == NULL)
431da178c77SXin LI 		err(EX_NOINPUT, "%s", filename);
432da178c77SXin LI 	while (fgets(line, sizeof(line), file) != NULL) {
433da178c77SXin LI 		lineno++;
434da178c77SXin LI 		p = line;
435da178c77SXin LI 		pq = strchr(line, '\'');
436da178c77SXin LI 		pdq = strchr(line, '\"');
437da178c77SXin LI 		/* Replace the first # with \0. */
438da178c77SXin LI 		while((p = strchr(p, '#')) != NULL) {
439da178c77SXin LI 			if (pq != NULL && p > pq) {
440da178c77SXin LI 				if ((p = strchr(pq+1, '\'')) != NULL)
441da178c77SXin LI 					*(++p) = '\0';
442da178c77SXin LI 				break;
443da178c77SXin LI 			} else if (pdq != NULL && p > pdq) {
444da178c77SXin LI 				if ((p = strchr(pdq+1, '\"')) != NULL)
445da178c77SXin LI 					*(++p) = '\0';
446da178c77SXin LI 				break;
447da178c77SXin LI 			} else if (p == line || *(p-1) != '\\') {
448da178c77SXin LI 				*p = '\0';
449da178c77SXin LI 				break;
450da178c77SXin LI 			}
451da178c77SXin LI 			p++;
452da178c77SXin LI 		}
453da178c77SXin LI 		/* Trim spaces */
454da178c77SXin LI 		p = line + strlen(line) - 1;
455da178c77SXin LI 		while (p >= line && isspace((int)*p)) {
456da178c77SXin LI 			*p = '\0';
457da178c77SXin LI 			p--;
458da178c77SXin LI 		}
459da178c77SXin LI 		p = line;
460da178c77SXin LI 		while (isspace((int)*p))
461da178c77SXin LI 			p++;
462da178c77SXin LI 		if (*p == '\0')
463da178c77SXin LI 			continue;
464da178c77SXin LI 		else
465da178c77SXin LI 			warncount += parse(p, lineno);
466da178c77SXin LI 	}
467da178c77SXin LI 	fclose(file);
468da178c77SXin LI 
469da178c77SXin LI 	return (warncount);
470dea673e9SRodney W. Grimes }
471dea673e9SRodney W. Grimes 
4721d86b91cSPoul-Henning Kamp /* These functions will dump out various interesting structures. */
473dea673e9SRodney W. Grimes 
4741d86b91cSPoul-Henning Kamp static int
47559101c5dSJohn Baldwin S_clockinfo(size_t l2, void *p)
4761d86b91cSPoul-Henning Kamp {
4771d86b91cSPoul-Henning Kamp 	struct clockinfo *ci = (struct clockinfo*)p;
47821e1f596SDavid Malone 
479996076bbSAlfred Perlstein 	if (l2 != sizeof(*ci)) {
48059101c5dSJohn Baldwin 		warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci));
4816b6b665bSBruce Evans 		return (1);
482996076bbSAlfred Perlstein 	}
48345817aaaSDag-Erling Smørgrav 	printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
48445817aaaSDag-Erling Smørgrav 		"{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
485b35c8f28SPoul-Henning Kamp 		ci->hz, ci->tick, ci->profhz, ci->stathz);
4861d86b91cSPoul-Henning Kamp 	return (0);
487dea673e9SRodney W. Grimes }
488dea673e9SRodney W. Grimes 
4891d86b91cSPoul-Henning Kamp static int
49059101c5dSJohn Baldwin S_loadavg(size_t l2, void *p)
4911d86b91cSPoul-Henning Kamp {
4921d86b91cSPoul-Henning Kamp 	struct loadavg *tv = (struct loadavg*)p;
4931d86b91cSPoul-Henning Kamp 
494996076bbSAlfred Perlstein 	if (l2 != sizeof(*tv)) {
49559101c5dSJohn Baldwin 		warnx("S_loadavg %zu != %zu", l2, sizeof(*tv));
4966b6b665bSBruce Evans 		return (1);
497996076bbSAlfred Perlstein 	}
49845817aaaSDag-Erling Smørgrav 	printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
4991d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[0]/(double)tv->fscale,
5001d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[1]/(double)tv->fscale,
5011d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[2]/(double)tv->fscale);
5021d86b91cSPoul-Henning Kamp 	return (0);
503dea673e9SRodney W. Grimes }
504dea673e9SRodney W. Grimes 
5051d86b91cSPoul-Henning Kamp static int
50659101c5dSJohn Baldwin S_timeval(size_t l2, void *p)
5071d86b91cSPoul-Henning Kamp {
5081d86b91cSPoul-Henning Kamp 	struct timeval *tv = (struct timeval*)p;
509c2deb608SBruce Evans 	time_t tv_sec;
5101d86b91cSPoul-Henning Kamp 	char *p1, *p2;
511dea673e9SRodney W. Grimes 
512996076bbSAlfred Perlstein 	if (l2 != sizeof(*tv)) {
51359101c5dSJohn Baldwin 		warnx("S_timeval %zu != %zu", l2, sizeof(*tv));
5146b6b665bSBruce Evans 		return (1);
515996076bbSAlfred Perlstein 	}
516db87e2dcSJohn Hay 	printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
517db87e2dcSJohn Hay 		"{ sec = %jd, usec = %ld } ",
518db87e2dcSJohn Hay 		(intmax_t)tv->tv_sec, tv->tv_usec);
519c2deb608SBruce Evans 	tv_sec = tv->tv_sec;
520c2deb608SBruce Evans 	p1 = strdup(ctime(&tv_sec));
5211d86b91cSPoul-Henning Kamp 	for (p2=p1; *p2 ; p2++)
5221d86b91cSPoul-Henning Kamp 		if (*p2 == '\n')
5231d86b91cSPoul-Henning Kamp 			*p2 = '\0';
5241d86b91cSPoul-Henning Kamp 	fputs(p1, stdout);
525f2359a24SRebecca Cran 	free(p1);
5261d86b91cSPoul-Henning Kamp 	return (0);
5271d86b91cSPoul-Henning Kamp }
5281d86b91cSPoul-Henning Kamp 
5291d86b91cSPoul-Henning Kamp static int
53059101c5dSJohn Baldwin S_vmtotal(size_t l2, void *p)
531f7550ecfSMatthew Dillon {
532f7550ecfSMatthew Dillon 	struct vmtotal *v = (struct vmtotal *)p;
533654e22e7SMatthew Dillon 	int pageKilo = getpagesize() / 1024;
534f7550ecfSMatthew Dillon 
535f7550ecfSMatthew Dillon 	if (l2 != sizeof(*v)) {
53659101c5dSJohn Baldwin 		warnx("S_vmtotal %zu != %zu", l2, sizeof(*v));
5376b6b665bSBruce Evans 		return (1);
538f7550ecfSMatthew Dillon 	}
539f7550ecfSMatthew Dillon 
540654e22e7SMatthew Dillon 	printf(
541654e22e7SMatthew Dillon 	    "\nSystem wide totals computed every five seconds:"
542654e22e7SMatthew Dillon 	    " (values in kilobytes)\n");
543f7550ecfSMatthew Dillon 	printf("===============================================\n");
544654e22e7SMatthew Dillon 	printf(
545bad4d172SRuslan Ermilov 	    "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
546bad4d172SRuslan Ermilov 	    "%hd Sleep: %hd)\n",
547f7550ecfSMatthew Dillon 	    v->t_rq, v->t_dw, v->t_pw, v->t_sl);
548654e22e7SMatthew Dillon 	printf(
54913e86ef7SMarko Zec 	    "Virtual Memory:\t\t(Total: %dK Active: %dK)\n",
550bad4d172SRuslan Ermilov 	    v->t_vm * pageKilo, v->t_avm * pageKilo);
55113e86ef7SMarko Zec 	printf("Real Memory:\t\t(Total: %dK Active: %dK)\n",
552bad4d172SRuslan Ermilov 	    v->t_rm * pageKilo, v->t_arm * pageKilo);
553bad4d172SRuslan Ermilov 	printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n",
554bad4d172SRuslan Ermilov 	    v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
555bad4d172SRuslan Ermilov 	printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
556bad4d172SRuslan Ermilov 	    v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
55759101c5dSJohn Baldwin 	printf("Free Memory:\t%dK", v->t_free * pageKilo);
558f7550ecfSMatthew Dillon 
559f7550ecfSMatthew Dillon 	return (0);
560f7550ecfSMatthew Dillon }
561f7550ecfSMatthew Dillon 
5627d8312ccSJohn Baldwin #ifdef __amd64__
5637d8312ccSJohn Baldwin #define efi_next_descriptor(ptr, size) \
5647d8312ccSJohn Baldwin 	((struct efi_md *)(((uint8_t *) ptr) + size))
5657d8312ccSJohn Baldwin 
5667d8312ccSJohn Baldwin static int
5677d8312ccSJohn Baldwin S_efi_map(size_t l2, void *p)
5687d8312ccSJohn Baldwin {
5697d8312ccSJohn Baldwin 	struct efi_map_header *efihdr;
5707d8312ccSJohn Baldwin 	struct efi_md *map;
5717d8312ccSJohn Baldwin 	const char *type;
5727d8312ccSJohn Baldwin 	size_t efisz;
5737d8312ccSJohn Baldwin 	int ndesc, i;
5747d8312ccSJohn Baldwin 
5757d8312ccSJohn Baldwin 	static const char *types[] = {
5767d8312ccSJohn Baldwin 		"Reserved",
5777d8312ccSJohn Baldwin 		"LoaderCode",
5787d8312ccSJohn Baldwin 		"LoaderData",
5797d8312ccSJohn Baldwin 		"BootServicesCode",
5807d8312ccSJohn Baldwin 		"BootServicesData",
5817d8312ccSJohn Baldwin 		"RuntimeServicesCode",
5827d8312ccSJohn Baldwin 		"RuntimeServicesData",
5837d8312ccSJohn Baldwin 		"ConventionalMemory",
5847d8312ccSJohn Baldwin 		"UnusableMemory",
5857d8312ccSJohn Baldwin 		"ACPIReclaimMemory",
5867d8312ccSJohn Baldwin 		"ACPIMemoryNVS",
5877d8312ccSJohn Baldwin 		"MemoryMappedIO",
5887d8312ccSJohn Baldwin 		"MemoryMappedIOPortSpace",
5897d8312ccSJohn Baldwin 		"PalCode"
5907d8312ccSJohn Baldwin 	};
5917d8312ccSJohn Baldwin 
5927d8312ccSJohn Baldwin 	/*
5937d8312ccSJohn Baldwin 	 * Memory map data provided by UEFI via the GetMemoryMap
5947d8312ccSJohn Baldwin 	 * Boot Services API.
5957d8312ccSJohn Baldwin 	 */
5967d8312ccSJohn Baldwin 	if (l2 < sizeof(*efihdr)) {
5977d8312ccSJohn Baldwin 		warnx("S_efi_map length less than header");
5987d8312ccSJohn Baldwin 		return (1);
5997d8312ccSJohn Baldwin 	}
6007d8312ccSJohn Baldwin 	efihdr = p;
6017d8312ccSJohn Baldwin 	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
6027d8312ccSJohn Baldwin 	map = (struct efi_md *)((uint8_t *)efihdr + efisz);
6037d8312ccSJohn Baldwin 
6047d8312ccSJohn Baldwin 	if (efihdr->descriptor_size == 0)
6057d8312ccSJohn Baldwin 		return (0);
6067d8312ccSJohn Baldwin 	if (l2 != efisz + efihdr->memory_size) {
6077d8312ccSJohn Baldwin 		warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz +
6087d8312ccSJohn Baldwin 		    efihdr->memory_size);
6097d8312ccSJohn Baldwin 		return (1);
6107d8312ccSJohn Baldwin 	}
6117d8312ccSJohn Baldwin 	ndesc = efihdr->memory_size / efihdr->descriptor_size;
6127d8312ccSJohn Baldwin 
6137d8312ccSJohn Baldwin 	printf("\n%23s %12s %12s %8s %4s",
6147d8312ccSJohn Baldwin 	    "Type", "Physical", "Virtual", "#Pages", "Attr");
6157d8312ccSJohn Baldwin 
6167d8312ccSJohn Baldwin 	for (i = 0; i < ndesc; i++,
6177d8312ccSJohn Baldwin 	    map = efi_next_descriptor(map, efihdr->descriptor_size)) {
6187d8312ccSJohn Baldwin 		if (map->md_type <= EFI_MD_TYPE_PALCODE)
6197d8312ccSJohn Baldwin 			type = types[map->md_type];
6207d8312ccSJohn Baldwin 		else
6217d8312ccSJohn Baldwin 			type = "<INVALID>";
6227d8312ccSJohn Baldwin 		printf("\n%23s %012lx %12p %08lx ", type, map->md_phys,
6237d8312ccSJohn Baldwin 		    map->md_virt, map->md_pages);
6247d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_UC)
6257d8312ccSJohn Baldwin 			printf("UC ");
6267d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WC)
6277d8312ccSJohn Baldwin 			printf("WC ");
6287d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WT)
6297d8312ccSJohn Baldwin 			printf("WT ");
6307d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WB)
6317d8312ccSJohn Baldwin 			printf("WB ");
6327d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_UCE)
6337d8312ccSJohn Baldwin 			printf("UCE ");
6347d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WP)
6357d8312ccSJohn Baldwin 			printf("WP ");
6367d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_RP)
6377d8312ccSJohn Baldwin 			printf("RP ");
6387d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_XP)
6397d8312ccSJohn Baldwin 			printf("XP ");
6407d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_RT)
6417d8312ccSJohn Baldwin 			printf("RUNTIME");
6427d8312ccSJohn Baldwin 	}
6437d8312ccSJohn Baldwin 	return (0);
6447d8312ccSJohn Baldwin }
6457d8312ccSJohn Baldwin #endif
6467d8312ccSJohn Baldwin 
64789871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
64889871cdeSJohn Baldwin static int
64959101c5dSJohn Baldwin S_bios_smap_xattr(size_t l2, void *p)
65089871cdeSJohn Baldwin {
65189871cdeSJohn Baldwin 	struct bios_smap_xattr *smap, *end;
65289871cdeSJohn Baldwin 
65389871cdeSJohn Baldwin 	if (l2 % sizeof(*smap) != 0) {
65459101c5dSJohn Baldwin 		warnx("S_bios_smap_xattr %zu is not a multiple of %zu", l2,
65589871cdeSJohn Baldwin 		    sizeof(*smap));
65689871cdeSJohn Baldwin 		return (1);
65789871cdeSJohn Baldwin 	}
65889871cdeSJohn Baldwin 
65989871cdeSJohn Baldwin 	end = (struct bios_smap_xattr *)((char *)p + l2);
66089871cdeSJohn Baldwin 	for (smap = p; smap < end; smap++)
66189871cdeSJohn Baldwin 		printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx",
66289871cdeSJohn Baldwin 		    smap->type, smap->xattr, (uintmax_t)smap->base,
66389871cdeSJohn Baldwin 		    (uintmax_t)smap->length);
66489871cdeSJohn Baldwin 	return (0);
66589871cdeSJohn Baldwin }
66689871cdeSJohn Baldwin #endif
66789871cdeSJohn Baldwin 
668f7550ecfSMatthew Dillon static int
669e267e00eSXin LI strIKtoi(const char *str, char **endptrp)
670d45564dcSHajimu UMEMOTO {
671e267e00eSXin LI 	int kelv;
672d45564dcSHajimu UMEMOTO 	float temp;
673e267e00eSXin LI 	size_t len;
674a7b5ad27SEd Schouten 	const char *p;
675d45564dcSHajimu UMEMOTO 
676e267e00eSXin LI 	assert(errno == 0);
677e267e00eSXin LI 
678e267e00eSXin LI 	len = strlen(str);
679e267e00eSXin LI 	/* caller already checked this */
680e267e00eSXin LI 	assert(len > 0);
681e267e00eSXin LI 
682d45564dcSHajimu UMEMOTO 	p = &str[len - 1];
683d45564dcSHajimu UMEMOTO 	if (*p == 'C' || *p == 'F') {
684e267e00eSXin LI 		temp = strtof(str, endptrp);
685689c8e8bSXin LI 		if (*endptrp != str && *endptrp == p && errno == 0) {
686d45564dcSHajimu UMEMOTO 			if (*p == 'F')
687d45564dcSHajimu UMEMOTO 				temp = (temp - 32) * 5 / 9;
688689c8e8bSXin LI 			*endptrp = NULL;
689e267e00eSXin LI 			return (temp * 10 + 2732);
690d45564dcSHajimu UMEMOTO 		}
691e267e00eSXin LI 	} else {
692e267e00eSXin LI 		kelv = (int)strtol(str, endptrp, 10);
693689c8e8bSXin LI 		if (*endptrp != str && *endptrp == p && errno == 0) {
694689c8e8bSXin LI 			*endptrp = NULL;
695e267e00eSXin LI 			return (kelv);
696e267e00eSXin LI 		}
697689c8e8bSXin LI 	}
698e267e00eSXin LI 
699e267e00eSXin LI 	errno = ERANGE;
700e267e00eSXin LI 	return (0);
701d45564dcSHajimu UMEMOTO }
702d45564dcSHajimu UMEMOTO 
7031d86b91cSPoul-Henning Kamp /*
7041d86b91cSPoul-Henning Kamp  * These functions uses a presently undocumented interface to the kernel
7051d86b91cSPoul-Henning Kamp  * to walk the tree and get the type so it can print the value.
7061d86b91cSPoul-Henning Kamp  * This interface is under work and consideration, and should probably
7071d86b91cSPoul-Henning Kamp  * be killed with a big axe by the first person who can find the time.
7081d86b91cSPoul-Henning Kamp  * (be aware though, that the proper interface isn't as obvious as it
7091d86b91cSPoul-Henning Kamp  * may seem, there are various conflicting requirements.
7101d86b91cSPoul-Henning Kamp  */
7111d86b91cSPoul-Henning Kamp 
7121d86b91cSPoul-Henning Kamp static int
713c58f8df6SXin LI name2oid(const char *name, int *oidp)
7141d86b91cSPoul-Henning Kamp {
7151d86b91cSPoul-Henning Kamp 	int oid[2];
716dbf9b92fSDoug Rabson 	int i;
717dbf9b92fSDoug Rabson 	size_t j;
7181d86b91cSPoul-Henning Kamp 
7191d86b91cSPoul-Henning Kamp 	oid[0] = 0;
7201d86b91cSPoul-Henning Kamp 	oid[1] = 3;
7211d86b91cSPoul-Henning Kamp 
7221d86b91cSPoul-Henning Kamp 	j = CTL_MAXNAME * sizeof(int);
7231d86b91cSPoul-Henning Kamp 	i = sysctl(oid, 2, oidp, &j, name, strlen(name));
7241d86b91cSPoul-Henning Kamp 	if (i < 0)
72521e1f596SDavid Malone 		return (i);
7261d86b91cSPoul-Henning Kamp 	j /= sizeof(int);
7271d86b91cSPoul-Henning Kamp 	return (j);
7281d86b91cSPoul-Henning Kamp }
7291d86b91cSPoul-Henning Kamp 
7301d86b91cSPoul-Henning Kamp static int
7311d86b91cSPoul-Henning Kamp oidfmt(int *oid, int len, char *fmt, u_int *kind)
7321d86b91cSPoul-Henning Kamp {
7331d86b91cSPoul-Henning Kamp 	int qoid[CTL_MAXNAME+2];
7341d86b91cSPoul-Henning Kamp 	u_char buf[BUFSIZ];
735dbf9b92fSDoug Rabson 	int i;
736dbf9b92fSDoug Rabson 	size_t j;
7371d86b91cSPoul-Henning Kamp 
7381d86b91cSPoul-Henning Kamp 	qoid[0] = 0;
7391d86b91cSPoul-Henning Kamp 	qoid[1] = 4;
7401d86b91cSPoul-Henning Kamp 	memcpy(qoid + 2, oid, len * sizeof(int));
7411d86b91cSPoul-Henning Kamp 
74231fb4661SDima Dorfman 	j = sizeof(buf);
7431d86b91cSPoul-Henning Kamp 	i = sysctl(qoid, len + 2, buf, &j, 0, 0);
7441d86b91cSPoul-Henning Kamp 	if (i)
7456d7a8f6cSUlrich Spörlein 		err(1, "sysctl fmt %d %zu %d", i, j, errno);
7461d86b91cSPoul-Henning Kamp 
7471d86b91cSPoul-Henning Kamp 	if (kind)
7481d86b91cSPoul-Henning Kamp 		*kind = *(u_int *)buf;
7491d86b91cSPoul-Henning Kamp 
7501d86b91cSPoul-Henning Kamp 	if (fmt)
7511d86b91cSPoul-Henning Kamp 		strcpy(fmt, (char *)(buf + sizeof(u_int)));
75221e1f596SDavid Malone 	return (0);
7531d86b91cSPoul-Henning Kamp }
7541d86b91cSPoul-Henning Kamp 
75560cf2c12SLuigi Rizzo /*
7561d86b91cSPoul-Henning Kamp  * This formats and outputs the value of one variable
7571d86b91cSPoul-Henning Kamp  *
7581d86b91cSPoul-Henning Kamp  * Returns zero if anything was actually output.
7591d86b91cSPoul-Henning Kamp  * Returns one if didn't know what to do with this.
7601d86b91cSPoul-Henning Kamp  * Return minus one if we had errors.
7611d86b91cSPoul-Henning Kamp  */
7621d86b91cSPoul-Henning Kamp static int
7631d86b91cSPoul-Henning Kamp show_var(int *oid, int nlen)
7641d86b91cSPoul-Henning Kamp {
765ccf25977SRuslan Ermilov 	u_char buf[BUFSIZ], *val, *oval, *p;
766403c7f59SAlfred Perlstein 	char name[BUFSIZ], fmt[BUFSIZ];
767fd8c668aSDavid Malone 	const char *sep, *sep1;
7681d86b91cSPoul-Henning Kamp 	int qoid[CTL_MAXNAME+2];
76921e1f596SDavid Malone 	uintmax_t umv;
77021e1f596SDavid Malone 	intmax_t mv;
771f8e4b4efSMatthew D Fleming 	int i, hexlen, sign, ctltype;
77241e419cbSDavid Malone 	size_t intlen;
773dbf9b92fSDoug Rabson 	size_t j, len;
7741d86b91cSPoul-Henning Kamp 	u_int kind;
77559101c5dSJohn Baldwin 	int (*func)(size_t, void *);
7761d86b91cSPoul-Henning Kamp 
7776d7a8f6cSUlrich Spörlein 	/* Silence GCC. */
7786d7a8f6cSUlrich Spörlein 	umv = mv = intlen = 0;
7796d7a8f6cSUlrich Spörlein 
7809f98e452SMatthew N. Dodd 	bzero(buf, BUFSIZ);
781403c7f59SAlfred Perlstein 	bzero(fmt, BUFSIZ);
7829f98e452SMatthew N. Dodd 	bzero(name, BUFSIZ);
78381e7454aSDag-Erling Smørgrav 	qoid[0] = 0;
78481e7454aSDag-Erling Smørgrav 	memcpy(qoid + 2, oid, nlen * sizeof(int));
78581e7454aSDag-Erling Smørgrav 
78681e7454aSDag-Erling Smørgrav 	qoid[1] = 1;
78731fb4661SDima Dorfman 	j = sizeof(name);
78881e7454aSDag-Erling Smørgrav 	i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
78981e7454aSDag-Erling Smørgrav 	if (i || !j)
7906d7a8f6cSUlrich Spörlein 		err(1, "sysctl name %d %zu %d", i, j, errno);
79181e7454aSDag-Erling Smørgrav 
792403c7f59SAlfred Perlstein 	oidfmt(oid, nlen, fmt, &kind);
793403c7f59SAlfred Perlstein 	/* if Wflag then only list sysctls that are writeable and not stats. */
794403c7f59SAlfred Perlstein 	if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0))
795403c7f59SAlfred Perlstein 		return 1;
796403c7f59SAlfred Perlstein 
797403c7f59SAlfred Perlstein 	/* if Tflag then only list sysctls that are tuneables. */
798403c7f59SAlfred Perlstein 	if (Tflag && (kind & CTLFLAG_TUN) == 0)
799403c7f59SAlfred Perlstein 		return 1;
800403c7f59SAlfred Perlstein 
801ca5fac55SDag-Erling Smørgrav 	if (Nflag) {
802ca5fac55SDag-Erling Smørgrav 		printf("%s", name);
803ca5fac55SDag-Erling Smørgrav 		return (0);
804ca5fac55SDag-Erling Smørgrav 	}
805ca5fac55SDag-Erling Smørgrav 
806d0b8aabbSAnton Berezin 	if (eflag)
807d0b8aabbSAnton Berezin 		sep = "=";
808d0b8aabbSAnton Berezin 	else
809d0b8aabbSAnton Berezin 		sep = ": ";
810d0b8aabbSAnton Berezin 
8116105f815SLuigi Rizzo 	if (dflag) {	/* just print description */
8126105f815SLuigi Rizzo 		qoid[1] = 5;
8136105f815SLuigi Rizzo 		j = sizeof(buf);
8146105f815SLuigi Rizzo 		i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
8156105f815SLuigi Rizzo 		if (!nflag)
8166105f815SLuigi Rizzo 			printf("%s%s", name, sep);
8176105f815SLuigi Rizzo 		printf("%s", buf);
8186105f815SLuigi Rizzo 		return (0);
8196105f815SLuigi Rizzo 	}
8201d86b91cSPoul-Henning Kamp 	/* find an estimate of how much we need for this var */
821*75820005SJohn-Mark Gurney 	if (Bflag)
822*75820005SJohn-Mark Gurney 		j = Bflag;
823*75820005SJohn-Mark Gurney 	else {
8241d86b91cSPoul-Henning Kamp 		j = 0;
8251d86b91cSPoul-Henning Kamp 		i = sysctl(oid, nlen, 0, &j, 0, 0);
8261d86b91cSPoul-Henning Kamp 		j += j; /* we want to be sure :-) */
827*75820005SJohn-Mark Gurney 	}
8281d86b91cSPoul-Henning Kamp 
829ccf25977SRuslan Ermilov 	val = oval = malloc(j + 1);
830ccf25977SRuslan Ermilov 	if (val == NULL) {
831ccf25977SRuslan Ermilov 		warnx("malloc failed");
8326b6b665bSBruce Evans 		return (1);
833ccf25977SRuslan Ermilov 	}
83404006eabSHans Petter Selasky 	ctltype = (kind & CTLTYPE);
8351d86b91cSPoul-Henning Kamp 	len = j;
8361d86b91cSPoul-Henning Kamp 	i = sysctl(oid, nlen, val, &len, 0, 0);
83704006eabSHans Petter Selasky 	if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) {
838ccf25977SRuslan Ermilov 		free(oval);
8391d86b91cSPoul-Henning Kamp 		return (1);
840ccf25977SRuslan Ermilov 	}
8411d86b91cSPoul-Henning Kamp 
8421d86b91cSPoul-Henning Kamp 	if (bflag) {
8431d86b91cSPoul-Henning Kamp 		fwrite(val, 1, len, stdout);
844ccf25977SRuslan Ermilov 		free(oval);
8451d86b91cSPoul-Henning Kamp 		return (0);
8461d86b91cSPoul-Henning Kamp 	}
84776d3dc52SAndrey A. Chernov 	val[len] = '\0';
8481d86b91cSPoul-Henning Kamp 	p = val;
849cbc134adSMatthew D Fleming 	sign = ctl_sign[ctltype];
850cbc134adSMatthew D Fleming 	intlen = ctl_size[ctltype];
851cbc134adSMatthew D Fleming 
852f8e4b4efSMatthew D Fleming 	switch (ctltype) {
853f8e4b4efSMatthew D Fleming 	case CTLTYPE_STRING:
8541d86b91cSPoul-Henning Kamp 		if (!nflag)
855d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
8566d7a8f6cSUlrich Spörlein 		printf("%.*s", (int)len, p);
857ccf25977SRuslan Ermilov 		free(oval);
8581d86b91cSPoul-Henning Kamp 		return (0);
8591d86b91cSPoul-Henning Kamp 
860f8e4b4efSMatthew D Fleming 	case CTLTYPE_INT:
861f8e4b4efSMatthew D Fleming 	case CTLTYPE_UINT:
862f8e4b4efSMatthew D Fleming 	case CTLTYPE_LONG:
863f8e4b4efSMatthew D Fleming 	case CTLTYPE_ULONG:
864cbc134adSMatthew D Fleming 	case CTLTYPE_S64:
865cbc134adSMatthew D Fleming 	case CTLTYPE_U64:
866dbf9b92fSDoug Rabson 		if (!nflag)
867d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
868e37d2b30SDavid Malone 		hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
869fd8c668aSDavid Malone 		sep1 = "";
87041e419cbSDavid Malone 		while (len >= intlen) {
871f8e4b4efSMatthew D Fleming 			switch (kind & CTLTYPE) {
872f8e4b4efSMatthew D Fleming 			case CTLTYPE_INT:
873f8e4b4efSMatthew D Fleming 			case CTLTYPE_UINT:
874e37d2b30SDavid Malone 				umv = *(u_int *)p;
875e37d2b30SDavid Malone 				mv = *(int *)p;
87641e419cbSDavid Malone 				break;
877f8e4b4efSMatthew D Fleming 			case CTLTYPE_LONG:
878f8e4b4efSMatthew D Fleming 			case CTLTYPE_ULONG:
879e37d2b30SDavid Malone 				umv = *(u_long *)p;
880e37d2b30SDavid Malone 				mv = *(long *)p;
88141e419cbSDavid Malone 				break;
882cbc134adSMatthew D Fleming 			case CTLTYPE_S64:
883cbc134adSMatthew D Fleming 			case CTLTYPE_U64:
884cbc134adSMatthew D Fleming 				umv = *(uint64_t *)p;
885cbc134adSMatthew D Fleming 				mv = *(int64_t *)p;
88641e419cbSDavid Malone 				break;
88741e419cbSDavid Malone 			}
888fd8c668aSDavid Malone 			fputs(sep1, stdout);
889f8e4b4efSMatthew D Fleming 			if (xflag)
890e37d2b30SDavid Malone 				printf("%#0*jx", hexlen, umv);
891f8e4b4efSMatthew D Fleming 			else if (!sign)
892f8e4b4efSMatthew D Fleming 				printf(hflag ? "%'ju" : "%ju", umv);
89341e419cbSDavid Malone 			else if (fmt[1] == 'K') {
894e37d2b30SDavid Malone 				if (mv < 0)
89521e1f596SDavid Malone 					printf("%jd", mv);
8969701cd40SJohn Baldwin 				else
89721e1f596SDavid Malone 					printf("%.1fC", (mv - 2732.0) / 10);
898c591d41fSPeter Wemm 			} else
899fd8c668aSDavid Malone 				printf(hflag ? "%'jd" : "%jd", mv);
900fd8c668aSDavid Malone 			sep1 = " ";
90141e419cbSDavid Malone 			len -= intlen;
90241e419cbSDavid Malone 			p += intlen;
903aa02fb57SPoul-Henning Kamp 		}
904ccf25977SRuslan Ermilov 		free(oval);
905dbf9b92fSDoug Rabson 		return (0);
906dbf9b92fSDoug Rabson 
907f8e4b4efSMatthew D Fleming 	case CTLTYPE_OPAQUE:
9081d86b91cSPoul-Henning Kamp 		i = 0;
909a89ab9bbSDag-Erling Smørgrav 		if (strcmp(fmt, "S,clockinfo") == 0)
910a89ab9bbSDag-Erling Smørgrav 			func = S_clockinfo;
911a89ab9bbSDag-Erling Smørgrav 		else if (strcmp(fmt, "S,timeval") == 0)
912a89ab9bbSDag-Erling Smørgrav 			func = S_timeval;
913a89ab9bbSDag-Erling Smørgrav 		else if (strcmp(fmt, "S,loadavg") == 0)
914a89ab9bbSDag-Erling Smørgrav 			func = S_loadavg;
915f7550ecfSMatthew Dillon 		else if (strcmp(fmt, "S,vmtotal") == 0)
916f7550ecfSMatthew Dillon 			func = S_vmtotal;
9177d8312ccSJohn Baldwin #ifdef __amd64__
9187d8312ccSJohn Baldwin 		else if (strcmp(fmt, "S,efi_map_header") == 0)
9197d8312ccSJohn Baldwin 			func = S_efi_map;
9207d8312ccSJohn Baldwin #endif
92189871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
92289871cdeSJohn Baldwin 		else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
92389871cdeSJohn Baldwin 			func = S_bios_smap_xattr;
92489871cdeSJohn Baldwin #endif
925a89ab9bbSDag-Erling Smørgrav 		else
926a89ab9bbSDag-Erling Smørgrav 			func = NULL;
9271d86b91cSPoul-Henning Kamp 		if (func) {
9281d86b91cSPoul-Henning Kamp 			if (!nflag)
929d0b8aabbSAnton Berezin 				printf("%s%s", name, sep);
93048cd487aSHartmut Brandt 			i = (*func)(len, p);
931ccf25977SRuslan Ermilov 			free(oval);
93248cd487aSHartmut Brandt 			return (i);
9331d86b91cSPoul-Henning Kamp 		}
9341d86b91cSPoul-Henning Kamp 		/* FALLTHROUGH */
935dea673e9SRodney W. Grimes 	default:
936ccf25977SRuslan Ermilov 		if (!oflag && !xflag) {
937ccf25977SRuslan Ermilov 			free(oval);
9381d86b91cSPoul-Henning Kamp 			return (1);
939ccf25977SRuslan Ermilov 		}
9401d86b91cSPoul-Henning Kamp 		if (!nflag)
941d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
9426d7a8f6cSUlrich Spörlein 		printf("Format:%s Length:%zu Dump:0x", fmt, len);
943a89ab9bbSDag-Erling Smørgrav 		while (len-- && (xflag || p < val + 16))
9441d86b91cSPoul-Henning Kamp 			printf("%02x", *p++);
945a89ab9bbSDag-Erling Smørgrav 		if (!xflag && len > 16)
9461d86b91cSPoul-Henning Kamp 			printf("...");
947ccf25977SRuslan Ermilov 		free(oval);
9481d86b91cSPoul-Henning Kamp 		return (0);
9491d86b91cSPoul-Henning Kamp 	}
950ccf25977SRuslan Ermilov 	free(oval);
9511d86b91cSPoul-Henning Kamp 	return (1);
952dea673e9SRodney W. Grimes }
953dea673e9SRodney W. Grimes 
9541d86b91cSPoul-Henning Kamp static int
9551d86b91cSPoul-Henning Kamp sysctl_all(int *oid, int len)
956dea673e9SRodney W. Grimes {
9571d86b91cSPoul-Henning Kamp 	int name1[22], name2[22];
958dbf9b92fSDoug Rabson 	int i, j;
959dbf9b92fSDoug Rabson 	size_t l1, l2;
960dea673e9SRodney W. Grimes 
9611d86b91cSPoul-Henning Kamp 	name1[0] = 0;
9621d86b91cSPoul-Henning Kamp 	name1[1] = 2;
9631d86b91cSPoul-Henning Kamp 	l1 = 2;
9641d86b91cSPoul-Henning Kamp 	if (len) {
9651d86b91cSPoul-Henning Kamp 		memcpy(name1+2, oid, len * sizeof(int));
9661d86b91cSPoul-Henning Kamp 		l1 += len;
9671d86b91cSPoul-Henning Kamp 	} else {
9681d86b91cSPoul-Henning Kamp 		name1[2] = 1;
9691d86b91cSPoul-Henning Kamp 		l1++;
9701d86b91cSPoul-Henning Kamp 	}
971a89ab9bbSDag-Erling Smørgrav 	for (;;) {
97231fb4661SDima Dorfman 		l2 = sizeof(name2);
9731d86b91cSPoul-Henning Kamp 		j = sysctl(name1, l1, name2, &l2, 0, 0);
974c1160fe4SBill Fumerola 		if (j < 0) {
9751d86b91cSPoul-Henning Kamp 			if (errno == ENOENT)
97621e1f596SDavid Malone 				return (0);
9771d86b91cSPoul-Henning Kamp 			else
9786d7a8f6cSUlrich Spörlein 				err(1, "sysctl(getnext) %d %zu", j, l2);
979c1160fe4SBill Fumerola 		}
9801d86b91cSPoul-Henning Kamp 
9811d86b91cSPoul-Henning Kamp 		l2 /= sizeof(int);
9821d86b91cSPoul-Henning Kamp 
983fd8c668aSDavid Malone 		if (len < 0 || l2 < (unsigned int)len)
98421e1f596SDavid Malone 			return (0);
9851d86b91cSPoul-Henning Kamp 
9861d86b91cSPoul-Henning Kamp 		for (i = 0; i < len; i++)
9871d86b91cSPoul-Henning Kamp 			if (name2[i] != oid[i])
98821e1f596SDavid Malone 				return (0);
9891d86b91cSPoul-Henning Kamp 
9901d86b91cSPoul-Henning Kamp 		i = show_var(name2, l2);
9911d86b91cSPoul-Henning Kamp 		if (!i && !bflag)
9921d86b91cSPoul-Henning Kamp 			putchar('\n');
9931d86b91cSPoul-Henning Kamp 
9941d86b91cSPoul-Henning Kamp 		memcpy(name1+2, name2, l2 * sizeof(int));
9951d86b91cSPoul-Henning Kamp 		l1 = 2 + l2;
9961d86b91cSPoul-Henning Kamp 	}
997dea673e9SRodney W. Grimes }
998