xref: /freebsd/sbin/sysctl/sysctl.c (revision c3220d0b6d72a1ed0ccfa188f0dfceef74421ab9)
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),
99*c3220d0bSConrad Meyer 	[CTLTYPE_U8] = sizeof(uint8_t),
100*c3220d0bSConrad Meyer 	[CTLTYPE_U16] = sizeof(uint16_t),
101e267e00eSXin LI };
102e267e00eSXin LI 
103e267e00eSXin LI static const char *ctl_typename[CTLTYPE+1] = {
104e267e00eSXin LI 	[CTLTYPE_INT] = "integer",
105e267e00eSXin LI 	[CTLTYPE_UINT] = "unsigned integer",
106e267e00eSXin LI 	[CTLTYPE_LONG] = "long integer",
107e267e00eSXin LI 	[CTLTYPE_ULONG] = "unsigned long",
108e267e00eSXin LI 	[CTLTYPE_S64] = "int64_t",
109e267e00eSXin LI 	[CTLTYPE_U64] = "uint64_t",
110*c3220d0bSConrad Meyer 	[CTLTYPE_U8] = "uint8_t",
111*c3220d0bSConrad Meyer 	[CTLTYPE_U16] = "uint16_t",
112e267e00eSXin LI };
113d58f0054SPoul-Henning Kamp 
1141d86b91cSPoul-Henning Kamp static void
1151d86b91cSPoul-Henning Kamp usage(void)
1161d86b91cSPoul-Henning Kamp {
117dea673e9SRodney W. Grimes 
1189a2402bcSDag-Erling Smørgrav 	(void)fprintf(stderr, "%s\n%s\n",
11975820005SJohn-Mark Gurney 	    "usage: sysctl [-bdehiNnoqTWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
12075820005SJohn-Mark Gurney 	    "       sysctl [-bdehNnoqTWx] [ -B <bufsize> ] -a");
1211d86b91cSPoul-Henning Kamp 	exit(1);
1221d86b91cSPoul-Henning Kamp }
123dea673e9SRodney W. Grimes 
124dea673e9SRodney W. Grimes int
1251d86b91cSPoul-Henning Kamp main(int argc, char **argv)
126dea673e9SRodney W. Grimes {
1271d86b91cSPoul-Henning Kamp 	int ch;
128da178c77SXin LI 	int warncount = 0;
12945817aaaSDag-Erling Smørgrav 
13045817aaaSDag-Erling Smørgrav 	setlocale(LC_NUMERIC, "");
1311d86b91cSPoul-Henning Kamp 	setbuf(stdout,0);
1321d86b91cSPoul-Henning Kamp 	setbuf(stderr,0);
133dea673e9SRodney W. Grimes 
13475820005SJohn-Mark Gurney 	while ((ch = getopt(argc, argv, "AabB:def:hiNnoqTwWxX")) != -1) {
135dea673e9SRodney W. Grimes 		switch (ch) {
136ca5fac55SDag-Erling Smørgrav 		case 'A':
1379a2402bcSDag-Erling Smørgrav 			/* compatibility */
1389a2402bcSDag-Erling Smørgrav 			aflag = oflag = 1;
139ca5fac55SDag-Erling Smørgrav 			break;
140ca5fac55SDag-Erling Smørgrav 		case 'a':
141ca5fac55SDag-Erling Smørgrav 			aflag = 1;
142ca5fac55SDag-Erling Smørgrav 			break;
143ca5fac55SDag-Erling Smørgrav 		case 'b':
144ca5fac55SDag-Erling Smørgrav 			bflag = 1;
145ca5fac55SDag-Erling Smørgrav 			break;
14675820005SJohn-Mark Gurney 		case 'B':
14775820005SJohn-Mark Gurney 			Bflag = strtol(optarg, NULL, 0);
14875820005SJohn-Mark Gurney 			break;
1496105f815SLuigi Rizzo 		case 'd':
1506105f815SLuigi Rizzo 			dflag = 1;
1516105f815SLuigi Rizzo 			break;
152d0b8aabbSAnton Berezin 		case 'e':
153d0b8aabbSAnton Berezin 			eflag = 1;
154d0b8aabbSAnton Berezin 			break;
155da178c77SXin LI 		case 'f':
156da178c77SXin LI 			conffile = optarg;
157da178c77SXin LI 			break;
15845817aaaSDag-Erling Smørgrav 		case 'h':
15945817aaaSDag-Erling Smørgrav 			hflag = 1;
16045817aaaSDag-Erling Smørgrav 			break;
16124b2aa32SGavin Atkinson 		case 'i':
16224b2aa32SGavin Atkinson 			iflag = 1;
16324b2aa32SGavin Atkinson 			break;
164ca5fac55SDag-Erling Smørgrav 		case 'N':
165ca5fac55SDag-Erling Smørgrav 			Nflag = 1;
166ca5fac55SDag-Erling Smørgrav 			break;
167ca5fac55SDag-Erling Smørgrav 		case 'n':
168ca5fac55SDag-Erling Smørgrav 			nflag = 1;
169ca5fac55SDag-Erling Smørgrav 			break;
1709a2402bcSDag-Erling Smørgrav 		case 'o':
1719a2402bcSDag-Erling Smørgrav 			oflag = 1;
1729a2402bcSDag-Erling Smørgrav 			break;
173f93d36fdSRobert Watson 		case 'q':
174f93d36fdSRobert Watson 			qflag = 1;
175f93d36fdSRobert Watson 			break;
1769ecd2e32SAlfred Perlstein 		case 'T':
1779ecd2e32SAlfred Perlstein 			Tflag = 1;
1789ecd2e32SAlfred Perlstein 			break;
179ca5fac55SDag-Erling Smørgrav 		case 'w':
1809a2402bcSDag-Erling Smørgrav 			/* compatibility */
1819a2402bcSDag-Erling Smørgrav 			/* ignored */
182ca5fac55SDag-Erling Smørgrav 			break;
1839ecd2e32SAlfred Perlstein 		case 'W':
1849ecd2e32SAlfred Perlstein 			Wflag = 1;
1859ecd2e32SAlfred Perlstein 			break;
186ca5fac55SDag-Erling Smørgrav 		case 'X':
1879a2402bcSDag-Erling Smørgrav 			/* compatibility */
1889a2402bcSDag-Erling Smørgrav 			aflag = xflag = 1;
1899a2402bcSDag-Erling Smørgrav 			break;
1909a2402bcSDag-Erling Smørgrav 		case 'x':
1919a2402bcSDag-Erling Smørgrav 			xflag = 1;
192ca5fac55SDag-Erling Smørgrav 			break;
193ca5fac55SDag-Erling Smørgrav 		default:
194ca5fac55SDag-Erling Smørgrav 			usage();
195dea673e9SRodney W. Grimes 		}
196dea673e9SRodney W. Grimes 	}
197dea673e9SRodney W. Grimes 	argc -= optind;
198dea673e9SRodney W. Grimes 	argv += optind;
199dea673e9SRodney W. Grimes 
2009a2402bcSDag-Erling Smørgrav 	if (Nflag && nflag)
20181e7454aSDag-Erling Smørgrav 		usage();
2029a2402bcSDag-Erling Smørgrav 	if (aflag && argc == 0)
2031d86b91cSPoul-Henning Kamp 		exit(sysctl_all(0, 0));
204da178c77SXin LI 	if (argc == 0 && conffile == NULL)
205dea673e9SRodney W. Grimes 		usage();
206d9fcd86cSMike Makonnen 
207d9fcd86cSMike Makonnen 	warncount = 0;
208da178c77SXin LI 	if (conffile != NULL)
209da178c77SXin LI 		warncount += parsefile(conffile);
210da178c77SXin LI 
211dea673e9SRodney W. Grimes 	while (argc-- > 0)
212da178c77SXin LI 		warncount += parse(*argv++, 0);
213da178c77SXin LI 
214da178c77SXin LI 	return (warncount);
215dea673e9SRodney W. Grimes }
216dea673e9SRodney W. Grimes 
217dea673e9SRodney W. Grimes /*
218dea673e9SRodney W. Grimes  * Parse a name into a MIB entry.
219dea673e9SRodney W. Grimes  * Lookup and print out the MIB entry if it exists.
220dea673e9SRodney W. Grimes  * Set a new value if requested.
221dea673e9SRodney W. Grimes  */
222da178c77SXin LI static int
223da178c77SXin LI parse(const char *string, int lineno)
224dea673e9SRodney W. Grimes {
2251d86b91cSPoul-Henning Kamp 	int len, i, j;
226e267e00eSXin LI 	const void *newval;
227e267e00eSXin LI 	const char *newvalstr = NULL;
228*c3220d0bSConrad Meyer 	uint8_t u8val;
229*c3220d0bSConrad Meyer 	uint16_t u16val;
2301ce1a53dSJim Pirzyk 	int intval;
2311ce1a53dSJim Pirzyk 	unsigned int uintval;
2321ce1a53dSJim Pirzyk 	long longval;
2331ce1a53dSJim Pirzyk 	unsigned long ulongval;
23475820005SJohn-Mark Gurney 	size_t newsize = Bflag;
235cbc134adSMatthew D Fleming 	int64_t i64val;
236cbc134adSMatthew D Fleming 	uint64_t u64val;
237dea673e9SRodney W. Grimes 	int mib[CTL_MAXNAME];
238e267e00eSXin LI 	char *cp, *bufp, buf[BUFSIZ], *endptr = NULL, fmt[BUFSIZ], line[BUFSIZ];
2391d86b91cSPoul-Henning Kamp 	u_int kind;
240dea673e9SRodney W. Grimes 
241da178c77SXin LI 	if (lineno)
242da178c77SXin LI 		snprintf(line, sizeof(line), " at line %d", lineno);
243da178c77SXin LI 	else
244da178c77SXin LI 		line[0] = '\0';
245da178c77SXin LI 
246aae75101SXin LI 	cp = buf;
247da178c77SXin LI 	if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) {
248c6919e7fSEdward Tomasz Napierala 		warnx("oid too long: '%s'%s", string, line);
249da178c77SXin LI 		return (1);
250da178c77SXin LI 	}
251da178c77SXin LI 	bufp = strsep(&cp, "=:");
252aae75101SXin LI 	if (cp != NULL) {
2539ecd2e32SAlfred Perlstein 		/* Tflag just lists tunables, do not allow assignment */
2549ecd2e32SAlfred Perlstein 		if (Tflag || Wflag) {
2559ecd2e32SAlfred Perlstein 			warnx("Can't set variables when using -T or -W");
2569ecd2e32SAlfred Perlstein 			usage();
2579ecd2e32SAlfred Perlstein 		}
258dea673e9SRodney W. Grimes 		while (isspace(*cp))
259dea673e9SRodney W. Grimes 			cp++;
260da178c77SXin LI 		/* Strip a pair of " or ' if any. */
261da178c77SXin LI 		switch (*cp) {
262da178c77SXin LI 		case '\"':
263da178c77SXin LI 		case '\'':
264da178c77SXin LI 			if (cp[strlen(cp) - 1] == *cp)
265da178c77SXin LI 				cp[strlen(cp) - 1] = '\0';
266da178c77SXin LI 			cp++;
267da178c77SXin LI 		}
268e267e00eSXin LI 		newvalstr = cp;
269dea673e9SRodney W. Grimes 		newsize = strlen(cp);
270dea673e9SRodney W. Grimes 	}
271ca587fdaSBaptiste Daroussin 	/* Trim spaces */
272ca587fdaSBaptiste Daroussin 	cp = bufp + strlen(bufp) - 1;
273ca587fdaSBaptiste Daroussin 	while (cp >= bufp && isspace((int)*cp)) {
274ca587fdaSBaptiste Daroussin 		*cp = '\0';
275ca587fdaSBaptiste Daroussin 		cp--;
276ca587fdaSBaptiste Daroussin 	}
2771d86b91cSPoul-Henning Kamp 	len = name2oid(bufp, mib);
2781d86b91cSPoul-Henning Kamp 
279f93d36fdSRobert Watson 	if (len < 0) {
28024b2aa32SGavin Atkinson 		if (iflag)
281da178c77SXin LI 			return (0);
282f93d36fdSRobert Watson 		if (qflag)
283da178c77SXin LI 			return (1);
284da178c77SXin LI 		else {
285e1619d12SBaptiste Daroussin 			if (errno == ENOENT) {
286e1619d12SBaptiste Daroussin 				warnx("unknown oid '%s'%s", bufp, line);
287e1619d12SBaptiste Daroussin 			} else {
288da178c77SXin LI 				warn("unknown oid '%s'%s", bufp, line);
289e1619d12SBaptiste Daroussin 			}
290da178c77SXin LI 			return (1);
291da178c77SXin LI 		}
292f93d36fdSRobert Watson 	}
2931d86b91cSPoul-Henning Kamp 
294da178c77SXin LI 	if (oidfmt(mib, len, fmt, &kind)) {
295da178c77SXin LI 		warn("couldn't find format of oid '%s'%s", bufp, line);
296da178c77SXin LI 		if (iflag)
297da178c77SXin LI 			return (1);
298da178c77SXin LI 		else
299da178c77SXin LI 			exit(1);
300da178c77SXin LI 	}
3011d86b91cSPoul-Henning Kamp 
302e267e00eSXin LI 	if (newvalstr == NULL || dflag) {
3031d86b91cSPoul-Henning Kamp 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
304b2680e20SMatthew N. Dodd 			if (dflag) {
305b2680e20SMatthew N. Dodd 				i = show_var(mib, len);
306b2680e20SMatthew N. Dodd 				if (!i && !bflag)
307b2680e20SMatthew N. Dodd 					putchar('\n');
308b2680e20SMatthew N. Dodd 			}
3091d86b91cSPoul-Henning Kamp 			sysctl_all(mib, len);
3101d86b91cSPoul-Henning Kamp 		} else {
3111d86b91cSPoul-Henning Kamp 			i = show_var(mib, len);
3121d86b91cSPoul-Henning Kamp 			if (!i && !bflag)
3131d86b91cSPoul-Henning Kamp 				putchar('\n');
314dea673e9SRodney W. Grimes 		}
3151d86b91cSPoul-Henning Kamp 	} else {
316da178c77SXin LI 		if ((kind & CTLTYPE) == CTLTYPE_NODE) {
317c6919e7fSEdward Tomasz Napierala 			warnx("oid '%s' isn't a leaf node%s", bufp, line);
318da178c77SXin LI 			return (1);
319da178c77SXin LI 		}
320dea673e9SRodney W. Grimes 
321ac8711d2SMike Silbersack 		if (!(kind & CTLFLAG_WR)) {
3229b4b73b7SMike Silbersack 			if (kind & CTLFLAG_TUN) {
3236f361351SXin LI 				warnx("oid '%s' is a read only tunable%s", bufp, line);
324da178c77SXin LI 				warnx("Tunable values are set in /boot/loader.conf");
325da178c77SXin LI 			} else
326da178c77SXin LI 				warnx("oid '%s' is read only%s", bufp, line);
327da178c77SXin LI 			return (1);
328ac8711d2SMike Silbersack 		}
329dea673e9SRodney W. Grimes 
330e267e00eSXin LI 		switch (kind & CTLTYPE) {
331*c3220d0bSConrad Meyer 		case CTLTYPE_U8:
332*c3220d0bSConrad Meyer 		case CTLTYPE_U16:
333e267e00eSXin LI 		case CTLTYPE_INT:
334e267e00eSXin LI 		case CTLTYPE_UINT:
335e267e00eSXin LI 		case CTLTYPE_LONG:
336e267e00eSXin LI 		case CTLTYPE_ULONG:
337e267e00eSXin LI 		case CTLTYPE_S64:
338e267e00eSXin LI 		case CTLTYPE_U64:
339e267e00eSXin LI 			if (strlen(newvalstr) == 0) {
340da178c77SXin LI 				warnx("empty numeric value");
341da178c77SXin LI 				return (1);
342da178c77SXin LI 			}
343e267e00eSXin LI 			/* FALLTHROUGH */
344e267e00eSXin LI 		case CTLTYPE_STRING:
345e267e00eSXin LI 			break;
346e267e00eSXin LI 		default:
347e267e00eSXin LI 			warnx("oid '%s' is type %d,"
348e267e00eSXin LI 				" cannot set that%s", bufp,
349e267e00eSXin LI 				kind & CTLTYPE, line);
350e267e00eSXin LI 			return (1);
351a78d3eafSRobert Watson 		}
352a78d3eafSRobert Watson 
3534b8740cdSXin LI 		errno = 0;
3544b8740cdSXin LI 
3551d86b91cSPoul-Henning Kamp 		switch (kind & CTLTYPE) {
356*c3220d0bSConrad Meyer 			case CTLTYPE_U8:
357*c3220d0bSConrad Meyer 				u8val = (uint8_t)strtoul(newvalstr, &endptr, 0);
358*c3220d0bSConrad Meyer 				newval = &u8val;
359*c3220d0bSConrad Meyer 				newsize = sizeof(u8val);
360*c3220d0bSConrad Meyer 				break;
361*c3220d0bSConrad Meyer 			case CTLTYPE_U16:
362*c3220d0bSConrad Meyer 				u16val = (uint16_t)strtoul(newvalstr, &endptr, 0);
363*c3220d0bSConrad Meyer 				newval = &u16val;
364*c3220d0bSConrad Meyer 				newsize = sizeof(u16val);
365*c3220d0bSConrad Meyer 				break;
366dea673e9SRodney W. Grimes 			case CTLTYPE_INT:
367aa255ef6SWarner Losh 				if (strncmp(fmt, "IK", 2) == 0)
368aa255ef6SWarner Losh 					intval = strIKtoi(newvalstr, &endptr, fmt);
369e267e00eSXin LI 				else
370e267e00eSXin LI 					intval = (int)strtol(newvalstr, &endptr,
371d45564dcSHajimu UMEMOTO 					    0);
372dea673e9SRodney W. Grimes 				newval = &intval;
37331fb4661SDima Dorfman 				newsize = sizeof(intval);
374dea673e9SRodney W. Grimes 				break;
3751ce1a53dSJim Pirzyk 			case CTLTYPE_UINT:
376e267e00eSXin LI 				uintval = (int) strtoul(newvalstr, &endptr, 0);
3771ce1a53dSJim Pirzyk 				newval = &uintval;
37821e1f596SDavid Malone 				newsize = sizeof(uintval);
3791ce1a53dSJim Pirzyk 				break;
3801ce1a53dSJim Pirzyk 			case CTLTYPE_LONG:
381e267e00eSXin LI 				longval = strtol(newvalstr, &endptr, 0);
3821ce1a53dSJim Pirzyk 				newval = &longval;
38321e1f596SDavid Malone 				newsize = sizeof(longval);
3841ce1a53dSJim Pirzyk 				break;
3851ce1a53dSJim Pirzyk 			case CTLTYPE_ULONG:
386e267e00eSXin LI 				ulongval = strtoul(newvalstr, &endptr, 0);
3871ce1a53dSJim Pirzyk 				newval = &ulongval;
38821e1f596SDavid Malone 				newsize = sizeof(ulongval);
3891d86b91cSPoul-Henning Kamp 				break;
3901d86b91cSPoul-Henning Kamp 			case CTLTYPE_STRING:
391e267e00eSXin LI 				newval = newvalstr;
3921d86b91cSPoul-Henning Kamp 				break;
393cbc134adSMatthew D Fleming 			case CTLTYPE_S64:
394e267e00eSXin LI 				i64val = strtoimax(newvalstr, &endptr, 0);
395cbc134adSMatthew D Fleming 				newval = &i64val;
396cbc134adSMatthew D Fleming 				newsize = sizeof(i64val);
397cbc134adSMatthew D Fleming 				break;
398cbc134adSMatthew D Fleming 			case CTLTYPE_U64:
399e267e00eSXin LI 				u64val = strtoumax(newvalstr, &endptr, 0);
400cbc134adSMatthew D Fleming 				newval = &u64val;
401cbc134adSMatthew D Fleming 				newsize = sizeof(u64val);
402dea673e9SRodney W. Grimes 				break;
4031d86b91cSPoul-Henning Kamp 			default:
404e267e00eSXin LI 				/* NOTREACHED */
405e267e00eSXin LI 				abort();
406e267e00eSXin LI 		}
407e267e00eSXin LI 
408e267e00eSXin LI 		if (errno != 0 || endptr == newvalstr ||
409e267e00eSXin LI 		    (endptr != NULL && *endptr != '\0')) {
410e267e00eSXin LI 			warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE],
411e267e00eSXin LI 			    newvalstr, line);
412da178c77SXin LI 			return (1);
413dea673e9SRodney W. Grimes 		}
4141d86b91cSPoul-Henning Kamp 
4151d86b91cSPoul-Henning Kamp 		i = show_var(mib, len);
4161d86b91cSPoul-Henning Kamp 		if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
4171d86b91cSPoul-Henning Kamp 			if (!i && !bflag)
4181d86b91cSPoul-Henning Kamp 				putchar('\n');
419dea673e9SRodney W. Grimes 			switch (errno) {
420dea673e9SRodney W. Grimes 			case EOPNOTSUPP:
421da178c77SXin LI 				warnx("%s: value is not available%s",
422da178c77SXin LI 					string, line);
423da178c77SXin LI 				return (1);
424dea673e9SRodney W. Grimes 			case ENOTDIR:
425da178c77SXin LI 				warnx("%s: specification is incomplete%s",
426da178c77SXin LI 					string, line);
427da178c77SXin LI 				return (1);
428dea673e9SRodney W. Grimes 			case ENOMEM:
429da178c77SXin LI 				warnx("%s: type is unknown to this program%s",
430da178c77SXin LI 					string, line);
431da178c77SXin LI 				return (1);
432dea673e9SRodney W. Grimes 			default:
433da178c77SXin LI 				warn("%s%s", string, line);
434da178c77SXin LI 				return (1);
435dea673e9SRodney W. Grimes 			}
436dea673e9SRodney W. Grimes 		}
4371d86b91cSPoul-Henning Kamp 		if (!bflag)
4381d86b91cSPoul-Henning Kamp 			printf(" -> ");
4391d86b91cSPoul-Henning Kamp 		i = nflag;
4401d86b91cSPoul-Henning Kamp 		nflag = 1;
4411d86b91cSPoul-Henning Kamp 		j = show_var(mib, len);
4421d86b91cSPoul-Henning Kamp 		if (!j && !bflag)
4431d86b91cSPoul-Henning Kamp 			putchar('\n');
4441d86b91cSPoul-Henning Kamp 		nflag = i;
445dea673e9SRodney W. Grimes 	}
446da178c77SXin LI 
447da178c77SXin LI 	return (0);
448da178c77SXin LI }
449da178c77SXin LI 
450da178c77SXin LI static int
451da178c77SXin LI parsefile(const char *filename)
452da178c77SXin LI {
453da178c77SXin LI 	FILE *file;
454da178c77SXin LI 	char line[BUFSIZ], *p, *pq, *pdq;
455da178c77SXin LI 	int warncount = 0, lineno = 0;
456da178c77SXin LI 
457da178c77SXin LI 	file = fopen(filename, "r");
458da178c77SXin LI 	if (file == NULL)
459da178c77SXin LI 		err(EX_NOINPUT, "%s", filename);
460da178c77SXin LI 	while (fgets(line, sizeof(line), file) != NULL) {
461da178c77SXin LI 		lineno++;
462da178c77SXin LI 		p = line;
463da178c77SXin LI 		pq = strchr(line, '\'');
464da178c77SXin LI 		pdq = strchr(line, '\"');
465da178c77SXin LI 		/* Replace the first # with \0. */
466da178c77SXin LI 		while((p = strchr(p, '#')) != NULL) {
467da178c77SXin LI 			if (pq != NULL && p > pq) {
468da178c77SXin LI 				if ((p = strchr(pq+1, '\'')) != NULL)
469da178c77SXin LI 					*(++p) = '\0';
470da178c77SXin LI 				break;
471da178c77SXin LI 			} else if (pdq != NULL && p > pdq) {
472da178c77SXin LI 				if ((p = strchr(pdq+1, '\"')) != NULL)
473da178c77SXin LI 					*(++p) = '\0';
474da178c77SXin LI 				break;
475da178c77SXin LI 			} else if (p == line || *(p-1) != '\\') {
476da178c77SXin LI 				*p = '\0';
477da178c77SXin LI 				break;
478da178c77SXin LI 			}
479da178c77SXin LI 			p++;
480da178c77SXin LI 		}
481da178c77SXin LI 		/* Trim spaces */
482da178c77SXin LI 		p = line + strlen(line) - 1;
483da178c77SXin LI 		while (p >= line && isspace((int)*p)) {
484da178c77SXin LI 			*p = '\0';
485da178c77SXin LI 			p--;
486da178c77SXin LI 		}
487da178c77SXin LI 		p = line;
488da178c77SXin LI 		while (isspace((int)*p))
489da178c77SXin LI 			p++;
490da178c77SXin LI 		if (*p == '\0')
491da178c77SXin LI 			continue;
492da178c77SXin LI 		else
493da178c77SXin LI 			warncount += parse(p, lineno);
494da178c77SXin LI 	}
495da178c77SXin LI 	fclose(file);
496da178c77SXin LI 
497da178c77SXin LI 	return (warncount);
498dea673e9SRodney W. Grimes }
499dea673e9SRodney W. Grimes 
5001d86b91cSPoul-Henning Kamp /* These functions will dump out various interesting structures. */
501dea673e9SRodney W. Grimes 
5021d86b91cSPoul-Henning Kamp static int
50359101c5dSJohn Baldwin S_clockinfo(size_t l2, void *p)
5041d86b91cSPoul-Henning Kamp {
5051d86b91cSPoul-Henning Kamp 	struct clockinfo *ci = (struct clockinfo*)p;
50621e1f596SDavid Malone 
507996076bbSAlfred Perlstein 	if (l2 != sizeof(*ci)) {
50859101c5dSJohn Baldwin 		warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci));
5096b6b665bSBruce Evans 		return (1);
510996076bbSAlfred Perlstein 	}
51145817aaaSDag-Erling Smørgrav 	printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
51245817aaaSDag-Erling Smørgrav 		"{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
513b35c8f28SPoul-Henning Kamp 		ci->hz, ci->tick, ci->profhz, ci->stathz);
5141d86b91cSPoul-Henning Kamp 	return (0);
515dea673e9SRodney W. Grimes }
516dea673e9SRodney W. Grimes 
5171d86b91cSPoul-Henning Kamp static int
51859101c5dSJohn Baldwin S_loadavg(size_t l2, void *p)
5191d86b91cSPoul-Henning Kamp {
5201d86b91cSPoul-Henning Kamp 	struct loadavg *tv = (struct loadavg*)p;
5211d86b91cSPoul-Henning Kamp 
522996076bbSAlfred Perlstein 	if (l2 != sizeof(*tv)) {
52359101c5dSJohn Baldwin 		warnx("S_loadavg %zu != %zu", l2, sizeof(*tv));
5246b6b665bSBruce Evans 		return (1);
525996076bbSAlfred Perlstein 	}
52645817aaaSDag-Erling Smørgrav 	printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
5271d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[0]/(double)tv->fscale,
5281d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[1]/(double)tv->fscale,
5291d86b91cSPoul-Henning Kamp 		(double)tv->ldavg[2]/(double)tv->fscale);
5301d86b91cSPoul-Henning Kamp 	return (0);
531dea673e9SRodney W. Grimes }
532dea673e9SRodney W. Grimes 
5331d86b91cSPoul-Henning Kamp static int
53459101c5dSJohn Baldwin S_timeval(size_t l2, void *p)
5351d86b91cSPoul-Henning Kamp {
5361d86b91cSPoul-Henning Kamp 	struct timeval *tv = (struct timeval*)p;
537c2deb608SBruce Evans 	time_t tv_sec;
5381d86b91cSPoul-Henning Kamp 	char *p1, *p2;
539dea673e9SRodney W. Grimes 
540996076bbSAlfred Perlstein 	if (l2 != sizeof(*tv)) {
54159101c5dSJohn Baldwin 		warnx("S_timeval %zu != %zu", l2, sizeof(*tv));
5426b6b665bSBruce Evans 		return (1);
543996076bbSAlfred Perlstein 	}
544db87e2dcSJohn Hay 	printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
545db87e2dcSJohn Hay 		"{ sec = %jd, usec = %ld } ",
546db87e2dcSJohn Hay 		(intmax_t)tv->tv_sec, tv->tv_usec);
547c2deb608SBruce Evans 	tv_sec = tv->tv_sec;
548c2deb608SBruce Evans 	p1 = strdup(ctime(&tv_sec));
5491d86b91cSPoul-Henning Kamp 	for (p2=p1; *p2 ; p2++)
5501d86b91cSPoul-Henning Kamp 		if (*p2 == '\n')
5511d86b91cSPoul-Henning Kamp 			*p2 = '\0';
5521d86b91cSPoul-Henning Kamp 	fputs(p1, stdout);
553f2359a24SRebecca Cran 	free(p1);
5541d86b91cSPoul-Henning Kamp 	return (0);
5551d86b91cSPoul-Henning Kamp }
5561d86b91cSPoul-Henning Kamp 
5571d86b91cSPoul-Henning Kamp static int
55859101c5dSJohn Baldwin S_vmtotal(size_t l2, void *p)
559f7550ecfSMatthew Dillon {
560f7550ecfSMatthew Dillon 	struct vmtotal *v = (struct vmtotal *)p;
561654e22e7SMatthew Dillon 	int pageKilo = getpagesize() / 1024;
562f7550ecfSMatthew Dillon 
563f7550ecfSMatthew Dillon 	if (l2 != sizeof(*v)) {
56459101c5dSJohn Baldwin 		warnx("S_vmtotal %zu != %zu", l2, sizeof(*v));
5656b6b665bSBruce Evans 		return (1);
566f7550ecfSMatthew Dillon 	}
567f7550ecfSMatthew Dillon 
568654e22e7SMatthew Dillon 	printf(
569654e22e7SMatthew Dillon 	    "\nSystem wide totals computed every five seconds:"
570654e22e7SMatthew Dillon 	    " (values in kilobytes)\n");
571f7550ecfSMatthew Dillon 	printf("===============================================\n");
572654e22e7SMatthew Dillon 	printf(
573bad4d172SRuslan Ermilov 	    "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
574bad4d172SRuslan Ermilov 	    "%hd Sleep: %hd)\n",
575f7550ecfSMatthew Dillon 	    v->t_rq, v->t_dw, v->t_pw, v->t_sl);
576654e22e7SMatthew Dillon 	printf(
57713e86ef7SMarko Zec 	    "Virtual Memory:\t\t(Total: %dK Active: %dK)\n",
578bad4d172SRuslan Ermilov 	    v->t_vm * pageKilo, v->t_avm * pageKilo);
57913e86ef7SMarko Zec 	printf("Real Memory:\t\t(Total: %dK Active: %dK)\n",
580bad4d172SRuslan Ermilov 	    v->t_rm * pageKilo, v->t_arm * pageKilo);
581bad4d172SRuslan Ermilov 	printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n",
582bad4d172SRuslan Ermilov 	    v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
583bad4d172SRuslan Ermilov 	printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
584bad4d172SRuslan Ermilov 	    v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
58559101c5dSJohn Baldwin 	printf("Free Memory:\t%dK", v->t_free * pageKilo);
586f7550ecfSMatthew Dillon 
587f7550ecfSMatthew Dillon 	return (0);
588f7550ecfSMatthew Dillon }
589f7550ecfSMatthew Dillon 
5907d8312ccSJohn Baldwin #ifdef __amd64__
5917d8312ccSJohn Baldwin #define efi_next_descriptor(ptr, size) \
5927d8312ccSJohn Baldwin 	((struct efi_md *)(((uint8_t *) ptr) + size))
5937d8312ccSJohn Baldwin 
5947d8312ccSJohn Baldwin static int
5957d8312ccSJohn Baldwin S_efi_map(size_t l2, void *p)
5967d8312ccSJohn Baldwin {
5977d8312ccSJohn Baldwin 	struct efi_map_header *efihdr;
5987d8312ccSJohn Baldwin 	struct efi_md *map;
5997d8312ccSJohn Baldwin 	const char *type;
6007d8312ccSJohn Baldwin 	size_t efisz;
6017d8312ccSJohn Baldwin 	int ndesc, i;
6027d8312ccSJohn Baldwin 
6037d8312ccSJohn Baldwin 	static const char *types[] = {
6047d8312ccSJohn Baldwin 		"Reserved",
6057d8312ccSJohn Baldwin 		"LoaderCode",
6067d8312ccSJohn Baldwin 		"LoaderData",
6077d8312ccSJohn Baldwin 		"BootServicesCode",
6087d8312ccSJohn Baldwin 		"BootServicesData",
6097d8312ccSJohn Baldwin 		"RuntimeServicesCode",
6107d8312ccSJohn Baldwin 		"RuntimeServicesData",
6117d8312ccSJohn Baldwin 		"ConventionalMemory",
6127d8312ccSJohn Baldwin 		"UnusableMemory",
6137d8312ccSJohn Baldwin 		"ACPIReclaimMemory",
6147d8312ccSJohn Baldwin 		"ACPIMemoryNVS",
6157d8312ccSJohn Baldwin 		"MemoryMappedIO",
6167d8312ccSJohn Baldwin 		"MemoryMappedIOPortSpace",
6177d8312ccSJohn Baldwin 		"PalCode"
6187d8312ccSJohn Baldwin 	};
6197d8312ccSJohn Baldwin 
6207d8312ccSJohn Baldwin 	/*
6217d8312ccSJohn Baldwin 	 * Memory map data provided by UEFI via the GetMemoryMap
6227d8312ccSJohn Baldwin 	 * Boot Services API.
6237d8312ccSJohn Baldwin 	 */
6247d8312ccSJohn Baldwin 	if (l2 < sizeof(*efihdr)) {
6257d8312ccSJohn Baldwin 		warnx("S_efi_map length less than header");
6267d8312ccSJohn Baldwin 		return (1);
6277d8312ccSJohn Baldwin 	}
6287d8312ccSJohn Baldwin 	efihdr = p;
6297d8312ccSJohn Baldwin 	efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
6307d8312ccSJohn Baldwin 	map = (struct efi_md *)((uint8_t *)efihdr + efisz);
6317d8312ccSJohn Baldwin 
6327d8312ccSJohn Baldwin 	if (efihdr->descriptor_size == 0)
6337d8312ccSJohn Baldwin 		return (0);
6347d8312ccSJohn Baldwin 	if (l2 != efisz + efihdr->memory_size) {
6357d8312ccSJohn Baldwin 		warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz +
6367d8312ccSJohn Baldwin 		    efihdr->memory_size);
6377d8312ccSJohn Baldwin 		return (1);
6387d8312ccSJohn Baldwin 	}
6397d8312ccSJohn Baldwin 	ndesc = efihdr->memory_size / efihdr->descriptor_size;
6407d8312ccSJohn Baldwin 
6417d8312ccSJohn Baldwin 	printf("\n%23s %12s %12s %8s %4s",
6427d8312ccSJohn Baldwin 	    "Type", "Physical", "Virtual", "#Pages", "Attr");
6437d8312ccSJohn Baldwin 
6447d8312ccSJohn Baldwin 	for (i = 0; i < ndesc; i++,
6457d8312ccSJohn Baldwin 	    map = efi_next_descriptor(map, efihdr->descriptor_size)) {
6467d8312ccSJohn Baldwin 		if (map->md_type <= EFI_MD_TYPE_PALCODE)
6477d8312ccSJohn Baldwin 			type = types[map->md_type];
6487d8312ccSJohn Baldwin 		else
6497d8312ccSJohn Baldwin 			type = "<INVALID>";
6507d8312ccSJohn Baldwin 		printf("\n%23s %012lx %12p %08lx ", type, map->md_phys,
6517d8312ccSJohn Baldwin 		    map->md_virt, map->md_pages);
6527d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_UC)
6537d8312ccSJohn Baldwin 			printf("UC ");
6547d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WC)
6557d8312ccSJohn Baldwin 			printf("WC ");
6567d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WT)
6577d8312ccSJohn Baldwin 			printf("WT ");
6587d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WB)
6597d8312ccSJohn Baldwin 			printf("WB ");
6607d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_UCE)
6617d8312ccSJohn Baldwin 			printf("UCE ");
6627d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_WP)
6637d8312ccSJohn Baldwin 			printf("WP ");
6647d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_RP)
6657d8312ccSJohn Baldwin 			printf("RP ");
6667d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_XP)
6677d8312ccSJohn Baldwin 			printf("XP ");
6687d8312ccSJohn Baldwin 		if (map->md_attr & EFI_MD_ATTR_RT)
6697d8312ccSJohn Baldwin 			printf("RUNTIME");
6707d8312ccSJohn Baldwin 	}
6717d8312ccSJohn Baldwin 	return (0);
6727d8312ccSJohn Baldwin }
6737d8312ccSJohn Baldwin #endif
6747d8312ccSJohn Baldwin 
67589871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
67689871cdeSJohn Baldwin static int
67759101c5dSJohn Baldwin S_bios_smap_xattr(size_t l2, void *p)
67889871cdeSJohn Baldwin {
67989871cdeSJohn Baldwin 	struct bios_smap_xattr *smap, *end;
68089871cdeSJohn Baldwin 
68189871cdeSJohn Baldwin 	if (l2 % sizeof(*smap) != 0) {
68259101c5dSJohn Baldwin 		warnx("S_bios_smap_xattr %zu is not a multiple of %zu", l2,
68389871cdeSJohn Baldwin 		    sizeof(*smap));
68489871cdeSJohn Baldwin 		return (1);
68589871cdeSJohn Baldwin 	}
68689871cdeSJohn Baldwin 
68789871cdeSJohn Baldwin 	end = (struct bios_smap_xattr *)((char *)p + l2);
68889871cdeSJohn Baldwin 	for (smap = p; smap < end; smap++)
68989871cdeSJohn Baldwin 		printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx",
69089871cdeSJohn Baldwin 		    smap->type, smap->xattr, (uintmax_t)smap->base,
69189871cdeSJohn Baldwin 		    (uintmax_t)smap->length);
69289871cdeSJohn Baldwin 	return (0);
69389871cdeSJohn Baldwin }
69489871cdeSJohn Baldwin #endif
69589871cdeSJohn Baldwin 
696f7550ecfSMatthew Dillon static int
697aa255ef6SWarner Losh strIKtoi(const char *str, char **endptrp, const char *fmt)
698d45564dcSHajimu UMEMOTO {
699e267e00eSXin LI 	int kelv;
700d45564dcSHajimu UMEMOTO 	float temp;
701e267e00eSXin LI 	size_t len;
702a7b5ad27SEd Schouten 	const char *p;
703aa255ef6SWarner Losh 	int prec, i;
704d45564dcSHajimu UMEMOTO 
705e267e00eSXin LI 	assert(errno == 0);
706e267e00eSXin LI 
707e267e00eSXin LI 	len = strlen(str);
708e267e00eSXin LI 	/* caller already checked this */
709e267e00eSXin LI 	assert(len > 0);
710e267e00eSXin LI 
711aa255ef6SWarner Losh 	/*
712aa255ef6SWarner Losh 	 * A format of "IK" is in deciKelvin. A format of "IK3" is in
713aa255ef6SWarner Losh 	 * milliKelvin. The single digit following IK is log10 of the
714aa255ef6SWarner Losh 	 * multiplying factor to convert Kelvin into the untis of this sysctl,
715aa255ef6SWarner Losh 	 * or the dividing factor to convert the sysctl value to Kelvin. Numbers
716aa255ef6SWarner Losh 	 * larger than 6 will run into precision issues with 32-bit integers.
717aa255ef6SWarner Losh 	 * Characters that aren't ASCII digits after the 'K' are ignored. No
718aa255ef6SWarner Losh 	 * localization is present because this is an interface from the kernel
719aa255ef6SWarner Losh 	 * to this program (eg not an end-user interface), so isdigit() isn't
720aa255ef6SWarner Losh 	 * used here.
721aa255ef6SWarner Losh 	 */
722aa255ef6SWarner Losh 	if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9')
723aa255ef6SWarner Losh 		prec = fmt[2] - '0';
724aa255ef6SWarner Losh 	else
725aa255ef6SWarner Losh 		prec = 1;
726d45564dcSHajimu UMEMOTO 	p = &str[len - 1];
727aa255ef6SWarner Losh 	if (*p == 'C' || *p == 'F' || *p == 'K') {
728e267e00eSXin LI 		temp = strtof(str, endptrp);
729689c8e8bSXin LI 		if (*endptrp != str && *endptrp == p && errno == 0) {
730d45564dcSHajimu UMEMOTO 			if (*p == 'F')
731d45564dcSHajimu UMEMOTO 				temp = (temp - 32) * 5 / 9;
732689c8e8bSXin LI 			*endptrp = NULL;
733aa255ef6SWarner Losh 			if (*p != 'K')
734aa255ef6SWarner Losh 				temp += 273.15;
735aa255ef6SWarner Losh 			for (i = 0; i < prec; i++)
736aa255ef6SWarner Losh 				temp *= 10.0;
737aa255ef6SWarner Losh 			return ((int)(temp + 0.5));
738d45564dcSHajimu UMEMOTO 		}
739e267e00eSXin LI 	} else {
740aa255ef6SWarner Losh 		/* No unit specified -> treat it as a raw number */
741e267e00eSXin LI 		kelv = (int)strtol(str, endptrp, 10);
742689c8e8bSXin LI 		if (*endptrp != str && *endptrp == p && errno == 0) {
743689c8e8bSXin LI 			*endptrp = NULL;
744e267e00eSXin LI 			return (kelv);
745e267e00eSXin LI 		}
746689c8e8bSXin LI 	}
747e267e00eSXin LI 
748e267e00eSXin LI 	errno = ERANGE;
749e267e00eSXin LI 	return (0);
750d45564dcSHajimu UMEMOTO }
751d45564dcSHajimu UMEMOTO 
7521d86b91cSPoul-Henning Kamp /*
7531d86b91cSPoul-Henning Kamp  * These functions uses a presently undocumented interface to the kernel
7541d86b91cSPoul-Henning Kamp  * to walk the tree and get the type so it can print the value.
7551d86b91cSPoul-Henning Kamp  * This interface is under work and consideration, and should probably
7561d86b91cSPoul-Henning Kamp  * be killed with a big axe by the first person who can find the time.
7571d86b91cSPoul-Henning Kamp  * (be aware though, that the proper interface isn't as obvious as it
7581d86b91cSPoul-Henning Kamp  * may seem, there are various conflicting requirements.
7591d86b91cSPoul-Henning Kamp  */
7601d86b91cSPoul-Henning Kamp 
7611d86b91cSPoul-Henning Kamp static int
762c58f8df6SXin LI name2oid(const char *name, int *oidp)
7631d86b91cSPoul-Henning Kamp {
7641d86b91cSPoul-Henning Kamp 	int oid[2];
765dbf9b92fSDoug Rabson 	int i;
766dbf9b92fSDoug Rabson 	size_t j;
7671d86b91cSPoul-Henning Kamp 
7681d86b91cSPoul-Henning Kamp 	oid[0] = 0;
7691d86b91cSPoul-Henning Kamp 	oid[1] = 3;
7701d86b91cSPoul-Henning Kamp 
7711d86b91cSPoul-Henning Kamp 	j = CTL_MAXNAME * sizeof(int);
7721d86b91cSPoul-Henning Kamp 	i = sysctl(oid, 2, oidp, &j, name, strlen(name));
7731d86b91cSPoul-Henning Kamp 	if (i < 0)
77421e1f596SDavid Malone 		return (i);
7751d86b91cSPoul-Henning Kamp 	j /= sizeof(int);
7761d86b91cSPoul-Henning Kamp 	return (j);
7771d86b91cSPoul-Henning Kamp }
7781d86b91cSPoul-Henning Kamp 
7791d86b91cSPoul-Henning Kamp static int
7801d86b91cSPoul-Henning Kamp oidfmt(int *oid, int len, char *fmt, u_int *kind)
7811d86b91cSPoul-Henning Kamp {
7821d86b91cSPoul-Henning Kamp 	int qoid[CTL_MAXNAME+2];
7831d86b91cSPoul-Henning Kamp 	u_char buf[BUFSIZ];
784dbf9b92fSDoug Rabson 	int i;
785dbf9b92fSDoug Rabson 	size_t j;
7861d86b91cSPoul-Henning Kamp 
7871d86b91cSPoul-Henning Kamp 	qoid[0] = 0;
7881d86b91cSPoul-Henning Kamp 	qoid[1] = 4;
7891d86b91cSPoul-Henning Kamp 	memcpy(qoid + 2, oid, len * sizeof(int));
7901d86b91cSPoul-Henning Kamp 
79131fb4661SDima Dorfman 	j = sizeof(buf);
7921d86b91cSPoul-Henning Kamp 	i = sysctl(qoid, len + 2, buf, &j, 0, 0);
7931d86b91cSPoul-Henning Kamp 	if (i)
7946d7a8f6cSUlrich Spörlein 		err(1, "sysctl fmt %d %zu %d", i, j, errno);
7951d86b91cSPoul-Henning Kamp 
7961d86b91cSPoul-Henning Kamp 	if (kind)
7971d86b91cSPoul-Henning Kamp 		*kind = *(u_int *)buf;
7981d86b91cSPoul-Henning Kamp 
7991d86b91cSPoul-Henning Kamp 	if (fmt)
8001d86b91cSPoul-Henning Kamp 		strcpy(fmt, (char *)(buf + sizeof(u_int)));
80121e1f596SDavid Malone 	return (0);
8021d86b91cSPoul-Henning Kamp }
8031d86b91cSPoul-Henning Kamp 
80460cf2c12SLuigi Rizzo /*
8051d86b91cSPoul-Henning Kamp  * This formats and outputs the value of one variable
8061d86b91cSPoul-Henning Kamp  *
8071d86b91cSPoul-Henning Kamp  * Returns zero if anything was actually output.
8081d86b91cSPoul-Henning Kamp  * Returns one if didn't know what to do with this.
8091d86b91cSPoul-Henning Kamp  * Return minus one if we had errors.
8101d86b91cSPoul-Henning Kamp  */
8111d86b91cSPoul-Henning Kamp static int
8121d86b91cSPoul-Henning Kamp show_var(int *oid, int nlen)
8131d86b91cSPoul-Henning Kamp {
814ccf25977SRuslan Ermilov 	u_char buf[BUFSIZ], *val, *oval, *p;
815403c7f59SAlfred Perlstein 	char name[BUFSIZ], fmt[BUFSIZ];
816fd8c668aSDavid Malone 	const char *sep, *sep1;
8171d86b91cSPoul-Henning Kamp 	int qoid[CTL_MAXNAME+2];
81821e1f596SDavid Malone 	uintmax_t umv;
81921e1f596SDavid Malone 	intmax_t mv;
820f8e4b4efSMatthew D Fleming 	int i, hexlen, sign, ctltype;
82141e419cbSDavid Malone 	size_t intlen;
822dbf9b92fSDoug Rabson 	size_t j, len;
8231d86b91cSPoul-Henning Kamp 	u_int kind;
824aa255ef6SWarner Losh 	float base;
82559101c5dSJohn Baldwin 	int (*func)(size_t, void *);
826aa255ef6SWarner Losh 	int prec;
8271d86b91cSPoul-Henning Kamp 
8286d7a8f6cSUlrich Spörlein 	/* Silence GCC. */
8296d7a8f6cSUlrich Spörlein 	umv = mv = intlen = 0;
8306d7a8f6cSUlrich Spörlein 
8319f98e452SMatthew N. Dodd 	bzero(buf, BUFSIZ);
832403c7f59SAlfred Perlstein 	bzero(fmt, BUFSIZ);
8339f98e452SMatthew N. Dodd 	bzero(name, BUFSIZ);
83481e7454aSDag-Erling Smørgrav 	qoid[0] = 0;
83581e7454aSDag-Erling Smørgrav 	memcpy(qoid + 2, oid, nlen * sizeof(int));
83681e7454aSDag-Erling Smørgrav 
83781e7454aSDag-Erling Smørgrav 	qoid[1] = 1;
83831fb4661SDima Dorfman 	j = sizeof(name);
83981e7454aSDag-Erling Smørgrav 	i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
84081e7454aSDag-Erling Smørgrav 	if (i || !j)
8416d7a8f6cSUlrich Spörlein 		err(1, "sysctl name %d %zu %d", i, j, errno);
84281e7454aSDag-Erling Smørgrav 
843403c7f59SAlfred Perlstein 	oidfmt(oid, nlen, fmt, &kind);
844403c7f59SAlfred Perlstein 	/* if Wflag then only list sysctls that are writeable and not stats. */
845403c7f59SAlfred Perlstein 	if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0))
846403c7f59SAlfred Perlstein 		return 1;
847403c7f59SAlfred Perlstein 
848403c7f59SAlfred Perlstein 	/* if Tflag then only list sysctls that are tuneables. */
849403c7f59SAlfred Perlstein 	if (Tflag && (kind & CTLFLAG_TUN) == 0)
850403c7f59SAlfred Perlstein 		return 1;
851403c7f59SAlfred Perlstein 
852ca5fac55SDag-Erling Smørgrav 	if (Nflag) {
853ca5fac55SDag-Erling Smørgrav 		printf("%s", name);
854ca5fac55SDag-Erling Smørgrav 		return (0);
855ca5fac55SDag-Erling Smørgrav 	}
856ca5fac55SDag-Erling Smørgrav 
857d0b8aabbSAnton Berezin 	if (eflag)
858d0b8aabbSAnton Berezin 		sep = "=";
859d0b8aabbSAnton Berezin 	else
860d0b8aabbSAnton Berezin 		sep = ": ";
861d0b8aabbSAnton Berezin 
8626105f815SLuigi Rizzo 	if (dflag) {	/* just print description */
8636105f815SLuigi Rizzo 		qoid[1] = 5;
8646105f815SLuigi Rizzo 		j = sizeof(buf);
8656105f815SLuigi Rizzo 		i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
8666105f815SLuigi Rizzo 		if (!nflag)
8676105f815SLuigi Rizzo 			printf("%s%s", name, sep);
8686105f815SLuigi Rizzo 		printf("%s", buf);
8696105f815SLuigi Rizzo 		return (0);
8706105f815SLuigi Rizzo 	}
8711d86b91cSPoul-Henning Kamp 	/* find an estimate of how much we need for this var */
87275820005SJohn-Mark Gurney 	if (Bflag)
87375820005SJohn-Mark Gurney 		j = Bflag;
87475820005SJohn-Mark Gurney 	else {
8751d86b91cSPoul-Henning Kamp 		j = 0;
8761d86b91cSPoul-Henning Kamp 		i = sysctl(oid, nlen, 0, &j, 0, 0);
8771d86b91cSPoul-Henning Kamp 		j += j; /* we want to be sure :-) */
87875820005SJohn-Mark Gurney 	}
8791d86b91cSPoul-Henning Kamp 
880ccf25977SRuslan Ermilov 	val = oval = malloc(j + 1);
881ccf25977SRuslan Ermilov 	if (val == NULL) {
882ccf25977SRuslan Ermilov 		warnx("malloc failed");
8836b6b665bSBruce Evans 		return (1);
884ccf25977SRuslan Ermilov 	}
88504006eabSHans Petter Selasky 	ctltype = (kind & CTLTYPE);
8861d86b91cSPoul-Henning Kamp 	len = j;
8871d86b91cSPoul-Henning Kamp 	i = sysctl(oid, nlen, val, &len, 0, 0);
88804006eabSHans Petter Selasky 	if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) {
889ccf25977SRuslan Ermilov 		free(oval);
8901d86b91cSPoul-Henning Kamp 		return (1);
891ccf25977SRuslan Ermilov 	}
8921d86b91cSPoul-Henning Kamp 
8931d86b91cSPoul-Henning Kamp 	if (bflag) {
8941d86b91cSPoul-Henning Kamp 		fwrite(val, 1, len, stdout);
895ccf25977SRuslan Ermilov 		free(oval);
8961d86b91cSPoul-Henning Kamp 		return (0);
8971d86b91cSPoul-Henning Kamp 	}
89876d3dc52SAndrey A. Chernov 	val[len] = '\0';
8991d86b91cSPoul-Henning Kamp 	p = val;
900cbc134adSMatthew D Fleming 	sign = ctl_sign[ctltype];
901cbc134adSMatthew D Fleming 	intlen = ctl_size[ctltype];
902cbc134adSMatthew D Fleming 
903f8e4b4efSMatthew D Fleming 	switch (ctltype) {
904f8e4b4efSMatthew D Fleming 	case CTLTYPE_STRING:
9051d86b91cSPoul-Henning Kamp 		if (!nflag)
906d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
9076d7a8f6cSUlrich Spörlein 		printf("%.*s", (int)len, p);
908ccf25977SRuslan Ermilov 		free(oval);
9091d86b91cSPoul-Henning Kamp 		return (0);
9101d86b91cSPoul-Henning Kamp 
911*c3220d0bSConrad Meyer 	case CTLTYPE_U8:
912*c3220d0bSConrad Meyer 	case CTLTYPE_U16:
913f8e4b4efSMatthew D Fleming 	case CTLTYPE_INT:
914f8e4b4efSMatthew D Fleming 	case CTLTYPE_UINT:
915f8e4b4efSMatthew D Fleming 	case CTLTYPE_LONG:
916f8e4b4efSMatthew D Fleming 	case CTLTYPE_ULONG:
917cbc134adSMatthew D Fleming 	case CTLTYPE_S64:
918cbc134adSMatthew D Fleming 	case CTLTYPE_U64:
919dbf9b92fSDoug Rabson 		if (!nflag)
920d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
921e37d2b30SDavid Malone 		hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
922fd8c668aSDavid Malone 		sep1 = "";
92341e419cbSDavid Malone 		while (len >= intlen) {
924f8e4b4efSMatthew D Fleming 			switch (kind & CTLTYPE) {
925*c3220d0bSConrad Meyer 			case CTLTYPE_U8:
926*c3220d0bSConrad Meyer 				umv = *(uint8_t *)p;
927*c3220d0bSConrad Meyer 				mv = *(int8_t *)p;
928*c3220d0bSConrad Meyer 				break;
929*c3220d0bSConrad Meyer 			case CTLTYPE_U16:
930*c3220d0bSConrad Meyer 				umv = *(uint16_t *)p;
931*c3220d0bSConrad Meyer 				mv = *(int16_t *)p;
932*c3220d0bSConrad Meyer 				break;
933f8e4b4efSMatthew D Fleming 			case CTLTYPE_INT:
934f8e4b4efSMatthew D Fleming 			case CTLTYPE_UINT:
935e37d2b30SDavid Malone 				umv = *(u_int *)p;
936e37d2b30SDavid Malone 				mv = *(int *)p;
93741e419cbSDavid Malone 				break;
938f8e4b4efSMatthew D Fleming 			case CTLTYPE_LONG:
939f8e4b4efSMatthew D Fleming 			case CTLTYPE_ULONG:
940e37d2b30SDavid Malone 				umv = *(u_long *)p;
941e37d2b30SDavid Malone 				mv = *(long *)p;
94241e419cbSDavid Malone 				break;
943cbc134adSMatthew D Fleming 			case CTLTYPE_S64:
944cbc134adSMatthew D Fleming 			case CTLTYPE_U64:
945cbc134adSMatthew D Fleming 				umv = *(uint64_t *)p;
946cbc134adSMatthew D Fleming 				mv = *(int64_t *)p;
94741e419cbSDavid Malone 				break;
94841e419cbSDavid Malone 			}
949fd8c668aSDavid Malone 			fputs(sep1, stdout);
950f8e4b4efSMatthew D Fleming 			if (xflag)
951e37d2b30SDavid Malone 				printf("%#0*jx", hexlen, umv);
952f8e4b4efSMatthew D Fleming 			else if (!sign)
953f8e4b4efSMatthew D Fleming 				printf(hflag ? "%'ju" : "%ju", umv);
95441e419cbSDavid Malone 			else if (fmt[1] == 'K') {
955e37d2b30SDavid Malone 				if (mv < 0)
95621e1f596SDavid Malone 					printf("%jd", mv);
957aa255ef6SWarner Losh 				else {
958aa255ef6SWarner Losh 					/*
959aa255ef6SWarner Losh 					 * See strIKtoi for details on fmt.
960aa255ef6SWarner Losh 					 */
961aa255ef6SWarner Losh 					prec = 1;
962aa255ef6SWarner Losh 					if (fmt[2] != '\0')
963aa255ef6SWarner Losh 						prec = fmt[2] - '0';
964aa255ef6SWarner Losh 					base = 1.0;
965aa255ef6SWarner Losh 					for (int i = 0; i < prec; i++)
966aa255ef6SWarner Losh 						base *= 10.0;
967aa255ef6SWarner Losh 					printf("%.*fC", prec,
968aa255ef6SWarner Losh 					    (float)mv / base - 273.15);
969aa255ef6SWarner Losh 				}
970c591d41fSPeter Wemm 			} else
971fd8c668aSDavid Malone 				printf(hflag ? "%'jd" : "%jd", mv);
972fd8c668aSDavid Malone 			sep1 = " ";
97341e419cbSDavid Malone 			len -= intlen;
97441e419cbSDavid Malone 			p += intlen;
975aa02fb57SPoul-Henning Kamp 		}
976ccf25977SRuslan Ermilov 		free(oval);
977dbf9b92fSDoug Rabson 		return (0);
978dbf9b92fSDoug Rabson 
979f8e4b4efSMatthew D Fleming 	case CTLTYPE_OPAQUE:
9801d86b91cSPoul-Henning Kamp 		i = 0;
981a89ab9bbSDag-Erling Smørgrav 		if (strcmp(fmt, "S,clockinfo") == 0)
982a89ab9bbSDag-Erling Smørgrav 			func = S_clockinfo;
983a89ab9bbSDag-Erling Smørgrav 		else if (strcmp(fmt, "S,timeval") == 0)
984a89ab9bbSDag-Erling Smørgrav 			func = S_timeval;
985a89ab9bbSDag-Erling Smørgrav 		else if (strcmp(fmt, "S,loadavg") == 0)
986a89ab9bbSDag-Erling Smørgrav 			func = S_loadavg;
987f7550ecfSMatthew Dillon 		else if (strcmp(fmt, "S,vmtotal") == 0)
988f7550ecfSMatthew Dillon 			func = S_vmtotal;
9897d8312ccSJohn Baldwin #ifdef __amd64__
9907d8312ccSJohn Baldwin 		else if (strcmp(fmt, "S,efi_map_header") == 0)
9917d8312ccSJohn Baldwin 			func = S_efi_map;
9927d8312ccSJohn Baldwin #endif
99389871cdeSJohn Baldwin #if defined(__amd64__) || defined(__i386__)
99489871cdeSJohn Baldwin 		else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
99589871cdeSJohn Baldwin 			func = S_bios_smap_xattr;
99689871cdeSJohn Baldwin #endif
997a89ab9bbSDag-Erling Smørgrav 		else
998a89ab9bbSDag-Erling Smørgrav 			func = NULL;
9991d86b91cSPoul-Henning Kamp 		if (func) {
10001d86b91cSPoul-Henning Kamp 			if (!nflag)
1001d0b8aabbSAnton Berezin 				printf("%s%s", name, sep);
100248cd487aSHartmut Brandt 			i = (*func)(len, p);
1003ccf25977SRuslan Ermilov 			free(oval);
100448cd487aSHartmut Brandt 			return (i);
10051d86b91cSPoul-Henning Kamp 		}
10061d86b91cSPoul-Henning Kamp 		/* FALLTHROUGH */
1007dea673e9SRodney W. Grimes 	default:
1008ccf25977SRuslan Ermilov 		if (!oflag && !xflag) {
1009ccf25977SRuslan Ermilov 			free(oval);
10101d86b91cSPoul-Henning Kamp 			return (1);
1011ccf25977SRuslan Ermilov 		}
10121d86b91cSPoul-Henning Kamp 		if (!nflag)
1013d0b8aabbSAnton Berezin 			printf("%s%s", name, sep);
10146d7a8f6cSUlrich Spörlein 		printf("Format:%s Length:%zu Dump:0x", fmt, len);
1015a89ab9bbSDag-Erling Smørgrav 		while (len-- && (xflag || p < val + 16))
10161d86b91cSPoul-Henning Kamp 			printf("%02x", *p++);
1017a89ab9bbSDag-Erling Smørgrav 		if (!xflag && len > 16)
10181d86b91cSPoul-Henning Kamp 			printf("...");
1019ccf25977SRuslan Ermilov 		free(oval);
10201d86b91cSPoul-Henning Kamp 		return (0);
10211d86b91cSPoul-Henning Kamp 	}
1022ccf25977SRuslan Ermilov 	free(oval);
10231d86b91cSPoul-Henning Kamp 	return (1);
1024dea673e9SRodney W. Grimes }
1025dea673e9SRodney W. Grimes 
10261d86b91cSPoul-Henning Kamp static int
10271d86b91cSPoul-Henning Kamp sysctl_all(int *oid, int len)
1028dea673e9SRodney W. Grimes {
10291d86b91cSPoul-Henning Kamp 	int name1[22], name2[22];
1030dbf9b92fSDoug Rabson 	int i, j;
1031dbf9b92fSDoug Rabson 	size_t l1, l2;
1032dea673e9SRodney W. Grimes 
10331d86b91cSPoul-Henning Kamp 	name1[0] = 0;
10341d86b91cSPoul-Henning Kamp 	name1[1] = 2;
10351d86b91cSPoul-Henning Kamp 	l1 = 2;
10361d86b91cSPoul-Henning Kamp 	if (len) {
10371d86b91cSPoul-Henning Kamp 		memcpy(name1+2, oid, len * sizeof(int));
10381d86b91cSPoul-Henning Kamp 		l1 += len;
10391d86b91cSPoul-Henning Kamp 	} else {
10401d86b91cSPoul-Henning Kamp 		name1[2] = 1;
10411d86b91cSPoul-Henning Kamp 		l1++;
10421d86b91cSPoul-Henning Kamp 	}
1043a89ab9bbSDag-Erling Smørgrav 	for (;;) {
104431fb4661SDima Dorfman 		l2 = sizeof(name2);
10451d86b91cSPoul-Henning Kamp 		j = sysctl(name1, l1, name2, &l2, 0, 0);
1046c1160fe4SBill Fumerola 		if (j < 0) {
10471d86b91cSPoul-Henning Kamp 			if (errno == ENOENT)
104821e1f596SDavid Malone 				return (0);
10491d86b91cSPoul-Henning Kamp 			else
10506d7a8f6cSUlrich Spörlein 				err(1, "sysctl(getnext) %d %zu", j, l2);
1051c1160fe4SBill Fumerola 		}
10521d86b91cSPoul-Henning Kamp 
10531d86b91cSPoul-Henning Kamp 		l2 /= sizeof(int);
10541d86b91cSPoul-Henning Kamp 
1055fd8c668aSDavid Malone 		if (len < 0 || l2 < (unsigned int)len)
105621e1f596SDavid Malone 			return (0);
10571d86b91cSPoul-Henning Kamp 
10581d86b91cSPoul-Henning Kamp 		for (i = 0; i < len; i++)
10591d86b91cSPoul-Henning Kamp 			if (name2[i] != oid[i])
106021e1f596SDavid Malone 				return (0);
10611d86b91cSPoul-Henning Kamp 
10621d86b91cSPoul-Henning Kamp 		i = show_var(name2, l2);
10631d86b91cSPoul-Henning Kamp 		if (!i && !bflag)
10641d86b91cSPoul-Henning Kamp 			putchar('\n');
10651d86b91cSPoul-Henning Kamp 
10661d86b91cSPoul-Henning Kamp 		memcpy(name1+2, name2, l2 * sizeof(int));
10671d86b91cSPoul-Henning Kamp 		l1 = 2 + l2;
10681d86b91cSPoul-Henning Kamp 	}
1069dea673e9SRodney W. Grimes }
1070