122ce4affSfengbojiang /*-
222ce4affSfengbojiang * SPDX-License-Identifier: BSD-3-Clause
322ce4affSfengbojiang *
47abd0fb2Slogwang * Copyright (c) 1993
57abd0fb2Slogwang * The Regents of the University of California. All rights reserved.
67abd0fb2Slogwang *
77abd0fb2Slogwang * Redistribution and use in source and binary forms, with or without
87abd0fb2Slogwang * modification, are permitted provided that the following conditions
97abd0fb2Slogwang * are met:
107abd0fb2Slogwang * 1. Redistributions of source code must retain the above copyright
117abd0fb2Slogwang * notice, this list of conditions and the following disclaimer.
127abd0fb2Slogwang * 2. Redistributions in binary form must reproduce the above copyright
137abd0fb2Slogwang * notice, this list of conditions and the following disclaimer in the
147abd0fb2Slogwang * documentation and/or other materials provided with the distribution.
1522ce4affSfengbojiang * 3. Neither the name of the University nor the names of its contributors
167abd0fb2Slogwang * may be used to endorse or promote products derived from this software
177abd0fb2Slogwang * without specific prior written permission.
187abd0fb2Slogwang *
197abd0fb2Slogwang * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
207abd0fb2Slogwang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
217abd0fb2Slogwang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
227abd0fb2Slogwang * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
237abd0fb2Slogwang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
247abd0fb2Slogwang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
257abd0fb2Slogwang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
267abd0fb2Slogwang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
277abd0fb2Slogwang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
287abd0fb2Slogwang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
297abd0fb2Slogwang * SUCH DAMAGE.
307abd0fb2Slogwang */
317abd0fb2Slogwang
3222ce4affSfengbojiang #include <sys/cdefs.h>
3322ce4affSfengbojiang __FBSDID("$FreeBSD$");
347abd0fb2Slogwang
35*d4a07e70Sfengbojiang #ifndef FSTACK
362d99e60cSlogwang #include <sys/param.h>
372d99e60cSlogwang #include <sys/time.h>
382d99e60cSlogwang #include <sys/resource.h>
392d99e60cSlogwang #include <sys/stat.h>
402d99e60cSlogwang #include <sys/sysctl.h>
412d99e60cSlogwang #include <sys/vmmeter.h>
4222ce4affSfengbojiang #include <dev/evdev/input.h>
432d99e60cSlogwang
442d99e60cSlogwang #ifdef __amd64__
452d99e60cSlogwang #include <sys/efi.h>
462d99e60cSlogwang #include <machine/metadata.h>
472d99e60cSlogwang #endif
482d99e60cSlogwang
492d99e60cSlogwang #if defined(__amd64__) || defined(__i386__)
502d99e60cSlogwang #include <machine/pc/bios.h>
512d99e60cSlogwang #endif
522d99e60cSlogwang
53*d4a07e70Sfengbojiang #endif
54*d4a07e70Sfengbojiang
557abd0fb2Slogwang #include <assert.h>
567abd0fb2Slogwang #include <ctype.h>
577abd0fb2Slogwang #include <err.h>
587abd0fb2Slogwang #include <errno.h>
597abd0fb2Slogwang #include <inttypes.h>
607abd0fb2Slogwang #include <locale.h>
6122ce4affSfengbojiang #include <stdbool.h>
627abd0fb2Slogwang #include <stdio.h>
637abd0fb2Slogwang #include <stdlib.h>
647abd0fb2Slogwang #include <string.h>
657abd0fb2Slogwang #include <sysexits.h>
667abd0fb2Slogwang #include <unistd.h>
677abd0fb2Slogwang
68*d4a07e70Sfengbojiang #ifdef FSTACK
69*d4a07e70Sfengbojiang #include <time.h>
70*d4a07e70Sfengbojiang #include <limits.h>
71*d4a07e70Sfengbojiang
72*d4a07e70Sfengbojiang #include "sys/sysctl.h"
73*d4a07e70Sfengbojiang #include "ff_ipc.h"
74*d4a07e70Sfengbojiang
75*d4a07e70Sfengbojiang struct clockinfo {
76*d4a07e70Sfengbojiang int hz; /* clock frequency */
77*d4a07e70Sfengbojiang int tick; /* micro-seconds per hz tick */
78*d4a07e70Sfengbojiang int spare;
79*d4a07e70Sfengbojiang int stathz; /* statistics clock frequency */
80*d4a07e70Sfengbojiang int profhz; /* profiling clock frequency */
81*d4a07e70Sfengbojiang };
82*d4a07e70Sfengbojiang
83*d4a07e70Sfengbojiang struct loadavg {
84*d4a07e70Sfengbojiang __uint32_t ldavg[3];
85*d4a07e70Sfengbojiang long fscale;
86*d4a07e70Sfengbojiang };
87*d4a07e70Sfengbojiang
88*d4a07e70Sfengbojiang /* Structure extended to include extended attribute field in ACPI 3.0. */
89*d4a07e70Sfengbojiang struct bios_smap_xattr {
90*d4a07e70Sfengbojiang u_int64_t base;
91*d4a07e70Sfengbojiang u_int64_t length;
92*d4a07e70Sfengbojiang u_int32_t type;
93*d4a07e70Sfengbojiang u_int32_t xattr;
94*d4a07e70Sfengbojiang } __packed;
95*d4a07e70Sfengbojiang
96*d4a07e70Sfengbojiang /* systemwide totals computed every five seconds */
97*d4a07e70Sfengbojiang struct vmtotal {
98*d4a07e70Sfengbojiang int16_t t_rq; /* length of the run queue */
99*d4a07e70Sfengbojiang int16_t t_dw; /* jobs in ``disk wait'' (neg priority) */
100*d4a07e70Sfengbojiang int16_t t_pw; /* jobs in page wait */
101*d4a07e70Sfengbojiang int16_t t_sl; /* jobs sleeping in core */
102*d4a07e70Sfengbojiang int16_t t_sw; /* swapped out runnable/short block jobs */
103*d4a07e70Sfengbojiang int32_t t_vm; /* total virtual memory */
104*d4a07e70Sfengbojiang int32_t t_avm; /* active virtual memory */
105*d4a07e70Sfengbojiang int32_t t_rm; /* total real memory in use */
106*d4a07e70Sfengbojiang int32_t t_arm; /* active real memory */
107*d4a07e70Sfengbojiang int32_t t_vmshr; /* shared virtual memory */
108*d4a07e70Sfengbojiang int32_t t_avmshr; /* active shared virtual memory */
109*d4a07e70Sfengbojiang int32_t t_rmshr; /* shared real memory */
110*d4a07e70Sfengbojiang int32_t t_armshr; /* active shared real memory */
111*d4a07e70Sfengbojiang int32_t t_free; /* free memory pages */
112*d4a07e70Sfengbojiang };
113*d4a07e70Sfengbojiang
114*d4a07e70Sfengbojiang struct efi_md {
115*d4a07e70Sfengbojiang uint32_t md_type;
116*d4a07e70Sfengbojiang #define EFI_MD_TYPE_NULL 0
117*d4a07e70Sfengbojiang #define EFI_MD_TYPE_CODE 1 /* Loader text. */
118*d4a07e70Sfengbojiang #define EFI_MD_TYPE_DATA 2 /* Loader data. */
119*d4a07e70Sfengbojiang #define EFI_MD_TYPE_BS_CODE 3 /* Boot services text. */
120*d4a07e70Sfengbojiang #define EFI_MD_TYPE_BS_DATA 4 /* Boot services data. */
121*d4a07e70Sfengbojiang #define EFI_MD_TYPE_RT_CODE 5 /* Runtime services text. */
122*d4a07e70Sfengbojiang #define EFI_MD_TYPE_RT_DATA 6 /* Runtime services data. */
123*d4a07e70Sfengbojiang #define EFI_MD_TYPE_FREE 7 /* Unused/free memory. */
124*d4a07e70Sfengbojiang #define EFI_MD_TYPE_BAD 8 /* Bad memory */
125*d4a07e70Sfengbojiang #define EFI_MD_TYPE_RECLAIM 9 /* ACPI reclaimable memory. */
126*d4a07e70Sfengbojiang #define EFI_MD_TYPE_FIRMWARE 10 /* ACPI NV memory */
127*d4a07e70Sfengbojiang #define EFI_MD_TYPE_IOMEM 11 /* Memory-mapped I/O. */
128*d4a07e70Sfengbojiang #define EFI_MD_TYPE_IOPORT 12 /* I/O port space. */
129*d4a07e70Sfengbojiang #define EFI_MD_TYPE_PALCODE 13 /* PAL */
130*d4a07e70Sfengbojiang #define EFI_MD_TYPE_PERSISTENT 14 /* Persistent memory. */
131*d4a07e70Sfengbojiang uint32_t __pad;
132*d4a07e70Sfengbojiang uint64_t md_phys;
133*d4a07e70Sfengbojiang void *md_virt;
134*d4a07e70Sfengbojiang uint64_t md_pages;
135*d4a07e70Sfengbojiang uint64_t md_attr;
136*d4a07e70Sfengbojiang #define EFI_MD_ATTR_UC 0x0000000000000001UL
137*d4a07e70Sfengbojiang #define EFI_MD_ATTR_WC 0x0000000000000002UL
138*d4a07e70Sfengbojiang #define EFI_MD_ATTR_WT 0x0000000000000004UL
139*d4a07e70Sfengbojiang #define EFI_MD_ATTR_WB 0x0000000000000008UL
140*d4a07e70Sfengbojiang #define EFI_MD_ATTR_UCE 0x0000000000000010UL
141*d4a07e70Sfengbojiang #define EFI_MD_ATTR_WP 0x0000000000001000UL
142*d4a07e70Sfengbojiang #define EFI_MD_ATTR_RP 0x0000000000002000UL
143*d4a07e70Sfengbojiang #define EFI_MD_ATTR_XP 0x0000000000004000UL
144*d4a07e70Sfengbojiang #define EFI_MD_ATTR_RT 0x8000000000000000UL
145*d4a07e70Sfengbojiang };
146*d4a07e70Sfengbojiang
147*d4a07e70Sfengbojiang struct efi_map_header {
148*d4a07e70Sfengbojiang uint64_t memory_size;
149*d4a07e70Sfengbojiang uint64_t descriptor_size;
150*d4a07e70Sfengbojiang uint32_t descriptor_version;
151*d4a07e70Sfengbojiang };
152*d4a07e70Sfengbojiang
153*d4a07e70Sfengbojiang struct input_id {
154*d4a07e70Sfengbojiang uint16_t bustype;
155*d4a07e70Sfengbojiang uint16_t vendor;
156*d4a07e70Sfengbojiang uint16_t product;
157*d4a07e70Sfengbojiang uint16_t version;
158*d4a07e70Sfengbojiang };
159*d4a07e70Sfengbojiang
160*d4a07e70Sfengbojiang /*
161*d4a07e70Sfengbojiang * Top-level identifiers
162*d4a07e70Sfengbojiang */
163*d4a07e70Sfengbojiang #define CTL_SYSCTL 0 /* "magic" numbers */
164*d4a07e70Sfengbojiang #define CTL_KERN 1 /* "high kernel": proc, limits */
165*d4a07e70Sfengbojiang #define CTL_VM 2 /* virtual memory */
166*d4a07e70Sfengbojiang #define CTL_VFS 3 /* filesystem, mount type is next */
167*d4a07e70Sfengbojiang #define CTL_NET 4 /* network, see socket.h */
168*d4a07e70Sfengbojiang #define CTL_DEBUG 5 /* debugging parameters */
169*d4a07e70Sfengbojiang #define CTL_HW 6 /* generic cpu/io */
170*d4a07e70Sfengbojiang #define CTL_MACHDEP 7 /* machine dependent */
171*d4a07e70Sfengbojiang #define CTL_USER 8 /* user-level */
172*d4a07e70Sfengbojiang #define CTL_P1003_1B 9 /* POSIX 1003.1B */
173*d4a07e70Sfengbojiang
174*d4a07e70Sfengbojiang /*
175*d4a07e70Sfengbojiang * CTL_SYSCTL identifiers
176*d4a07e70Sfengbojiang */
177*d4a07e70Sfengbojiang #define CTL_SYSCTL_DEBUG 0 /* printf all nodes */
178*d4a07e70Sfengbojiang #define CTL_SYSCTL_NAME 1 /* string name of OID */
179*d4a07e70Sfengbojiang #define CTL_SYSCTL_NEXT 2 /* next OID, honoring CTLFLAG_SKIP */
180*d4a07e70Sfengbojiang #define CTL_SYSCTL_NAME2OID 3 /* int array of name */
181*d4a07e70Sfengbojiang #define CTL_SYSCTL_OIDFMT 4 /* OID's kind and format */
182*d4a07e70Sfengbojiang #define CTL_SYSCTL_OIDDESCR 5 /* OID's description */
183*d4a07e70Sfengbojiang #define CTL_SYSCTL_OIDLABEL 6 /* aggregation label */
184*d4a07e70Sfengbojiang #define CTL_SYSCTL_NEXTNOSKIP 7 /* next OID, ignoring CTLFLAG_SKIP */
185*d4a07e70Sfengbojiang
186*d4a07e70Sfengbojiang #endif
187*d4a07e70Sfengbojiang
1887abd0fb2Slogwang static const char *conffile;
1897abd0fb2Slogwang
1907abd0fb2Slogwang static int aflag, bflag, Bflag, dflag, eflag, hflag, iflag;
1917abd0fb2Slogwang static int Nflag, nflag, oflag, qflag, tflag, Tflag, Wflag, xflag;
1927abd0fb2Slogwang
1937abd0fb2Slogwang static int oidfmt(int *, int, char *, u_int *);
1947abd0fb2Slogwang static int parsefile(const char *);
1957abd0fb2Slogwang static int parse(const char *, int);
19622ce4affSfengbojiang static int show_var(int *, int, bool);
19722ce4affSfengbojiang static int sysctl_all(int *, int);
1987abd0fb2Slogwang static int name2oid(const char *, int *);
1997abd0fb2Slogwang
2007abd0fb2Slogwang static int strIKtoi(const char *, char **, const char *);
2017abd0fb2Slogwang
2027abd0fb2Slogwang static int ctl_sign[CTLTYPE+1] = {
2037abd0fb2Slogwang [CTLTYPE_INT] = 1,
2047abd0fb2Slogwang [CTLTYPE_LONG] = 1,
2057abd0fb2Slogwang [CTLTYPE_S8] = 1,
2067abd0fb2Slogwang [CTLTYPE_S16] = 1,
2077abd0fb2Slogwang [CTLTYPE_S32] = 1,
2087abd0fb2Slogwang [CTLTYPE_S64] = 1,
2097abd0fb2Slogwang };
2107abd0fb2Slogwang
2117abd0fb2Slogwang static int ctl_size[CTLTYPE+1] = {
2127abd0fb2Slogwang [CTLTYPE_INT] = sizeof(int),
2137abd0fb2Slogwang [CTLTYPE_UINT] = sizeof(u_int),
2147abd0fb2Slogwang [CTLTYPE_LONG] = sizeof(long),
2157abd0fb2Slogwang [CTLTYPE_ULONG] = sizeof(u_long),
2167abd0fb2Slogwang [CTLTYPE_S8] = sizeof(int8_t),
2177abd0fb2Slogwang [CTLTYPE_S16] = sizeof(int16_t),
2187abd0fb2Slogwang [CTLTYPE_S32] = sizeof(int32_t),
2197abd0fb2Slogwang [CTLTYPE_S64] = sizeof(int64_t),
2207abd0fb2Slogwang [CTLTYPE_U8] = sizeof(uint8_t),
2217abd0fb2Slogwang [CTLTYPE_U16] = sizeof(uint16_t),
2227abd0fb2Slogwang [CTLTYPE_U32] = sizeof(uint32_t),
2237abd0fb2Slogwang [CTLTYPE_U64] = sizeof(uint64_t),
2247abd0fb2Slogwang };
2257abd0fb2Slogwang
2267abd0fb2Slogwang static const char *ctl_typename[CTLTYPE+1] = {
2277abd0fb2Slogwang [CTLTYPE_INT] = "integer",
2287abd0fb2Slogwang [CTLTYPE_UINT] = "unsigned integer",
2297abd0fb2Slogwang [CTLTYPE_LONG] = "long integer",
2307abd0fb2Slogwang [CTLTYPE_ULONG] = "unsigned long",
2317abd0fb2Slogwang [CTLTYPE_U8] = "uint8_t",
2327abd0fb2Slogwang [CTLTYPE_U16] = "uint16_t",
23322ce4affSfengbojiang [CTLTYPE_U32] = "uint32_t",
2347abd0fb2Slogwang [CTLTYPE_U64] = "uint64_t",
2357abd0fb2Slogwang [CTLTYPE_S8] = "int8_t",
2367abd0fb2Slogwang [CTLTYPE_S16] = "int16_t",
2377abd0fb2Slogwang [CTLTYPE_S32] = "int32_t",
2387abd0fb2Slogwang [CTLTYPE_S64] = "int64_t",
2397abd0fb2Slogwang [CTLTYPE_NODE] = "node",
2407abd0fb2Slogwang [CTLTYPE_STRING] = "string",
2417abd0fb2Slogwang [CTLTYPE_OPAQUE] = "opaque",
2427abd0fb2Slogwang };
2437abd0fb2Slogwang
2447abd0fb2Slogwang static void
usage(void)2457abd0fb2Slogwang usage(void)
2467abd0fb2Slogwang {
247*d4a07e70Sfengbojiang #ifndef FSTACK
2487abd0fb2Slogwang (void)fprintf(stderr, "%s\n%s\n",
2492d99e60cSlogwang "usage: sysctl [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
2502d99e60cSlogwang " sysctl [-bdehNnoqTtWx] [ -B <bufsize> ] -a");
251*d4a07e70Sfengbojiang #else
252*d4a07e70Sfengbojiang (void)fprintf(stderr, "%s\n%s\n",
253*d4a07e70Sfengbojiang "usage: sysctl -p <f-stack proc_id> [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...",
254*d4a07e70Sfengbojiang " sysctl -p <f-stack proc_id> [-bdehNnoqTtWx] [ -B <bufsize> ] -a");
255*d4a07e70Sfengbojiang ff_ipc_exit();
256*d4a07e70Sfengbojiang #endif
2577abd0fb2Slogwang exit(1);
2587abd0fb2Slogwang }
2597abd0fb2Slogwang
2607abd0fb2Slogwang int
main(int argc,char ** argv)2617abd0fb2Slogwang main(int argc, char **argv)
2627abd0fb2Slogwang {
2637abd0fb2Slogwang int ch;
2647abd0fb2Slogwang int warncount = 0;
2657abd0fb2Slogwang
266*d4a07e70Sfengbojiang #ifdef FSTACK
267*d4a07e70Sfengbojiang ff_ipc_init();
268*d4a07e70Sfengbojiang #endif
269*d4a07e70Sfengbojiang
2707abd0fb2Slogwang setlocale(LC_NUMERIC, "");
2717abd0fb2Slogwang setbuf(stdout,0);
2727abd0fb2Slogwang setbuf(stderr,0);
2737abd0fb2Slogwang
274*d4a07e70Sfengbojiang #ifndef FSTACK
2752d99e60cSlogwang while ((ch = getopt(argc, argv, "AabB:def:hiNnoqtTwWxX")) != -1) {
276*d4a07e70Sfengbojiang #else
277*d4a07e70Sfengbojiang while ((ch = getopt(argc, argv, "AabB:def:hiNnoqtTwWxXp:")) != -1) {
278*d4a07e70Sfengbojiang #endif
2797abd0fb2Slogwang switch (ch) {
2807abd0fb2Slogwang case 'A':
2817abd0fb2Slogwang /* compatibility */
2827abd0fb2Slogwang aflag = oflag = 1;
2837abd0fb2Slogwang break;
2847abd0fb2Slogwang case 'a':
2857abd0fb2Slogwang aflag = 1;
2867abd0fb2Slogwang break;
2877abd0fb2Slogwang case 'b':
2887abd0fb2Slogwang bflag = 1;
2897abd0fb2Slogwang break;
2907abd0fb2Slogwang case 'B':
2917abd0fb2Slogwang Bflag = strtol(optarg, NULL, 0);
2927abd0fb2Slogwang break;
2937abd0fb2Slogwang case 'd':
2947abd0fb2Slogwang dflag = 1;
2957abd0fb2Slogwang break;
2967abd0fb2Slogwang case 'e':
2977abd0fb2Slogwang eflag = 1;
2987abd0fb2Slogwang break;
2997abd0fb2Slogwang case 'f':
3007abd0fb2Slogwang conffile = optarg;
3017abd0fb2Slogwang break;
3027abd0fb2Slogwang case 'h':
3037abd0fb2Slogwang hflag = 1;
3047abd0fb2Slogwang break;
3057abd0fb2Slogwang case 'i':
3067abd0fb2Slogwang iflag = 1;
3077abd0fb2Slogwang break;
3087abd0fb2Slogwang case 'N':
3097abd0fb2Slogwang Nflag = 1;
3107abd0fb2Slogwang break;
3117abd0fb2Slogwang case 'n':
3127abd0fb2Slogwang nflag = 1;
3137abd0fb2Slogwang break;
3147abd0fb2Slogwang case 'o':
3157abd0fb2Slogwang oflag = 1;
3167abd0fb2Slogwang break;
3177abd0fb2Slogwang case 'q':
3187abd0fb2Slogwang qflag = 1;
3197abd0fb2Slogwang break;
3207abd0fb2Slogwang case 't':
3217abd0fb2Slogwang tflag = 1;
3227abd0fb2Slogwang break;
3237abd0fb2Slogwang case 'T':
3247abd0fb2Slogwang Tflag = 1;
3257abd0fb2Slogwang break;
3267abd0fb2Slogwang case 'w':
3277abd0fb2Slogwang /* compatibility */
3287abd0fb2Slogwang /* ignored */
3297abd0fb2Slogwang break;
3307abd0fb2Slogwang case 'W':
3317abd0fb2Slogwang Wflag = 1;
3327abd0fb2Slogwang break;
3337abd0fb2Slogwang case 'X':
3347abd0fb2Slogwang /* compatibility */
3357abd0fb2Slogwang aflag = xflag = 1;
3367abd0fb2Slogwang break;
3377abd0fb2Slogwang case 'x':
3387abd0fb2Slogwang xflag = 1;
3397abd0fb2Slogwang break;
340*d4a07e70Sfengbojiang #ifdef FSTACK
341*d4a07e70Sfengbojiang case 'p':
342*d4a07e70Sfengbojiang ff_set_proc_id(atoi(optarg));
343*d4a07e70Sfengbojiang break;
344*d4a07e70Sfengbojiang #endif
3457abd0fb2Slogwang default:
3467abd0fb2Slogwang usage();
3477abd0fb2Slogwang }
3487abd0fb2Slogwang }
3497abd0fb2Slogwang argc -= optind;
3507abd0fb2Slogwang argv += optind;
3517abd0fb2Slogwang
3527abd0fb2Slogwang if (Nflag && nflag)
3537abd0fb2Slogwang usage();
35422ce4affSfengbojiang if (aflag && argc == 0)
355*d4a07e70Sfengbojiang #ifndef FSTACK
35622ce4affSfengbojiang exit(sysctl_all(NULL, 0));
357*d4a07e70Sfengbojiang #else
358*d4a07e70Sfengbojiang {
359*d4a07e70Sfengbojiang int ret = sysctl_all(0, 0);
360*d4a07e70Sfengbojiang ff_ipc_exit();
361*d4a07e70Sfengbojiang exit(ret);
362*d4a07e70Sfengbojiang }
363*d4a07e70Sfengbojiang #endif
364*d4a07e70Sfengbojiang
3657abd0fb2Slogwang if (argc == 0 && conffile == NULL)
3667abd0fb2Slogwang usage();
3677abd0fb2Slogwang
3687abd0fb2Slogwang warncount = 0;
3697abd0fb2Slogwang if (conffile != NULL)
3707abd0fb2Slogwang warncount += parsefile(conffile);
3717abd0fb2Slogwang
3727abd0fb2Slogwang while (argc-- > 0)
3737abd0fb2Slogwang warncount += parse(*argv++, 0);
3747abd0fb2Slogwang
375*d4a07e70Sfengbojiang #ifdef FSTACK
376*d4a07e70Sfengbojiang ff_ipc_exit();
377*d4a07e70Sfengbojiang #endif
378*d4a07e70Sfengbojiang
3797abd0fb2Slogwang return (warncount);
3807abd0fb2Slogwang }
3817abd0fb2Slogwang
3827abd0fb2Slogwang /*
38322ce4affSfengbojiang * Parse a single numeric value, append it to 'newbuf', and update
38422ce4affSfengbojiang * 'newsize'. Returns true if the value was parsed and false if the
38522ce4affSfengbojiang * value was invalid. Non-numeric types (strings) are handled
38622ce4affSfengbojiang * directly in parse().
3877abd0fb2Slogwang */
38822ce4affSfengbojiang static bool
38922ce4affSfengbojiang parse_numeric(const char *newvalstr, const char *fmt, u_int kind,
39022ce4affSfengbojiang void **newbufp, size_t *newsizep)
3917abd0fb2Slogwang {
39222ce4affSfengbojiang void *newbuf;
3937abd0fb2Slogwang const void *newval;
3947abd0fb2Slogwang int8_t i8val;
3957abd0fb2Slogwang uint8_t u8val;
3967abd0fb2Slogwang int16_t i16val;
3977abd0fb2Slogwang uint16_t u16val;
3987abd0fb2Slogwang int32_t i32val;
3997abd0fb2Slogwang uint32_t u32val;
4007abd0fb2Slogwang int intval;
4017abd0fb2Slogwang unsigned int uintval;
4027abd0fb2Slogwang long longval;
4037abd0fb2Slogwang unsigned long ulongval;
4047abd0fb2Slogwang int64_t i64val;
4057abd0fb2Slogwang uint64_t u64val;
40622ce4affSfengbojiang size_t valsize;
40722ce4affSfengbojiang char *endptr = NULL;
40822ce4affSfengbojiang
40922ce4affSfengbojiang errno = 0;
41022ce4affSfengbojiang
41122ce4affSfengbojiang switch (kind & CTLTYPE) {
41222ce4affSfengbojiang case CTLTYPE_INT:
41322ce4affSfengbojiang if (strncmp(fmt, "IK", 2) == 0)
41422ce4affSfengbojiang intval = strIKtoi(newvalstr, &endptr, fmt);
41522ce4affSfengbojiang else
41622ce4affSfengbojiang intval = (int)strtol(newvalstr, &endptr, 0);
41722ce4affSfengbojiang newval = &intval;
41822ce4affSfengbojiang valsize = sizeof(intval);
41922ce4affSfengbojiang break;
42022ce4affSfengbojiang case CTLTYPE_UINT:
42122ce4affSfengbojiang uintval = (int) strtoul(newvalstr, &endptr, 0);
42222ce4affSfengbojiang newval = &uintval;
42322ce4affSfengbojiang valsize = sizeof(uintval);
42422ce4affSfengbojiang break;
42522ce4affSfengbojiang case CTLTYPE_LONG:
42622ce4affSfengbojiang longval = strtol(newvalstr, &endptr, 0);
42722ce4affSfengbojiang newval = &longval;
42822ce4affSfengbojiang valsize = sizeof(longval);
42922ce4affSfengbojiang break;
43022ce4affSfengbojiang case CTLTYPE_ULONG:
43122ce4affSfengbojiang ulongval = strtoul(newvalstr, &endptr, 0);
43222ce4affSfengbojiang newval = &ulongval;
43322ce4affSfengbojiang valsize = sizeof(ulongval);
43422ce4affSfengbojiang break;
43522ce4affSfengbojiang case CTLTYPE_S8:
43622ce4affSfengbojiang i8val = (int8_t)strtol(newvalstr, &endptr, 0);
43722ce4affSfengbojiang newval = &i8val;
43822ce4affSfengbojiang valsize = sizeof(i8val);
43922ce4affSfengbojiang break;
44022ce4affSfengbojiang case CTLTYPE_S16:
44122ce4affSfengbojiang i16val = (int16_t)strtol(newvalstr, &endptr, 0);
44222ce4affSfengbojiang newval = &i16val;
44322ce4affSfengbojiang valsize = sizeof(i16val);
44422ce4affSfengbojiang break;
44522ce4affSfengbojiang case CTLTYPE_S32:
44622ce4affSfengbojiang i32val = (int32_t)strtol(newvalstr, &endptr, 0);
44722ce4affSfengbojiang newval = &i32val;
44822ce4affSfengbojiang valsize = sizeof(i32val);
44922ce4affSfengbojiang break;
45022ce4affSfengbojiang case CTLTYPE_S64:
45122ce4affSfengbojiang i64val = strtoimax(newvalstr, &endptr, 0);
45222ce4affSfengbojiang newval = &i64val;
45322ce4affSfengbojiang valsize = sizeof(i64val);
45422ce4affSfengbojiang break;
45522ce4affSfengbojiang case CTLTYPE_U8:
45622ce4affSfengbojiang u8val = (uint8_t)strtoul(newvalstr, &endptr, 0);
45722ce4affSfengbojiang newval = &u8val;
45822ce4affSfengbojiang valsize = sizeof(u8val);
45922ce4affSfengbojiang break;
46022ce4affSfengbojiang case CTLTYPE_U16:
46122ce4affSfengbojiang u16val = (uint16_t)strtoul(newvalstr, &endptr, 0);
46222ce4affSfengbojiang newval = &u16val;
46322ce4affSfengbojiang valsize = sizeof(u16val);
46422ce4affSfengbojiang break;
46522ce4affSfengbojiang case CTLTYPE_U32:
46622ce4affSfengbojiang u32val = (uint32_t)strtoul(newvalstr, &endptr, 0);
46722ce4affSfengbojiang newval = &u32val;
46822ce4affSfengbojiang valsize = sizeof(u32val);
46922ce4affSfengbojiang break;
47022ce4affSfengbojiang case CTLTYPE_U64:
47122ce4affSfengbojiang u64val = strtoumax(newvalstr, &endptr, 0);
47222ce4affSfengbojiang newval = &u64val;
47322ce4affSfengbojiang valsize = sizeof(u64val);
47422ce4affSfengbojiang break;
47522ce4affSfengbojiang default:
47622ce4affSfengbojiang /* NOTREACHED */
47722ce4affSfengbojiang abort();
47822ce4affSfengbojiang }
47922ce4affSfengbojiang
48022ce4affSfengbojiang if (errno != 0 || endptr == newvalstr ||
48122ce4affSfengbojiang (endptr != NULL && *endptr != '\0'))
48222ce4affSfengbojiang return (false);
48322ce4affSfengbojiang
48422ce4affSfengbojiang newbuf = realloc(*newbufp, *newsizep + valsize);
48522ce4affSfengbojiang if (newbuf == NULL)
48622ce4affSfengbojiang err(1, "out of memory");
48722ce4affSfengbojiang memcpy((char *)newbuf + *newsizep, newval, valsize);
48822ce4affSfengbojiang *newbufp = newbuf;
48922ce4affSfengbojiang *newsizep += valsize;
49022ce4affSfengbojiang
49122ce4affSfengbojiang return (true);
49222ce4affSfengbojiang }
49322ce4affSfengbojiang
49422ce4affSfengbojiang /*
49522ce4affSfengbojiang * Parse a name into a MIB entry.
49622ce4affSfengbojiang * Lookup and print out the MIB entry if it exists.
49722ce4affSfengbojiang * Set a new value if requested.
49822ce4affSfengbojiang */
49922ce4affSfengbojiang static int
50022ce4affSfengbojiang parse(const char *string, int lineno)
50122ce4affSfengbojiang {
50222ce4affSfengbojiang int len, i, j, save_errno;
50322ce4affSfengbojiang const void *newval;
50422ce4affSfengbojiang char *newvalstr = NULL;
50522ce4affSfengbojiang void *newbuf;
50622ce4affSfengbojiang size_t newsize = Bflag;
5077abd0fb2Slogwang int mib[CTL_MAXNAME];
50822ce4affSfengbojiang char *cp, *bufp, *buf, fmt[BUFSIZ], line[BUFSIZ];
5097abd0fb2Slogwang u_int kind;
5107abd0fb2Slogwang
5117abd0fb2Slogwang if (lineno)
5127abd0fb2Slogwang snprintf(line, sizeof(line), " at line %d", lineno);
5137abd0fb2Slogwang else
5147abd0fb2Slogwang line[0] = '\0';
5157abd0fb2Slogwang
51622ce4affSfengbojiang /*
51722ce4affSfengbojiang * Split the string into name and value.
51822ce4affSfengbojiang *
51922ce4affSfengbojiang * Either = or : may be used as the delimiter.
52022ce4affSfengbojiang * Whitespace surrounding the delimiter is trimmed.
52122ce4affSfengbojiang * Quotes around the value are stripped.
52222ce4affSfengbojiang */
52322ce4affSfengbojiang cp = buf = strdup(string);
5247abd0fb2Slogwang bufp = strsep(&cp, "=:");
5257abd0fb2Slogwang if (cp != NULL) {
5267abd0fb2Slogwang /* Tflag just lists tunables, do not allow assignment */
5277abd0fb2Slogwang if (Tflag || Wflag) {
5287abd0fb2Slogwang warnx("Can't set variables when using -T or -W");
5297abd0fb2Slogwang usage();
5307abd0fb2Slogwang }
53122ce4affSfengbojiang /* Trim whitespace before the value. */
5327abd0fb2Slogwang while (isspace(*cp))
5337abd0fb2Slogwang cp++;
5347abd0fb2Slogwang /* Strip a pair of " or ' if any. */
5357abd0fb2Slogwang switch (*cp) {
5367abd0fb2Slogwang case '\"':
5377abd0fb2Slogwang case '\'':
5387abd0fb2Slogwang if (cp[strlen(cp) - 1] == *cp)
5397abd0fb2Slogwang cp[strlen(cp) - 1] = '\0';
5407abd0fb2Slogwang cp++;
5417abd0fb2Slogwang }
5427abd0fb2Slogwang newvalstr = cp;
5437abd0fb2Slogwang newsize = strlen(cp);
5447abd0fb2Slogwang }
54522ce4affSfengbojiang /* Trim whitespace after the name. */
5467abd0fb2Slogwang cp = bufp + strlen(bufp) - 1;
5477abd0fb2Slogwang while (cp >= bufp && isspace((int)*cp)) {
5487abd0fb2Slogwang *cp = '\0';
5497abd0fb2Slogwang cp--;
5507abd0fb2Slogwang }
5517abd0fb2Slogwang
55222ce4affSfengbojiang /*
55322ce4affSfengbojiang * Check the name is a useable oid.
55422ce4affSfengbojiang */
55522ce4affSfengbojiang len = name2oid(bufp, mib);
5567abd0fb2Slogwang if (len < 0) {
55722ce4affSfengbojiang if (iflag) {
55822ce4affSfengbojiang free(buf);
5597abd0fb2Slogwang return (0);
56022ce4affSfengbojiang }
56122ce4affSfengbojiang if (!qflag) {
5627abd0fb2Slogwang if (errno == ENOENT) {
5637abd0fb2Slogwang warnx("unknown oid '%s'%s", bufp, line);
5647abd0fb2Slogwang } else {
5657abd0fb2Slogwang warn("unknown oid '%s'%s", bufp, line);
5667abd0fb2Slogwang }
5677abd0fb2Slogwang }
56822ce4affSfengbojiang free(buf);
56922ce4affSfengbojiang return (1);
5707abd0fb2Slogwang }
5717abd0fb2Slogwang
5727abd0fb2Slogwang if (oidfmt(mib, len, fmt, &kind)) {
5737abd0fb2Slogwang warn("couldn't find format of oid '%s'%s", bufp, line);
57422ce4affSfengbojiang free(buf);
5757abd0fb2Slogwang if (iflag)
5767abd0fb2Slogwang return (1);
57722ce4affSfengbojiang else
578*d4a07e70Sfengbojiang #ifndef FSTACK
5797abd0fb2Slogwang exit(1);
580*d4a07e70Sfengbojiang #else
581*d4a07e70Sfengbojiang {
582*d4a07e70Sfengbojiang ff_ipc_exit();
583*d4a07e70Sfengbojiang exit(1);
584*d4a07e70Sfengbojiang }
585*d4a07e70Sfengbojiang #endif
5867abd0fb2Slogwang }
5877abd0fb2Slogwang
58822ce4affSfengbojiang /*
58922ce4affSfengbojiang * We have a useable oid to work with. If there is no value given,
59022ce4affSfengbojiang * show the node and its children. Otherwise, set the new value.
59122ce4affSfengbojiang */
5927abd0fb2Slogwang if (newvalstr == NULL || dflag) {
59322ce4affSfengbojiang free(buf);
5947abd0fb2Slogwang if ((kind & CTLTYPE) == CTLTYPE_NODE) {
5957abd0fb2Slogwang if (dflag) {
59622ce4affSfengbojiang i = show_var(mib, len, false);
5977abd0fb2Slogwang if (!i && !bflag)
5987abd0fb2Slogwang putchar('\n');
5997abd0fb2Slogwang }
6007abd0fb2Slogwang sysctl_all(mib, len);
6017abd0fb2Slogwang } else {
60222ce4affSfengbojiang i = show_var(mib, len, false);
6037abd0fb2Slogwang if (!i && !bflag)
6047abd0fb2Slogwang putchar('\n');
6057abd0fb2Slogwang }
60622ce4affSfengbojiang return (0);
60722ce4affSfengbojiang }
60822ce4affSfengbojiang
60922ce4affSfengbojiang /*
61022ce4affSfengbojiang * We have a new value to set. Check its validity and parse if numeric.
61122ce4affSfengbojiang */
6127abd0fb2Slogwang if ((kind & CTLTYPE) == CTLTYPE_NODE) {
6137abd0fb2Slogwang warnx("oid '%s' isn't a leaf node%s", bufp, line);
61422ce4affSfengbojiang free(buf);
6157abd0fb2Slogwang return (1);
6167abd0fb2Slogwang }
6177abd0fb2Slogwang
6187abd0fb2Slogwang if (!(kind & CTLFLAG_WR)) {
6197abd0fb2Slogwang if (kind & CTLFLAG_TUN) {
6207abd0fb2Slogwang warnx("oid '%s' is a read only tunable%s", bufp, line);
6217abd0fb2Slogwang warnx("Tunable values are set in /boot/loader.conf");
6227abd0fb2Slogwang } else
6237abd0fb2Slogwang warnx("oid '%s' is read only%s", bufp, line);
62422ce4affSfengbojiang free(buf);
6257abd0fb2Slogwang return (1);
6267abd0fb2Slogwang }
6277abd0fb2Slogwang
6287abd0fb2Slogwang switch (kind & CTLTYPE) {
6297abd0fb2Slogwang case CTLTYPE_INT:
6307abd0fb2Slogwang case CTLTYPE_UINT:
6317abd0fb2Slogwang case CTLTYPE_LONG:
6327abd0fb2Slogwang case CTLTYPE_ULONG:
6337abd0fb2Slogwang case CTLTYPE_S8:
6347abd0fb2Slogwang case CTLTYPE_S16:
6357abd0fb2Slogwang case CTLTYPE_S32:
6367abd0fb2Slogwang case CTLTYPE_S64:
6377abd0fb2Slogwang case CTLTYPE_U8:
6387abd0fb2Slogwang case CTLTYPE_U16:
6397abd0fb2Slogwang case CTLTYPE_U32:
6407abd0fb2Slogwang case CTLTYPE_U64:
6417abd0fb2Slogwang if (strlen(newvalstr) == 0) {
6427abd0fb2Slogwang warnx("empty numeric value");
64322ce4affSfengbojiang free(buf);
6447abd0fb2Slogwang return (1);
6457abd0fb2Slogwang }
6467abd0fb2Slogwang /* FALLTHROUGH */
6477abd0fb2Slogwang case CTLTYPE_STRING:
6487abd0fb2Slogwang break;
6497abd0fb2Slogwang default:
65022ce4affSfengbojiang warnx("oid '%s' is type %d, cannot set that%s",
65122ce4affSfengbojiang bufp, kind & CTLTYPE, line);
65222ce4affSfengbojiang free(buf);
6537abd0fb2Slogwang return (1);
6547abd0fb2Slogwang }
6557abd0fb2Slogwang
65622ce4affSfengbojiang newbuf = NULL;
6577abd0fb2Slogwang
6587abd0fb2Slogwang switch (kind & CTLTYPE) {
6597abd0fb2Slogwang case CTLTYPE_STRING:
6607abd0fb2Slogwang newval = newvalstr;
6617abd0fb2Slogwang break;
6627abd0fb2Slogwang default:
66322ce4affSfengbojiang newsize = 0;
66422ce4affSfengbojiang while ((cp = strsep(&newvalstr, " ,")) != NULL) {
66522ce4affSfengbojiang if (*cp == '\0')
66622ce4affSfengbojiang continue;
66722ce4affSfengbojiang if (!parse_numeric(cp, fmt, kind, &newbuf, &newsize)) {
66822ce4affSfengbojiang warnx("invalid %s '%s'%s",
66922ce4affSfengbojiang ctl_typename[kind & CTLTYPE], cp, line);
67022ce4affSfengbojiang free(newbuf);
67122ce4affSfengbojiang free(buf);
6727abd0fb2Slogwang return (1);
6737abd0fb2Slogwang }
67422ce4affSfengbojiang }
67522ce4affSfengbojiang newval = newbuf;
67622ce4affSfengbojiang break;
67722ce4affSfengbojiang }
6787abd0fb2Slogwang
67922ce4affSfengbojiang /*
68022ce4affSfengbojiang * Show the current value, then set and show the new value.
68122ce4affSfengbojiang */
68222ce4affSfengbojiang i = show_var(mib, len, false);
6832d99e60cSlogwang if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
68422ce4affSfengbojiang save_errno = errno;
68522ce4affSfengbojiang free(newbuf);
68622ce4affSfengbojiang free(buf);
6877abd0fb2Slogwang if (!i && !bflag)
6887abd0fb2Slogwang putchar('\n');
68922ce4affSfengbojiang switch (save_errno) {
6907abd0fb2Slogwang case EOPNOTSUPP:
6917abd0fb2Slogwang warnx("%s: value is not available%s",
6927abd0fb2Slogwang string, line);
6937abd0fb2Slogwang return (1);
6947abd0fb2Slogwang case ENOTDIR:
6957abd0fb2Slogwang warnx("%s: specification is incomplete%s",
6967abd0fb2Slogwang string, line);
6977abd0fb2Slogwang return (1);
6987abd0fb2Slogwang case ENOMEM:
6997abd0fb2Slogwang warnx("%s: type is unknown to this program%s",
7007abd0fb2Slogwang string, line);
7017abd0fb2Slogwang return (1);
7027abd0fb2Slogwang default:
703*d4a07e70Sfengbojiang #ifndef FSTACK
70422ce4affSfengbojiang warnc(save_errno, "%s%s", string, line);
705*d4a07e70Sfengbojiang #else
706*d4a07e70Sfengbojiang warn("%s%s", string, line);
707*d4a07e70Sfengbojiang #endif
7087abd0fb2Slogwang return (1);
7097abd0fb2Slogwang }
7107abd0fb2Slogwang }
71122ce4affSfengbojiang free(newbuf);
71222ce4affSfengbojiang free(buf);
7137abd0fb2Slogwang if (!bflag)
7147abd0fb2Slogwang printf(" -> ");
7157abd0fb2Slogwang i = nflag;
7167abd0fb2Slogwang nflag = 1;
71722ce4affSfengbojiang j = show_var(mib, len, false);
7187abd0fb2Slogwang if (!j && !bflag)
7197abd0fb2Slogwang putchar('\n');
7207abd0fb2Slogwang nflag = i;
7217abd0fb2Slogwang
7227abd0fb2Slogwang return (0);
7237abd0fb2Slogwang }
7247abd0fb2Slogwang
7257abd0fb2Slogwang static int
7267abd0fb2Slogwang parsefile(const char *filename)
7277abd0fb2Slogwang {
7287abd0fb2Slogwang FILE *file;
7297abd0fb2Slogwang char line[BUFSIZ], *p, *pq, *pdq;
7307abd0fb2Slogwang int warncount = 0, lineno = 0;
7317abd0fb2Slogwang
7327abd0fb2Slogwang file = fopen(filename, "r");
7337abd0fb2Slogwang if (file == NULL)
7347abd0fb2Slogwang err(EX_NOINPUT, "%s", filename);
7357abd0fb2Slogwang while (fgets(line, sizeof(line), file) != NULL) {
7367abd0fb2Slogwang lineno++;
7377abd0fb2Slogwang p = line;
7387abd0fb2Slogwang pq = strchr(line, '\'');
7397abd0fb2Slogwang pdq = strchr(line, '\"');
7407abd0fb2Slogwang /* Replace the first # with \0. */
7417abd0fb2Slogwang while((p = strchr(p, '#')) != NULL) {
7427abd0fb2Slogwang if (pq != NULL && p > pq) {
7437abd0fb2Slogwang if ((p = strchr(pq+1, '\'')) != NULL)
7447abd0fb2Slogwang *(++p) = '\0';
7457abd0fb2Slogwang break;
7467abd0fb2Slogwang } else if (pdq != NULL && p > pdq) {
7477abd0fb2Slogwang if ((p = strchr(pdq+1, '\"')) != NULL)
7487abd0fb2Slogwang *(++p) = '\0';
7497abd0fb2Slogwang break;
7507abd0fb2Slogwang } else if (p == line || *(p-1) != '\\') {
7517abd0fb2Slogwang *p = '\0';
7527abd0fb2Slogwang break;
7537abd0fb2Slogwang }
7547abd0fb2Slogwang p++;
7557abd0fb2Slogwang }
7567abd0fb2Slogwang /* Trim spaces */
7577abd0fb2Slogwang p = line + strlen(line) - 1;
7587abd0fb2Slogwang while (p >= line && isspace((int)*p)) {
7597abd0fb2Slogwang *p = '\0';
7607abd0fb2Slogwang p--;
7617abd0fb2Slogwang }
7627abd0fb2Slogwang p = line;
7637abd0fb2Slogwang while (isspace((int)*p))
7647abd0fb2Slogwang p++;
7657abd0fb2Slogwang if (*p == '\0')
7667abd0fb2Slogwang continue;
7677abd0fb2Slogwang else
7687abd0fb2Slogwang warncount += parse(p, lineno);
7697abd0fb2Slogwang }
7707abd0fb2Slogwang fclose(file);
7717abd0fb2Slogwang
7727abd0fb2Slogwang return (warncount);
7737abd0fb2Slogwang }
7747abd0fb2Slogwang
7757abd0fb2Slogwang /* These functions will dump out various interesting structures. */
7767abd0fb2Slogwang
7777abd0fb2Slogwang static int
7787abd0fb2Slogwang S_clockinfo(size_t l2, void *p)
7797abd0fb2Slogwang {
7807abd0fb2Slogwang struct clockinfo *ci = (struct clockinfo*)p;
7817abd0fb2Slogwang
7827abd0fb2Slogwang if (l2 != sizeof(*ci)) {
7837abd0fb2Slogwang warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci));
7847abd0fb2Slogwang return (1);
7857abd0fb2Slogwang }
7867abd0fb2Slogwang printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
7877abd0fb2Slogwang "{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
7887abd0fb2Slogwang ci->hz, ci->tick, ci->profhz, ci->stathz);
7897abd0fb2Slogwang return (0);
7907abd0fb2Slogwang }
7917abd0fb2Slogwang
7927abd0fb2Slogwang static int
7937abd0fb2Slogwang S_loadavg(size_t l2, void *p)
7947abd0fb2Slogwang {
7957abd0fb2Slogwang struct loadavg *tv = (struct loadavg*)p;
7967abd0fb2Slogwang
7977abd0fb2Slogwang if (l2 != sizeof(*tv)) {
7987abd0fb2Slogwang warnx("S_loadavg %zu != %zu", l2, sizeof(*tv));
7997abd0fb2Slogwang return (1);
8007abd0fb2Slogwang }
8017abd0fb2Slogwang printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
8027abd0fb2Slogwang (double)tv->ldavg[0]/(double)tv->fscale,
8037abd0fb2Slogwang (double)tv->ldavg[1]/(double)tv->fscale,
8047abd0fb2Slogwang (double)tv->ldavg[2]/(double)tv->fscale);
8057abd0fb2Slogwang return (0);
8067abd0fb2Slogwang }
8077abd0fb2Slogwang
8087abd0fb2Slogwang static int
8097abd0fb2Slogwang S_timeval(size_t l2, void *p)
8107abd0fb2Slogwang {
8117abd0fb2Slogwang struct timeval *tv = (struct timeval*)p;
8127abd0fb2Slogwang time_t tv_sec;
8137abd0fb2Slogwang char *p1, *p2;
8147abd0fb2Slogwang
8157abd0fb2Slogwang if (l2 != sizeof(*tv)) {
8167abd0fb2Slogwang warnx("S_timeval %zu != %zu", l2, sizeof(*tv));
8177abd0fb2Slogwang return (1);
8187abd0fb2Slogwang }
8197abd0fb2Slogwang printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
8207abd0fb2Slogwang "{ sec = %jd, usec = %ld } ",
8217abd0fb2Slogwang (intmax_t)tv->tv_sec, tv->tv_usec);
8227abd0fb2Slogwang tv_sec = tv->tv_sec;
8237abd0fb2Slogwang p1 = strdup(ctime(&tv_sec));
8247abd0fb2Slogwang for (p2=p1; *p2 ; p2++)
8257abd0fb2Slogwang if (*p2 == '\n')
8267abd0fb2Slogwang *p2 = '\0';
8277abd0fb2Slogwang fputs(p1, stdout);
8287abd0fb2Slogwang free(p1);
8297abd0fb2Slogwang return (0);
8307abd0fb2Slogwang }
8317abd0fb2Slogwang
8327abd0fb2Slogwang static int
8337abd0fb2Slogwang S_vmtotal(size_t l2, void *p)
8347abd0fb2Slogwang {
83522ce4affSfengbojiang struct vmtotal *v;
83622ce4affSfengbojiang int pageKilo;
8377abd0fb2Slogwang
8387abd0fb2Slogwang if (l2 != sizeof(*v)) {
8397abd0fb2Slogwang warnx("S_vmtotal %zu != %zu", l2, sizeof(*v));
8407abd0fb2Slogwang return (1);
8417abd0fb2Slogwang }
8427abd0fb2Slogwang
84322ce4affSfengbojiang v = p;
84422ce4affSfengbojiang pageKilo = getpagesize() / 1024;
84522ce4affSfengbojiang
84622ce4affSfengbojiang #define pg2k(a) ((uintmax_t)(a) * pageKilo)
84722ce4affSfengbojiang printf("\nSystem wide totals computed every five seconds:"
8487abd0fb2Slogwang " (values in kilobytes)\n");
8497abd0fb2Slogwang printf("===============================================\n");
85022ce4affSfengbojiang printf("Processes:\t\t(RUNQ: %d Disk Wait: %d Page Wait: "
85122ce4affSfengbojiang "%d Sleep: %d)\n",
8527abd0fb2Slogwang v->t_rq, v->t_dw, v->t_pw, v->t_sl);
85322ce4affSfengbojiang printf("Virtual Memory:\t\t(Total: %juK Active: %juK)\n",
85422ce4affSfengbojiang pg2k(v->t_vm), pg2k(v->t_avm));
85522ce4affSfengbojiang printf("Real Memory:\t\t(Total: %juK Active: %juK)\n",
85622ce4affSfengbojiang pg2k(v->t_rm), pg2k(v->t_arm));
85722ce4affSfengbojiang printf("Shared Virtual Memory:\t(Total: %juK Active: %juK)\n",
85822ce4affSfengbojiang pg2k(v->t_vmshr), pg2k(v->t_avmshr));
85922ce4affSfengbojiang printf("Shared Real Memory:\t(Total: %juK Active: %juK)\n",
86022ce4affSfengbojiang pg2k(v->t_rmshr), pg2k(v->t_armshr));
86122ce4affSfengbojiang printf("Free Memory:\t%juK", pg2k(v->t_free));
86222ce4affSfengbojiang return (0);
86322ce4affSfengbojiang }
86422ce4affSfengbojiang
86522ce4affSfengbojiang static int
86622ce4affSfengbojiang S_input_id(size_t l2, void *p)
86722ce4affSfengbojiang {
86822ce4affSfengbojiang struct input_id *id = p;
86922ce4affSfengbojiang
87022ce4affSfengbojiang if (l2 != sizeof(*id)) {
87122ce4affSfengbojiang warnx("S_input_id %zu != %zu", l2, sizeof(*id));
87222ce4affSfengbojiang return (1);
87322ce4affSfengbojiang }
87422ce4affSfengbojiang
87522ce4affSfengbojiang printf("{ bustype = 0x%04x, vendor = 0x%04x, "
87622ce4affSfengbojiang "product = 0x%04x, version = 0x%04x }",
87722ce4affSfengbojiang id->bustype, id->vendor, id->product, id->version);
87822ce4affSfengbojiang return (0);
87922ce4affSfengbojiang }
88022ce4affSfengbojiang
88122ce4affSfengbojiang static int
88222ce4affSfengbojiang S_pagesizes(size_t l2, void *p)
88322ce4affSfengbojiang {
88422ce4affSfengbojiang char buf[256];
88522ce4affSfengbojiang u_long *ps;
88622ce4affSfengbojiang size_t l;
88722ce4affSfengbojiang int i;
88822ce4affSfengbojiang
88922ce4affSfengbojiang l = snprintf(buf, sizeof(buf), "{ ");
89022ce4affSfengbojiang ps = p;
89122ce4affSfengbojiang for (i = 0; i * sizeof(*ps) < l2 && ps[i] != 0 && l < sizeof(buf);
89222ce4affSfengbojiang i++) {
89322ce4affSfengbojiang l += snprintf(&buf[l], sizeof(buf) - l,
89422ce4affSfengbojiang "%s%lu", i == 0 ? "" : ", ", ps[i]);
89522ce4affSfengbojiang }
89622ce4affSfengbojiang if (l < sizeof(buf))
89722ce4affSfengbojiang (void)snprintf(&buf[l], sizeof(buf) - l, " }");
89822ce4affSfengbojiang
89922ce4affSfengbojiang printf("%s", buf);
9007abd0fb2Slogwang
9017abd0fb2Slogwang return (0);
9027abd0fb2Slogwang }
9037abd0fb2Slogwang
9047abd0fb2Slogwang #ifdef __amd64__
905*d4a07e70Sfengbojiang #ifdef FSTACK
906*d4a07e70Sfengbojiang #define efi_next_descriptor(ptr, size) \
907*d4a07e70Sfengbojiang ((struct efi_md *)(((uint8_t *)(ptr)) + (size)))
908*d4a07e70Sfengbojiang #endif
909*d4a07e70Sfengbojiang
9107abd0fb2Slogwang static int
9117abd0fb2Slogwang S_efi_map(size_t l2, void *p)
9127abd0fb2Slogwang {
9137abd0fb2Slogwang struct efi_map_header *efihdr;
9147abd0fb2Slogwang struct efi_md *map;
9157abd0fb2Slogwang const char *type;
9167abd0fb2Slogwang size_t efisz;
9177abd0fb2Slogwang int ndesc, i;
9187abd0fb2Slogwang
91922ce4affSfengbojiang static const char * const types[] = {
92022ce4affSfengbojiang [EFI_MD_TYPE_NULL] = "Reserved",
92122ce4affSfengbojiang [EFI_MD_TYPE_CODE] = "LoaderCode",
92222ce4affSfengbojiang [EFI_MD_TYPE_DATA] = "LoaderData",
92322ce4affSfengbojiang [EFI_MD_TYPE_BS_CODE] = "BootServicesCode",
92422ce4affSfengbojiang [EFI_MD_TYPE_BS_DATA] = "BootServicesData",
92522ce4affSfengbojiang [EFI_MD_TYPE_RT_CODE] = "RuntimeServicesCode",
92622ce4affSfengbojiang [EFI_MD_TYPE_RT_DATA] = "RuntimeServicesData",
92722ce4affSfengbojiang [EFI_MD_TYPE_FREE] = "ConventionalMemory",
92822ce4affSfengbojiang [EFI_MD_TYPE_BAD] = "UnusableMemory",
92922ce4affSfengbojiang [EFI_MD_TYPE_RECLAIM] = "ACPIReclaimMemory",
93022ce4affSfengbojiang [EFI_MD_TYPE_FIRMWARE] = "ACPIMemoryNVS",
93122ce4affSfengbojiang [EFI_MD_TYPE_IOMEM] = "MemoryMappedIO",
93222ce4affSfengbojiang [EFI_MD_TYPE_IOPORT] = "MemoryMappedIOPortSpace",
93322ce4affSfengbojiang [EFI_MD_TYPE_PALCODE] = "PalCode",
93422ce4affSfengbojiang [EFI_MD_TYPE_PERSISTENT] = "PersistentMemory",
9357abd0fb2Slogwang };
9367abd0fb2Slogwang
9377abd0fb2Slogwang /*
9387abd0fb2Slogwang * Memory map data provided by UEFI via the GetMemoryMap
9397abd0fb2Slogwang * Boot Services API.
9407abd0fb2Slogwang */
9417abd0fb2Slogwang if (l2 < sizeof(*efihdr)) {
9427abd0fb2Slogwang warnx("S_efi_map length less than header");
9437abd0fb2Slogwang return (1);
9447abd0fb2Slogwang }
9457abd0fb2Slogwang efihdr = p;
9467abd0fb2Slogwang efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf;
9477abd0fb2Slogwang map = (struct efi_md *)((uint8_t *)efihdr + efisz);
9487abd0fb2Slogwang
9497abd0fb2Slogwang if (efihdr->descriptor_size == 0)
9507abd0fb2Slogwang return (0);
9517abd0fb2Slogwang if (l2 != efisz + efihdr->memory_size) {
9527abd0fb2Slogwang warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz +
9537abd0fb2Slogwang efihdr->memory_size);
9547abd0fb2Slogwang return (1);
9557abd0fb2Slogwang }
9567abd0fb2Slogwang ndesc = efihdr->memory_size / efihdr->descriptor_size;
9577abd0fb2Slogwang
9587abd0fb2Slogwang printf("\n%23s %12s %12s %8s %4s",
9597abd0fb2Slogwang "Type", "Physical", "Virtual", "#Pages", "Attr");
9607abd0fb2Slogwang
9617abd0fb2Slogwang for (i = 0; i < ndesc; i++,
9627abd0fb2Slogwang map = efi_next_descriptor(map, efihdr->descriptor_size)) {
96322ce4affSfengbojiang type = NULL;
96422ce4affSfengbojiang if (map->md_type < nitems(types))
9657abd0fb2Slogwang type = types[map->md_type];
96622ce4affSfengbojiang if (type == NULL)
9677abd0fb2Slogwang type = "<INVALID>";
96822ce4affSfengbojiang printf("\n%23s %012jx %12p %08jx ", type,
96922ce4affSfengbojiang (uintmax_t)map->md_phys, map->md_virt,
97022ce4affSfengbojiang (uintmax_t)map->md_pages);
9717abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_UC)
9727abd0fb2Slogwang printf("UC ");
9737abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_WC)
9747abd0fb2Slogwang printf("WC ");
9757abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_WT)
9767abd0fb2Slogwang printf("WT ");
9777abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_WB)
9787abd0fb2Slogwang printf("WB ");
9797abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_UCE)
9807abd0fb2Slogwang printf("UCE ");
9817abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_WP)
9827abd0fb2Slogwang printf("WP ");
9837abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_RP)
9847abd0fb2Slogwang printf("RP ");
9857abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_XP)
9867abd0fb2Slogwang printf("XP ");
9877abd0fb2Slogwang if (map->md_attr & EFI_MD_ATTR_RT)
9887abd0fb2Slogwang printf("RUNTIME");
9897abd0fb2Slogwang }
9907abd0fb2Slogwang return (0);
9917abd0fb2Slogwang }
9927abd0fb2Slogwang #endif
9937abd0fb2Slogwang
9947abd0fb2Slogwang #if defined(__amd64__) || defined(__i386__)
9957abd0fb2Slogwang static int
9967abd0fb2Slogwang S_bios_smap_xattr(size_t l2, void *p)
9977abd0fb2Slogwang {
9987abd0fb2Slogwang struct bios_smap_xattr *smap, *end;
9997abd0fb2Slogwang
10007abd0fb2Slogwang if (l2 % sizeof(*smap) != 0) {
10017abd0fb2Slogwang warnx("S_bios_smap_xattr %zu is not a multiple of %zu", l2,
10027abd0fb2Slogwang sizeof(*smap));
10037abd0fb2Slogwang return (1);
10047abd0fb2Slogwang }
10057abd0fb2Slogwang
10067abd0fb2Slogwang end = (struct bios_smap_xattr *)((char *)p + l2);
10077abd0fb2Slogwang for (smap = p; smap < end; smap++)
10087abd0fb2Slogwang printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx",
10097abd0fb2Slogwang smap->type, smap->xattr, (uintmax_t)smap->base,
10107abd0fb2Slogwang (uintmax_t)smap->length);
10117abd0fb2Slogwang return (0);
10127abd0fb2Slogwang }
10137abd0fb2Slogwang #endif
10147abd0fb2Slogwang
10157abd0fb2Slogwang static int
10167abd0fb2Slogwang strIKtoi(const char *str, char **endptrp, const char *fmt)
10177abd0fb2Slogwang {
10187abd0fb2Slogwang int kelv;
10197abd0fb2Slogwang float temp;
10207abd0fb2Slogwang size_t len;
10217abd0fb2Slogwang const char *p;
10227abd0fb2Slogwang int prec, i;
10237abd0fb2Slogwang
10247abd0fb2Slogwang assert(errno == 0);
10257abd0fb2Slogwang
10267abd0fb2Slogwang len = strlen(str);
10277abd0fb2Slogwang /* caller already checked this */
10287abd0fb2Slogwang assert(len > 0);
10297abd0fb2Slogwang
10307abd0fb2Slogwang /*
10317abd0fb2Slogwang * A format of "IK" is in deciKelvin. A format of "IK3" is in
10327abd0fb2Slogwang * milliKelvin. The single digit following IK is log10 of the
10337abd0fb2Slogwang * multiplying factor to convert Kelvin into the untis of this sysctl,
10347abd0fb2Slogwang * or the dividing factor to convert the sysctl value to Kelvin. Numbers
10357abd0fb2Slogwang * larger than 6 will run into precision issues with 32-bit integers.
10367abd0fb2Slogwang * Characters that aren't ASCII digits after the 'K' are ignored. No
10377abd0fb2Slogwang * localization is present because this is an interface from the kernel
10387abd0fb2Slogwang * to this program (eg not an end-user interface), so isdigit() isn't
10397abd0fb2Slogwang * used here.
10407abd0fb2Slogwang */
10417abd0fb2Slogwang if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9')
10427abd0fb2Slogwang prec = fmt[2] - '0';
10437abd0fb2Slogwang else
10447abd0fb2Slogwang prec = 1;
10457abd0fb2Slogwang p = &str[len - 1];
10467abd0fb2Slogwang if (*p == 'C' || *p == 'F' || *p == 'K') {
10477abd0fb2Slogwang temp = strtof(str, endptrp);
10487abd0fb2Slogwang if (*endptrp != str && *endptrp == p && errno == 0) {
10497abd0fb2Slogwang if (*p == 'F')
10507abd0fb2Slogwang temp = (temp - 32) * 5 / 9;
10517abd0fb2Slogwang *endptrp = NULL;
10527abd0fb2Slogwang if (*p != 'K')
10537abd0fb2Slogwang temp += 273.15;
10547abd0fb2Slogwang for (i = 0; i < prec; i++)
10557abd0fb2Slogwang temp *= 10.0;
10567abd0fb2Slogwang return ((int)(temp + 0.5));
10577abd0fb2Slogwang }
10587abd0fb2Slogwang } else {
10597abd0fb2Slogwang /* No unit specified -> treat it as a raw number */
10607abd0fb2Slogwang kelv = (int)strtol(str, endptrp, 10);
10617abd0fb2Slogwang if (*endptrp != str && *endptrp == p && errno == 0) {
10627abd0fb2Slogwang *endptrp = NULL;
10637abd0fb2Slogwang return (kelv);
10647abd0fb2Slogwang }
10657abd0fb2Slogwang }
10667abd0fb2Slogwang
10677abd0fb2Slogwang errno = ERANGE;
10687abd0fb2Slogwang return (0);
10697abd0fb2Slogwang }
10707abd0fb2Slogwang
10717abd0fb2Slogwang /*
10727abd0fb2Slogwang * These functions uses a presently undocumented interface to the kernel
10737abd0fb2Slogwang * to walk the tree and get the type so it can print the value.
10747abd0fb2Slogwang * This interface is under work and consideration, and should probably
10757abd0fb2Slogwang * be killed with a big axe by the first person who can find the time.
10767abd0fb2Slogwang * (be aware though, that the proper interface isn't as obvious as it
10777abd0fb2Slogwang * may seem, there are various conflicting requirements.
10787abd0fb2Slogwang */
10797abd0fb2Slogwang
10807abd0fb2Slogwang static int
10817abd0fb2Slogwang name2oid(const char *name, int *oidp)
10827abd0fb2Slogwang {
10837abd0fb2Slogwang int oid[2];
10847abd0fb2Slogwang int i;
10857abd0fb2Slogwang size_t j;
10867abd0fb2Slogwang
108722ce4affSfengbojiang oid[0] = CTL_SYSCTL;
108822ce4affSfengbojiang oid[1] = CTL_SYSCTL_NAME2OID;
10897abd0fb2Slogwang
10907abd0fb2Slogwang j = CTL_MAXNAME * sizeof(int);
10912d99e60cSlogwang i = sysctl(oid, 2, oidp, &j, name, strlen(name));
10927abd0fb2Slogwang if (i < 0)
10937abd0fb2Slogwang return (i);
10947abd0fb2Slogwang j /= sizeof(int);
10957abd0fb2Slogwang return (j);
10967abd0fb2Slogwang }
10977abd0fb2Slogwang
10987abd0fb2Slogwang static int
10997abd0fb2Slogwang oidfmt(int *oid, int len, char *fmt, u_int *kind)
11007abd0fb2Slogwang {
11017abd0fb2Slogwang int qoid[CTL_MAXNAME+2];
11027abd0fb2Slogwang u_char buf[BUFSIZ];
11037abd0fb2Slogwang int i;
11047abd0fb2Slogwang size_t j;
11057abd0fb2Slogwang
110622ce4affSfengbojiang qoid[0] = CTL_SYSCTL;
110722ce4affSfengbojiang qoid[1] = CTL_SYSCTL_OIDFMT;
11087abd0fb2Slogwang memcpy(qoid + 2, oid, len * sizeof(int));
11097abd0fb2Slogwang
11107abd0fb2Slogwang j = sizeof(buf);
11112d99e60cSlogwang i = sysctl(qoid, len + 2, buf, &j, 0, 0);
11127abd0fb2Slogwang if (i)
11137abd0fb2Slogwang err(1, "sysctl fmt %d %zu %d", i, j, errno);
11147abd0fb2Slogwang
11157abd0fb2Slogwang if (kind)
11167abd0fb2Slogwang *kind = *(u_int *)buf;
11177abd0fb2Slogwang
11187abd0fb2Slogwang if (fmt)
11197abd0fb2Slogwang strcpy(fmt, (char *)(buf + sizeof(u_int)));
11207abd0fb2Slogwang return (0);
11217abd0fb2Slogwang }
11227abd0fb2Slogwang
11237abd0fb2Slogwang /*
11247abd0fb2Slogwang * This formats and outputs the value of one variable
11257abd0fb2Slogwang *
11267abd0fb2Slogwang * Returns zero if anything was actually output.
11277abd0fb2Slogwang * Returns one if didn't know what to do with this.
11287abd0fb2Slogwang * Return minus one if we had errors.
11297abd0fb2Slogwang */
11307abd0fb2Slogwang static int
113122ce4affSfengbojiang show_var(int *oid, int nlen, bool honor_skip)
11327abd0fb2Slogwang {
113322ce4affSfengbojiang static int skip_len = 0, skip_oid[CTL_MAXNAME];
11347abd0fb2Slogwang u_char buf[BUFSIZ], *val, *oval, *p;
11357abd0fb2Slogwang char name[BUFSIZ], fmt[BUFSIZ];
11367abd0fb2Slogwang const char *sep, *sep1, *prntype;
11377abd0fb2Slogwang int qoid[CTL_MAXNAME+2];
11387abd0fb2Slogwang uintmax_t umv;
11397abd0fb2Slogwang intmax_t mv;
11407abd0fb2Slogwang int i, hexlen, sign, ctltype;
11417abd0fb2Slogwang size_t intlen;
11427abd0fb2Slogwang size_t j, len;
11437abd0fb2Slogwang u_int kind;
11447abd0fb2Slogwang float base;
11457abd0fb2Slogwang int (*func)(size_t, void *);
11467abd0fb2Slogwang int prec;
11477abd0fb2Slogwang
11487abd0fb2Slogwang /* Silence GCC. */
11497abd0fb2Slogwang umv = mv = intlen = 0;
11507abd0fb2Slogwang
11517abd0fb2Slogwang bzero(buf, BUFSIZ);
11527abd0fb2Slogwang bzero(fmt, BUFSIZ);
11537abd0fb2Slogwang bzero(name, BUFSIZ);
115422ce4affSfengbojiang qoid[0] = CTL_SYSCTL;
11557abd0fb2Slogwang memcpy(qoid + 2, oid, nlen * sizeof(int));
11567abd0fb2Slogwang
115722ce4affSfengbojiang qoid[1] = CTL_SYSCTL_NAME;
11587abd0fb2Slogwang j = sizeof(name);
11592d99e60cSlogwang i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
11607abd0fb2Slogwang if (i || !j)
11617abd0fb2Slogwang err(1, "sysctl name %d %zu %d", i, j, errno);
11627abd0fb2Slogwang
11637abd0fb2Slogwang oidfmt(oid, nlen, fmt, &kind);
11647abd0fb2Slogwang /* if Wflag then only list sysctls that are writeable and not stats. */
11657abd0fb2Slogwang if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0))
116622ce4affSfengbojiang return (1);
11677abd0fb2Slogwang
11687abd0fb2Slogwang /* if Tflag then only list sysctls that are tuneables. */
11697abd0fb2Slogwang if (Tflag && (kind & CTLFLAG_TUN) == 0)
117022ce4affSfengbojiang return (1);
11717abd0fb2Slogwang
11727abd0fb2Slogwang if (Nflag) {
11737abd0fb2Slogwang printf("%s", name);
11747abd0fb2Slogwang return (0);
11757abd0fb2Slogwang }
11767abd0fb2Slogwang
11777abd0fb2Slogwang if (eflag)
11787abd0fb2Slogwang sep = "=";
11797abd0fb2Slogwang else
11807abd0fb2Slogwang sep = ": ";
11817abd0fb2Slogwang
11827abd0fb2Slogwang ctltype = (kind & CTLTYPE);
11837abd0fb2Slogwang if (tflag || dflag) {
11847abd0fb2Slogwang if (!nflag)
11857abd0fb2Slogwang printf("%s%s", name, sep);
11867abd0fb2Slogwang if (ctl_typename[ctltype] != NULL)
11877abd0fb2Slogwang prntype = ctl_typename[ctltype];
11887abd0fb2Slogwang else
11897abd0fb2Slogwang prntype = "unknown";
11907abd0fb2Slogwang if (tflag && dflag)
11917abd0fb2Slogwang printf("%s%s", prntype, sep);
11927abd0fb2Slogwang else if (tflag) {
11937abd0fb2Slogwang printf("%s", prntype);
11947abd0fb2Slogwang return (0);
11957abd0fb2Slogwang }
119622ce4affSfengbojiang qoid[1] = CTL_SYSCTL_OIDDESCR;
11977abd0fb2Slogwang j = sizeof(buf);
11982d99e60cSlogwang i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
11997abd0fb2Slogwang printf("%s", buf);
12007abd0fb2Slogwang return (0);
12017abd0fb2Slogwang }
120222ce4affSfengbojiang
120322ce4affSfengbojiang /* keep track of encountered skip nodes, ignoring descendants */
120422ce4affSfengbojiang if ((skip_len == 0 || skip_len >= nlen * (int)sizeof(int)) &&
120522ce4affSfengbojiang (kind & CTLFLAG_SKIP) != 0) {
120622ce4affSfengbojiang /* Save this oid so we can skip descendants. */
120722ce4affSfengbojiang skip_len = nlen * sizeof(int);
120822ce4affSfengbojiang memcpy(skip_oid, oid, skip_len);
120922ce4affSfengbojiang }
121022ce4affSfengbojiang
121122ce4affSfengbojiang /* bail before fetching the value if we're honoring skip */
121222ce4affSfengbojiang if (honor_skip) {
121322ce4affSfengbojiang if (0 < skip_len && skip_len <= nlen * (int)sizeof(int) &&
121422ce4affSfengbojiang memcmp(skip_oid, oid, skip_len) == 0)
121522ce4affSfengbojiang return (1);
121622ce4affSfengbojiang /* Not a skip node or descendant of a skip node. */
121722ce4affSfengbojiang skip_len = 0;
121822ce4affSfengbojiang }
121922ce4affSfengbojiang
122022ce4affSfengbojiang /* don't fetch opaques that we don't know how to print */
122122ce4affSfengbojiang if (ctltype == CTLTYPE_OPAQUE) {
122222ce4affSfengbojiang if (strcmp(fmt, "S,clockinfo") == 0)
122322ce4affSfengbojiang func = S_clockinfo;
122422ce4affSfengbojiang else if (strcmp(fmt, "S,timeval") == 0)
122522ce4affSfengbojiang func = S_timeval;
122622ce4affSfengbojiang else if (strcmp(fmt, "S,loadavg") == 0)
122722ce4affSfengbojiang func = S_loadavg;
122822ce4affSfengbojiang else if (strcmp(fmt, "S,vmtotal") == 0)
122922ce4affSfengbojiang func = S_vmtotal;
123022ce4affSfengbojiang else if (strcmp(fmt, "S,input_id") == 0)
123122ce4affSfengbojiang func = S_input_id;
123222ce4affSfengbojiang else if (strcmp(fmt, "S,pagesizes") == 0)
123322ce4affSfengbojiang func = S_pagesizes;
123422ce4affSfengbojiang #ifdef __amd64__
123522ce4affSfengbojiang else if (strcmp(fmt, "S,efi_map_header") == 0)
123622ce4affSfengbojiang func = S_efi_map;
123722ce4affSfengbojiang #endif
123822ce4affSfengbojiang #if defined(__amd64__) || defined(__i386__)
123922ce4affSfengbojiang else if (strcmp(fmt, "S,bios_smap_xattr") == 0)
124022ce4affSfengbojiang func = S_bios_smap_xattr;
124122ce4affSfengbojiang #endif
124222ce4affSfengbojiang else {
124322ce4affSfengbojiang func = NULL;
124422ce4affSfengbojiang if (!bflag && !oflag && !xflag)
124522ce4affSfengbojiang return (1);
124622ce4affSfengbojiang }
124722ce4affSfengbojiang }
124822ce4affSfengbojiang
12497abd0fb2Slogwang /* find an estimate of how much we need for this var */
12507abd0fb2Slogwang if (Bflag)
12517abd0fb2Slogwang j = Bflag;
12527abd0fb2Slogwang else {
12537abd0fb2Slogwang j = 0;
12542d99e60cSlogwang i = sysctl(oid, nlen, 0, &j, 0, 0);
12557abd0fb2Slogwang j += j; /* we want to be sure :-) */
12567abd0fb2Slogwang }
12577abd0fb2Slogwang
12587abd0fb2Slogwang val = oval = malloc(j + 1);
12597abd0fb2Slogwang if (val == NULL) {
12607abd0fb2Slogwang warnx("malloc failed");
12617abd0fb2Slogwang return (1);
12627abd0fb2Slogwang }
12637abd0fb2Slogwang len = j;
12642d99e60cSlogwang i = sysctl(oid, nlen, val, &len, 0, 0);
12657abd0fb2Slogwang if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) {
12667abd0fb2Slogwang free(oval);
12677abd0fb2Slogwang return (1);
12687abd0fb2Slogwang }
12697abd0fb2Slogwang
12707abd0fb2Slogwang if (bflag) {
12717abd0fb2Slogwang fwrite(val, 1, len, stdout);
12727abd0fb2Slogwang free(oval);
12737abd0fb2Slogwang return (0);
12747abd0fb2Slogwang }
12757abd0fb2Slogwang val[len] = '\0';
12767abd0fb2Slogwang p = val;
12777abd0fb2Slogwang sign = ctl_sign[ctltype];
12787abd0fb2Slogwang intlen = ctl_size[ctltype];
12797abd0fb2Slogwang
12807abd0fb2Slogwang switch (ctltype) {
12817abd0fb2Slogwang case CTLTYPE_STRING:
12827abd0fb2Slogwang if (!nflag)
12837abd0fb2Slogwang printf("%s%s", name, sep);
12847abd0fb2Slogwang printf("%.*s", (int)len, p);
12857abd0fb2Slogwang free(oval);
12867abd0fb2Slogwang return (0);
12877abd0fb2Slogwang
12887abd0fb2Slogwang case CTLTYPE_INT:
12897abd0fb2Slogwang case CTLTYPE_UINT:
12907abd0fb2Slogwang case CTLTYPE_LONG:
12917abd0fb2Slogwang case CTLTYPE_ULONG:
12927abd0fb2Slogwang case CTLTYPE_S8:
12937abd0fb2Slogwang case CTLTYPE_S16:
12947abd0fb2Slogwang case CTLTYPE_S32:
12957abd0fb2Slogwang case CTLTYPE_S64:
12967abd0fb2Slogwang case CTLTYPE_U8:
12977abd0fb2Slogwang case CTLTYPE_U16:
12987abd0fb2Slogwang case CTLTYPE_U32:
12997abd0fb2Slogwang case CTLTYPE_U64:
13007abd0fb2Slogwang if (!nflag)
13017abd0fb2Slogwang printf("%s%s", name, sep);
13027abd0fb2Slogwang hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
13037abd0fb2Slogwang sep1 = "";
13047abd0fb2Slogwang while (len >= intlen) {
13057abd0fb2Slogwang switch (kind & CTLTYPE) {
13067abd0fb2Slogwang case CTLTYPE_INT:
13077abd0fb2Slogwang case CTLTYPE_UINT:
13087abd0fb2Slogwang umv = *(u_int *)p;
13097abd0fb2Slogwang mv = *(int *)p;
13107abd0fb2Slogwang break;
13117abd0fb2Slogwang case CTLTYPE_LONG:
13127abd0fb2Slogwang case CTLTYPE_ULONG:
13137abd0fb2Slogwang umv = *(u_long *)p;
13147abd0fb2Slogwang mv = *(long *)p;
13157abd0fb2Slogwang break;
13167abd0fb2Slogwang case CTLTYPE_S8:
13177abd0fb2Slogwang case CTLTYPE_U8:
13187abd0fb2Slogwang umv = *(uint8_t *)p;
13197abd0fb2Slogwang mv = *(int8_t *)p;
13207abd0fb2Slogwang break;
13217abd0fb2Slogwang case CTLTYPE_S16:
13227abd0fb2Slogwang case CTLTYPE_U16:
13237abd0fb2Slogwang umv = *(uint16_t *)p;
13247abd0fb2Slogwang mv = *(int16_t *)p;
13257abd0fb2Slogwang break;
13267abd0fb2Slogwang case CTLTYPE_S32:
13277abd0fb2Slogwang case CTLTYPE_U32:
13287abd0fb2Slogwang umv = *(uint32_t *)p;
13297abd0fb2Slogwang mv = *(int32_t *)p;
13307abd0fb2Slogwang break;
13317abd0fb2Slogwang case CTLTYPE_S64:
13327abd0fb2Slogwang case CTLTYPE_U64:
13337abd0fb2Slogwang umv = *(uint64_t *)p;
13347abd0fb2Slogwang mv = *(int64_t *)p;
13357abd0fb2Slogwang break;
13367abd0fb2Slogwang }
13377abd0fb2Slogwang fputs(sep1, stdout);
13387abd0fb2Slogwang if (xflag)
13397abd0fb2Slogwang printf("%#0*jx", hexlen, umv);
13407abd0fb2Slogwang else if (!sign)
13417abd0fb2Slogwang printf(hflag ? "%'ju" : "%ju", umv);
13427abd0fb2Slogwang else if (fmt[1] == 'K') {
13437abd0fb2Slogwang if (mv < 0)
13447abd0fb2Slogwang printf("%jd", mv);
13457abd0fb2Slogwang else {
13467abd0fb2Slogwang /*
13477abd0fb2Slogwang * See strIKtoi for details on fmt.
13487abd0fb2Slogwang */
13497abd0fb2Slogwang prec = 1;
13507abd0fb2Slogwang if (fmt[2] != '\0')
13517abd0fb2Slogwang prec = fmt[2] - '0';
13527abd0fb2Slogwang base = 1.0;
13532d99e60cSlogwang for (int i = 0; i < prec; i++)
13547abd0fb2Slogwang base *= 10.0;
13557abd0fb2Slogwang printf("%.*fC", prec,
13567abd0fb2Slogwang (float)mv / base - 273.15);
13577abd0fb2Slogwang }
13587abd0fb2Slogwang } else
13597abd0fb2Slogwang printf(hflag ? "%'jd" : "%jd", mv);
13607abd0fb2Slogwang sep1 = " ";
13617abd0fb2Slogwang len -= intlen;
13627abd0fb2Slogwang p += intlen;
13637abd0fb2Slogwang }
13647abd0fb2Slogwang free(oval);
13657abd0fb2Slogwang return (0);
13667abd0fb2Slogwang
13677abd0fb2Slogwang case CTLTYPE_OPAQUE:
13687abd0fb2Slogwang i = 0;
13697abd0fb2Slogwang if (func) {
13707abd0fb2Slogwang if (!nflag)
13717abd0fb2Slogwang printf("%s%s", name, sep);
13727abd0fb2Slogwang i = (*func)(len, p);
13737abd0fb2Slogwang free(oval);
13747abd0fb2Slogwang return (i);
13757abd0fb2Slogwang }
13767abd0fb2Slogwang /* FALLTHROUGH */
13777abd0fb2Slogwang default:
13787abd0fb2Slogwang if (!oflag && !xflag) {
13797abd0fb2Slogwang free(oval);
13807abd0fb2Slogwang return (1);
13817abd0fb2Slogwang }
13827abd0fb2Slogwang if (!nflag)
13837abd0fb2Slogwang printf("%s%s", name, sep);
13847abd0fb2Slogwang printf("Format:%s Length:%zu Dump:0x", fmt, len);
13857abd0fb2Slogwang while (len-- && (xflag || p < val + 16))
13867abd0fb2Slogwang printf("%02x", *p++);
13877abd0fb2Slogwang if (!xflag && len > 16)
13887abd0fb2Slogwang printf("...");
13897abd0fb2Slogwang free(oval);
13907abd0fb2Slogwang return (0);
13917abd0fb2Slogwang }
13927abd0fb2Slogwang free(oval);
13937abd0fb2Slogwang return (1);
13947abd0fb2Slogwang }
13957abd0fb2Slogwang
13967abd0fb2Slogwang static int
13977abd0fb2Slogwang sysctl_all(int *oid, int len)
13987abd0fb2Slogwang {
13997abd0fb2Slogwang int name1[22], name2[22];
14007abd0fb2Slogwang int i, j;
14017abd0fb2Slogwang size_t l1, l2;
14027abd0fb2Slogwang
140322ce4affSfengbojiang name1[0] = CTL_SYSCTL;
140422ce4affSfengbojiang name1[1] = (oid != NULL || Nflag || dflag || tflag) ?
140522ce4affSfengbojiang CTL_SYSCTL_NEXTNOSKIP : CTL_SYSCTL_NEXT;
14067abd0fb2Slogwang l1 = 2;
14077abd0fb2Slogwang if (len) {
14087abd0fb2Slogwang memcpy(name1 + 2, oid, len * sizeof(int));
14097abd0fb2Slogwang l1 += len;
14107abd0fb2Slogwang } else {
141122ce4affSfengbojiang name1[2] = CTL_KERN;
14127abd0fb2Slogwang l1++;
14137abd0fb2Slogwang }
14147abd0fb2Slogwang for (;;) {
14157abd0fb2Slogwang l2 = sizeof(name2);
14162d99e60cSlogwang j = sysctl(name1, l1, name2, &l2, 0, 0);
14177abd0fb2Slogwang if (j < 0) {
14187abd0fb2Slogwang if (errno == ENOENT)
14197abd0fb2Slogwang return (0);
14207abd0fb2Slogwang else
14212d99e60cSlogwang err(1, "sysctl(getnext) %d %zu", j, l2);
14227abd0fb2Slogwang }
14237abd0fb2Slogwang
14247abd0fb2Slogwang l2 /= sizeof(int);
14257abd0fb2Slogwang
14267abd0fb2Slogwang if (len < 0 || l2 < (unsigned int)len)
14277abd0fb2Slogwang return (0);
14287abd0fb2Slogwang
142922ce4affSfengbojiang if (memcmp(name2, oid, len * sizeof(int)) != 0)
14307abd0fb2Slogwang return (0);
14317abd0fb2Slogwang
143222ce4affSfengbojiang i = show_var(name2, l2, true);
14337abd0fb2Slogwang if (!i && !bflag)
14347abd0fb2Slogwang putchar('\n');
14357abd0fb2Slogwang
14367abd0fb2Slogwang memcpy(name1 + 2, name2, l2 * sizeof(int));
14377abd0fb2Slogwang l1 = 2 + l2;
14387abd0fb2Slogwang }
14397abd0fb2Slogwang }
1440