xref: /freebsd/sbin/sysctl/sysctl.c (revision ca587fdaacefd37fa5c2efd4766931897b8a831a)
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 
7475820005SJohn-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 
84aa255ef6SWarner Losh static int	strIKtoi(const char *, char **, const 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",
11575820005SJohn-Mark Gurney 	    "usage: sysctl [-bdehiNnoqTWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
11675820005SJohn-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 
13075820005SJohn-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;
14275820005SJohn-Mark Gurney 		case 'B':
14375820005SJohn-Mark Gurney 			Bflag = strtol(optarg, NULL, 0);
14475820005SJohn-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;
22875820005SJohn-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 	}
265*ca587fdaSBaptiste Daroussin 	/* Trim spaces */
266*ca587fdaSBaptiste Daroussin 	cp = bufp + strlen(bufp) - 1;
267*ca587fdaSBaptiste Daroussin 	while (cp >= bufp && isspace((int)*cp)) {
268*ca587fdaSBaptiste Daroussin 		*cp = '\0';
269*ca587fdaSBaptiste Daroussin 		cp--;
270*ca587fdaSBaptiste Daroussin 	}
2711d86b91cSPoul-Henning Kamp 	len = name2oid(bufp, mib);
2721d86b91cSPoul-Henning Kamp 
273f93d36fdSRobert Watson 	if (len < 0) {
27424b2aa32SGavin Atkinson 		if (iflag)
275da178c77SXin LI 			return (0);
276f93d36fdSRobert Watson 		if (qflag)
277da178c77SXin LI 			return (1);
278da178c77SXin LI 		else {
279da178c77SXin LI 			warn("unknown oid '%s'%s", bufp, line);
280da178c77SXin LI 			return (1);
281da178c77SXin LI 		}
282f93d36fdSRobert Watson 	}
2831d86b91cSPoul-Henning Kamp 
284da178c77SXin LI 	if (oidfmt(mib, len, fmt, &kind)) {
285da178c77SXin LI 		warn("couldn't find format of oid '%s'%s", bufp, line);
286da178c77SXin LI 		if (iflag)
287da178c77SXin LI 			return (1);
288da178c77SXin LI 		else
289da178c77SXin LI 			exit(1);
290da178c77SXin LI 	}
2911d86b91cSPoul-Henning Kamp 
292e267e00eSXin LI 	if (newvalstr == NULL || dflag) {
2931d86b91cSPoul-Henning Kamp 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
294b2680e20SMatthew N. Dodd 			if (dflag) {
295b2680e20SMatthew N. Dodd 				i = show_var(mib, len);
296b2680e20SMatthew N. Dodd 				if (!i && !bflag)
297b2680e20SMatthew N. Dodd 					putchar('\n');
298b2680e20SMatthew N. Dodd 			}
2991d86b91cSPoul-Henning Kamp 			sysctl_all(mib, len);
3001d86b91cSPoul-Henning Kamp 		} else {
3011d86b91cSPoul-Henning Kamp 			i = show_var(mib, len);
3021d86b91cSPoul-Henning Kamp 			if (!i && !bflag)
3031d86b91cSPoul-Henning Kamp 				putchar('\n');
304dea673e9SRodney W. Grimes 		}
3051d86b91cSPoul-Henning Kamp 	} else {
306da178c77SXin LI 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
307c6919e7fSEdward Tomasz Napierala 			warnx("oid '%s' isn't a leaf node%s", bufp, line);
308da178c77SXin LI 			return (1);
309da178c77SXin LI 		}
310dea673e9SRodney W. Grimes 
311ac8711d2SMike Silbersack 		if (!(kind & CTLFLAG_WR)) {
3129b4b73b7SMike Silbersack 			if (kind & CTLFLAG_TUN) {
3136f361351SXin LI 				warnx("oid '%s' is a read only tunable%s", bufp, line);
314da178c77SXin LI 				warnx("Tunable values are set in /boot/loader.conf");
315da178c77SXin LI 			} else
316da178c77SXin LI 				warnx("oid '%s' is read only%s", bufp, line);
317da178c77SXin LI 			return (1);
318ac8711d2SMike Silbersack 		}
319dea673e9SRodney W. Grimes 
320e267e00eSXin LI 		switch (kind & CTLTYPE) {
321e267e00eSXin LI 		case CTLTYPE_INT:
322e267e00eSXin LI 		case CTLTYPE_UINT:
323e267e00eSXin LI 		case CTLTYPE_LONG:
324e267e00eSXin LI 		case CTLTYPE_ULONG:
325e267e00eSXin LI 		case CTLTYPE_S64:
326e267e00eSXin LI 		case CTLTYPE_U64:
327e267e00eSXin LI 			if (strlen(newvalstr) == 0) {
328da178c77SXin LI 				warnx("empty numeric value");
329da178c77SXin LI 				return (1);
330da178c77SXin LI 			}
331e267e00eSXin LI 			/* FALLTHROUGH */
332e267e00eSXin LI 		case CTLTYPE_STRING:
333e267e00eSXin LI 			break;
334e267e00eSXin LI 		default:
335e267e00eSXin LI 			warnx("oid '%s' is type %d,"
336e267e00eSXin LI 				" cannot set that%s", bufp,
337e267e00eSXin LI 				kind & CTLTYPE, line);
338e267e00eSXin LI 			return (1);
339a78d3eafSRobert Watson 		}
340a78d3eafSRobert Watson 
3414b8740cdSXin LI 		errno = 0;
3424b8740cdSXin LI 
3431d86b91cSPoul-Henning Kamp 		switch (kind & CTLTYPE) {
344dea673e9SRodney W. Grimes 			case CTLTYPE_INT:
345aa255ef6SWarner Losh 				if (strncmp(fmt, "IK", 2) == 0)
346aa255ef6SWarner Losh 					intval = strIKtoi(newvalstr, &endptr, fmt);
347e267e00eSXin LI 				else
348e267e00eSXin LI 					intval = (int)strtol(newvalstr, &endptr,
349d45564dcSHajimu UMEMOTO 					    0);
350dea673e9SRodney W. Grimes 				newval = &intval;
35131fb4661SDima Dorfman 				newsize = sizeof(intval);
352dea673e9SRodney W. Grimes 				break;
3531ce1a53dSJim Pirzyk 			case CTLTYPE_UINT:
354e267e00eSXin LI 				uintval = (int) strtoul(newvalstr, &endptr, 0);
3551ce1a53dSJim Pirzyk 				newval = &uintval;
35621e1f596SDavid Malone 				newsize = sizeof(uintval);
3571ce1a53dSJim Pirzyk 				break;
3581ce1a53dSJim Pirzyk 			case CTLTYPE_LONG:
359e267e00eSXin LI 				longval = strtol(newvalstr, &endptr, 0);
3601ce1a53dSJim Pirzyk 				newval = &longval;
36121e1f596SDavid Malone 				newsize = sizeof(longval);
3621ce1a53dSJim Pirzyk 				break;
3631ce1a53dSJim Pirzyk 			case CTLTYPE_ULONG:
364e267e00eSXin LI 				ulongval = strtoul(newvalstr, &endptr, 0);
3651ce1a53dSJim Pirzyk 				newval = &ulongval;
36621e1f596SDavid Malone 				newsize = sizeof(ulongval);
3671d86b91cSPoul-Henning Kamp 				break;
3681d86b91cSPoul-Henning Kamp 			case CTLTYPE_STRING:
369e267e00eSXin LI 				newval = newvalstr;
3701d86b91cSPoul-Henning Kamp 				break;
371cbc134adSMatthew D Fleming 			case CTLTYPE_S64:
372e267e00eSXin LI 				i64val = strtoimax(newvalstr, &endptr, 0);
373cbc134adSMatthew D Fleming 				newval = &i64val;
374cbc134adSMatthew D Fleming 				newsize = sizeof(i64val);
375cbc134adSMatthew D Fleming 				break;
376cbc134adSMatthew D Fleming 			case CTLTYPE_U64:
377e267e00eSXin LI 				u64val = strtoumax(newvalstr, &endptr, 0);
378cbc134adSMatthew D Fleming 				newval = &u64val;
379cbc134adSMatthew D Fleming 				newsize = sizeof(u64val);
380dea673e9SRodney W. Grimes 				break;
3811d86b91cSPoul-Henning Kamp 			default:
382e267e00eSXin LI 				/* NOTREACHED */
383e267e00eSXin LI 				abort();
384e267e00eSXin LI 		}
385e267e00eSXin LI 
386e267e00eSXin LI 		if (errno != 0 || endptr == newvalstr ||
387e267e00eSXin LI 		    (endptr != NULL && *endptr != '\0')) {
388e267e00eSXin LI 			warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE],
389e267e00eSXin LI 			    newvalstr, line);
390da178c77SXin LI 			return (1);
391dea673e9SRodney W. Grimes 		}
3921d86b91cSPoul-Henning Kamp 
3931d86b91cSPoul-Henning Kamp 		i = show_var(mib, len);
3941d86b91cSPoul-Henning Kamp 		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
3951d86b91cSPoul-Henning Kamp 			if (!i && !bflag)
3961d86b91cSPoul-Henning Kamp 				putchar('\n');
397dea673e9SRodney W. Grimes 			switch (errno) {
398dea673e9SRodney W. Grimes 			case EOPNOTSUPP:
399da178c77SXin LI 				warnx("%s: value is not available%s",
400da178c77SXin LI 					string, line);
401da178c77SXin LI 				return (1);
402dea673e9SRodney W. Grimes 			case ENOTDIR:
403da178c77SXin LI 				warnx("%s: specification is incomplete%s",
404da178c77SXin LI 					string, line);
405da178c77SXin LI 				return (1);
406dea673e9SRodney W. Grimes 			case ENOMEM:
407da178c77SXin LI 				warnx("%s: type is unknown to this program%s",
408da178c77SXin LI 					string, line);
409da178c77SXin LI 				return (1);
410dea673e9SRodney W. Grimes 			default:
411da178c77SXin LI 				warn("%s%s", string, line);
412da178c77SXin LI 				return (1);
413dea673e9SRodney W. Grimes 			}
414dea673e9SRodney W. Grimes 		}
4151d86b91cSPoul-Henning Kamp 		if (!bflag)
4161d86b91cSPoul-Henning Kamp 			printf(" -> ");
4171d86b91cSPoul-Henning Kamp 		i = nflag;
4181d86b91cSPoul-Henning Kamp 		nflag = 1;
4191d86b91cSPoul-Henning Kamp 		j = show_var(mib, len);
4201d86b91cSPoul-Henning Kamp 		if (!j && !bflag)
4211d86b91cSPoul-Henning Kamp 			putchar('\n');
4221d86b91cSPoul-Henning Kamp 		nflag = i;
423dea673e9SRodney W. Grimes 	}
424da178c77SXin LI 
425da178c77SXin LI 	return (0);
426da178c77SXin LI }
427da178c77SXin LI 
428da178c77SXin LI static int
429da178c77SXin LI parsefile(const char *filename)
430da178c77SXin LI {
431da178c77SXin LI 	FILE *file;
432da178c77SXin LI 	char line[BUFSIZ], *p, *pq, *pdq;
433da178c77SXin LI 	int warncount = 0, lineno = 0;
434da178c77SXin LI 
435da178c77SXin LI 	file = fopen(filename, "r");
436da178c77SXin LI 	if (file == NULL)
437da178c77SXin LI 		err(EX_NOINPUT, "%s", filename);
438da178c77SXin LI 	while (fgets(line, sizeof(line), file) != NULL) {
439da178c77SXin LI 		lineno++;
440da178c77SXin LI 		p = line;
441da178c77SXin LI 		pq = strchr(line, '\'');
442da178c77SXin LI 		pdq = strchr(line, '\"');
443da178c77SXin LI 		/* Replace the first # with \0. */
444da178c77SXin LI 		while((p = strchr(p, '#')) != NULL) {
445da178c77SXin LI 			if (pq != NULL && p > pq) {
446da178c77SXin LI 				if ((p = strchr(pq+1, '\'')) != NULL)
447da178c77SXin LI 					*(++p) = '\0';
448da178c77SXin LI 				break;
449da178c77SXin LI 			} else if (pdq != NULL && p > pdq) {
450da178c77SXin LI 				if ((p = strchr(pdq+1, '\"')) != NULL)
451da178c77SXin LI 					*(++p) = '\0';
452da178c77SXin LI 				break;
453da178c77SXin LI 			} else if (p == line || *(p-1) != '\\') {
454da178c77SXin LI 				*p = '\0';
455da178c77SXin LI 				break;
456da178c77SXin LI 			}
457da178c77SXin LI 			p++;
458da178c77SXin LI 		}
459da178c77SXin LI 		/* Trim spaces */
460da178c77SXin LI 		p = line + strlen(line) - 1;
461da178c77SXin LI 		while (p >= line && isspace((int)*p)) {
462da178c77SXin LI 			*p = '\0';
463da178c77SXin LI 			p--;
464da178c77SXin LI 		}
465da178c77SXin LI 		p = line;
466da178c77SXin LI 		while (isspace((int)*p))
467da178c77SXin LI 			p++;
468da178c77SXin LI 		if (*p == '\0')
469da178c77SXin LI 			continue;
470da178c77SXin LI 		else
471da178c77SXin LI 			warncount += parse(p, lineno);
472da178c77SXin LI 	}
473da178c77SXin LI 	fclose(file);
474da178c77SXin LI 
475da178c77SXin LI 	return (warncount);
476dea673e9SRodney W. Grimes }
477dea673e9SRodney W. Grimes 
4781d86b91cSPoul-Henning Kamp /* These functions will dump out various interesting structures. */
479dea673e9SRodney W. Grimes 
4801d86b91cSPoul-Henning Kamp static int
48159101c5dSJohn Baldwin S_clockinfo(size_t l2, void *p)
4821d86b91cSPoul-Henning Kamp {
4831d86b91cSPoul-Henning Kamp 	struct clockinfo *ci = (struct clockinfo*)p;
48421e1f596SDavid Malone 
485996076bbSAlfred Perlstein 	if (l2 != sizeof(*ci)) {
48659101c5dSJohn Baldwin 		warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci));
4876b6b665bSBruce Evans 		return (1);
488996076bbSAlfred Perlstein 	}
48945817aaaSDag-Erling Smørgrav 	printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
49045817aaaSDag-Erling Smørgrav 		"{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
491b35c8f28SPoul-Henning Kamp 		ci->hz, ci->tick, ci->profhz, ci->stathz);
4921d86b91cSPoul-Henning Kamp 	return (0);
493dea673e9SRodney W. Grimes }
494dea673e9SRodney W. Grimes 
4951d86b91cSPoul-Henning Kamp static int
49659101c5dSJohn Baldwin S_loadavg(size_t l2, void *p)
4971d86b91cSPoul-Henning Kamp {
4981d86b91cSPoul-Henning Kamp 	struct loadavg *tv = (struct loadavg*)p;
4991d86b91cSPoul-Henning Kamp 
500996076bbSAlfred Perlstein 	if (l2 != sizeof(*tv)) {
50159101c5dSJohn Baldwin 		warnx("S_loadavg %zu != %zu", l2, sizeof(*tv));
5026b6b665bSBruce Evans 		return (1);
503996076bbSAlfred Perlstein 	}
50445817aaaSDag-Erling Smørgrav 	printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
5051d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[0]/(double)tv->fscale,
5061d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[1]/(double)tv->fscale,
5071d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[2]/(double)tv->fscale);
5081d86b91cSPoul-Henning Kamp 	return (0);
509dea673e9SRodney W. Grimes }
510dea673e9SRodney W. Grimes 
5111d86b91cSPoul-Henning Kamp static int
51259101c5dSJohn Baldwin S_timeval(size_t l2, void *p)
5131d86b91cSPoul-Henning Kamp {
5141d86b91cSPoul-Henning Kamp 	struct timeval *tv = (struct timeval*)p;
515c2deb608SBruce Evans 	time_t tv_sec;
5161d86b91cSPoul-Henning Kamp 	char *p1, *p2;
517dea673e9SRodney W. Grimes 
518996076bbSAlfred Perlstein 	if (l2 != sizeof(*tv)) {
51959101c5dSJohn Baldwin 		warnx("S_timeval %zu != %zu", l2, sizeof(*tv));
5206b6b665bSBruce Evans 		return (1);
521996076bbSAlfred Perlstein 	}
522db87e2dcSJohn Hay 	printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
523db87e2dcSJohn Hay 		"{ sec = %jd, usec = %ld } ",
524db87e2dcSJohn Hay 		(intmax_t)tv->tv_sec, tv->tv_usec);
525c2deb608SBruce Evans 	tv_sec = tv->tv_sec;
526c2deb608SBruce Evans 	p1 = strdup(ctime(&tv_sec));
5271d86b91cSPoul-Henning Kamp 	for (p2=p1; *p2 ; p2++)
5281d86b91cSPoul-Henning Kamp 		if (*p2 == '\n')
5291d86b91cSPoul-Henning Kamp 			*p2 = '\0';
5301d86b91cSPoul-Henning Kamp 	fputs(p1, stdout);
531f2359a24SRebecca Cran 	free(p1);
5321d86b91cSPoul-Henning Kamp 	return (0);
5331d86b91cSPoul-Henning Kamp }
5341d86b91cSPoul-Henning Kamp 
5351d86b91cSPoul-Henning Kamp static int
53659101c5dSJohn Baldwin S_vmtotal(size_t l2, void *p)
537f7550ecfSMatthew Dillon {
538f7550ecfSMatthew Dillon 	struct vmtotal *v = (struct vmtotal *)p;
539654e22e7SMatthew Dillon 	int pageKilo = getpagesize() / 1024;
540f7550ecfSMatthew Dillon 
541f7550ecfSMatthew Dillon 	if (l2 != sizeof(*v)) {
54259101c5dSJohn Baldwin 		warnx("S_vmtotal %zu != %zu", l2, sizeof(*v));
5436b6b665bSBruce Evans 		return (1);
544f7550ecfSMatthew Dillon 	}
545f7550ecfSMatthew Dillon 
546654e22e7SMatthew Dillon 	printf(
547654e22e7SMatthew Dillon 	    "\nSystem wide totals computed every five seconds:"
548654e22e7SMatthew Dillon 	    " (values in kilobytes)\n");
549f7550ecfSMatthew Dillon 	printf("===============================================\n");
550654e22e7SMatthew Dillon 	printf(
551bad4d172SRuslan Ermilov 	    "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
552bad4d172SRuslan Ermilov 	    "%hd Sleep: %hd)\n",
553f7550ecfSMatthew Dillon 	    v->t_rq, v->t_dw, v->t_pw, v->t_sl);
554654e22e7SMatthew Dillon 	printf(
55513e86ef7SMarko Zec 	    "Virtual Memory:\t\t(Total: %dK Active: %dK)\n",
556bad4d172SRuslan Ermilov 	    v->t_vm * pageKilo, v->t_avm * pageKilo);
55713e86ef7SMarko Zec 	printf("Real Memory:\t\t(Total: %dK Active: %dK)\n",
558bad4d172SRuslan Ermilov 	    v->t_rm * pageKilo, v->t_arm * pageKilo);
559bad4d172SRuslan Ermilov 	printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n",
560bad4d172SRuslan Ermilov 	    v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
561bad4d172SRuslan Ermilov 	printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
562bad4d172SRuslan Ermilov 	    v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
56359101c5dSJohn Baldwin 	printf("Free Memory:\t%dK", v->t_free * pageKilo);
564f7550ecfSMatthew Dillon 
565f7550ecfSMatthew Dillon 	return (0);
566f7550ecfSMatthew Dillon }
567f7550ecfSMatthew Dillon 
5687d8312ccSJohn Baldwin #ifdef __amd64__
5697d8312ccSJohn Baldwin #define efi_next_descriptor(ptr, size) \
5707d8312ccSJohn Baldwin 	((struct efi_md *)(((uint8_t *) ptr) + size))
5717d8312ccSJohn Baldwin 
5727d8312ccSJohn Baldwin static int
5737d8312ccSJohn Baldwin S_efi_map(size_t l2, void *p)
5747d8312ccSJohn Baldwin {
5757d8312ccSJohn Baldwin 	struct efi_map_header *efihdr;
5767d8312ccSJohn Baldwin 	struct efi_md *map;
5777d8312ccSJohn Baldwin 	const char *type;
5787d8312ccSJohn Baldwin 	size_t efisz;
5797d8312ccSJohn Baldwin 	int ndesc, i;
5807d8312ccSJohn Baldwin 
5817d8312ccSJohn Baldwin 	static const char *types[] = {
5827d8312ccSJohn Baldwin 		"Reserved",
5837d8312ccSJohn Baldwin 		"LoaderCode",
5847d8312ccSJohn Baldwin 		"LoaderData",
5857d8312ccSJohn Baldwin 		"BootServicesCode",
5867d8312ccSJohn Baldwin 		"BootServicesData",
5877d8312ccSJohn Baldwin 		"RuntimeServicesCode",
5887d8312ccSJohn Baldwin 		"RuntimeServicesData",
5897d8312ccSJohn Baldwin 		"ConventionalMemory",
5907d8312ccSJohn Baldwin 		"UnusableMemory",
5917d8312ccSJohn Baldwin 		"ACPIReclaimMemory",
5927d8312ccSJohn Baldwin 		"ACPIMemoryNVS",
5937d8312ccSJohn Baldwin 		"MemoryMappedIO",
5947d8312ccSJohn Baldwin 		"MemoryMappedIOPortSpace",
5957d8312ccSJohn Baldwin 		"PalCode"
5967d8312ccSJohn Baldwin 	};
5977d8312ccSJohn Baldwin 
5987d8312ccSJohn Baldwin 	/*
5997d8312ccSJohn Baldwin 	 * Memory map data provided by UEFI via the GetMemoryMap
6007d8312ccSJohn Baldwin 	 * Boot Services API.
6017d8312ccSJohn Baldwin 	 */
6027d8312ccSJohn Baldwin 	if (l2 < sizeof(*efihdr)) {
6037d8312ccSJohn Baldwin 		warnx("S_efi_map length less than header");
6047d8312ccSJohn Baldwin 		return (1);
6057d8312ccSJohn Baldwin 	}
6067d8312ccSJohn Baldwin 	efihdr = p;
6077d8312ccSJohn Baldwin 	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
6087d8312ccSJohn Baldwin 	map = (struct efi_md *)((uint8_t *)efihdr + efisz);
6097d8312ccSJohn Baldwin 
6107d8312ccSJohn Baldwin 	if (efihdr->descriptor_size == 0)
6117d8312ccSJohn Baldwin 		return (0);
6127d8312ccSJohn Baldwin 	if (l2 != efisz + efihdr->memory_size) {
6137d8312ccSJohn Baldwin 		warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz +
6147d8312ccSJohn Baldwin 		    efihdr->memory_size);
6157d8312ccSJohn Baldwin 		return (1);
6167d8312ccSJohn Baldwin 	}
6177d8312ccSJohn Baldwin 	ndesc = efihdr->memory_size / efihdr->descriptor_size;
6187d8312ccSJohn Baldwin 
6197d8312ccSJohn Baldwin 	printf("\n%23s %12s %12s %8s %4s",
6207d8312ccSJohn Baldwin 	    "Type", "Physical", "Virtual", "#Pages", "Attr");
6217d8312ccSJohn Baldwin 
6227d8312ccSJohn Baldwin 	for (i = 0; i < ndesc; i++,
6237d8312ccSJohn Baldwin 	    map = efi_next_descriptor(map, efihdr->descriptor_size)) {
6247d8312ccSJohn Baldwin 		if (map->md_type <= EFI_MD_TYPE_PALCODE)
6257d8312ccSJohn Baldwin 			type = types[map->md_type];
6267d8312ccSJohn Baldwin 		else
6277d8312ccSJohn Baldwin 			type = "<INVALID>";
6287d8312ccSJohn Baldwin 		printf("\n%23s %012lx %12p %08lx ", type, map->md_phys,
6297d8312ccSJohn Baldwin 		    map->md_virt, map->md_pages);
6307d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_UC)
6317d8312ccSJohn Baldwin 			printf("UC ");
6327d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WC)
6337d8312ccSJohn Baldwin 			printf("WC ");
6347d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WT)
6357d8312ccSJohn Baldwin 			printf("WT ");
6367d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WB)
6377d8312ccSJohn Baldwin 			printf("WB ");
6387d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_UCE)
6397d8312ccSJohn Baldwin 			printf("UCE ");
6407d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WP)
6417d8312ccSJohn Baldwin 			printf("WP ");
6427d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_RP)
6437d8312ccSJohn Baldwin 			printf("RP ");
6447d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_XP)
6457d8312ccSJohn Baldwin 			printf("XP ");
6467d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_RT)
6477d8312ccSJohn Baldwin 			printf("RUNTIME");
6487d8312ccSJohn Baldwin 	}
6497d8312ccSJohn Baldwin 	return (0);
6507d8312ccSJohn Baldwin }
6517d8312ccSJohn Baldwin #endif
6527d8312ccSJohn Baldwin 
65389871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
65489871cdeSJohn Baldwin static int
65559101c5dSJohn Baldwin S_bios_smap_xattr(size_t l2, void *p)
65689871cdeSJohn Baldwin {
65789871cdeSJohn Baldwin 	struct bios_smap_xattr *smap, *end;
65889871cdeSJohn Baldwin 
65989871cdeSJohn Baldwin 	if (l2 % sizeof(*smap) != 0) {
66059101c5dSJohn Baldwin 		warnx("S_bios_smap_xattr %zu is not a multiple of %zu", l2,
66189871cdeSJohn Baldwin 		    sizeof(*smap));
66289871cdeSJohn Baldwin 		return (1);
66389871cdeSJohn Baldwin 	}
66489871cdeSJohn Baldwin 
66589871cdeSJohn Baldwin 	end = (struct bios_smap_xattr *)((char *)p + l2);
66689871cdeSJohn Baldwin 	for (smap = p; smap < end; smap++)
66789871cdeSJohn Baldwin 		printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx",
66889871cdeSJohn Baldwin 		    smap->type, smap->xattr, (uintmax_t)smap->base,
66989871cdeSJohn Baldwin 		    (uintmax_t)smap->length);
67089871cdeSJohn Baldwin 	return (0);
67189871cdeSJohn Baldwin }
67289871cdeSJohn Baldwin #endif
67389871cdeSJohn Baldwin 
674f7550ecfSMatthew Dillon static int
675aa255ef6SWarner Losh strIKtoi(const char *str, char **endptrp, const char *fmt)
676d45564dcSHajimu UMEMOTO {
677e267e00eSXin LI 	int kelv;
678d45564dcSHajimu UMEMOTO 	float temp;
679e267e00eSXin LI 	size_t len;
680a7b5ad27SEd Schouten 	const char *p;
681aa255ef6SWarner Losh 	int prec, i;
682d45564dcSHajimu UMEMOTO 
683e267e00eSXin LI 	assert(errno == 0);
684e267e00eSXin LI 
685e267e00eSXin LI 	len = strlen(str);
686e267e00eSXin LI 	/* caller already checked this */
687e267e00eSXin LI 	assert(len > 0);
688e267e00eSXin LI 
689aa255ef6SWarner Losh 	/*
690aa255ef6SWarner Losh 	 * A format of "IK" is in deciKelvin. A format of "IK3" is in
691aa255ef6SWarner Losh 	 * milliKelvin. The single digit following IK is log10 of the
692aa255ef6SWarner Losh 	 * multiplying factor to convert Kelvin into the untis of this sysctl,
693aa255ef6SWarner Losh 	 * or the dividing factor to convert the sysctl value to Kelvin. Numbers
694aa255ef6SWarner Losh 	 * larger than 6 will run into precision issues with 32-bit integers.
695aa255ef6SWarner Losh 	 * Characters that aren't ASCII digits after the 'K' are ignored. No
696aa255ef6SWarner Losh 	 * localization is present because this is an interface from the kernel
697aa255ef6SWarner Losh 	 * to this program (eg not an end-user interface), so isdigit() isn't
698aa255ef6SWarner Losh 	 * used here.
699aa255ef6SWarner Losh 	 */
700aa255ef6SWarner Losh 	if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9')
701aa255ef6SWarner Losh 		prec = fmt[2] - '0';
702aa255ef6SWarner Losh 	else
703aa255ef6SWarner Losh 		prec = 1;
704d45564dcSHajimu UMEMOTO 	p = &str[len - 1];
705aa255ef6SWarner Losh 	if (*p == 'C' || *p == 'F' || *p == 'K') {
706e267e00eSXin LI 		temp = strtof(str, endptrp);
707689c8e8bSXin LI 		if (*endptrp != str && *endptrp == p && errno == 0) {
708d45564dcSHajimu UMEMOTO 			if (*p == 'F')
709d45564dcSHajimu UMEMOTO 				temp = (temp - 32) * 5 / 9;
710689c8e8bSXin LI 			*endptrp = NULL;
711aa255ef6SWarner Losh 			if (*p != 'K')
712aa255ef6SWarner Losh 				temp += 273.15;
713aa255ef6SWarner Losh 			for (i = 0; i < prec; i++)
714aa255ef6SWarner Losh 				temp *= 10.0;
715aa255ef6SWarner Losh 			return ((int)(temp + 0.5));
716d45564dcSHajimu UMEMOTO 		}
717e267e00eSXin LI 	} else {
718aa255ef6SWarner Losh 		/* No unit specified -> treat it as a raw number */
719e267e00eSXin LI 		kelv = (int)strtol(str, endptrp, 10);
720689c8e8bSXin LI 		if (*endptrp != str && *endptrp == p && errno == 0) {
721689c8e8bSXin LI 			*endptrp = NULL;
722e267e00eSXin LI 			return (kelv);
723e267e00eSXin LI 		}
724689c8e8bSXin LI 	}
725e267e00eSXin LI 
726e267e00eSXin LI 	errno = ERANGE;
727e267e00eSXin LI 	return (0);
728d45564dcSHajimu UMEMOTO }
729d45564dcSHajimu UMEMOTO 
7301d86b91cSPoul-Henning Kamp /*
7311d86b91cSPoul-Henning Kamp  * These functions uses a presently undocumented interface to the kernel
7321d86b91cSPoul-Henning Kamp  * to walk the tree and get the type so it can print the value.
7331d86b91cSPoul-Henning Kamp  * This interface is under work and consideration, and should probably
7341d86b91cSPoul-Henning Kamp  * be killed with a big axe by the first person who can find the time.
7351d86b91cSPoul-Henning Kamp  * (be aware though, that the proper interface isn't as obvious as it
7361d86b91cSPoul-Henning Kamp  * may seem, there are various conflicting requirements.
7371d86b91cSPoul-Henning Kamp  */
7381d86b91cSPoul-Henning Kamp 
7391d86b91cSPoul-Henning Kamp static int
740c58f8df6SXin LI name2oid(const char *name, int *oidp)
7411d86b91cSPoul-Henning Kamp {
7421d86b91cSPoul-Henning Kamp 	int oid[2];
743dbf9b92fSDoug Rabson 	int i;
744dbf9b92fSDoug Rabson 	size_t j;
7451d86b91cSPoul-Henning Kamp 
7461d86b91cSPoul-Henning Kamp 	oid[0] = 0;
7471d86b91cSPoul-Henning Kamp 	oid[1] = 3;
7481d86b91cSPoul-Henning Kamp 
7491d86b91cSPoul-Henning Kamp 	j = CTL_MAXNAME * sizeof(int);
7501d86b91cSPoul-Henning Kamp 	i = sysctl(oid, 2, oidp, &j, name, strlen(name));
7511d86b91cSPoul-Henning Kamp 	if (i < 0)
75221e1f596SDavid Malone 		return (i);
7531d86b91cSPoul-Henning Kamp 	j /= sizeof(int);
7541d86b91cSPoul-Henning Kamp 	return (j);
7551d86b91cSPoul-Henning Kamp }
7561d86b91cSPoul-Henning Kamp 
7571d86b91cSPoul-Henning Kamp static int
7581d86b91cSPoul-Henning Kamp oidfmt(int *oid, int len, char *fmt, u_int *kind)
7591d86b91cSPoul-Henning Kamp {
7601d86b91cSPoul-Henning Kamp 	int qoid[CTL_MAXNAME+2];
7611d86b91cSPoul-Henning Kamp 	u_char buf[BUFSIZ];
762dbf9b92fSDoug Rabson 	int i;
763dbf9b92fSDoug Rabson 	size_t j;
7641d86b91cSPoul-Henning Kamp 
7651d86b91cSPoul-Henning Kamp 	qoid[0] = 0;
7661d86b91cSPoul-Henning Kamp 	qoid[1] = 4;
7671d86b91cSPoul-Henning Kamp 	memcpy(qoid + 2, oid, len * sizeof(int));
7681d86b91cSPoul-Henning Kamp 
76931fb4661SDima Dorfman 	j = sizeof(buf);
7701d86b91cSPoul-Henning Kamp 	i = sysctl(qoid, len + 2, buf, &j, 0, 0);
7711d86b91cSPoul-Henning Kamp 	if (i)
7726d7a8f6cSUlrich Spörlein 		err(1, "sysctl fmt %d %zu %d", i, j, errno);
7731d86b91cSPoul-Henning Kamp 
7741d86b91cSPoul-Henning Kamp 	if (kind)
7751d86b91cSPoul-Henning Kamp 		*kind = *(u_int *)buf;
7761d86b91cSPoul-Henning Kamp 
7771d86b91cSPoul-Henning Kamp 	if (fmt)
7781d86b91cSPoul-Henning Kamp 		strcpy(fmt, (char *)(buf + sizeof(u_int)));
77921e1f596SDavid Malone 	return (0);
7801d86b91cSPoul-Henning Kamp }
7811d86b91cSPoul-Henning Kamp 
78260cf2c12SLuigi Rizzo /*
7831d86b91cSPoul-Henning Kamp  * This formats and outputs the value of one variable
7841d86b91cSPoul-Henning Kamp  *
7851d86b91cSPoul-Henning Kamp  * Returns zero if anything was actually output.
7861d86b91cSPoul-Henning Kamp  * Returns one if didn't know what to do with this.
7871d86b91cSPoul-Henning Kamp  * Return minus one if we had errors.
7881d86b91cSPoul-Henning Kamp  */
7891d86b91cSPoul-Henning Kamp static int
7901d86b91cSPoul-Henning Kamp show_var(int *oid, int nlen)
7911d86b91cSPoul-Henning Kamp {
792ccf25977SRuslan Ermilov 	u_char buf[BUFSIZ], *val, *oval, *p;
793403c7f59SAlfred Perlstein 	char name[BUFSIZ], fmt[BUFSIZ];
794fd8c668aSDavid Malone 	const char *sep, *sep1;
7951d86b91cSPoul-Henning Kamp 	int qoid[CTL_MAXNAME+2];
79621e1f596SDavid Malone 	uintmax_t umv;
79721e1f596SDavid Malone 	intmax_t mv;
798f8e4b4efSMatthew D Fleming 	int i, hexlen, sign, ctltype;
79941e419cbSDavid Malone 	size_t intlen;
800dbf9b92fSDoug Rabson 	size_t j, len;
8011d86b91cSPoul-Henning Kamp 	u_int kind;
802aa255ef6SWarner Losh 	float base;
80359101c5dSJohn Baldwin 	int (*func)(size_t, void *);
804aa255ef6SWarner Losh 	int prec;
8051d86b91cSPoul-Henning Kamp 
8066d7a8f6cSUlrich Spörlein 	/* Silence GCC. */
8076d7a8f6cSUlrich Spörlein 	umv = mv = intlen = 0;
8086d7a8f6cSUlrich Spörlein 
8099f98e452SMatthew N. Dodd 	bzero(buf, BUFSIZ);
810403c7f59SAlfred Perlstein 	bzero(fmt, BUFSIZ);
8119f98e452SMatthew N. Dodd 	bzero(name, BUFSIZ);
81281e7454aSDag-Erling Smørgrav 	qoid[0] = 0;
81381e7454aSDag-Erling Smørgrav 	memcpy(qoid + 2, oid, nlen * sizeof(int));
81481e7454aSDag-Erling Smørgrav 
81581e7454aSDag-Erling Smørgrav 	qoid[1] = 1;
81631fb4661SDima Dorfman 	j = sizeof(name);
81781e7454aSDag-Erling Smørgrav 	i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
81881e7454aSDag-Erling Smørgrav 	if (i || !j)
8196d7a8f6cSUlrich Spörlein 		err(1, "sysctl name %d %zu %d", i, j, errno);
82081e7454aSDag-Erling Smørgrav 
821403c7f59SAlfred Perlstein 	oidfmt(oid, nlen, fmt, &kind);
822403c7f59SAlfred Perlstein 	/* if Wflag then only list sysctls that are writeable and not stats. */
823403c7f59SAlfred Perlstein 	if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0))
824403c7f59SAlfred Perlstein 		return 1;
825403c7f59SAlfred Perlstein 
826403c7f59SAlfred Perlstein 	/* if Tflag then only list sysctls that are tuneables. */
827403c7f59SAlfred Perlstein 	if (Tflag && (kind & CTLFLAG_TUN) == 0)
828403c7f59SAlfred Perlstein 		return 1;
829403c7f59SAlfred Perlstein 
830ca5fac55SDag-Erling Smørgrav 	if (Nflag) {
831ca5fac55SDag-Erling Smørgrav 		printf("%s", name);
832ca5fac55SDag-Erling Smørgrav 		return (0);
833ca5fac55SDag-Erling Smørgrav 	}
834ca5fac55SDag-Erling Smørgrav 
835d0b8aabbSAnton Berezin 	if (eflag)
836d0b8aabbSAnton Berezin 		sep = "=";
837d0b8aabbSAnton Berezin 	else
838d0b8aabbSAnton Berezin 		sep = ": ";
839d0b8aabbSAnton Berezin 
8406105f815SLuigi Rizzo 	if (dflag) {	/* just print description */
8416105f815SLuigi Rizzo 		qoid[1] = 5;
8426105f815SLuigi Rizzo 		j = sizeof(buf);
8436105f815SLuigi Rizzo 		i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
8446105f815SLuigi Rizzo 		if (!nflag)
8456105f815SLuigi Rizzo 			printf("%s%s", name, sep);
8466105f815SLuigi Rizzo 		printf("%s", buf);
8476105f815SLuigi Rizzo 		return (0);
8486105f815SLuigi Rizzo 	}
8491d86b91cSPoul-Henning Kamp 	/* find an estimate of how much we need for this var */
85075820005SJohn-Mark Gurney 	if (Bflag)
85175820005SJohn-Mark Gurney 		j = Bflag;
85275820005SJohn-Mark Gurney 	else {
8531d86b91cSPoul-Henning Kamp 		j = 0;
8541d86b91cSPoul-Henning Kamp 		i = sysctl(oid, nlen, 0, &j, 0, 0);
8551d86b91cSPoul-Henning Kamp 		j += j; /* we want to be sure :-) */
85675820005SJohn-Mark Gurney 	}
8571d86b91cSPoul-Henning Kamp 
858ccf25977SRuslan Ermilov 	val = oval = malloc(j + 1);
859ccf25977SRuslan Ermilov 	if (val == NULL) {
860ccf25977SRuslan Ermilov 		warnx("malloc failed");
8616b6b665bSBruce Evans 		return (1);
862ccf25977SRuslan Ermilov 	}
86304006eabSHans Petter Selasky 	ctltype = (kind & CTLTYPE);
8641d86b91cSPoul-Henning Kamp 	len = j;
8651d86b91cSPoul-Henning Kamp 	i = sysctl(oid, nlen, val, &len, 0, 0);
86604006eabSHans Petter Selasky 	if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) {
867ccf25977SRuslan Ermilov 		free(oval);
8681d86b91cSPoul-Henning Kamp 		return (1);
869ccf25977SRuslan Ermilov 	}
8701d86b91cSPoul-Henning Kamp 
8711d86b91cSPoul-Henning Kamp 	if (bflag) {
8721d86b91cSPoul-Henning Kamp 		fwrite(val, 1, len, stdout);
873ccf25977SRuslan Ermilov 		free(oval);
8741d86b91cSPoul-Henning Kamp 		return (0);
8751d86b91cSPoul-Henning Kamp 	}
87676d3dc52SAndrey A. Chernov 	val[len] = '\0';
8771d86b91cSPoul-Henning Kamp 	p = val;
878cbc134adSMatthew D Fleming 	sign = ctl_sign[ctltype];
879cbc134adSMatthew D Fleming 	intlen = ctl_size[ctltype];
880cbc134adSMatthew D Fleming 
881f8e4b4efSMatthew D Fleming 	switch (ctltype) {
882f8e4b4efSMatthew D Fleming 	case CTLTYPE_STRING:
8831d86b91cSPoul-Henning Kamp 		if (!nflag)
884d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
8856d7a8f6cSUlrich Spörlein 		printf("%.*s", (int)len, p);
886ccf25977SRuslan Ermilov 		free(oval);
8871d86b91cSPoul-Henning Kamp 		return (0);
8881d86b91cSPoul-Henning Kamp 
889f8e4b4efSMatthew D Fleming 	case CTLTYPE_INT:
890f8e4b4efSMatthew D Fleming 	case CTLTYPE_UINT:
891f8e4b4efSMatthew D Fleming 	case CTLTYPE_LONG:
892f8e4b4efSMatthew D Fleming 	case CTLTYPE_ULONG:
893cbc134adSMatthew D Fleming 	case CTLTYPE_S64:
894cbc134adSMatthew D Fleming 	case CTLTYPE_U64:
895dbf9b92fSDoug Rabson 		if (!nflag)
896d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
897e37d2b30SDavid Malone 		hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
898fd8c668aSDavid Malone 		sep1 = "";
89941e419cbSDavid Malone 		while (len >= intlen) {
900f8e4b4efSMatthew D Fleming 			switch (kind & CTLTYPE) {
901f8e4b4efSMatthew D Fleming 			case CTLTYPE_INT:
902f8e4b4efSMatthew D Fleming 			case CTLTYPE_UINT:
903e37d2b30SDavid Malone 				umv = *(u_int *)p;
904e37d2b30SDavid Malone 				mv = *(int *)p;
90541e419cbSDavid Malone 				break;
906f8e4b4efSMatthew D Fleming 			case CTLTYPE_LONG:
907f8e4b4efSMatthew D Fleming 			case CTLTYPE_ULONG:
908e37d2b30SDavid Malone 				umv = *(u_long *)p;
909e37d2b30SDavid Malone 				mv = *(long *)p;
91041e419cbSDavid Malone 				break;
911cbc134adSMatthew D Fleming 			case CTLTYPE_S64:
912cbc134adSMatthew D Fleming 			case CTLTYPE_U64:
913cbc134adSMatthew D Fleming 				umv = *(uint64_t *)p;
914cbc134adSMatthew D Fleming 				mv = *(int64_t *)p;
91541e419cbSDavid Malone 				break;
91641e419cbSDavid Malone 			}
917fd8c668aSDavid Malone 			fputs(sep1, stdout);
918f8e4b4efSMatthew D Fleming 			if (xflag)
919e37d2b30SDavid Malone 				printf("%#0*jx", hexlen, umv);
920f8e4b4efSMatthew D Fleming 			else if (!sign)
921f8e4b4efSMatthew D Fleming 				printf(hflag ? "%'ju" : "%ju", umv);
92241e419cbSDavid Malone 			else if (fmt[1] == 'K') {
923e37d2b30SDavid Malone 				if (mv < 0)
92421e1f596SDavid Malone 					printf("%jd", mv);
925aa255ef6SWarner Losh 				else {
926aa255ef6SWarner Losh 					/*
927aa255ef6SWarner Losh 					 * See strIKtoi for details on fmt.
928aa255ef6SWarner Losh 					 */
929aa255ef6SWarner Losh 					prec = 1;
930aa255ef6SWarner Losh 					if (fmt[2] != '\0')
931aa255ef6SWarner Losh 						prec = fmt[2] - '0';
932aa255ef6SWarner Losh 					base = 1.0;
933aa255ef6SWarner Losh 					for (int i = 0; i < prec; i++)
934aa255ef6SWarner Losh 						base *= 10.0;
935aa255ef6SWarner Losh 					printf("%.*fC", prec,
936aa255ef6SWarner Losh 					    (float)mv / base - 273.15);
937aa255ef6SWarner Losh 				}
938c591d41fSPeter Wemm 			} else
939fd8c668aSDavid Malone 				printf(hflag ? "%'jd" : "%jd", mv);
940fd8c668aSDavid Malone 			sep1 = " ";
94141e419cbSDavid Malone 			len -= intlen;
94241e419cbSDavid Malone 			p += intlen;
943aa02fb57SPoul-Henning Kamp 		}
944ccf25977SRuslan Ermilov 		free(oval);
945dbf9b92fSDoug Rabson 		return (0);
946dbf9b92fSDoug Rabson 
947f8e4b4efSMatthew D Fleming 	case CTLTYPE_OPAQUE:
9481d86b91cSPoul-Henning Kamp 		i = 0;
949a89ab9bbSDag-Erling Smørgrav 		if (strcmp(fmt, "S,clockinfo") == 0)
950a89ab9bbSDag-Erling Smørgrav 			func = S_clockinfo;
951a89ab9bbSDag-Erling Smørgrav 		else if (strcmp(fmt, "S,timeval") == 0)
952a89ab9bbSDag-Erling Smørgrav 			func = S_timeval;
953a89ab9bbSDag-Erling Smørgrav 		else if (strcmp(fmt, "S,loadavg") == 0)
954a89ab9bbSDag-Erling Smørgrav 			func = S_loadavg;
955f7550ecfSMatthew Dillon 		else if (strcmp(fmt, "S,vmtotal") == 0)
956f7550ecfSMatthew Dillon 			func = S_vmtotal;
9577d8312ccSJohn Baldwin #ifdef __amd64__
9587d8312ccSJohn Baldwin 		else if (strcmp(fmt, "S,efi_map_header") == 0)
9597d8312ccSJohn Baldwin 			func = S_efi_map;
9607d8312ccSJohn Baldwin #endif
96189871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
96289871cdeSJohn Baldwin 		else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
96389871cdeSJohn Baldwin 			func = S_bios_smap_xattr;
96489871cdeSJohn Baldwin #endif
965a89ab9bbSDag-Erling Smørgrav 		else
966a89ab9bbSDag-Erling Smørgrav 			func = NULL;
9671d86b91cSPoul-Henning Kamp 		if (func) {
9681d86b91cSPoul-Henning Kamp 			if (!nflag)
969d0b8aabbSAnton Berezin 				printf("%s%s", name, sep);
97048cd487aSHartmut Brandt 			i = (*func)(len, p);
971ccf25977SRuslan Ermilov 			free(oval);
97248cd487aSHartmut Brandt 			return (i);
9731d86b91cSPoul-Henning Kamp 		}
9741d86b91cSPoul-Henning Kamp 		/* FALLTHROUGH */
975dea673e9SRodney W. Grimes 	default:
976ccf25977SRuslan Ermilov 		if (!oflag && !xflag) {
977ccf25977SRuslan Ermilov 			free(oval);
9781d86b91cSPoul-Henning Kamp 			return (1);
979ccf25977SRuslan Ermilov 		}
9801d86b91cSPoul-Henning Kamp 		if (!nflag)
981d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
9826d7a8f6cSUlrich Spörlein 		printf("Format:%s Length:%zu Dump:0x", fmt, len);
983a89ab9bbSDag-Erling Smørgrav 		while (len-- && (xflag || p < val + 16))
9841d86b91cSPoul-Henning Kamp 			printf("%02x", *p++);
985a89ab9bbSDag-Erling Smørgrav 		if (!xflag && len > 16)
9861d86b91cSPoul-Henning Kamp 			printf("...");
987ccf25977SRuslan Ermilov 		free(oval);
9881d86b91cSPoul-Henning Kamp 		return (0);
9891d86b91cSPoul-Henning Kamp 	}
990ccf25977SRuslan Ermilov 	free(oval);
9911d86b91cSPoul-Henning Kamp 	return (1);
992dea673e9SRodney W. Grimes }
993dea673e9SRodney W. Grimes 
9941d86b91cSPoul-Henning Kamp static int
9951d86b91cSPoul-Henning Kamp sysctl_all(int *oid, int len)
996dea673e9SRodney W. Grimes {
9971d86b91cSPoul-Henning Kamp 	int name1[22], name2[22];
998dbf9b92fSDoug Rabson 	int i, j;
999dbf9b92fSDoug Rabson 	size_t l1, l2;
1000dea673e9SRodney W. Grimes 
10011d86b91cSPoul-Henning Kamp 	name1[0] = 0;
10021d86b91cSPoul-Henning Kamp 	name1[1] = 2;
10031d86b91cSPoul-Henning Kamp 	l1 = 2;
10041d86b91cSPoul-Henning Kamp 	if (len) {
10051d86b91cSPoul-Henning Kamp 		memcpy(name1+2, oid, len * sizeof(int));
10061d86b91cSPoul-Henning Kamp 		l1 += len;
10071d86b91cSPoul-Henning Kamp 	} else {
10081d86b91cSPoul-Henning Kamp 		name1[2] = 1;
10091d86b91cSPoul-Henning Kamp 		l1++;
10101d86b91cSPoul-Henning Kamp 	}
1011a89ab9bbSDag-Erling Smørgrav 	for (;;) {
101231fb4661SDima Dorfman 		l2 = sizeof(name2);
10131d86b91cSPoul-Henning Kamp 		j = sysctl(name1, l1, name2, &l2, 0, 0);
1014c1160fe4SBill Fumerola 		if (j < 0) {
10151d86b91cSPoul-Henning Kamp 			if (errno == ENOENT)
101621e1f596SDavid Malone 				return (0);
10171d86b91cSPoul-Henning Kamp 			else
10186d7a8f6cSUlrich Spörlein 				err(1, "sysctl(getnext) %d %zu", j, l2);
1019c1160fe4SBill Fumerola 		}
10201d86b91cSPoul-Henning Kamp 
10211d86b91cSPoul-Henning Kamp 		l2 /= sizeof(int);
10221d86b91cSPoul-Henning Kamp 
1023fd8c668aSDavid Malone 		if (len < 0 || l2 < (unsigned int)len)
102421e1f596SDavid Malone 			return (0);
10251d86b91cSPoul-Henning Kamp 
10261d86b91cSPoul-Henning Kamp 		for (i = 0; i < len; i++)
10271d86b91cSPoul-Henning Kamp 			if (name2[i] != oid[i])
102821e1f596SDavid Malone 				return (0);
10291d86b91cSPoul-Henning Kamp 
10301d86b91cSPoul-Henning Kamp 		i = show_var(name2, l2);
10311d86b91cSPoul-Henning Kamp 		if (!i && !bflag)
10321d86b91cSPoul-Henning Kamp 			putchar('\n');
10331d86b91cSPoul-Henning Kamp 
10341d86b91cSPoul-Henning Kamp 		memcpy(name1+2, name2, l2 * sizeof(int));
10351d86b91cSPoul-Henning Kamp 		l1 = 2 + l2;
10361d86b91cSPoul-Henning Kamp 	}
1037dea673e9SRodney W. Grimes }
1038