Fri Jan 10 18:37:18 2014 UTC ()
use __func__, EXIT_{SUCCESS,FAILURE}


(christos)
diff -r1.150 -r1.151 src/sbin/sysctl/sysctl.c

cvs diff -r1.150 -r1.151 src/sbin/sysctl/sysctl.c (switch to unified diff)

--- src/sbin/sysctl/sysctl.c 2014/01/10 09:38:56 1.150
+++ src/sbin/sysctl/sysctl.c 2014/01/10 18:37:18 1.151
@@ -1,2790 +1,2790 @@ @@ -1,2790 +1,2790 @@
1/* $NetBSD: sysctl.c,v 1.150 2014/01/10 09:38:56 pooka Exp $ */ 1/* $NetBSD: sysctl.c,v 1.151 2014/01/10 18:37:18 christos Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2003 The NetBSD Foundation, Inc. 4 * Copyright (c) 2003 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Brown. 8 * by Andrew Brown.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1993 33 * Copyright (c) 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 */ 59 */
60 60
61#include <sys/cdefs.h> 61#include <sys/cdefs.h>
62#ifndef lint 62#ifndef lint
63__COPYRIGHT("@(#) Copyright (c) 1993\ 63__COPYRIGHT("@(#) Copyright (c) 1993\
64 The Regents of the University of California. All rights reserved."); 64 The Regents of the University of California. All rights reserved.");
65#endif /* not lint */ 65#endif /* not lint */
66 66
67#ifndef lint 67#ifndef lint
68#if 0 68#if 0
69static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93"; 69static char sccsid[] = "@(#)sysctl.c 8.1 (Berkeley) 6/6/93";
70#else 70#else
71__RCSID("$NetBSD: sysctl.c,v 1.150 2014/01/10 09:38:56 pooka Exp $"); 71__RCSID("$NetBSD: sysctl.c,v 1.151 2014/01/10 18:37:18 christos Exp $");
72#endif 72#endif
73#endif /* not lint */ 73#endif /* not lint */
74 74
75#include <sys/types.h> 75#include <sys/types.h>
76#include <sys/param.h> 76#include <sys/param.h>
77#include <sys/sysctl.h> 77#include <sys/sysctl.h>
78#include <sys/mount.h> 78#include <sys/mount.h>
79#include <sys/resource.h> 79#include <sys/resource.h>
80#include <sys/stat.h> 80#include <sys/stat.h>
81#include <sys/sched.h> 81#include <sys/sched.h>
82#include <sys/socket.h> 82#include <sys/socket.h>
83#include <sys/bitops.h> 83#include <sys/bitops.h>
84#include <netinet/in.h> 84#include <netinet/in.h>
85#include <netinet/ip_var.h> 85#include <netinet/ip_var.h>
86#include <netinet/tcp.h> 86#include <netinet/tcp.h>
87#include <netinet/tcp_timer.h> 87#include <netinet/tcp_timer.h>
88#include <netinet/tcp_var.h> 88#include <netinet/tcp_var.h>
89#include <netinet/icmp6.h> 89#include <netinet/icmp6.h>
90#include <nfs/rpcv2.h> 90#include <nfs/rpcv2.h>
91#include <nfs/nfsproto.h> 91#include <nfs/nfsproto.h>
92#include <nfs/nfs.h> 92#include <nfs/nfs.h>
93#include <machine/cpu.h> 93#include <machine/cpu.h>
94 94
95#include <assert.h> 95#include <assert.h>
96#include <ctype.h> 96#include <ctype.h>
97#include <err.h> 97#include <err.h>
98#include <errno.h> 98#include <errno.h>
99#include <inttypes.h> 99#include <inttypes.h>
100#include <regex.h> 100#include <regex.h>
101#include <stdarg.h> 101#include <stdarg.h>
102#include <stdio.h> 102#include <stdio.h>
103#include <stdlib.h> 103#include <stdlib.h>
104#include <string.h> 104#include <string.h>
105#include <time.h> 105#include <time.h>
106#include <unistd.h> 106#include <unistd.h>
107 107
108#include "prog_ops.h" 108#include "prog_ops.h"
109 109
110/* 110/*
111 * this needs to be able to do the printing and the setting 111 * this needs to be able to do the printing and the setting
112 */ 112 */
113#define HANDLER_PROTO const char *, const char *, char *, \ 113#define HANDLER_PROTO const char *, const char *, char *, \
114 int *, u_int, const struct sysctlnode *, \ 114 int *, u_int, const struct sysctlnode *, \
115 u_int, void * 115 u_int, void *
116#define HANDLER_ARGS const char *sname, const char *dname, char *value, \ 116#define HANDLER_ARGS const char *sname, const char *dname, char *value, \
117 int *name, u_int namelen, const struct sysctlnode *pnode, \ 117 int *name, u_int namelen, const struct sysctlnode *pnode, \
118 u_int type, void *v 118 u_int type, void *v
119#define DISPLAY_VALUE 0 119#define DISPLAY_VALUE 0
120#define DISPLAY_OLD 1 120#define DISPLAY_OLD 1
121#define DISPLAY_NEW 2 121#define DISPLAY_NEW 2
122 122
123/* 123/*
124 * generic routines 124 * generic routines
125 */ 125 */
126static const struct handlespec *findhandler(const char *, regex_t *, size_t *); 126static const struct handlespec *findhandler(const char *, regex_t *, size_t *);
127static void canonicalize(const char *, char *); 127static void canonicalize(const char *, char *);
128static void purge_tree(struct sysctlnode *); 128static void purge_tree(struct sysctlnode *);
129static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *, 129static void print_tree(int *, u_int, struct sysctlnode *, u_int, int, regex_t *,
130 size_t *); 130 size_t *);
131static void write_number(int *, u_int, struct sysctlnode *, char *); 131static void write_number(int *, u_int, struct sysctlnode *, char *);
132static void write_string(int *, u_int, struct sysctlnode *, char *); 132static void write_string(int *, u_int, struct sysctlnode *, char *);
133static void display_number(const struct sysctlnode *, const char *, 133static void display_number(const struct sysctlnode *, const char *,
134 const void *, size_t, int); 134 const void *, size_t, int);
135static void display_string(const struct sysctlnode *, const char *, 135static void display_string(const struct sysctlnode *, const char *,
136 const void *, size_t, int); 136 const void *, size_t, int);
137static void display_struct(const struct sysctlnode *, const char *, 137static void display_struct(const struct sysctlnode *, const char *,
138 const void *, size_t, int); 138 const void *, size_t, int);
139static void hex_dump(const unsigned char *, size_t); 139static void hex_dump(const unsigned char *, size_t);
140__dead static void usage(void); 140__dead static void usage(void);
141static void parse(char *, regex_t *, size_t *); 141static void parse(char *, regex_t *, size_t *);
142static void parse_create(char *); 142static void parse_create(char *);
143static void parse_destroy(char *); 143static void parse_destroy(char *);
144static void parse_describe(char *); 144static void parse_describe(char *);
145static void getdesc1(int *, u_int, struct sysctlnode *); 145static void getdesc1(int *, u_int, struct sysctlnode *);
146static void getdesc(int *, u_int, struct sysctlnode *); 146static void getdesc(int *, u_int, struct sysctlnode *);
147static void trim_whitespace(char *, int); 147static void trim_whitespace(char *, int);
148static void sysctlerror(int); 148static void sysctlerror(int);
149static void sysctlparseerror(u_int, const char *); 149static void sysctlparseerror(u_int, const char *);
150static void sysctlperror(const char *, ...) __printflike(1, 2); 150static void sysctlperror(const char *, ...) __printflike(1, 2);
151#define EXIT(n) do { \ 151#define EXIT(n) do { \
152 if (fn == NULL) exit(n); else return; } while (/*CONSTCOND*/0) 152 if (fn == NULL) exit(n); else return; } while (/*CONSTCOND*/0)
153 153
154/* 154/*
155 * "borrowed" from libc:sysctlgetmibinfo.c 155 * "borrowed" from libc:sysctlgetmibinfo.c
156 */ 156 */
157int __learn_tree(int *, u_int, struct sysctlnode *); 157int __learn_tree(int *, u_int, struct sysctlnode *);
158 158
159/* 159/*
160 * "handlers" 160 * "handlers"
161 */ 161 */
162static void printother(HANDLER_PROTO); 162static void printother(HANDLER_PROTO);
163static void kern_clockrate(HANDLER_PROTO); 163static void kern_clockrate(HANDLER_PROTO);
164static void kern_boottime(HANDLER_PROTO); 164static void kern_boottime(HANDLER_PROTO);
165static void kern_consdev(HANDLER_PROTO); 165static void kern_consdev(HANDLER_PROTO);
166static void kern_cp_time(HANDLER_PROTO); 166static void kern_cp_time(HANDLER_PROTO);
167static void kern_cp_id(HANDLER_PROTO); 167static void kern_cp_id(HANDLER_PROTO);
168static void kern_drivers(HANDLER_PROTO); 168static void kern_drivers(HANDLER_PROTO);
169static void vm_loadavg(HANDLER_PROTO); 169static void vm_loadavg(HANDLER_PROTO);
170static void proc_limit(HANDLER_PROTO); 170static void proc_limit(HANDLER_PROTO);
171#ifdef CPU_DISKINFO 171#ifdef CPU_DISKINFO
172static void machdep_diskinfo(HANDLER_PROTO); 172static void machdep_diskinfo(HANDLER_PROTO);
173#endif /* CPU_DISKINFO */ 173#endif /* CPU_DISKINFO */
174static void mode_bits(HANDLER_PROTO); 174static void mode_bits(HANDLER_PROTO);
175static void reserve(HANDLER_PROTO); 175static void reserve(HANDLER_PROTO);
176 176
177static const struct handlespec { 177static const struct handlespec {
178 const char *ps_re; 178 const char *ps_re;
179 void (*ps_p)(HANDLER_PROTO); 179 void (*ps_p)(HANDLER_PROTO);
180 void (*ps_w)(HANDLER_PROTO); 180 void (*ps_w)(HANDLER_PROTO);
181 const void *ps_d; 181 const void *ps_d;
182} handlers[] = { 182} handlers[] = {
183 { "/kern/clockrate", kern_clockrate, NULL, NULL }, 183 { "/kern/clockrate", kern_clockrate, NULL, NULL },
184 { "/kern/vnode", printother, NULL, "pstat" }, 184 { "/kern/vnode", printother, NULL, "pstat" },
185 { "/kern/proc(2|_args)?", printother, NULL, "ps" }, 185 { "/kern/proc(2|_args)?", printother, NULL, "ps" },
186 { "/kern/file2?", printother, NULL, "pstat" }, 186 { "/kern/file2?", printother, NULL, "pstat" },
187 { "/kern/ntptime", printother, NULL, 187 { "/kern/ntptime", printother, NULL,
188 "ntpdc -c kerninfo" }, 188 "ntpdc -c kerninfo" },
189 { "/kern/msgbuf", printother, NULL, "dmesg" }, 189 { "/kern/msgbuf", printother, NULL, "dmesg" },
190 { "/kern/boottime", kern_boottime, NULL, NULL }, 190 { "/kern/boottime", kern_boottime, NULL, NULL },
191 { "/kern/consdev", kern_consdev, NULL, NULL }, 191 { "/kern/consdev", kern_consdev, NULL, NULL },
192 { "/kern/cp_time(/[0-9]+)?", kern_cp_time, NULL, NULL }, 192 { "/kern/cp_time(/[0-9]+)?", kern_cp_time, NULL, NULL },
193 { "/kern/sysvipc_info", printother, NULL, "ipcs" }, 193 { "/kern/sysvipc_info", printother, NULL, "ipcs" },
194 { "/kern/cp_id(/[0-9]+)?", kern_cp_id, NULL, NULL }, 194 { "/kern/cp_id(/[0-9]+)?", kern_cp_id, NULL, NULL },
195 195
196 { "/kern/coredump/setid/mode", mode_bits, mode_bits, NULL }, 196 { "/kern/coredump/setid/mode", mode_bits, mode_bits, NULL },
197 { "/kern/drivers", kern_drivers, NULL, NULL }, 197 { "/kern/drivers", kern_drivers, NULL, NULL },
198 198
199 { "/vm/vmmeter", printother, NULL, 199 { "/vm/vmmeter", printother, NULL,
200 "vmstat' or 'systat" }, 200 "vmstat' or 'systat" },
201 { "/vm/loadavg", vm_loadavg, NULL, NULL }, 201 { "/vm/loadavg", vm_loadavg, NULL, NULL },
202 { "/vm/uvmexp2?", printother, NULL, 202 { "/vm/uvmexp2?", printother, NULL,
203 "vmstat' or 'systat" }, 203 "vmstat' or 'systat" },
204 204
205 { "/vfs/nfs/nfsstats", printother, NULL, "nfsstat" }, 205 { "/vfs/nfs/nfsstats", printother, NULL, "nfsstat" },
206 206
207 { "/net/inet6?/tcp6?/ident", printother, NULL, "identd" }, 207 { "/net/inet6?/tcp6?/ident", printother, NULL, "identd" },
208 { "/net/inet6/icmp6/nd6_[dp]rlist", printother, NULL, "ndp" }, 208 { "/net/inet6/icmp6/nd6_[dp]rlist", printother, NULL, "ndp" },
209 { "/net/key/dumps[ap]", printother, NULL, "setkey" }, 209 { "/net/key/dumps[ap]", printother, NULL, "setkey" },
210 { "/net/[^/]+/[^/]+/pcblist", printother, NULL, 210 { "/net/[^/]+/[^/]+/pcblist", printother, NULL,
211 "netstat' or 'sockstat" }, 211 "netstat' or 'sockstat" },
212 { "/net/(inet|inet6)/[^/]+/stats", printother, NULL, "netstat"}, 212 { "/net/(inet|inet6)/[^/]+/stats", printother, NULL, "netstat"},
213 { "/net/bpf/(stats|peers)", printother, NULL, "netstat"}, 213 { "/net/bpf/(stats|peers)", printother, NULL, "netstat"},
214 214
215 { "/net/inet.*/tcp.*/deb.*", printother, NULL, "trpt" }, 215 { "/net/inet.*/tcp.*/deb.*", printother, NULL, "trpt" },
216 216
217 { "/net/inet.*/ip.*/anonportalgo/reserve", reserve, reserve, NULL }, 217 { "/net/inet.*/ip.*/anonportalgo/reserve", reserve, reserve, NULL },
218 218
219 { "/net/ns/spp/deb.*", printother, NULL, "trsp" }, 219 { "/net/ns/spp/deb.*", printother, NULL, "trsp" },
220 220
221 { "/hw/diskstats", printother, NULL, "iostat" }, 221 { "/hw/diskstats", printother, NULL, "iostat" },
222 222
223#ifdef CPU_CONSDEV 223#ifdef CPU_CONSDEV
224 { "/machdep/consdev", kern_consdev, NULL, NULL }, 224 { "/machdep/consdev", kern_consdev, NULL, NULL },
225#endif /* CPU_CONSDEV */ 225#endif /* CPU_CONSDEV */
226#ifdef CPU_DISKINFO 226#ifdef CPU_DISKINFO
227 { "/machdep/diskinfo", machdep_diskinfo, NULL, NULL }, 227 { "/machdep/diskinfo", machdep_diskinfo, NULL, NULL },
228#endif /* CPU_CONSDEV */ 228#endif /* CPU_CONSDEV */
229 229
230 { "/proc/[^/]+/rlimit/[^/]+/[^/]+", proc_limit, proc_limit, NULL }, 230 { "/proc/[^/]+/rlimit/[^/]+/[^/]+", proc_limit, proc_limit, NULL },
231 231
232 /* 232 /*
233 * these will only be called when the given node has no children 233 * these will only be called when the given node has no children
234 */ 234 */
235 { "/net/[^/]+", printother, NULL, NULL }, 235 { "/net/[^/]+", printother, NULL, NULL },
236 { "/debug", printother, NULL, NULL }, 236 { "/debug", printother, NULL, NULL },
237 { "/ddb", printother, NULL, NULL }, 237 { "/ddb", printother, NULL, NULL },
238 { "/vendor", printother, NULL, NULL }, 238 { "/vendor", printother, NULL, NULL },
239 239
240 { NULL, NULL, NULL, NULL }, 240 { NULL, NULL, NULL, NULL },
241}; 241};
242 242
243struct sysctlnode my_root = { 243struct sysctlnode my_root = {
244 .sysctl_flags = SYSCTL_VERSION|CTLFLAG_ROOT|CTLTYPE_NODE, 244 .sysctl_flags = SYSCTL_VERSION|CTLFLAG_ROOT|CTLTYPE_NODE,
245 sysc_init_field(_sysctl_size, sizeof(struct sysctlnode)), 245 sysc_init_field(_sysctl_size, sizeof(struct sysctlnode)),
246 .sysctl_num = 0, 246 .sysctl_num = 0,
247 .sysctl_name = "(prog_root)", 247 .sysctl_name = "(prog_root)",
248}; 248};
249 249
250int Aflag, aflag, dflag, Mflag, nflag, qflag, rflag, wflag, xflag; 250int Aflag, aflag, dflag, Mflag, nflag, qflag, rflag, wflag, xflag;
251size_t nr; 251size_t nr;
252char *fn; 252char *fn;
253int req, stale, errs; 253int req, stale, errs;
254FILE *warnfp = stderr; 254FILE *warnfp = stderr;
255 255
256#define MAXPORTS 0x10000 256#define MAXPORTS 0x10000
257 257
258/* 258/*
259 * vah-riables n stuff 259 * vah-riables n stuff
260 */ 260 */
261char gsname[SYSCTL_NAMELEN * CTL_MAXNAME + CTL_MAXNAME], 261char gsname[SYSCTL_NAMELEN * CTL_MAXNAME + CTL_MAXNAME],
262 canonname[SYSCTL_NAMELEN * CTL_MAXNAME + CTL_MAXNAME], 262 canonname[SYSCTL_NAMELEN * CTL_MAXNAME + CTL_MAXNAME],
263 gdname[10 * CTL_MAXNAME + CTL_MAXNAME]; 263 gdname[10 * CTL_MAXNAME + CTL_MAXNAME];
264char sep[] = "."; 264char sep[] = ".";
265const char *eq = " = "; 265const char *eq = " = ";
266const char *lname[] = { 266const char *lname[] = {
267 "top", "second", "third", "fourth", "fifth", "sixth", 267 "top", "second", "third", "fourth", "fifth", "sixth",
268 "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth" 268 "seventh", "eighth", "ninth", "tenth", "eleventh", "twelfth"
269}; 269};
270 270
271/* 271/*
272 * you've heard of main, haven't you? 272 * you've heard of main, haven't you?
273 */ 273 */
274int 274int
275main(int argc, char *argv[]) 275main(int argc, char *argv[])
276{ 276{
277 int name[CTL_MAXNAME]; 277 int name[CTL_MAXNAME];
278 int ch; 278 int ch;
279 size_t lastcompiled = 0; 279 size_t lastcompiled = 0;
280 regex_t *re; 280 regex_t *re;
281 281
282 setprogname(argv[0]); 282 setprogname(argv[0]);
283 while ((ch = getopt(argc, argv, "Aabdef:Mnqrwx")) != -1) { 283 while ((ch = getopt(argc, argv, "Aabdef:Mnqrwx")) != -1) {
284 switch (ch) { 284 switch (ch) {
285 case 'A': 285 case 'A':
286 Aflag++; 286 Aflag++;
287 break; 287 break;
288 case 'a': 288 case 'a':
289 aflag++; 289 aflag++;
290 break; 290 break;
291 case 'd': 291 case 'd':
292 dflag++; 292 dflag++;
293 break; 293 break;
294 case 'e': 294 case 'e':
295 eq = "="; 295 eq = "=";
296 break; 296 break;
297 case 'f': 297 case 'f':
298 fn = optarg; 298 fn = optarg;
299 wflag++; 299 wflag++;
300 break; 300 break;
301 case 'M': 301 case 'M':
302 Mflag++; 302 Mflag++;
303 break; 303 break;
304 case 'n': 304 case 'n':
305 nflag++; 305 nflag++;
306 break; 306 break;
307 case 'q': 307 case 'q':
308 qflag++; 308 qflag++;
309 break; 309 break;
310 case 'b': /* FreeBSD compat */ 310 case 'b': /* FreeBSD compat */
311 case 'r': 311 case 'r':
312 rflag++;  312 rflag++;
313 break; 313 break;
314 case 'w': 314 case 'w':
315 wflag++; 315 wflag++;
316 break; 316 break;
317 case 'x': 317 case 'x':
318 xflag++; 318 xflag++;
319 break; 319 break;
320 default: 320 default:
321 usage(); 321 usage();
322 } 322 }
323 } 323 }
324 324
325 argc -= optind; 325 argc -= optind;
326 argv += optind; 326 argv += optind;
327 327
328 if (xflag && rflag) 328 if (xflag && rflag)
329 usage(); 329 usage();
330 /* if ((xflag || rflag) && wflag) 330 /* if ((xflag || rflag) && wflag)
331 usage(); */ 331 usage(); */
332 /* if (aflag && (Mflag || qflag)) 332 /* if (aflag && (Mflag || qflag))
333 usage(); */ 333 usage(); */
334 if ((aflag || Aflag) && qflag) 334 if ((aflag || Aflag) && qflag)
335 usage(); 335 usage();
336 if ((Aflag || Mflag || dflag) && argc == 0 && fn == NULL) 336 if ((Aflag || Mflag || dflag) && argc == 0 && fn == NULL)
337 aflag = 1; 337 aflag = 1;
338 338
339 if (prog_init && prog_init() == -1) 339 if (prog_init && prog_init() == -1)
340 err(1, "prog init failed"); 340 err(EXIT_FAILURE, "prog init failed");
341 341
342 if (Aflag) 342 if (Aflag)
343 warnfp = stdout; 343 warnfp = stdout;
344 stale = req = 0; 344 stale = req = 0;
345 345
346 if ((re = malloc(sizeof(*re) * __arraycount(handlers))) == NULL) 346 if ((re = malloc(sizeof(*re) * __arraycount(handlers))) == NULL)
347 err(1, "malloc regex"); 347 err(EXIT_FAILURE, "malloc regex");
348 348
349 if (aflag) { 349 if (aflag) {
350 print_tree(&name[0], 0, NULL, CTLTYPE_NODE, 1, 350 print_tree(&name[0], 0, NULL, CTLTYPE_NODE, 1,
351 re, &lastcompiled); 351 re, &lastcompiled);
352 /* if (argc == 0) */ 352 /* if (argc == 0) */
353 return (0); 353 return (0);
354 } 354 }
355 355
356 if (fn) { 356 if (fn) {
357 FILE *fp; 357 FILE *fp;
358 char *l; 358 char *l;
359 359
360 fp = fopen(fn, "r"); 360 fp = fopen(fn, "r");
361 if (fp == NULL) { 361 if (fp == NULL) {
362 err(1, "%s", fn); 362 err(EXIT_FAILURE, "%s", fn);
363 } else { 363 } else {
364 nr = 0; 364 nr = 0;
365 while ((l = fparseln(fp, NULL, &nr, NULL, 0)) != NULL) 365 while ((l = fparseln(fp, NULL, &nr, NULL, 0)) != NULL)
366 { 366 {
367 if (*l) { 367 if (*l) {
368 parse(l, re, &lastcompiled); 368 parse(l, re, &lastcompiled);
369 free(l); 369 free(l);
370 } 370 }
371 } 371 }
372 fclose(fp); 372 fclose(fp);
373 } 373 }
374 return errs ? 1 : 0; 374 return errs ? 1 : 0;
375 } 375 }
376 376
377 if (argc == 0) 377 if (argc == 0)
378 usage(); 378 usage();
379 379
380 while (argc-- > 0) 380 while (argc-- > 0)
381 parse(*argv++, re, &lastcompiled); 381 parse(*argv++, re, &lastcompiled);
382 382
383 return errs ? 1 : 0; 383 return errs ? EXIT_FAILURE : EXIT_SUCCESS;
384} 384}
385 385
386/* 386/*
387 * ******************************************************************** 387 * ********************************************************************
388 * how to find someone special to handle the reading (or maybe even 388 * how to find someone special to handle the reading (or maybe even
389 * writing) of a particular node 389 * writing) of a particular node
390 * ******************************************************************** 390 * ********************************************************************
391 */ 391 */
392static const struct handlespec * 392static const struct handlespec *
393findhandler(const char *s, regex_t *re, size_t *lastcompiled) 393findhandler(const char *s, regex_t *re, size_t *lastcompiled)
394{ 394{
395 const struct handlespec *p; 395 const struct handlespec *p;
396 size_t i, l; 396 size_t i, l;
397 int j; 397 int j;
398 char eb[64]; 398 char eb[64];
399 regmatch_t match; 399 regmatch_t match;
400 400
401 p = &handlers[0]; 401 p = &handlers[0];
402 l = strlen(s); 402 l = strlen(s);
403 for (i = 0; p[i].ps_re != NULL; i++) { 403 for (i = 0; p[i].ps_re != NULL; i++) {
404 if (i >= *lastcompiled) { 404 if (i >= *lastcompiled) {
405 j = regcomp(&re[i], p[i].ps_re, REG_EXTENDED); 405 j = regcomp(&re[i], p[i].ps_re, REG_EXTENDED);
406 if (j != 0) { 406 if (j != 0) {
407 regerror(j, &re[i], eb, sizeof(eb)); 407 regerror(j, &re[i], eb, sizeof(eb));
408 errx(1, "regcomp: %s: %s", p[i].ps_re, eb); 408 errx(EXIT_FAILURE, "regcomp: %s: %s", p[i].ps_re, eb);
409 } 409 }
410 *lastcompiled = i + 1; 410 *lastcompiled = i + 1;
411 } 411 }
412 j = regexec(&re[i], s, 1, &match, 0); 412 j = regexec(&re[i], s, 1, &match, 0);
413 if (j == 0) { 413 if (j == 0) {
414 if (match.rm_so == 0 && match.rm_eo == (int)l) 414 if (match.rm_so == 0 && match.rm_eo == (int)l)
415 return &p[i]; 415 return &p[i];
416 } 416 }
417 else if (j != REG_NOMATCH) { 417 else if (j != REG_NOMATCH) {
418 regerror(j, &re[i], eb, sizeof(eb)); 418 regerror(j, &re[i], eb, sizeof(eb));
419 errx(1, "regexec: %s: %s", p[i].ps_re, eb); 419 errx(EXIT_FAILURE, "regexec: %s: %s", p[i].ps_re, eb);
420 } 420 }
421 } 421 }
422 422
423 return NULL; 423 return NULL;
424} 424}
425 425
426/* 426/*
427 * after sysctlgetmibinfo is done with the name, we convert all 427 * after sysctlgetmibinfo is done with the name, we convert all
428 * separators to / and stuff one at the front if it was missing 428 * separators to / and stuff one at the front if it was missing
429 */ 429 */
430static void 430static void
431canonicalize(const char *i, char *o) 431canonicalize(const char *i, char *o)
432{ 432{
433 const char *t; 433 const char *t;
434 char p[SYSCTL_NAMELEN + 1]; 434 char p[SYSCTL_NAMELEN + 1];
435 int l; 435 int l;
436 436
437 if (i[0] != *sep) { 437 if (i[0] != *sep) {
438 o[0] = '/'; 438 o[0] = '/';
439 o[1] = '\0'; 439 o[1] = '\0';
440 } 440 }
441 else 441 else
442 o[0] = '\0'; 442 o[0] = '\0';
443 443
444 t = i; 444 t = i;
445 do { 445 do {
446 i = t; 446 i = t;
447 t = strchr(i, sep[0]); 447 t = strchr(i, sep[0]);
448 if (t == NULL) 448 if (t == NULL)
449 strcat(o, i); 449 strcat(o, i);
450 else { 450 else {
451 l = t - i; 451 l = t - i;
452 t++; 452 t++;
453 memcpy(p, i, l); 453 memcpy(p, i, l);
454 p[l] = '\0'; 454 p[l] = '\0';
455 strcat(o, p); 455 strcat(o, p);
456 strcat(o, "/"); 456 strcat(o, "/");
457 } 457 }
458 } while (t != NULL); 458 } while (t != NULL);
459} 459}
460 460
461/* 461/*
462 * ******************************************************************** 462 * ********************************************************************
463 * convert this special number to a special string so we can print the 463 * convert this special number to a special string so we can print the
464 * mib 464 * mib
465 * ******************************************************************** 465 * ********************************************************************
466 */ 466 */
467static const char * 467static const char *
468sf(u_int f) 468sf(u_int f)
469{ 469{
470 static char s[256]; 470 static char s[256];
471 const char *c; 471 const char *c;
472 472
473 s[0] = '\0'; 473 s[0] = '\0';
474 c = ""; 474 c = "";
475 475
476#define print_flag(_f, _s, _c, _q, _x) \ 476#define print_flag(_f, _s, _c, _q, _x) \
477 if (((_f) & (__CONCAT(CTLFLAG_,_x))) == (__CONCAT(CTLFLAG_,_q))) { \ 477 if (((_f) & (__CONCAT(CTLFLAG_,_x))) == (__CONCAT(CTLFLAG_,_q))) { \
478 strlcat((_s), (_c), sizeof(_s)); \ 478 strlcat((_s), (_c), sizeof(_s)); \
479 strlcat((_s), __STRING(_q), sizeof(_s)); \ 479 strlcat((_s), __STRING(_q), sizeof(_s)); \
480 (_c) = ","; \ 480 (_c) = ","; \
481 (_f) &= ~(__CONCAT(CTLFLAG_,_x)); \ 481 (_f) &= ~(__CONCAT(CTLFLAG_,_x)); \
482 } 482 }
483 print_flag(f, s, c, READONLY, READWRITE); 483 print_flag(f, s, c, READONLY, READWRITE);
484 print_flag(f, s, c, READWRITE, READWRITE); 484 print_flag(f, s, c, READWRITE, READWRITE);
485 print_flag(f, s, c, ANYWRITE, ANYWRITE); 485 print_flag(f, s, c, ANYWRITE, ANYWRITE);
486 print_flag(f, s, c, PRIVATE, PRIVATE); 486 print_flag(f, s, c, PRIVATE, PRIVATE);
487 print_flag(f, s, c, PERMANENT, PERMANENT); 487 print_flag(f, s, c, PERMANENT, PERMANENT);
488 print_flag(f, s, c, OWNDATA, OWNDATA); 488 print_flag(f, s, c, OWNDATA, OWNDATA);
489 print_flag(f, s, c, IMMEDIATE, IMMEDIATE); 489 print_flag(f, s, c, IMMEDIATE, IMMEDIATE);
490 print_flag(f, s, c, HEX, HEX); 490 print_flag(f, s, c, HEX, HEX);
491 print_flag(f, s, c, ROOT, ROOT); 491 print_flag(f, s, c, ROOT, ROOT);
492 print_flag(f, s, c, ANYNUMBER, ANYNUMBER); 492 print_flag(f, s, c, ANYNUMBER, ANYNUMBER);
493 print_flag(f, s, c, HIDDEN, HIDDEN); 493 print_flag(f, s, c, HIDDEN, HIDDEN);
494 print_flag(f, s, c, ALIAS, ALIAS); 494 print_flag(f, s, c, ALIAS, ALIAS);
495#undef print_flag 495#undef print_flag
496 496
497 if (f) { 497 if (f) {
498 char foo[9]; 498 char foo[9];
499 snprintf(foo, sizeof(foo), "%x", f); 499 snprintf(foo, sizeof(foo), "%x", f);
500 strlcat(s, c, sizeof(s)); 500 strlcat(s, c, sizeof(s));
501 strlcat(s, foo, sizeof(s)); 501 strlcat(s, foo, sizeof(s));
502 } 502 }
503 503
504 return (s); 504 return (s);
505} 505}
506 506
507static const char * 507static const char *
508st(u_int t) 508st(u_int t)
509{ 509{
510 510
511 switch (t) { 511 switch (t) {
512 case CTLTYPE_NODE: 512 case CTLTYPE_NODE:
513 return "NODE"; 513 return "NODE";
514 case CTLTYPE_INT: 514 case CTLTYPE_INT:
515 return "INT"; 515 return "INT";
516 case CTLTYPE_STRING: 516 case CTLTYPE_STRING:
517 return "STRING"; 517 return "STRING";
518 case CTLTYPE_QUAD: 518 case CTLTYPE_QUAD:
519 return "QUAD"; 519 return "QUAD";
520 case CTLTYPE_STRUCT: 520 case CTLTYPE_STRUCT:
521 return "STRUCT"; 521 return "STRUCT";
522 case CTLTYPE_BOOL: 522 case CTLTYPE_BOOL:
523 return "BOOL"; 523 return "BOOL";
524 } 524 }
525 525
526 return "???"; 526 return "???";
527} 527}
528 528
529/* 529/*
530 * ******************************************************************** 530 * ********************************************************************
531 * recursively eliminate all data belonging to the given node 531 * recursively eliminate all data belonging to the given node
532 * ******************************************************************** 532 * ********************************************************************
533 */ 533 */
534static void 534static void
535purge_tree(struct sysctlnode *rnode) 535purge_tree(struct sysctlnode *rnode)
536{ 536{
537 struct sysctlnode *node; 537 struct sysctlnode *node;
538 538
539 if (rnode == NULL || 539 if (rnode == NULL ||
540 SYSCTL_TYPE(rnode->sysctl_flags) != CTLTYPE_NODE || 540 SYSCTL_TYPE(rnode->sysctl_flags) != CTLTYPE_NODE ||
541 rnode->sysctl_child == NULL) 541 rnode->sysctl_child == NULL)
542 return; 542 return;
543 543
544 for (node = rnode->sysctl_child; 544 for (node = rnode->sysctl_child;
545 node < &rnode->sysctl_child[rnode->sysctl_clen]; 545 node < &rnode->sysctl_child[rnode->sysctl_clen];
546 node++) 546 node++)
547 purge_tree(node); 547 purge_tree(node);
548 free(rnode->sysctl_child); 548 free(rnode->sysctl_child);
549 rnode->sysctl_csize = 0; 549 rnode->sysctl_csize = 0;
550 rnode->sysctl_clen = 0; 550 rnode->sysctl_clen = 0;
551 rnode->sysctl_child = NULL; 551 rnode->sysctl_child = NULL;
552 552
553 if (rnode->sysctl_desc == (const char*)-1) 553 if (rnode->sysctl_desc == (const char*)-1)
554 rnode->sysctl_desc = NULL; 554 rnode->sysctl_desc = NULL;
555 if (rnode->sysctl_desc != NULL) 555 if (rnode->sysctl_desc != NULL)
556 free(__UNCONST(rnode->sysctl_desc)); 556 free(__UNCONST(rnode->sysctl_desc));
557 rnode->sysctl_desc = NULL; 557 rnode->sysctl_desc = NULL;
558} 558}
559 559
560static void __attribute__((__format__(__printf__, 3, 4))) 560static void __attribute__((__format__(__printf__, 3, 4)))
561appendprintf(char **bp, size_t *lbp, const char *fmt, ...) 561appendprintf(char **bp, size_t *lbp, const char *fmt, ...)
562{ 562{
563 int r; 563 int r;
564 va_list ap; 564 va_list ap;
565 565
566 va_start(ap, fmt); 566 va_start(ap, fmt);
567 r = vsnprintf(*bp, *lbp, fmt, ap); 567 r = vsnprintf(*bp, *lbp, fmt, ap);
568 va_end(ap); 568 va_end(ap);
569 if (r < 0 || (size_t)r > *lbp) 569 if (r < 0 || (size_t)r > *lbp)
570 r = *lbp; 570 r = *lbp;
571 *bp += r; 571 *bp += r;
572 *lbp -= r; 572 *lbp -= r;
573} 573}
574 574
575/* 575/*
576 * ******************************************************************** 576 * ********************************************************************
577 * print this node and any others underneath it 577 * print this node and any others underneath it
578 * ******************************************************************** 578 * ********************************************************************
579 */ 579 */
580static void 580static void
581print_tree(int *name, u_int namelen, struct sysctlnode *pnode, u_int type, 581print_tree(int *name, u_int namelen, struct sysctlnode *pnode, u_int type,
582 int add, regex_t *re, size_t *lastcompiled) 582 int add, regex_t *re, size_t *lastcompiled)
583{ 583{
584 struct sysctlnode *node; 584 struct sysctlnode *node;
585 int rc; 585 int rc;
586 size_t ni, sz, ldp, lsp; 586 size_t ni, sz, ldp, lsp;
587 char *sp, *dp, *tsp, *tdp; 587 char *sp, *dp, *tsp, *tdp;
588 const struct handlespec *p; 588 const struct handlespec *p;
589 589
590 sp = tsp = &gsname[strlen(gsname)]; 590 sp = tsp = &gsname[strlen(gsname)];
591 dp = tdp = &gdname[strlen(gdname)]; 591 dp = tdp = &gdname[strlen(gdname)];
592 ldp = sizeof(gdname) - (dp - gdname); 592 ldp = sizeof(gdname) - (dp - gdname);
593 lsp = sizeof(gsname) - (sp - gsname); 593 lsp = sizeof(gsname) - (sp - gsname);
594 594
595 if (sp != &gsname[0] && dp == &gdname[0]) { 595 if (sp != &gsname[0] && dp == &gdname[0]) {
596 /* 596 /*
597 * aw...shucks. now we must play catch up 597 * aw...shucks. now we must play catch up
598 */ 598 */
599 for (ni = 0; ni < namelen; ni++) 599 for (ni = 0; ni < namelen; ni++)
600 appendprintf(&tdp, &ldp, "%s%d", ni > 0 ? "." : "", 600 appendprintf(&tdp, &ldp, "%s%d", ni > 0 ? "." : "",
601 name[ni]); 601 name[ni]);
602 } 602 }
603 603
604 if (pnode == NULL) 604 if (pnode == NULL)
605 pnode = &my_root; 605 pnode = &my_root;
606 else if (add) { 606 else if (add) {
607 appendprintf(&tsp, &lsp, "%s%s", namelen > 1 ? sep : "",  607 appendprintf(&tsp, &lsp, "%s%s", namelen > 1 ? sep : "",
608 pnode->sysctl_name); 608 pnode->sysctl_name);
609 appendprintf(&tdp, &ldp, "%s%d", namelen > 1 ? "." : "",  609 appendprintf(&tdp, &ldp, "%s%d", namelen > 1 ? "." : "",
610 pnode->sysctl_num); 610 pnode->sysctl_num);
611 } 611 }
612 612
613 if (Mflag && pnode != &my_root) { 613 if (Mflag && pnode != &my_root) {
614 if (nflag) 614 if (nflag)
615 printf("%s: ", gdname); 615 printf("%s: ", gdname);
616 else 616 else
617 printf("%s (%s): ", gsname, gdname); 617 printf("%s (%s): ", gsname, gdname);
618 printf("CTLTYPE_%s", st(type)); 618 printf("CTLTYPE_%s", st(type));
619 if (type == CTLTYPE_NODE) { 619 if (type == CTLTYPE_NODE) {
620 if (SYSCTL_FLAGS(pnode->sysctl_flags) & CTLFLAG_ALIAS) 620 if (SYSCTL_FLAGS(pnode->sysctl_flags) & CTLFLAG_ALIAS)
621 printf(", alias %d", 621 printf(", alias %d",
622 pnode->sysctl_alias); 622 pnode->sysctl_alias);
623 else 623 else
624 printf(", children %d/%d", 624 printf(", children %d/%d",
625 pnode->sysctl_clen, 625 pnode->sysctl_clen,
626 pnode->sysctl_csize); 626 pnode->sysctl_csize);
627 } 627 }
628 printf(", size %zu", pnode->sysctl_size); 628 printf(", size %zu", pnode->sysctl_size);
629 printf(", flags 0x%x<%s>", 629 printf(", flags 0x%x<%s>",
630 SYSCTL_FLAGS(pnode->sysctl_flags), 630 SYSCTL_FLAGS(pnode->sysctl_flags),
631 sf(SYSCTL_FLAGS(pnode->sysctl_flags))); 631 sf(SYSCTL_FLAGS(pnode->sysctl_flags)));
632 if (pnode->sysctl_func) 632 if (pnode->sysctl_func)
633 printf(", func=%p", pnode->sysctl_func); 633 printf(", func=%p", pnode->sysctl_func);
634 printf(", ver=%d", pnode->sysctl_ver); 634 printf(", ver=%d", pnode->sysctl_ver);
635 printf("\n"); 635 printf("\n");
636 if (type != CTLTYPE_NODE) { 636 if (type != CTLTYPE_NODE) {
637 *sp = *dp = '\0'; 637 *sp = *dp = '\0';
638 return; 638 return;
639 } 639 }
640 } 640 }
641 641
642 if (dflag && pnode != &my_root) { 642 if (dflag && pnode != &my_root) {
643 if (Aflag || type != CTLTYPE_NODE) { 643 if (Aflag || type != CTLTYPE_NODE) {
644 if (pnode->sysctl_desc == NULL) 644 if (pnode->sysctl_desc == NULL)
645 getdesc1(name, namelen, pnode); 645 getdesc1(name, namelen, pnode);
646 if (Aflag || !add || 646 if (Aflag || !add ||
647 (pnode->sysctl_desc != NULL && 647 (pnode->sysctl_desc != NULL &&
648 pnode->sysctl_desc != (const char*)-1)) { 648 pnode->sysctl_desc != (const char*)-1)) {
649 if (!nflag) 649 if (!nflag)
650 printf("%s: ", gsname); 650 printf("%s: ", gsname);
651 if (pnode->sysctl_desc == NULL || 651 if (pnode->sysctl_desc == NULL ||
652 pnode->sysctl_desc == (const char*)-1) 652 pnode->sysctl_desc == (const char*)-1)
653 printf("(no description)\n"); 653 printf("(no description)\n");
654 else 654 else
655 printf("%s\n", pnode->sysctl_desc); 655 printf("%s\n", pnode->sysctl_desc);
656 } 656 }
657 } 657 }
658 658
659 if (type != CTLTYPE_NODE) { 659 if (type != CTLTYPE_NODE) {
660 *sp = *dp = '\0'; 660 *sp = *dp = '\0';
661 return; 661 return;
662 } 662 }
663 } 663 }
664 664
665 /* 665 /*
666 * if this is an alias and we added our name, that means we 666 * if this is an alias and we added our name, that means we
667 * got here by recursing down into the tree, so skip it. The 667 * got here by recursing down into the tree, so skip it. The
668 * only way to print an aliased node is with either -M or by 668 * only way to print an aliased node is with either -M or by
669 * name specifically. 669 * name specifically.
670 */ 670 */
671 if (SYSCTL_FLAGS(pnode->sysctl_flags) & CTLFLAG_ALIAS && add) { 671 if (SYSCTL_FLAGS(pnode->sysctl_flags) & CTLFLAG_ALIAS && add) {
672 *sp = *dp = '\0'; 672 *sp = *dp = '\0';
673 return; 673 return;
674 } 674 }
675 675
676 canonicalize(gsname, canonname); 676 canonicalize(gsname, canonname);
677 p = findhandler(canonname, re, lastcompiled); 677 p = findhandler(canonname, re, lastcompiled);
678 if (type != CTLTYPE_NODE && p != NULL) { 678 if (type != CTLTYPE_NODE && p != NULL) {
679 if (p->ps_p == NULL) { 679 if (p->ps_p == NULL) {
680 sysctlperror("Cannot print `%s': %s\n", gsname,  680 sysctlperror("Cannot print `%s': %s\n", gsname,
681 strerror(EOPNOTSUPP)); 681 strerror(EOPNOTSUPP));
682 exit(1); 682 exit(EXIT_FAILURE);
683 } 683 }
684 (*p->ps_p)(gsname, gdname, NULL, name, namelen, pnode, type, 684 (*p->ps_p)(gsname, gdname, NULL, name, namelen, pnode, type,
685 __UNCONST(p->ps_d)); 685 __UNCONST(p->ps_d));
686 *sp = *dp = '\0'; 686 *sp = *dp = '\0';
687 return; 687 return;
688 } 688 }
689 689
690 if (type != CTLTYPE_NODE && pnode->sysctl_size == 0) { 690 if (type != CTLTYPE_NODE && pnode->sysctl_size == 0) {
691 rc = prog_sysctl(&name[0], namelen, NULL, &sz, NULL, 0); 691 rc = prog_sysctl(&name[0], namelen, NULL, &sz, NULL, 0);
692 if (rc == -1) { 692 if (rc == -1) {
693 sysctlerror(1); 693 sysctlerror(1);
694 *sp = *dp = '\0'; 694 *sp = *dp = '\0';
695 return; 695 return;
696 } 696 }
697 if (sz == 0) { 697 if (sz == 0) {
698 if ((Aflag || req) && !Mflag) 698 if ((Aflag || req) && !Mflag)
699 printf("%s: node contains no data\n", gsname); 699 printf("%s: node contains no data\n", gsname);
700 *sp = *dp = '\0'; 700 *sp = *dp = '\0';
701 return; 701 return;
702 } 702 }
703 } 703 }
704 else 704 else
705 sz = pnode->sysctl_size; 705 sz = pnode->sysctl_size;
706 706
707 switch (type) { 707 switch (type) {
708 case CTLTYPE_NODE: { 708 case CTLTYPE_NODE: {
709 __learn_tree(name, namelen, pnode); 709 __learn_tree(name, namelen, pnode);
710 node = pnode->sysctl_child; 710 node = pnode->sysctl_child;
711 if (node == NULL) { 711 if (node == NULL) {
712 if (dflag) 712 if (dflag)
713 /* do nothing */; 713 /* do nothing */;
714 else if (p != NULL) 714 else if (p != NULL)
715 (*p->ps_p)(gsname, gdname, NULL, name, namelen, 715 (*p->ps_p)(gsname, gdname, NULL, name, namelen,
716 pnode, type, __UNCONST(p->ps_d)); 716 pnode, type, __UNCONST(p->ps_d));
717 else if ((Aflag || req) && !Mflag) 717 else if ((Aflag || req) && !Mflag)
718 printf("%s: no children\n", gsname); 718 printf("%s: no children\n", gsname);
719 } 719 }
720 else { 720 else {
721 if (dflag) 721 if (dflag)
722 /* 722 /*
723 * get all descriptions for next level 723 * get all descriptions for next level
724 * in one chunk 724 * in one chunk
725 */ 725 */
726 getdesc(name, namelen, pnode); 726 getdesc(name, namelen, pnode);
727 req = 0; 727 req = 0;
728 for (ni = 0; ni < pnode->sysctl_clen; ni++) { 728 for (ni = 0; ni < pnode->sysctl_clen; ni++) {
729 name[namelen] = node[ni].sysctl_num; 729 name[namelen] = node[ni].sysctl_num;
730 if ((node[ni].sysctl_flags & CTLFLAG_HIDDEN) && 730 if ((node[ni].sysctl_flags & CTLFLAG_HIDDEN) &&
731 !(Aflag || req)) 731 !(Aflag || req))
732 continue; 732 continue;
733 print_tree(name, namelen + 1, &node[ni], 733 print_tree(name, namelen + 1, &node[ni],
734 SYSCTL_TYPE(node[ni].sysctl_flags), 734 SYSCTL_TYPE(node[ni].sysctl_flags),
735 1, re, lastcompiled); 735 1, re, lastcompiled);
736 } 736 }
737 } 737 }
738 break; 738 break;
739 } 739 }
740 case CTLTYPE_INT: { 740 case CTLTYPE_INT: {
741 int i; 741 int i;
742 rc = prog_sysctl(name, namelen, &i, &sz, NULL, 0); 742 rc = prog_sysctl(name, namelen, &i, &sz, NULL, 0);
743 if (rc == -1) { 743 if (rc == -1) {
744 sysctlerror(1); 744 sysctlerror(1);
745 break; 745 break;
746 } 746 }
747 display_number(pnode, gsname, &i, sizeof(i), DISPLAY_VALUE); 747 display_number(pnode, gsname, &i, sizeof(i), DISPLAY_VALUE);
748 break; 748 break;
749 } 749 }
750 case CTLTYPE_BOOL: { 750 case CTLTYPE_BOOL: {
751 bool b; 751 bool b;
752 rc = prog_sysctl(name, namelen, &b, &sz, NULL, 0); 752 rc = prog_sysctl(name, namelen, &b, &sz, NULL, 0);
753 if (rc == -1) { 753 if (rc == -1) {
754 sysctlerror(1); 754 sysctlerror(1);
755 break; 755 break;
756 } 756 }
757 display_number(pnode, gsname, &b, sizeof(b), DISPLAY_VALUE); 757 display_number(pnode, gsname, &b, sizeof(b), DISPLAY_VALUE);
758 break; 758 break;
759 } 759 }
760 case CTLTYPE_STRING: { 760 case CTLTYPE_STRING: {
761 unsigned char buf[1024], *tbuf; 761 unsigned char buf[1024], *tbuf;
762 tbuf = buf; 762 tbuf = buf;
763 sz = sizeof(buf); 763 sz = sizeof(buf);
764 rc = prog_sysctl(&name[0], namelen, tbuf, &sz, NULL, 0); 764 rc = prog_sysctl(&name[0], namelen, tbuf, &sz, NULL, 0);
765 if (rc == -1 && errno == ENOMEM) { 765 if (rc == -1 && errno == ENOMEM) {
766 tbuf = malloc(sz); 766 tbuf = malloc(sz);
767 if (tbuf == NULL) { 767 if (tbuf == NULL) {
768 sysctlerror(1); 768 sysctlerror(1);
769 break; 769 break;
770 } 770 }
771 rc = prog_sysctl(&name[0], namelen, tbuf, &sz, NULL, 0); 771 rc = prog_sysctl(&name[0], namelen, tbuf, &sz, NULL, 0);
772 } 772 }
773 if (rc == -1) 773 if (rc == -1)
774 sysctlerror(1); 774 sysctlerror(1);
775 else 775 else
776 display_string(pnode, gsname, tbuf, sz, DISPLAY_VALUE); 776 display_string(pnode, gsname, tbuf, sz, DISPLAY_VALUE);
777 if (tbuf != buf) 777 if (tbuf != buf)
778 free(tbuf); 778 free(tbuf);
779 break; 779 break;
780 } 780 }
781 case CTLTYPE_QUAD: { 781 case CTLTYPE_QUAD: {
782 u_quad_t q; 782 u_quad_t q;
783 sz = sizeof(q); 783 sz = sizeof(q);
784 rc = prog_sysctl(&name[0], namelen, &q, &sz, NULL, 0); 784 rc = prog_sysctl(&name[0], namelen, &q, &sz, NULL, 0);
785 if (rc == -1) { 785 if (rc == -1) {
786 sysctlerror(1); 786 sysctlerror(1);
787 break; 787 break;
788 } 788 }
789 display_number(pnode, gsname, &q, sizeof(q), DISPLAY_VALUE); 789 display_number(pnode, gsname, &q, sizeof(q), DISPLAY_VALUE);
790 break; 790 break;
791 } 791 }
792 case CTLTYPE_STRUCT: { 792 case CTLTYPE_STRUCT: {
793 /* 793 /*
794 * we shouldn't actually get here, but if we 794 * we shouldn't actually get here, but if we
795 * do, would it be nice to have *something* to 795 * do, would it be nice to have *something* to
796 * do other than completely ignore the 796 * do other than completely ignore the
797 * request. 797 * request.
798 */ 798 */
799 unsigned char *d; 799 unsigned char *d;
800 if ((d = malloc(sz)) == NULL) { 800 if ((d = malloc(sz)) == NULL) {
801 fprintf(warnfp, "%s: !malloc failed!\n", gsname); 801 fprintf(warnfp, "%s: !malloc failed!\n", gsname);
802 break; 802 break;
803 } 803 }
804 rc = prog_sysctl(&name[0], namelen, d, &sz, NULL, 0); 804 rc = prog_sysctl(&name[0], namelen, d, &sz, NULL, 0);
805 if (rc == -1) { 805 if (rc == -1) {
806 sysctlerror(1); 806 sysctlerror(1);
807 break; 807 break;
808 } 808 }
809 display_struct(pnode, gsname, d, sz, DISPLAY_VALUE); 809 display_struct(pnode, gsname, d, sz, DISPLAY_VALUE);
810 free(d); 810 free(d);
811 break; 811 break;
812 } 812 }
813 default: 813 default:
814 /* should i print an error here? */ 814 /* should i print an error here? */
815 break; 815 break;
816 } 816 }
817 817
818 *sp = *dp = '\0'; 818 *sp = *dp = '\0';
819} 819}
820 820
821/* 821/*
822 * ******************************************************************** 822 * ********************************************************************
823 * parse a request, possibly determining that it's a create or destroy 823 * parse a request, possibly determining that it's a create or destroy
824 * request 824 * request
825 * ******************************************************************** 825 * ********************************************************************
826 */ 826 */
827static void 827static void
828parse(char *l, regex_t *re, size_t *lastcompiled) 828parse(char *l, regex_t *re, size_t *lastcompiled)
829{ 829{
830 struct sysctlnode *node; 830 struct sysctlnode *node;
831 const struct handlespec *w; 831 const struct handlespec *w;
832 int name[CTL_MAXNAME], dodesc = 0; 832 int name[CTL_MAXNAME], dodesc = 0;
833 u_int namelen, type; 833 u_int namelen, type;
834 char *key, *value, *dot; 834 char *key, *value, *dot;
835 size_t sz; 835 size_t sz;
836 bool optional = false; 836 bool optional = false;
837 837
838 req = 1; 838 req = 1;
839 key = l; 839 key = l;
840 840
841 if ((value = strchr(l, '=')) != NULL) { 841 if ((value = strchr(l, '=')) != NULL) {
842 if (value > l && value[-1] == '?') { 842 if (value > l && value[-1] == '?') {
843 value[-1] = '\0'; 843 value[-1] = '\0';
844 optional = true; 844 optional = true;
845 } 845 }
846 *value++ = '\0'; 846 *value++ = '\0';
847 } 847 }
848 848
849 if ((dot = strpbrk(key, "./")) == NULL) 849 if ((dot = strpbrk(key, "./")) == NULL)
850 sep[0] = '.'; 850 sep[0] = '.';
851 else 851 else
852 sep[0] = dot[0]; 852 sep[0] = dot[0];
853 sep[1] = '\0'; 853 sep[1] = '\0';
854 854
855 while (key[0] == sep[0] && key[1] == sep[0]) { 855 while (key[0] == sep[0] && key[1] == sep[0]) {
856 if (value != NULL) 856 if (value != NULL)
857 value[-1] = '='; 857 value[-1] = '=';
858 if (strncmp(key + 2, "create", 6) == 0 && 858 if (strncmp(key + 2, "create", 6) == 0 &&
859 (key[8] == '=' || key[8] == sep[0])) 859 (key[8] == '=' || key[8] == sep[0]))
860 parse_create(key + 8 + (key[8] == '=' ? 1 : 0)); 860 parse_create(key + 8 + (key[8] == '=' ? 1 : 0));
861 else if (strncmp(key + 2, "destroy", 7) == 0 && 861 else if (strncmp(key + 2, "destroy", 7) == 0 &&
862 (key[9] == '=' || key[9] == sep[0])) 862 (key[9] == '=' || key[9] == sep[0]))
863 parse_destroy(key + 9 + (key[9] == '=' ? 1 : 0)); 863 parse_destroy(key + 9 + (key[9] == '=' ? 1 : 0));
864 else if (strncmp(key + 2, "describe", 8) == 0 && 864 else if (strncmp(key + 2, "describe", 8) == 0 &&
865 (key[10] == '=' || key[10] == sep[0])) { 865 (key[10] == '=' || key[10] == sep[0])) {
866 key += 10 + (key[10] == '='); 866 key += 10 + (key[10] == '=');
867 if ((value = strchr(key, '=')) != NULL) 867 if ((value = strchr(key, '=')) != NULL)
868 parse_describe(key); 868 parse_describe(key);
869 else { 869 else {
870 if (!dflag) 870 if (!dflag)
871 dodesc = 1; 871 dodesc = 1;
872 break; 872 break;
873 } 873 }
874 } 874 }
875 else 875 else
876 sysctlperror("unable to parse '%s'\n", key); 876 sysctlperror("unable to parse '%s'\n", key);
877 return; 877 return;
878 } 878 }
879 879
880 if (stale) { 880 if (stale) {
881 purge_tree(&my_root); 881 purge_tree(&my_root);
882 stale = 0; 882 stale = 0;
883 } 883 }
884 node = &my_root; 884 node = &my_root;
885 namelen = CTL_MAXNAME; 885 namelen = CTL_MAXNAME;
886 sz = sizeof(gsname); 886 sz = sizeof(gsname);
887 887
888 if (sysctlgetmibinfo(key, &name[0], &namelen, gsname, &sz, &node, 888 if (sysctlgetmibinfo(key, &name[0], &namelen, gsname, &sz, &node,
889 SYSCTL_VERSION) == -1) { 889 SYSCTL_VERSION) == -1) {
890 if (optional) 890 if (optional)
891 return; 891 return;
892 sysctlparseerror(namelen, l); 892 sysctlparseerror(namelen, l);
893 EXIT(1); 893 EXIT(EXIT_FAILURE);
894 } 894 }
895 895
896 type = SYSCTL_TYPE(node->sysctl_flags); 896 type = SYSCTL_TYPE(node->sysctl_flags);
897 897
898 if (value == NULL) { 898 if (value == NULL) {
899 if (dodesc) 899 if (dodesc)
900 dflag = 1; 900 dflag = 1;
901 print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); 901 print_tree(&name[0], namelen, node, type, 0, re, lastcompiled);
902 if (dodesc) 902 if (dodesc)
903 dflag = 0; 903 dflag = 0;
904 gsname[0] = '\0'; 904 gsname[0] = '\0';
905 return; 905 return;
906 } 906 }
907 907
908 if (fn) 908 if (fn)
909 trim_whitespace(value, 1); 909 trim_whitespace(value, 1);
910 910
911 if (!wflag) { 911 if (!wflag) {
912 sysctlperror("Must specify -w to set variables\n"); 912 sysctlperror("Must specify -w to set variables\n");
913 exit(1); 913 exit(EXIT_FAILURE);
914 } 914 }
915 915
916 canonicalize(gsname, canonname); 916 canonicalize(gsname, canonname);
917 if (type != CTLTYPE_NODE && (w = findhandler(canonname, re, 917 if (type != CTLTYPE_NODE && (w = findhandler(canonname, re,
918 lastcompiled)) != NULL) { 918 lastcompiled)) != NULL) {
919 if (w->ps_w == NULL) { 919 if (w->ps_w == NULL) {
920 sysctlperror("Cannot write `%s': %s\n", gsname,  920 sysctlperror("Cannot write `%s': %s\n", gsname,
921 strerror(EOPNOTSUPP)); 921 strerror(EOPNOTSUPP));
922 exit(1); 922 exit(EXIT_FAILURE);
923 } 923 }
924 (*w->ps_w)(gsname, gdname, value, name, namelen, node, type, 924 (*w->ps_w)(gsname, gdname, value, name, namelen, node, type,
925 __UNCONST(w->ps_d)); 925 __UNCONST(w->ps_d));
926 gsname[0] = '\0'; 926 gsname[0] = '\0';
927 return; 927 return;
928 } 928 }
929 929
930 switch (type) { 930 switch (type) {
931 case CTLTYPE_NODE: 931 case CTLTYPE_NODE:
932 /* 932 /*
933 * XXX old behavior is to print. should we error instead? 933 * XXX old behavior is to print. should we error instead?
934 */ 934 */
935 print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re, 935 print_tree(&name[0], namelen, node, CTLTYPE_NODE, 1, re,
936 lastcompiled); 936 lastcompiled);
937 break; 937 break;
938 case CTLTYPE_INT: 938 case CTLTYPE_INT:
939 case CTLTYPE_BOOL: 939 case CTLTYPE_BOOL:
940 case CTLTYPE_QUAD: 940 case CTLTYPE_QUAD:
941 write_number(&name[0], namelen, node, value); 941 write_number(&name[0], namelen, node, value);
942 break; 942 break;
943 case CTLTYPE_STRING: 943 case CTLTYPE_STRING:
944 write_string(&name[0], namelen, node, value); 944 write_string(&name[0], namelen, node, value);
945 break; 945 break;
946 case CTLTYPE_STRUCT: 946 case CTLTYPE_STRUCT:
947 /* 947 /*
948 * XXX old behavior is to print. should we error instead? 948 * XXX old behavior is to print. should we error instead?
949 */ 949 */
950 /* fprintf(warnfp, "you can't write to %s\n", gsname); */ 950 /* fprintf(warnfp, "you can't write to %s\n", gsname); */
951 print_tree(&name[0], namelen, node, type, 0, re, lastcompiled); 951 print_tree(&name[0], namelen, node, type, 0, re, lastcompiled);
952 break; 952 break;
953 } 953 }
954} 954}
955 955
956/* 956/*
957 957
958 //create=foo.bar.whatever..., 958 //create=foo.bar.whatever...,
959 [type=(int|quad|string|struct|node),] 959 [type=(int|quad|string|struct|node),]
960 [size=###,] 960 [size=###,]
961 [n=###,] 961 [n=###,]
962 [flags=(iohxparw12),] 962 [flags=(iohxparw12),]
963 [addr=0x####,|symbol=...|value=...] 963 [addr=0x####,|symbol=...|value=...]
964 964
965 size is optional for some types. type must be set before anything 965 size is optional for some types. type must be set before anything
966 else. nodes can have [rwhp], but nothing else applies. if no 966 else. nodes can have [rwhp], but nothing else applies. if no
967 size or type is given, node is asserted. writeable is the default, 967 size or type is given, node is asserted. writeable is the default,
968 with [rw] being read-only and unconditionally writeable 968 with [rw] being read-only and unconditionally writeable
969 respectively. if you specify addr, it is assumed to be the name of 969 respectively. if you specify addr, it is assumed to be the name of
970 a kernel symbol, if value, CTLFLAG_OWNDATA will be asserted for 970 a kernel symbol, if value, CTLFLAG_OWNDATA will be asserted for
971 strings, CTLFLAG_IMMEDIATE for ints and u_quad_ts. you cannot 971 strings, CTLFLAG_IMMEDIATE for ints and u_quad_ts. you cannot
972 specify both value and addr. 972 specify both value and addr.
973 973
974*/ 974*/
975 975
976static void 976static void
977parse_create(char *l) 977parse_create(char *l)
978{ 978{
979 struct sysctlnode node; 979 struct sysctlnode node;
980 size_t sz; 980 size_t sz;
981 char *nname, *key, *value, *data, *addr, *c, *t; 981 char *nname, *key, *value, *data, *addr, *c, *t;
982 int name[CTL_MAXNAME], i, rc, method, flags, rw; 982 int name[CTL_MAXNAME], i, rc, method, flags, rw;
983 u_int namelen, type; 983 u_int namelen, type;
984 u_quad_t uq; 984 u_quad_t uq;
985 quad_t q; 985 quad_t q;
986 bool b; 986 bool b;
987 987
988 if (!wflag) { 988 if (!wflag) {
989 sysctlperror("Must specify -w to create nodes\n"); 989 sysctlperror("Must specify -w to create nodes\n");
990 exit(1); 990 exit(EXIT_FAILURE);
991 } 991 }
992 992
993 /* 993 /*
994 * these are the pieces that make up the description of a new 994 * these are the pieces that make up the description of a new
995 * node 995 * node
996 */ 996 */
997 memset(&node, 0, sizeof(node)); 997 memset(&node, 0, sizeof(node));
998 node.sysctl_num = CTL_CREATE; /* any number is fine */ 998 node.sysctl_num = CTL_CREATE; /* any number is fine */
999 flags = 0; 999 flags = 0;
1000 rw = -1; 1000 rw = -1;
1001 type = 0; 1001 type = 0;
1002 sz = 0; 1002 sz = 0;
1003 data = addr = NULL; 1003 data = addr = NULL;
1004 memset(name, 0, sizeof(name)); 1004 memset(name, 0, sizeof(name));
1005 namelen = 0; 1005 namelen = 0;
1006 method = 0; 1006 method = 0;
1007 1007
1008 /* 1008 /*
1009 * misc stuff used when constructing 1009 * misc stuff used when constructing
1010 */ 1010 */
1011 i = 0; 1011 i = 0;
1012 b = false; 1012 b = false;
1013 uq = 0; 1013 uq = 0;
1014 key = NULL; 1014 key = NULL;
1015 value = NULL; 1015 value = NULL;
1016 1016
1017 /* 1017 /*
1018 * the name of the thing we're trying to create is first, so 1018 * the name of the thing we're trying to create is first, so
1019 * pick it off. 1019 * pick it off.
1020 */ 1020 */
1021 nname = l; 1021 nname = l;
1022 if ((c = strchr(nname, ',')) != NULL) 1022 if ((c = strchr(nname, ',')) != NULL)
1023 *c++ = '\0'; 1023 *c++ = '\0';
1024 1024
1025 while (c != NULL) { 1025 while (c != NULL) {
1026 1026
1027 /* 1027 /*
1028 * pull off the next "key=value" pair 1028 * pull off the next "key=value" pair
1029 */ 1029 */
1030 key = c; 1030 key = c;
1031 if ((t = strchr(key, '=')) != NULL) { 1031 if ((t = strchr(key, '=')) != NULL) {
1032 *t++ = '\0'; 1032 *t++ = '\0';
1033 value = t; 1033 value = t;
1034 } 1034 }
1035 else 1035 else
1036 value = NULL; 1036 value = NULL;
1037 1037
1038 /* 1038 /*
1039 * if the "key" is "value", then that eats the rest of 1039 * if the "key" is "value", then that eats the rest of
1040 * the string, so we're done, otherwise bite it off at 1040 * the string, so we're done, otherwise bite it off at
1041 * the next comma. 1041 * the next comma.
1042 */ 1042 */
1043 if (strcmp(key, "value") == 0) { 1043 if (strcmp(key, "value") == 0) {
1044 c = NULL; 1044 c = NULL;
1045 data = value; 1045 data = value;
1046 break; 1046 break;
1047 } 1047 }
1048 else if (value) { 1048 else if (value) {
1049 if ((c = strchr(value, ',')) != NULL) 1049 if ((c = strchr(value, ',')) != NULL)
1050 *c++ = '\0'; 1050 *c++ = '\0';
1051 } 1051 }
1052 1052
1053 /* 1053 /*
1054 * note that we (mostly) let the invoker of prog_sysctl(8) 1054 * note that we (mostly) let the invoker of prog_sysctl(8)
1055 * play rampant here and depend on the kernel to tell 1055 * play rampant here and depend on the kernel to tell
1056 * them that they were wrong. well...within reason. 1056 * them that they were wrong. well...within reason.
1057 * we later check the various parameters against each 1057 * we later check the various parameters against each
1058 * other to make sure it makes some sort of sense. 1058 * other to make sure it makes some sort of sense.
1059 */ 1059 */
1060 if (strcmp(key, "addr") == 0) { 1060 if (strcmp(key, "addr") == 0) {
1061 /* 1061 /*
1062 * we can't check these two. only the kernel 1062 * we can't check these two. only the kernel
1063 * can tell us when it fails to find the name 1063 * can tell us when it fails to find the name
1064 * (or if the address is invalid). 1064 * (or if the address is invalid).
1065 */ 1065 */
1066 if (method != 0) { 1066 if (method != 0) {
1067 sysctlperror( 1067 sysctlperror(
1068 "%s: already have %s for new node\n", 1068 "%s: already have %s for new node\n",
1069 nname, 1069 nname,
1070 method == CTL_CREATE ? "addr" : "symbol"); 1070 method == CTL_CREATE ? "addr" : "symbol");
1071 EXIT(1); 1071 EXIT(EXIT_FAILURE);
1072 } 1072 }
1073 if (value == NULL) { 1073 if (value == NULL) {
1074 sysctlperror("%s: missing value\n", nname); 1074 sysctlperror("%s: missing value\n", nname);
1075 EXIT(1); 1075 EXIT(EXIT_FAILURE);
1076 } 1076 }
1077 errno = 0; 1077 errno = 0;
1078 addr = (void*)strtoul(value, &t, 0); 1078 addr = (void*)strtoul(value, &t, 0);
1079 if (t == value || *t != '\0' || errno != 0) { 1079 if (t == value || *t != '\0' || errno != 0) {
1080 sysctlperror( 1080 sysctlperror(
1081 "%s: '%s' is not a valid address\n", 1081 "%s: '%s' is not a valid address\n",
1082 nname, value); 1082 nname, value);
1083 EXIT(1); 1083 EXIT(EXIT_FAILURE);
1084 } 1084 }
1085 method = CTL_CREATE; 1085 method = CTL_CREATE;
1086 } 1086 }
1087 else if (strcmp(key, "symbol") == 0) { 1087 else if (strcmp(key, "symbol") == 0) {
1088 if (method != 0) { 1088 if (method != 0) {
1089 sysctlperror( 1089 sysctlperror(
1090 "%s: already have %s for new node\n", 1090 "%s: already have %s for new node\n",
1091 nname, 1091 nname,
1092 method == CTL_CREATE ? "addr" : "symbol"); 1092 method == CTL_CREATE ? "addr" : "symbol");
1093 EXIT(1); 1093 EXIT(EXIT_FAILURE);
1094 } 1094 }
1095 addr = value; 1095 addr = value;
1096 method = CTL_CREATESYM; 1096 method = CTL_CREATESYM;
1097 } 1097 }
1098 else if (strcmp(key, "type") == 0) { 1098 else if (strcmp(key, "type") == 0) {
1099 if (value == NULL) { 1099 if (value == NULL) {
1100 sysctlperror("%s: missing value\n", nname); 1100 sysctlperror("%s: missing value\n", nname);
1101 EXIT(1); 1101 EXIT(EXIT_FAILURE);
1102 } 1102 }
1103 if (strcmp(value, "node") == 0) 1103 if (strcmp(value, "node") == 0)
1104 type = CTLTYPE_NODE; 1104 type = CTLTYPE_NODE;
1105 else if (strcmp(value, "int") == 0) { 1105 else if (strcmp(value, "int") == 0) {
1106 sz = sizeof(int); 1106 sz = sizeof(int);
1107 type = CTLTYPE_INT; 1107 type = CTLTYPE_INT;
1108 } 1108 }
1109 else if (strcmp(value, "bool") == 0) { 1109 else if (strcmp(value, "bool") == 0) {
1110 sz = sizeof(bool); 1110 sz = sizeof(bool);
1111 type = CTLTYPE_BOOL; 1111 type = CTLTYPE_BOOL;
1112 } 1112 }
1113 else if (strcmp(value, "string") == 0) 1113 else if (strcmp(value, "string") == 0)
1114 type = CTLTYPE_STRING; 1114 type = CTLTYPE_STRING;
1115 else if (strcmp(value, "quad") == 0) { 1115 else if (strcmp(value, "quad") == 0) {
1116 sz = sizeof(u_quad_t); 1116 sz = sizeof(u_quad_t);
1117 type = CTLTYPE_QUAD; 1117 type = CTLTYPE_QUAD;
1118 } 1118 }
1119 else if (strcmp(value, "struct") == 0) 1119 else if (strcmp(value, "struct") == 0)
1120 type = CTLTYPE_STRUCT; 1120 type = CTLTYPE_STRUCT;
1121 else { 1121 else {
1122 sysctlperror( 1122 sysctlperror(
1123 "%s: '%s' is not a valid type\n", 1123 "%s: '%s' is not a valid type\n",
1124 nname, value); 1124 nname, value);
1125 EXIT(1); 1125 EXIT(EXIT_FAILURE);
1126 } 1126 }
1127 } 1127 }
1128 else if (strcmp(key, "size") == 0) { 1128 else if (strcmp(key, "size") == 0) {
1129 if (value == NULL) { 1129 if (value == NULL) {
1130 sysctlperror("%s: missing value\n", nname); 1130 sysctlperror("%s: missing value\n", nname);
1131 EXIT(1); 1131 EXIT(EXIT_FAILURE);
1132 } 1132 }
1133 errno = 0; 1133 errno = 0;
1134 /* 1134 /*
1135 * yes, i know size_t is not an unsigned long, 1135 * yes, i know size_t is not an unsigned long,
1136 * but we can all agree that it ought to be, 1136 * but we can all agree that it ought to be,
1137 * right? 1137 * right?
1138 */ 1138 */
1139 sz = strtoul(value, &t, 0); 1139 sz = strtoul(value, &t, 0);
1140 if (t == value || *t != '\0' || errno != 0) { 1140 if (t == value || *t != '\0' || errno != 0) {
1141 sysctlperror( 1141 sysctlperror(
1142 "%s: '%s' is not a valid size\n", 1142 "%s: '%s' is not a valid size\n",
1143 nname, value); 1143 nname, value);
1144 EXIT(1); 1144 EXIT(EXIT_FAILURE);
1145 } 1145 }
1146 } 1146 }
1147 else if (strcmp(key, "n") == 0) { 1147 else if (strcmp(key, "n") == 0) {
1148 if (value == NULL) { 1148 if (value == NULL) {
1149 sysctlperror("%s: missing value\n", nname); 1149 sysctlperror("%s: missing value\n", nname);
1150 EXIT(1); 1150 EXIT(EXIT_FAILURE);
1151 } 1151 }
1152 errno = 0; 1152 errno = 0;
1153 q = strtoll(value, &t, 0); 1153 q = strtoll(value, &t, 0);
1154 if (t == value || *t != '\0' || errno != 0 || 1154 if (t == value || *t != '\0' || errno != 0 ||
1155 q < INT_MIN || q > UINT_MAX) { 1155 q < INT_MIN || q > UINT_MAX) {
1156 sysctlperror( 1156 sysctlperror(
1157 "%s: '%s' is not a valid mib number\n", 1157 "%s: '%s' is not a valid mib number\n",
1158 nname, value); 1158 nname, value);
1159 EXIT(1); 1159 EXIT(EXIT_FAILURE);
1160 } 1160 }
1161 node.sysctl_num = (int)q; 1161 node.sysctl_num = (int)q;
1162 } 1162 }
1163 else if (strcmp(key, "flags") == 0) { 1163 else if (strcmp(key, "flags") == 0) {
1164 if (value == NULL) { 1164 if (value == NULL) {
1165 sysctlperror("%s: missing value\n", nname); 1165 sysctlperror("%s: missing value\n", nname);
1166 EXIT(1); 1166 EXIT(EXIT_FAILURE);
1167 } 1167 }
1168 t = value; 1168 t = value;
1169 while (*t != '\0') { 1169 while (*t != '\0') {
1170 switch (*t) { 1170 switch (*t) {
1171 case 'a': 1171 case 'a':
1172 flags |= CTLFLAG_ANYWRITE; 1172 flags |= CTLFLAG_ANYWRITE;
1173 break; 1173 break;
1174 case 'h': 1174 case 'h':
1175 flags |= CTLFLAG_HIDDEN; 1175 flags |= CTLFLAG_HIDDEN;
1176 break; 1176 break;
1177 case 'i': 1177 case 'i':
1178 flags |= CTLFLAG_IMMEDIATE; 1178 flags |= CTLFLAG_IMMEDIATE;
1179 break; 1179 break;
1180 case 'o': 1180 case 'o':
1181 flags |= CTLFLAG_OWNDATA; 1181 flags |= CTLFLAG_OWNDATA;
1182 break; 1182 break;
1183 case 'p': 1183 case 'p':
1184 flags |= CTLFLAG_PRIVATE; 1184 flags |= CTLFLAG_PRIVATE;
1185 break; 1185 break;
1186 case 'u': 1186 case 'u':
1187 flags |= CTLFLAG_UNSIGNED; 1187 flags |= CTLFLAG_UNSIGNED;
1188 break; 1188 break;
1189 case 'x': 1189 case 'x':
1190 flags |= CTLFLAG_HEX; 1190 flags |= CTLFLAG_HEX;
1191 break; 1191 break;
1192 1192
1193 case 'r': 1193 case 'r':
1194 rw = CTLFLAG_READONLY; 1194 rw = CTLFLAG_READONLY;
1195 break; 1195 break;
1196 case 'w': 1196 case 'w':
1197 rw = CTLFLAG_READWRITE; 1197 rw = CTLFLAG_READWRITE;
1198 break; 1198 break;
1199 default: 1199 default:
1200 sysctlperror( 1200 sysctlperror(
1201 "%s: '%c' is not a valid flag\n", 1201 "%s: '%c' is not a valid flag\n",
1202 nname, *t); 1202 nname, *t);
1203 EXIT(1); 1203 EXIT(EXIT_FAILURE);
1204 } 1204 }
1205 t++; 1205 t++;
1206 } 1206 }
1207 } 1207 }
1208 else { 1208 else {
1209 sysctlperror("%s: unrecognized keyword '%s'\n", 1209 sysctlperror("%s: unrecognized keyword '%s'\n",
1210 nname, key); 1210 nname, key);
1211 EXIT(1); 1211 EXIT(EXIT_FAILURE);
1212 } 1212 }
1213 } 1213 }
1214 1214
1215 /* 1215 /*
1216 * now that we've finished parsing the given string, fill in 1216 * now that we've finished parsing the given string, fill in
1217 * anything they didn't specify 1217 * anything they didn't specify
1218 */ 1218 */
1219 if (type == 0) 1219 if (type == 0)
1220 type = CTLTYPE_NODE; 1220 type = CTLTYPE_NODE;
1221 1221
1222 /* 1222 /*
1223 * the "data" can be interpreted various ways depending on the 1223 * the "data" can be interpreted various ways depending on the
1224 * type of node we're creating, as can the size 1224 * type of node we're creating, as can the size
1225 */ 1225 */
1226 if (data != NULL) { 1226 if (data != NULL) {
1227 if (addr != NULL) { 1227 if (addr != NULL) {
1228 sysctlperror( 1228 sysctlperror(
1229 "%s: cannot specify both value and " 1229 "%s: cannot specify both value and "
1230 "address\n", nname); 1230 "address\n", nname);
1231 EXIT(1); 1231 EXIT(EXIT_FAILURE);
1232 } 1232 }
1233 1233
1234 switch (type) { 1234 switch (type) {
1235 case CTLTYPE_INT: 1235 case CTLTYPE_INT:
1236 errno = 0; 1236 errno = 0;
1237 q = strtoll(data, &t, 0); 1237 q = strtoll(data, &t, 0);
1238 if (t == data || *t != '\0' || errno != 0 || 1238 if (t == data || *t != '\0' || errno != 0 ||
1239 q < INT_MIN || q > UINT_MAX) { 1239 q < INT_MIN || q > UINT_MAX) {
1240 sysctlperror( 1240 sysctlperror(
1241 "%s: '%s' is not a valid integer\n", 1241 "%s: '%s' is not a valid integer\n",
1242 nname, value); 1242 nname, value);
1243 EXIT(1); 1243 EXIT(EXIT_FAILURE);
1244 } 1244 }
1245 i = (int)q; 1245 i = (int)q;
1246 if (!(flags & CTLFLAG_OWNDATA)) { 1246 if (!(flags & CTLFLAG_OWNDATA)) {
1247 flags |= CTLFLAG_IMMEDIATE; 1247 flags |= CTLFLAG_IMMEDIATE;
1248 node.sysctl_idata = i; 1248 node.sysctl_idata = i;
1249 } 1249 }
1250 else 1250 else
1251 node.sysctl_data = &i; 1251 node.sysctl_data = &i;
1252 if (sz == 0) 1252 if (sz == 0)
1253 sz = sizeof(int); 1253 sz = sizeof(int);
1254 break; 1254 break;
1255 case CTLTYPE_BOOL: 1255 case CTLTYPE_BOOL:
1256 errno = 0; 1256 errno = 0;
1257 q = strtoll(data, &t, 0); 1257 q = strtoll(data, &t, 0);
1258 if (t == data || *t != '\0' || errno != 0 || 1258 if (t == data || *t != '\0' || errno != 0 ||
1259 (q != 0 && q != 1)) { 1259 (q != 0 && q != 1)) {
1260 sysctlperror( 1260 sysctlperror(
1261 "%s: '%s' is not a valid bool\n", 1261 "%s: '%s' is not a valid bool\n",
1262 nname, value); 1262 nname, value);
1263 EXIT(1); 1263 EXIT(EXIT_FAILURE);
1264 } 1264 }
1265 b = q == 1; 1265 b = q == 1;
1266 if (!(flags & CTLFLAG_OWNDATA)) { 1266 if (!(flags & CTLFLAG_OWNDATA)) {
1267 flags |= CTLFLAG_IMMEDIATE; 1267 flags |= CTLFLAG_IMMEDIATE;
1268 node.sysctl_idata = b; 1268 node.sysctl_idata = b;
1269 } 1269 }
1270 else 1270 else
1271 node.sysctl_data = &b; 1271 node.sysctl_data = &b;
1272 if (sz == 0) 1272 if (sz == 0)
1273 sz = sizeof(bool); 1273 sz = sizeof(bool);
1274 break; 1274 break;
1275 case CTLTYPE_STRING: 1275 case CTLTYPE_STRING:
1276 flags |= CTLFLAG_OWNDATA; 1276 flags |= CTLFLAG_OWNDATA;
1277 node.sysctl_data = data; 1277 node.sysctl_data = data;
1278 if (sz == 0) 1278 if (sz == 0)
1279 sz = strlen(data) + 1; 1279 sz = strlen(data) + 1;
1280 else if (sz < strlen(data) + 1) { 1280 else if (sz < strlen(data) + 1) {
1281 sysctlperror("%s: ignoring size=%zu for " 1281 sysctlperror("%s: ignoring size=%zu for "
1282 "string node, too small for given " 1282 "string node, too small for given "
1283 "value\n", nname, sz); 1283 "value\n", nname, sz);
1284 sz = strlen(data) + 1; 1284 sz = strlen(data) + 1;
1285 } 1285 }
1286 break; 1286 break;
1287 case CTLTYPE_QUAD: 1287 case CTLTYPE_QUAD:
1288 errno = 0; 1288 errno = 0;
1289 uq = strtouq(data, &t, 0); 1289 uq = strtouq(data, &t, 0);
1290 if (t == data || *t != '\0' || errno != 0) { 1290 if (t == data || *t != '\0' || errno != 0) {
1291 sysctlperror( 1291 sysctlperror(
1292 "%s: '%s' is not a valid quad\n", 1292 "%s: '%s' is not a valid quad\n",
1293 nname, value); 1293 nname, value);
1294 EXIT(1); 1294 EXIT(EXIT_FAILURE);
1295 } 1295 }
1296 if (!(flags & CTLFLAG_OWNDATA)) { 1296 if (!(flags & CTLFLAG_OWNDATA)) {
1297 flags |= CTLFLAG_IMMEDIATE; 1297 flags |= CTLFLAG_IMMEDIATE;
1298 node.sysctl_qdata = uq; 1298 node.sysctl_qdata = uq;
1299 } 1299 }
1300 else 1300 else
1301 node.sysctl_data = &uq; 1301 node.sysctl_data = &uq;
1302 if (sz == 0) 1302 if (sz == 0)
1303 sz = sizeof(u_quad_t); 1303 sz = sizeof(u_quad_t);
1304 break; 1304 break;
1305 case CTLTYPE_STRUCT: 1305 case CTLTYPE_STRUCT:
1306 sysctlperror("%s: struct not initializable\n", 1306 sysctlperror("%s: struct not initializable\n",
1307 nname); 1307 nname);
1308 EXIT(1); 1308 EXIT(EXIT_FAILURE);
1309 } 1309 }
1310 1310
1311 /* 1311 /*
1312 * these methods have all provided local starting 1312 * these methods have all provided local starting
1313 * values that the kernel must copy in 1313 * values that the kernel must copy in
1314 */ 1314 */
1315 } 1315 }
1316 1316
1317 /* 1317 /*
1318 * hmm...no data, but we have an address of data. that's 1318 * hmm...no data, but we have an address of data. that's
1319 * fine. 1319 * fine.
1320 */ 1320 */
1321 else if (addr != 0) 1321 else if (addr != 0)
1322 node.sysctl_data = (void*)addr; 1322 node.sysctl_data = (void*)addr;
1323 1323
1324 /* 1324 /*
1325 * no data and no address? well...okay. we might be able to 1325 * no data and no address? well...okay. we might be able to
1326 * manage that. 1326 * manage that.
1327 */ 1327 */
1328 else if (type != CTLTYPE_NODE) { 1328 else if (type != CTLTYPE_NODE) {
1329 if (sz == 0) { 1329 if (sz == 0) {
1330 sysctlperror( 1330 sysctlperror(
1331 "%s: need a size or a starting value\n", 1331 "%s: need a size or a starting value\n",
1332 nname); 1332 nname);
1333 EXIT(1); 1333 EXIT(EXIT_FAILURE);
1334 } 1334 }
1335 if (!(flags & CTLFLAG_IMMEDIATE)) 1335 if (!(flags & CTLFLAG_IMMEDIATE))
1336 flags |= CTLFLAG_OWNDATA; 1336 flags |= CTLFLAG_OWNDATA;
1337 } 1337 }
1338 1338
1339 /* 1339 /*
1340 * now we do a few sanity checks on the description we've 1340 * now we do a few sanity checks on the description we've
1341 * assembled 1341 * assembled
1342 */ 1342 */
1343 if ((flags & CTLFLAG_IMMEDIATE) && 1343 if ((flags & CTLFLAG_IMMEDIATE) &&
1344 (type == CTLTYPE_STRING || type == CTLTYPE_STRUCT)) { 1344 (type == CTLTYPE_STRING || type == CTLTYPE_STRUCT)) {
1345 sysctlperror("%s: cannot make an immediate %s\n",  1345 sysctlperror("%s: cannot make an immediate %s\n",
1346 nname, 1346 nname,
1347 (type == CTLTYPE_STRING) ? "string" : "struct"); 1347 (type == CTLTYPE_STRING) ? "string" : "struct");
1348 EXIT(1); 1348 EXIT(EXIT_FAILURE);
1349 } 1349 }
1350 if (type == CTLTYPE_NODE && node.sysctl_data != NULL) { 1350 if (type == CTLTYPE_NODE && node.sysctl_data != NULL) {
1351 sysctlperror("%s: nodes do not have data\n", nname); 1351 sysctlperror("%s: nodes do not have data\n", nname);
1352 EXIT(1); 1352 EXIT(EXIT_FAILURE);
1353 } 1353 }
1354  1354
1355 /* 1355 /*
1356 * some types must have a particular size 1356 * some types must have a particular size
1357 */ 1357 */
1358 if (sz != 0) { 1358 if (sz != 0) {
1359 if ((type == CTLTYPE_INT && sz != sizeof(int)) || 1359 if ((type == CTLTYPE_INT && sz != sizeof(int)) ||
1360 (type == CTLTYPE_BOOL && sz != sizeof(bool)) || 1360 (type == CTLTYPE_BOOL && sz != sizeof(bool)) ||
1361 (type == CTLTYPE_QUAD && sz != sizeof(u_quad_t)) || 1361 (type == CTLTYPE_QUAD && sz != sizeof(u_quad_t)) ||
1362 (type == CTLTYPE_NODE && sz != 0)) { 1362 (type == CTLTYPE_NODE && sz != 0)) {
1363 sysctlperror("%s: wrong size for type\n", nname); 1363 sysctlperror("%s: wrong size for type\n", nname);
1364 EXIT(1); 1364 EXIT(EXIT_FAILURE);
1365 } 1365 }
1366 } 1366 }
1367 else if (type == CTLTYPE_STRUCT) { 1367 else if (type == CTLTYPE_STRUCT) {
1368 sysctlperror("%s: struct must have size\n", nname); 1368 sysctlperror("%s: struct must have size\n", nname);
1369 EXIT(1); 1369 EXIT(EXIT_FAILURE);
1370 } 1370 }
1371 1371
1372 /* 1372 /*
1373 * now...if no one said anything yet, we default nodes or 1373 * now...if no one said anything yet, we default nodes or
1374 * any type that owns data being writeable, and everything 1374 * any type that owns data being writeable, and everything
1375 * else being readonly. 1375 * else being readonly.
1376 */ 1376 */
1377 if (rw == -1) { 1377 if (rw == -1) {
1378 if (type == CTLTYPE_NODE || 1378 if (type == CTLTYPE_NODE ||
1379 (flags & (CTLFLAG_OWNDATA|CTLFLAG_IMMEDIATE))) 1379 (flags & (CTLFLAG_OWNDATA|CTLFLAG_IMMEDIATE)))
1380 rw = CTLFLAG_READWRITE; 1380 rw = CTLFLAG_READWRITE;
1381 else 1381 else
1382 rw = CTLFLAG_READONLY; 1382 rw = CTLFLAG_READONLY;
1383 } 1383 }
1384 1384
1385 /* 1385 /*
1386 * if a kernel address was specified, that can't be made 1386 * if a kernel address was specified, that can't be made
1387 * writeable by us. 1387 * writeable by us.
1388 if (rw != CTLFLAG_READONLY && addr) { 1388 if (rw != CTLFLAG_READONLY && addr) {
1389 sysctlperror("%s: kernel data can only be readable\n", nname); 1389 sysctlperror("%s: kernel data can only be readable\n", nname);
1390 EXIT(1); 1390 EXIT(EXIT_FAILURE);
1391 } 1391 }
1392 */ 1392 */
1393 1393
1394 /* 1394 /*
1395 * what separator were they using in the full name of the new 1395 * what separator were they using in the full name of the new
1396 * node? 1396 * node?
1397 */ 1397 */
1398 if ((t = strpbrk(nname, "./")) == NULL) 1398 if ((t = strpbrk(nname, "./")) == NULL)
1399 sep[0] = '.'; 1399 sep[0] = '.';
1400 else 1400 else
1401 sep[0] = t[0]; 1401 sep[0] = t[0];
1402 sep[1] = '\0'; 1402 sep[1] = '\0';
1403 1403
1404 /* 1404 /*
1405 * put it all together, now. t'ain't much, is it? 1405 * put it all together, now. t'ain't much, is it?
1406 */ 1406 */
1407 node.sysctl_flags = SYSCTL_VERSION|flags|rw|type; 1407 node.sysctl_flags = SYSCTL_VERSION|flags|rw|type;
1408 node.sysctl_size = sz; 1408 node.sysctl_size = sz;
1409 t = strrchr(nname, sep[0]); 1409 t = strrchr(nname, sep[0]);
1410 if (t != NULL) 1410 if (t != NULL)
1411 strlcpy(node.sysctl_name, t + 1, sizeof(node.sysctl_name)); 1411 strlcpy(node.sysctl_name, t + 1, sizeof(node.sysctl_name));
1412 else 1412 else
1413 strlcpy(node.sysctl_name, nname, sizeof(node.sysctl_name)); 1413 strlcpy(node.sysctl_name, nname, sizeof(node.sysctl_name));
1414 if (t == nname) 1414 if (t == nname)
1415 t = NULL; 1415 t = NULL;
1416 1416
1417 /* 1417 /*
1418 * if this is a new top-level node, then we don't need to find 1418 * if this is a new top-level node, then we don't need to find
1419 * the mib for its parent 1419 * the mib for its parent
1420 */ 1420 */
1421 if (t == NULL) { 1421 if (t == NULL) {
1422 namelen = 0; 1422 namelen = 0;
1423 gsname[0] = '\0'; 1423 gsname[0] = '\0';
1424 } 1424 }
1425 1425
1426 /* 1426 /*
1427 * on the other hand, if it's not a top-level node... 1427 * on the other hand, if it's not a top-level node...
1428 */ 1428 */
1429 else { 1429 else {
1430 namelen = sizeof(name) / sizeof(name[0]); 1430 namelen = sizeof(name) / sizeof(name[0]);
1431 sz = sizeof(gsname); 1431 sz = sizeof(gsname);
1432 *t = '\0'; 1432 *t = '\0';
1433 rc = sysctlgetmibinfo(nname, &name[0], &namelen, 1433 rc = sysctlgetmibinfo(nname, &name[0], &namelen,
1434 gsname, &sz, NULL, SYSCTL_VERSION); 1434 gsname, &sz, NULL, SYSCTL_VERSION);
1435 *t = sep[0]; 1435 *t = sep[0];
1436 if (rc == -1) { 1436 if (rc == -1) {
1437 sysctlparseerror(namelen, nname); 1437 sysctlparseerror(namelen, nname);
1438 EXIT(1); 1438 EXIT(EXIT_FAILURE);
1439 } 1439 }
1440 } 1440 }
1441 1441
1442 /* 1442 /*
1443 * yes, a new node is being created 1443 * yes, a new node is being created
1444 */ 1444 */
1445 if (method != 0) 1445 if (method != 0)
1446 name[namelen++] = method; 1446 name[namelen++] = method;
1447 else 1447 else
1448 name[namelen++] = CTL_CREATE; 1448 name[namelen++] = CTL_CREATE;
1449 1449
1450 sz = sizeof(node); 1450 sz = sizeof(node);
1451 rc = prog_sysctl(&name[0], namelen, &node, &sz, &node, sizeof(node)); 1451 rc = prog_sysctl(&name[0], namelen, &node, &sz, &node, sizeof(node));
1452 1452
1453 if (rc == -1) { 1453 if (rc == -1) {
1454 sysctlperror("%s: CTL_CREATE failed: %s\n", 1454 sysctlperror("%s: CTL_CREATE failed: %s\n",
1455 nname, strerror(errno)); 1455 nname, strerror(errno));
1456 EXIT(1); 1456 EXIT(EXIT_FAILURE);
1457 } 1457 }
1458 else { 1458 else {
1459 if (!qflag && !nflag) 1459 if (!qflag && !nflag)
1460 printf("%s(%s): (created)\n", nname, st(type)); 1460 printf("%s(%s): (created)\n", nname, st(type));
1461 stale = 1; 1461 stale = 1;
1462 } 1462 }
1463} 1463}
1464 1464
1465static void 1465static void
1466parse_destroy(char *l) 1466parse_destroy(char *l)
1467{ 1467{
1468 struct sysctlnode node; 1468 struct sysctlnode node;
1469 size_t sz; 1469 size_t sz;
1470 int name[CTL_MAXNAME], rc; 1470 int name[CTL_MAXNAME], rc;
1471 u_int namelen; 1471 u_int namelen;
1472 1472
1473 if (!wflag) { 1473 if (!wflag) {
1474 sysctlperror("Must specify -w to destroy nodes\n"); 1474 sysctlperror("Must specify -w to destroy nodes\n");
1475 exit(1); 1475 exit(EXIT_FAILURE);
1476 } 1476 }
1477 1477
1478 memset(name, 0, sizeof(name)); 1478 memset(name, 0, sizeof(name));
1479 namelen = sizeof(name) / sizeof(name[0]); 1479 namelen = sizeof(name) / sizeof(name[0]);
1480 sz = sizeof(gsname); 1480 sz = sizeof(gsname);
1481 rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL, 1481 rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL,
1482 SYSCTL_VERSION); 1482 SYSCTL_VERSION);
1483 if (rc == -1) { 1483 if (rc == -1) {
1484 sysctlparseerror(namelen, l); 1484 sysctlparseerror(namelen, l);
1485 EXIT(1); 1485 EXIT(EXIT_FAILURE);
1486 } 1486 }
1487 1487
1488 memset(&node, 0, sizeof(node)); 1488 memset(&node, 0, sizeof(node));
1489 node.sysctl_flags = SYSCTL_VERSION; 1489 node.sysctl_flags = SYSCTL_VERSION;
1490 node.sysctl_num = name[namelen - 1]; 1490 node.sysctl_num = name[namelen - 1];
1491 name[namelen - 1] = CTL_DESTROY; 1491 name[namelen - 1] = CTL_DESTROY;
1492 1492
1493 sz = sizeof(node); 1493 sz = sizeof(node);
1494 rc = prog_sysctl(&name[0], namelen, &node, &sz, &node, sizeof(node)); 1494 rc = prog_sysctl(&name[0], namelen, &node, &sz, &node, sizeof(node));
1495 1495
1496 if (rc == -1) { 1496 if (rc == -1) {
1497 sysctlperror("%s: CTL_DESTROY failed: %s\n", 1497 sysctlperror("%s: CTL_DESTROY failed: %s\n",
1498 l, strerror(errno)); 1498 l, strerror(errno));
1499 EXIT(1); 1499 EXIT(EXIT_FAILURE);
1500 } 1500 }
1501 else { 1501 else {
1502 if (!qflag && !nflag) 1502 if (!qflag && !nflag)
1503 printf("%s(%s): (destroyed)\n", gsname, 1503 printf("%s(%s): (destroyed)\n", gsname,
1504 st(SYSCTL_TYPE(node.sysctl_flags))); 1504 st(SYSCTL_TYPE(node.sysctl_flags)));
1505 stale = 1; 1505 stale = 1;
1506 } 1506 }
1507} 1507}
1508 1508
1509static void 1509static void
1510parse_describe(char *l) 1510parse_describe(char *l)
1511{ 1511{
1512 struct sysctlnode newdesc; 1512 struct sysctlnode newdesc;
1513 char buf[1024], *value; 1513 char buf[1024], *value;
1514 struct sysctldesc *d = (void*)&buf[0]; 1514 struct sysctldesc *d = (void*)&buf[0];
1515 int name[CTL_MAXNAME], rc; 1515 int name[CTL_MAXNAME], rc;
1516 u_int namelen; 1516 u_int namelen;
1517 size_t sz; 1517 size_t sz;
1518 1518
1519 if (!wflag) { 1519 if (!wflag) {
1520 sysctlperror("Must specify -w to set descriptions\n"); 1520 sysctlperror("Must specify -w to set descriptions\n");
1521 exit(1); 1521 exit(EXIT_FAILURE);
1522 } 1522 }
1523 1523
1524 value = strchr(l, '='); 1524 value = strchr(l, '=');
1525 *value++ = '\0'; 1525 *value++ = '\0';
1526 1526
1527 memset(name, 0, sizeof(name)); 1527 memset(name, 0, sizeof(name));
1528 namelen = sizeof(name) / sizeof(name[0]); 1528 namelen = sizeof(name) / sizeof(name[0]);
1529 sz = sizeof(gsname); 1529 sz = sizeof(gsname);
1530 rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL, 1530 rc = sysctlgetmibinfo(l, &name[0], &namelen, gsname, &sz, NULL,
1531 SYSCTL_VERSION); 1531 SYSCTL_VERSION);
1532 if (rc == -1) { 1532 if (rc == -1) {
1533 sysctlparseerror(namelen, l); 1533 sysctlparseerror(namelen, l);
1534 EXIT(1); 1534 EXIT(EXIT_FAILURE);
1535 } 1535 }
1536 1536
1537 sz = sizeof(buf); 1537 sz = sizeof(buf);
1538 memset(&newdesc, 0, sizeof(newdesc)); 1538 memset(&newdesc, 0, sizeof(newdesc));
1539 newdesc.sysctl_flags = SYSCTL_VERSION|CTLFLAG_OWNDESC; 1539 newdesc.sysctl_flags = SYSCTL_VERSION|CTLFLAG_OWNDESC;
1540 newdesc.sysctl_num = name[namelen - 1]; 1540 newdesc.sysctl_num = name[namelen - 1];
1541 newdesc.sysctl_desc = value; 1541 newdesc.sysctl_desc = value;
1542 name[namelen - 1] = CTL_DESCRIBE; 1542 name[namelen - 1] = CTL_DESCRIBE;
1543 rc = prog_sysctl(name, namelen, d, &sz, &newdesc, sizeof(newdesc)); 1543 rc = prog_sysctl(name, namelen, d, &sz, &newdesc, sizeof(newdesc));
1544 if (rc == -1) 1544 if (rc == -1)
1545 sysctlperror("%s: CTL_DESCRIBE failed: %s\n", 1545 sysctlperror("%s: CTL_DESCRIBE failed: %s\n",
1546 gsname, strerror(errno)); 1546 gsname, strerror(errno));
1547 else if (d->descr_len == 1) 1547 else if (d->descr_len == 1)
1548 sysctlperror("%s: description not set\n", gsname); 1548 sysctlperror("%s: description not set\n", gsname);
1549 else if (!qflag && !nflag) 1549 else if (!qflag && !nflag)
1550 printf("%s: %s\n", gsname, d->descr_str); 1550 printf("%s: %s\n", gsname, d->descr_str);
1551} 1551}
1552 1552
1553/* 1553/*
1554 * ******************************************************************** 1554 * ********************************************************************
1555 * when things go wrong... 1555 * when things go wrong...
1556 * ******************************************************************** 1556 * ********************************************************************
1557 */ 1557 */
1558static void 1558static void
1559usage(void) 1559usage(void)
1560{ 1560{
1561 const char *progname = getprogname(); 1561 const char *progname = getprogname();
1562 1562
1563 (void)fprintf(stderr, 1563 (void)fprintf(stderr,
1564 "usage:\t%s %s\n" 1564 "usage:\t%s %s\n"
1565 "\t%s %s\n" 1565 "\t%s %s\n"
1566 "\t%s %s\n" 1566 "\t%s %s\n"
1567 "\t%s %s\n" 1567 "\t%s %s\n"
1568 "\t%s %s\n" 1568 "\t%s %s\n"
1569 "\t%s %s\n", 1569 "\t%s %s\n",
1570 progname, "[-dneq] [-x[x]|-r] variable ...", 1570 progname, "[-dneq] [-x[x]|-r] variable ...",
1571 progname, "[-ne] [-q] -w variable=value ...", 1571 progname, "[-ne] [-q] -w variable=value ...",
1572 progname, "[-dne] -a", 1572 progname, "[-dne] -a",
1573 progname, "[-dne] -A", 1573 progname, "[-dne] -A",
1574 progname, "[-ne] -M", 1574 progname, "[-ne] -M",
1575 progname, "[-dne] [-q] -f file"); 1575 progname, "[-dne] [-q] -f file");
1576 exit(1); 1576 exit(EXIT_FAILURE);
1577} 1577}
1578 1578
1579static void 1579static void
1580getdesc1(int *name, u_int namelen, struct sysctlnode *pnode) 1580getdesc1(int *name, u_int namelen, struct sysctlnode *pnode)
1581{ 1581{
1582 struct sysctlnode node; 1582 struct sysctlnode node;
1583 char buf[1024], *desc; 1583 char buf[1024], *desc;
1584 struct sysctldesc *d = (void*)buf; 1584 struct sysctldesc *d = (void*)buf;
1585 size_t sz = sizeof(buf); 1585 size_t sz = sizeof(buf);
1586 int rc; 1586 int rc;
1587 1587
1588 memset(&node, 0, sizeof(node)); 1588 memset(&node, 0, sizeof(node));
1589 node.sysctl_flags = SYSCTL_VERSION; 1589 node.sysctl_flags = SYSCTL_VERSION;
1590 node.sysctl_num = name[namelen - 1]; 1590 node.sysctl_num = name[namelen - 1];
1591 name[namelen - 1] = CTL_DESCRIBE; 1591 name[namelen - 1] = CTL_DESCRIBE;
1592 rc = prog_sysctl(name, namelen, d, &sz, &node, sizeof(node)); 1592 rc = prog_sysctl(name, namelen, d, &sz, &node, sizeof(node));
1593 1593
1594 if (rc == -1 || 1594 if (rc == -1 ||
1595 d->descr_len == 1 || 1595 d->descr_len == 1 ||
1596 d->descr_num != pnode->sysctl_num || 1596 d->descr_num != pnode->sysctl_num ||
1597 d->descr_ver != pnode->sysctl_ver) 1597 d->descr_ver != pnode->sysctl_ver)
1598 desc = (char *)-1; 1598 desc = (char *)-1;
1599 else 1599 else
1600 desc = malloc(d->descr_len); 1600 desc = malloc(d->descr_len);
1601 1601
1602 if (desc == NULL) 1602 if (desc == NULL)
1603 desc = (char *)-1; 1603 desc = (char *)-1;
1604 if (desc != (char *)-1) 1604 if (desc != (char *)-1)
1605 memcpy(desc, &d->descr_str[0], d->descr_len); 1605 memcpy(desc, &d->descr_str[0], d->descr_len);
1606 name[namelen - 1] = node.sysctl_num; 1606 name[namelen - 1] = node.sysctl_num;
1607 if (pnode->sysctl_desc != NULL && 1607 if (pnode->sysctl_desc != NULL &&
1608 pnode->sysctl_desc != (const char *)-1) 1608 pnode->sysctl_desc != (const char *)-1)
1609 free(__UNCONST(pnode->sysctl_desc)); 1609 free(__UNCONST(pnode->sysctl_desc));
1610 pnode->sysctl_desc = desc; 1610 pnode->sysctl_desc = desc;
1611} 1611}
1612 1612
1613static void 1613static void
1614getdesc(int *name, u_int namelen, struct sysctlnode *pnode) 1614getdesc(int *name, u_int namelen, struct sysctlnode *pnode)
1615{ 1615{
1616 struct sysctlnode *node = pnode->sysctl_child; 1616 struct sysctlnode *node = pnode->sysctl_child;
1617 struct sysctldesc *d, *p, *plim; 1617 struct sysctldesc *d, *p, *plim;
1618 char *desc; 1618 char *desc;
1619 size_t i, sz; 1619 size_t i, sz;
1620 int rc; 1620 int rc;
1621 1621
1622 sz = 128 * pnode->sysctl_clen; 1622 sz = 128 * pnode->sysctl_clen;
1623 name[namelen] = CTL_DESCRIBE; 1623 name[namelen] = CTL_DESCRIBE;
1624 1624
1625 /* 1625 /*
1626 * attempt *twice* to get the description chunk. if two tries 1626 * attempt *twice* to get the description chunk. if two tries
1627 * doesn't work, give up. 1627 * doesn't work, give up.
1628 */ 1628 */
1629 i = 0; 1629 i = 0;
1630 do { 1630 do {
1631 d = malloc(sz); 1631 d = malloc(sz);
1632 if (d == NULL) 1632 if (d == NULL)
1633 return; 1633 return;
1634 rc = prog_sysctl(name, namelen + 1, d, &sz, NULL, 0); 1634 rc = prog_sysctl(name, namelen + 1, d, &sz, NULL, 0);
1635 if (rc == -1) { 1635 if (rc == -1) {
1636 free(d); 1636 free(d);
1637 d = NULL; 1637 d = NULL;
1638 if (i == 0 && errno == ENOMEM) 1638 if (i == 0 && errno == ENOMEM)
1639 i = 1; 1639 i = 1;
1640 else 1640 else
1641 return; 1641 return;
1642 } 1642 }
1643 } while (d == NULL); 1643 } while (d == NULL);
1644 1644
1645 /* 1645 /*
1646 * hokey nested loop here, giving O(n**2) behavior, but should 1646 * hokey nested loop here, giving O(n**2) behavior, but should
1647 * suffice for now 1647 * suffice for now
1648 */ 1648 */
1649 plim = /*LINTED ptr cast*/(struct sysctldesc *)((char*)d + sz); 1649 plim = /*LINTED ptr cast*/(struct sysctldesc *)((char*)d + sz);
1650 for (i = 0; i < pnode->sysctl_clen; i++) { 1650 for (i = 0; i < pnode->sysctl_clen; i++) {
1651 node = &pnode->sysctl_child[i]; 1651 node = &pnode->sysctl_child[i];
1652 for (p = d; p < plim; p = NEXT_DESCR(p)) 1652 for (p = d; p < plim; p = NEXT_DESCR(p))
1653 if (node->sysctl_num == p->descr_num) 1653 if (node->sysctl_num == p->descr_num)
1654 break; 1654 break;
1655 if (p < plim && node->sysctl_ver == p->descr_ver) { 1655 if (p < plim && node->sysctl_ver == p->descr_ver) {
1656 /* 1656 /*
1657 * match found, attempt to attach description 1657 * match found, attempt to attach description
1658 */ 1658 */
1659 if (p->descr_len == 1) 1659 if (p->descr_len == 1)
1660 desc = NULL; 1660 desc = NULL;
1661 else 1661 else
1662 desc = malloc(p->descr_len); 1662 desc = malloc(p->descr_len);
1663 if (desc == NULL) 1663 if (desc == NULL)
1664 desc = (char *)-1; 1664 desc = (char *)-1;
1665 else 1665 else
1666 memcpy(desc, &p->descr_str[0], p->descr_len); 1666 memcpy(desc, &p->descr_str[0], p->descr_len);
1667 node->sysctl_desc = desc; 1667 node->sysctl_desc = desc;
1668 } 1668 }
1669 } 1669 }
1670 1670
1671 free(d); 1671 free(d);
1672} 1672}
1673 1673
1674static void 1674static void
1675trim_whitespace(char *s, int dir) 1675trim_whitespace(char *s, int dir)
1676{ 1676{
1677 char *i, *o; 1677 char *i, *o;
1678 1678
1679 i = o = s; 1679 i = o = s;
1680 if (dir & 1) 1680 if (dir & 1)
1681 while (isspace((unsigned char)*i)) 1681 while (isspace((unsigned char)*i))
1682 i++; 1682 i++;
1683 while ((*o++ = *i++) != '\0'); 1683 while ((*o++ = *i++) != '\0');
1684 o -= 2; /* already past nul, skip back to before it */ 1684 o -= 2; /* already past nul, skip back to before it */
1685 if (dir & 2) 1685 if (dir & 2)
1686 while (o > s && isspace((unsigned char)*o)) 1686 while (o > s && isspace((unsigned char)*o))
1687 *o-- = '\0'; 1687 *o-- = '\0';
1688} 1688}
1689 1689
1690void 1690void
1691sysctlerror(int soft) 1691sysctlerror(int soft)
1692{ 1692{
1693 if (soft) { 1693 if (soft) {
1694 switch (errno) { 1694 switch (errno) {
1695 case ENOENT: 1695 case ENOENT:
1696 case ENOPROTOOPT: 1696 case ENOPROTOOPT:
1697 case ENOTDIR: 1697 case ENOTDIR:
1698 case EINVAL: 1698 case EINVAL:
1699 case EOPNOTSUPP: 1699 case EOPNOTSUPP:
1700 case EPROTONOSUPPORT: 1700 case EPROTONOSUPPORT:
1701 if (Aflag || req) 1701 if (Aflag || req)
1702 sysctlperror("%s: the value is not available\n", 1702 sysctlperror("%s: the value is not available\n",
1703 gsname); 1703 gsname);
1704 return; 1704 return;
1705 } 1705 }
1706 } 1706 }
1707 1707
1708 if (Aflag || req) 1708 if (Aflag || req)
1709 sysctlperror("%s: %s\n", gsname, strerror(errno)); 1709 sysctlperror("%s: %s\n", gsname, strerror(errno));
1710 if (!soft) 1710 if (!soft)
1711 EXIT(1); 1711 EXIT(EXIT_FAILURE);
1712} 1712}
1713 1713
1714void 1714void
1715sysctlparseerror(u_int namelen, const char *pname) 1715sysctlparseerror(u_int namelen, const char *pname)
1716{ 1716{
1717 1717
1718 if (qflag) { 1718 if (qflag) {
1719 errs++; 1719 errs++;
1720 return; 1720 return;
1721 } 1721 }
1722 sysctlperror("%s level name '%s' in '%s' is invalid\n", 1722 sysctlperror("%s level name '%s' in '%s' is invalid\n",
1723 lname[namelen], gsname, pname); 1723 lname[namelen], gsname, pname);
1724} 1724}
1725 1725
1726static void 1726static void
1727sysctlperror(const char *fmt, ...) 1727sysctlperror(const char *fmt, ...)
1728{ 1728{
1729 va_list ap; 1729 va_list ap;
1730 1730
1731 (void)fprintf(warnfp, "%s: ", getprogname()); 1731 (void)fprintf(warnfp, "%s: ", getprogname());
1732 if (fn) 1732 if (fn)
1733 (void)fprintf(warnfp, "%s#%zu: ", fn, nr); 1733 (void)fprintf(warnfp, "%s#%zu: ", fn, nr);
1734 va_start(ap, fmt); 1734 va_start(ap, fmt);
1735 (void)vfprintf(warnfp, fmt, ap); 1735 (void)vfprintf(warnfp, fmt, ap);
1736 va_end(ap); 1736 va_end(ap);
1737 errs++; 1737 errs++;
1738} 1738}
1739 1739
1740 1740
1741/* 1741/*
1742 * ******************************************************************** 1742 * ********************************************************************
1743 * how to write to a "simple" node 1743 * how to write to a "simple" node
1744 * ******************************************************************** 1744 * ********************************************************************
1745 */ 1745 */
1746static void 1746static void
1747write_number(int *name, u_int namelen, struct sysctlnode *node, char *value) 1747write_number(int *name, u_int namelen, struct sysctlnode *node, char *value)
1748{ 1748{
1749 u_int ii, io; 1749 u_int ii, io;
1750 u_quad_t qi, qo; 1750 u_quad_t qi, qo;
1751 size_t si, so; 1751 size_t si, so;
1752 bool bi, bo; 1752 bool bi, bo;
1753 int rc; 1753 int rc;
1754 void *i, *o; 1754 void *i, *o;
1755 char *t; 1755 char *t;
1756 1756
1757 if (fn) 1757 if (fn)
1758 trim_whitespace(value, 3); 1758 trim_whitespace(value, 3);
1759 1759
1760 si = so = 0; 1760 si = so = 0;
1761 i = o = NULL; 1761 i = o = NULL;
1762 bi = bo = false; 1762 bi = bo = false;
1763 errno = 0; 1763 errno = 0;
1764 qi = strtouq(value, &t, 0); 1764 qi = strtouq(value, &t, 0);
1765 if (qi == UQUAD_MAX && errno == ERANGE) { 1765 if (qi == UQUAD_MAX && errno == ERANGE) {
1766 sysctlperror("%s: %s\n", value, strerror(errno)); 1766 sysctlperror("%s: %s\n", value, strerror(errno));
1767 EXIT(1); 1767 EXIT(EXIT_FAILURE);
1768 } 1768 }
1769 if (t == value || *t != '\0') { 1769 if (t == value || *t != '\0') {
1770 sysctlperror("%s: not a number\n", value); 1770 sysctlperror("%s: not a number\n", value);
1771 EXIT(1); 1771 EXIT(EXIT_FAILURE);
1772 } 1772 }
1773 1773
1774 switch (SYSCTL_TYPE(node->sysctl_flags)) { 1774 switch (SYSCTL_TYPE(node->sysctl_flags)) {
1775 case CTLTYPE_INT: 1775 case CTLTYPE_INT:
1776 ii = (u_int)qi; 1776 ii = (u_int)qi;
1777 io = (u_int)(qi >> 32); 1777 io = (u_int)(qi >> 32);
1778 if (io != (u_int)-1 && io != 0) { 1778 if (io != (u_int)-1 && io != 0) {
1779 sysctlperror("%s: %s\n", value, strerror(ERANGE)); 1779 sysctlperror("%s: %s\n", value, strerror(ERANGE));
1780 EXIT(1); 1780 EXIT(EXIT_FAILURE);
1781 } 1781 }
1782 o = &io; 1782 o = &io;
1783 so = sizeof(io); 1783 so = sizeof(io);
1784 i = &ii; 1784 i = &ii;
1785 si = sizeof(ii); 1785 si = sizeof(ii);
1786 break; 1786 break;
1787 case CTLTYPE_BOOL: 1787 case CTLTYPE_BOOL:
1788 bi = (bool)qi; 1788 bi = (bool)qi;
1789 o = &bo; 1789 o = &bo;
1790 so = sizeof(bo); 1790 so = sizeof(bo);
1791 i = &bi; 1791 i = &bi;
1792 si = sizeof(bi); 1792 si = sizeof(bi);
1793 break; 1793 break;
1794 case CTLTYPE_QUAD: 1794 case CTLTYPE_QUAD:
1795 o = &qo; 1795 o = &qo;
1796 so = sizeof(qo); 1796 so = sizeof(qo);
1797 i = &qi; 1797 i = &qi;
1798 si = sizeof(qi); 1798 si = sizeof(qi);
1799 break; 1799 break;
1800 } 1800 }
1801 1801
1802 rc = prog_sysctl(name, namelen, o, &so, i, si); 1802 rc = prog_sysctl(name, namelen, o, &so, i, si);
1803 if (rc == -1) { 1803 if (rc == -1) {
1804 sysctlerror(0); 1804 sysctlerror(0);
1805 return; 1805 return;
1806 } 1806 }
1807 1807
1808 switch (SYSCTL_TYPE(node->sysctl_flags)) { 1808 switch (SYSCTL_TYPE(node->sysctl_flags)) {
1809 case CTLTYPE_INT: 1809 case CTLTYPE_INT:
1810 display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD); 1810 display_number(node, gsname, &io, sizeof(io), DISPLAY_OLD);
1811 display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW); 1811 display_number(node, gsname, &ii, sizeof(ii), DISPLAY_NEW);
1812 break; 1812 break;
1813 case CTLTYPE_BOOL: 1813 case CTLTYPE_BOOL:
1814 display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD); 1814 display_number(node, gsname, &bo, sizeof(bo), DISPLAY_OLD);
1815 display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW); 1815 display_number(node, gsname, &bi, sizeof(bi), DISPLAY_NEW);
1816 break; 1816 break;
1817 case CTLTYPE_QUAD: 1817 case CTLTYPE_QUAD:
1818 display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD); 1818 display_number(node, gsname, &qo, sizeof(qo), DISPLAY_OLD);
1819 display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW); 1819 display_number(node, gsname, &qi, sizeof(qi), DISPLAY_NEW);
1820 break; 1820 break;
1821 } 1821 }
1822} 1822}
1823 1823
1824static void 1824static void
1825write_string(int *name, u_int namelen, struct sysctlnode *node, char *value) 1825write_string(int *name, u_int namelen, struct sysctlnode *node, char *value)
1826{ 1826{
1827 char *i, *o; 1827 char *i, *o;
1828 size_t si, so; 1828 size_t si, so;
1829 int rc; 1829 int rc;
1830 1830
1831 i = value; 1831 i = value;
1832 si = strlen(i) + 1; 1832 si = strlen(i) + 1;
1833 so = node->sysctl_size; 1833 so = node->sysctl_size;
1834 if (si > so && so != 0) { 1834 if (si > so && so != 0) {
1835 sysctlperror("%s: string too long\n", value); 1835 sysctlperror("%s: string too long\n", value);
1836 EXIT(1); 1836 EXIT(EXIT_FAILURE);
1837 } 1837 }
1838 o = malloc(so); 1838 o = malloc(so);
1839 if (o == NULL) { 1839 if (o == NULL) {
1840 sysctlperror("%s: !malloc failed!\n", gsname); 1840 sysctlperror("%s: !malloc failed!\n", gsname);
1841 exit(1); 1841 exit(EXIT_FAILURE);
1842 } 1842 }
1843 1843
1844 rc = prog_sysctl(name, namelen, o, &so, i, si); 1844 rc = prog_sysctl(name, namelen, o, &so, i, si);
1845 if (rc == -1) { 1845 if (rc == -1) {
1846 sysctlerror(0); 1846 sysctlerror(0);
1847 return; 1847 return;
1848 } 1848 }
1849 1849
1850 display_string(node, gsname, o, so, DISPLAY_OLD); 1850 display_string(node, gsname, o, so, DISPLAY_OLD);
1851 display_string(node, gsname, i, si, DISPLAY_NEW); 1851 display_string(node, gsname, i, si, DISPLAY_NEW);
1852 free(o); 1852 free(o);
1853} 1853}
1854 1854
1855/* 1855/*
1856 * ******************************************************************** 1856 * ********************************************************************
1857 * simple ways to print stuff consistently 1857 * simple ways to print stuff consistently
1858 * ******************************************************************** 1858 * ********************************************************************
1859 */ 1859 */
1860static void 1860static void
1861display_number(const struct sysctlnode *node, const char *name, 1861display_number(const struct sysctlnode *node, const char *name,
1862 const void *data, size_t sz, int n) 1862 const void *data, size_t sz, int n)
1863{ 1863{
1864 u_quad_t q; 1864 u_quad_t q;
1865 bool b; 1865 bool b;
1866 int i; 1866 int i;
1867 1867
1868 if (qflag) 1868 if (qflag)
1869 return; 1869 return;
1870 if ((nflag || rflag) && (n == DISPLAY_OLD)) 1870 if ((nflag || rflag) && (n == DISPLAY_OLD))
1871 return; 1871 return;
1872 1872
1873 if (rflag && n != DISPLAY_OLD) { 1873 if (rflag && n != DISPLAY_OLD) {
1874 fwrite(data, sz, 1, stdout); 1874 fwrite(data, sz, 1, stdout);
1875 return; 1875 return;
1876 } 1876 }
1877 1877
1878 if (!nflag) { 1878 if (!nflag) {
1879 if (n == DISPLAY_VALUE) 1879 if (n == DISPLAY_VALUE)
1880 printf("%s%s", name, eq); 1880 printf("%s%s", name, eq);
1881 else if (n == DISPLAY_OLD) 1881 else if (n == DISPLAY_OLD)
1882 printf("%s: ", name); 1882 printf("%s: ", name);
1883 } 1883 }
1884 1884
1885 if (xflag > 1) { 1885 if (xflag > 1) {
1886 if (n != DISPLAY_NEW) 1886 if (n != DISPLAY_NEW)
1887 printf("\n"); 1887 printf("\n");
1888 hex_dump(data, sz); 1888 hex_dump(data, sz);
1889 return; 1889 return;
1890 } 1890 }
1891 1891
1892 switch (SYSCTL_TYPE(node->sysctl_flags)) { 1892 switch (SYSCTL_TYPE(node->sysctl_flags)) {
1893 case CTLTYPE_INT: 1893 case CTLTYPE_INT:
1894 memcpy(&i, data, sz); 1894 memcpy(&i, data, sz);
1895 if (xflag) 1895 if (xflag)
1896 printf("0x%0*x", (int)sz * 2, i); 1896 printf("0x%0*x", (int)sz * 2, i);
1897 else if (node->sysctl_flags & CTLFLAG_HEX) 1897 else if (node->sysctl_flags & CTLFLAG_HEX)
1898 printf("%#x", i); 1898 printf("%#x", i);
1899 else if (node->sysctl_flags & CTLFLAG_UNSIGNED) 1899 else if (node->sysctl_flags & CTLFLAG_UNSIGNED)
1900 printf("%u", i); 1900 printf("%u", i);
1901 else 1901 else
1902 printf("%d", i); 1902 printf("%d", i);
1903 break; 1903 break;
1904 case CTLTYPE_BOOL: 1904 case CTLTYPE_BOOL:
1905 memcpy(&b, data, sz); 1905 memcpy(&b, data, sz);
1906 if (xflag) 1906 if (xflag)
1907 printf("0x%0*x", (int)sz * 2, b); 1907 printf("0x%0*x", (int)sz * 2, b);
1908 else if (node->sysctl_flags & CTLFLAG_HEX) 1908 else if (node->sysctl_flags & CTLFLAG_HEX)
1909 printf("%#x", b); 1909 printf("%#x", b);
1910 else 1910 else
1911 printf("%d", b); 1911 printf("%d", b);
1912 break; 1912 break;
1913 case CTLTYPE_QUAD: 1913 case CTLTYPE_QUAD:
1914 memcpy(&q, data, sz); 1914 memcpy(&q, data, sz);
1915 if (xflag) 1915 if (xflag)
1916 printf("0x%0*" PRIx64, (int)sz * 2, q); 1916 printf("0x%0*" PRIx64, (int)sz * 2, q);
1917 else if (node->sysctl_flags & CTLFLAG_HEX) 1917 else if (node->sysctl_flags & CTLFLAG_HEX)
1918 printf("%#" PRIx64, q); 1918 printf("%#" PRIx64, q);
1919 else if (node->sysctl_flags & CTLFLAG_UNSIGNED) 1919 else if (node->sysctl_flags & CTLFLAG_UNSIGNED)
1920 printf("%" PRIu64, q); 1920 printf("%" PRIu64, q);
1921 else 1921 else
1922 printf("%" PRIu64, q); 1922 printf("%" PRIu64, q);
1923 break; 1923 break;
1924 } 1924 }
1925 1925
1926 if (n == DISPLAY_OLD) 1926 if (n == DISPLAY_OLD)
1927 printf(" -> "); 1927 printf(" -> ");
1928 else 1928 else
1929 printf("\n"); 1929 printf("\n");
1930} 1930}
1931 1931
1932static void 1932static void
1933display_string(const struct sysctlnode *node, const char *name, 1933display_string(const struct sysctlnode *node, const char *name,
1934 const void *data, size_t sz, int n) 1934 const void *data, size_t sz, int n)
1935{ 1935{
1936 const unsigned char *buf = data; 1936 const unsigned char *buf = data;
1937 int ni; 1937 int ni;
1938 1938
1939 if (qflag) 1939 if (qflag)
1940 return; 1940 return;
1941 if ((nflag || rflag) && (n == DISPLAY_OLD)) 1941 if ((nflag || rflag) && (n == DISPLAY_OLD))
1942 return; 1942 return;
1943 1943
1944 if (rflag && n != DISPLAY_OLD) { 1944 if (rflag && n != DISPLAY_OLD) {
1945 fwrite(data, sz, 1, stdout); 1945 fwrite(data, sz, 1, stdout);
1946 return; 1946 return;
1947 } 1947 }
1948 1948
1949 if (!nflag) { 1949 if (!nflag) {
1950 if (n == DISPLAY_VALUE) 1950 if (n == DISPLAY_VALUE)
1951 printf("%s%s", name, eq); 1951 printf("%s%s", name, eq);
1952 else if (n == DISPLAY_OLD) 1952 else if (n == DISPLAY_OLD)
1953 printf("%s: ", name); 1953 printf("%s: ", name);
1954 } 1954 }
1955 1955
1956 if (xflag > 1) { 1956 if (xflag > 1) {
1957 if (n != DISPLAY_NEW) 1957 if (n != DISPLAY_NEW)
1958 printf("\n"); 1958 printf("\n");
1959 hex_dump(data, sz); 1959 hex_dump(data, sz);
1960 return; 1960 return;
1961 } 1961 }
1962 1962
1963 if (xflag || node->sysctl_flags & CTLFLAG_HEX) { 1963 if (xflag || node->sysctl_flags & CTLFLAG_HEX) {
1964 for (ni = 0; ni < (int)sz; ni++) { 1964 for (ni = 0; ni < (int)sz; ni++) {
1965 if (xflag) 1965 if (xflag)
1966 printf("%02x", buf[ni]); 1966 printf("%02x", buf[ni]);
1967 if (buf[ni] == '\0') 1967 if (buf[ni] == '\0')
1968 break; 1968 break;
1969 if (!xflag) 1969 if (!xflag)
1970 printf("\\x%2.2x", buf[ni]); 1970 printf("\\x%2.2x", buf[ni]);
1971 } 1971 }
1972 } 1972 }
1973 else 1973 else
1974 printf("%.*s", (int)sz, buf); 1974 printf("%.*s", (int)sz, buf);
1975 1975
1976 if (n == DISPLAY_OLD) 1976 if (n == DISPLAY_OLD)
1977 printf(" -> "); 1977 printf(" -> ");
1978 else 1978 else
1979 printf("\n"); 1979 printf("\n");
1980} 1980}
1981 1981
1982/*ARGSUSED*/ 1982/*ARGSUSED*/
1983static void 1983static void
1984display_struct(const struct sysctlnode *node, const char *name, 1984display_struct(const struct sysctlnode *node, const char *name,
1985 const void *data, size_t sz, int n) 1985 const void *data, size_t sz, int n)
1986{ 1986{
1987 const unsigned char *buf = data; 1987 const unsigned char *buf = data;
1988 int ni; 1988 int ni;
1989 size_t more; 1989 size_t more;
1990 1990
1991 if (qflag) 1991 if (qflag)
1992 return; 1992 return;
1993 if (!(xflag || rflag)) { 1993 if (!(xflag || rflag)) {
1994 if (Aflag || req) 1994 if (Aflag || req)
1995 sysctlperror( 1995 sysctlperror(
1996 "%s: this type is unknown to this program\n", 1996 "%s: this type is unknown to this program\n",
1997 gsname); 1997 gsname);
1998 return; 1998 return;
1999 } 1999 }
2000 if ((nflag || rflag) && (n == DISPLAY_OLD)) 2000 if ((nflag || rflag) && (n == DISPLAY_OLD))
2001 return; 2001 return;
2002 2002
2003 if (rflag && n != DISPLAY_OLD) { 2003 if (rflag && n != DISPLAY_OLD) {
2004 fwrite(data, sz, 1, stdout); 2004 fwrite(data, sz, 1, stdout);
2005 return; 2005 return;
2006 } 2006 }
2007 2007
2008 if (!nflag) { 2008 if (!nflag) {
2009 if (n == DISPLAY_VALUE) 2009 if (n == DISPLAY_VALUE)
2010 printf("%s%s", name, eq); 2010 printf("%s%s", name, eq);
2011 else if (n == DISPLAY_OLD) 2011 else if (n == DISPLAY_OLD)
2012 printf("%s: ", name); 2012 printf("%s: ", name);
2013 } 2013 }
2014 2014
2015 if (xflag > 1) { 2015 if (xflag > 1) {
2016 if (n != DISPLAY_NEW) 2016 if (n != DISPLAY_NEW)
2017 printf("\n"); 2017 printf("\n");
2018 hex_dump(data, sz); 2018 hex_dump(data, sz);
2019 return; 2019 return;
2020 } 2020 }
2021 2021
2022 if (sz > 16) { 2022 if (sz > 16) {
2023 more = sz - 16; 2023 more = sz - 16;
2024 sz = 16; 2024 sz = 16;
2025 } 2025 }
2026 else 2026 else
2027 more = 0; 2027 more = 0;
2028 for (ni = 0; ni < (int)sz; ni++) 2028 for (ni = 0; ni < (int)sz; ni++)
2029 printf("%02x", buf[ni]); 2029 printf("%02x", buf[ni]);
2030 if (more) 2030 if (more)
2031 printf("...(%zu more bytes)", more); 2031 printf("...(%zu more bytes)", more);
2032 printf("\n"); 2032 printf("\n");
2033} 2033}
2034 2034
2035static void 2035static void
2036hex_dump(const unsigned char *buf, size_t len) 2036hex_dump(const unsigned char *buf, size_t len)
2037{ 2037{
2038 unsigned int i; 2038 unsigned int i;
2039 int j; 2039 int j;
2040 char line[80], tmp[12]; 2040 char line[80], tmp[12];
2041 2041
2042 memset(line, ' ', sizeof(line)); 2042 memset(line, ' ', sizeof(line));
2043 for (i = 0, j = 15; i < len; i++) { 2043 for (i = 0, j = 15; i < len; i++) {
2044 j = i % 16; 2044 j = i % 16;
2045 /* reset line */ 2045 /* reset line */
2046 if (j == 0) { 2046 if (j == 0) {
2047 line[58] = '|'; 2047 line[58] = '|';
2048 line[77] = '|'; 2048 line[77] = '|';
2049 line[78] = 0; 2049 line[78] = 0;
2050 snprintf(tmp, sizeof(tmp), "%07x", i); 2050 snprintf(tmp, sizeof(tmp), "%07x", i);
2051 memcpy(&line[0], tmp, 7); 2051 memcpy(&line[0], tmp, 7);
2052 } 2052 }
2053 /* copy out hex version of byte */ 2053 /* copy out hex version of byte */
2054 snprintf(tmp, sizeof(tmp), "%02x", buf[i]); 2054 snprintf(tmp, sizeof(tmp), "%02x", buf[i]);
2055 memcpy(&line[9 + j * 3], tmp, 2); 2055 memcpy(&line[9 + j * 3], tmp, 2);
2056 /* copy out plain version of byte */ 2056 /* copy out plain version of byte */
2057 line[60 + j] = (isprint(buf[i])) ? buf[i] : '.'; 2057 line[60 + j] = (isprint(buf[i])) ? buf[i] : '.';
2058 /* print a full line and erase it */ 2058 /* print a full line and erase it */
2059 if (j == 15) { 2059 if (j == 15) {
2060 printf("%s\n", line); 2060 printf("%s\n", line);
2061 memset(line, ' ', sizeof(line)); 2061 memset(line, ' ', sizeof(line));
2062 } 2062 }
2063 } 2063 }
2064 if (line[0] != ' ') 2064 if (line[0] != ' ')
2065 printf("%s\n", line); 2065 printf("%s\n", line);
2066 printf("%07zu bytes\n", len); 2066 printf("%07zu bytes\n", len);
2067} 2067}
2068 2068
2069/* 2069/*
2070 * ******************************************************************** 2070 * ********************************************************************
2071 * functions that handle particular nodes 2071 * functions that handle particular nodes
2072 * ******************************************************************** 2072 * ********************************************************************
2073 */ 2073 */
2074/*ARGSUSED*/ 2074/*ARGSUSED*/
2075static void 2075static void
2076printother(HANDLER_ARGS) 2076printother(HANDLER_ARGS)
2077{ 2077{
2078 int rc; 2078 int rc;
2079 void *p; 2079 void *p;
2080 size_t sz1, sz2; 2080 size_t sz1, sz2;
2081 2081
2082 if (!(Aflag || req) || Mflag) 2082 if (!(Aflag || req) || Mflag)
2083 return; 2083 return;
2084 2084
2085 /* 2085 /*
2086 * okay...you asked for it, so let's give it a go 2086 * okay...you asked for it, so let's give it a go
2087 */ 2087 */
2088 while (type != CTLTYPE_NODE && (xflag || rflag)) { 2088 while (type != CTLTYPE_NODE && (xflag || rflag)) {
2089 rc = prog_sysctl(name, namelen, NULL, &sz1, NULL, 0); 2089 rc = prog_sysctl(name, namelen, NULL, &sz1, NULL, 0);
2090 if (rc == -1 || sz1 == 0) 2090 if (rc == -1 || sz1 == 0)
2091 break; 2091 break;
2092 p = malloc(sz1); 2092 p = malloc(sz1);
2093 if (p == NULL) 2093 if (p == NULL)
2094 break; 2094 break;
2095 sz2 = sz1; 2095 sz2 = sz1;
2096 rc = prog_sysctl(name, namelen, p, &sz2, NULL, 0); 2096 rc = prog_sysctl(name, namelen, p, &sz2, NULL, 0);
2097 if (rc == -1 || sz1 != sz2) { 2097 if (rc == -1 || sz1 != sz2) {
2098 free(p); 2098 free(p);
2099 break; 2099 break;
2100 } 2100 }
2101 display_struct(pnode, gsname, p, sz1, DISPLAY_VALUE); 2101 display_struct(pnode, gsname, p, sz1, DISPLAY_VALUE);
2102 free(p); 2102 free(p);
2103 return; 2103 return;
2104 } 2104 }
2105 2105
2106 /* 2106 /*
2107 * that didn't work...do we have a specific message for this 2107 * that didn't work...do we have a specific message for this
2108 * thing? 2108 * thing?
2109 */ 2109 */
2110 if (v != NULL) { 2110 if (v != NULL) {
2111 sysctlperror("%s: use '%s' to view this information\n", 2111 sysctlperror("%s: use '%s' to view this information\n",
2112 gsname, (const char *)v); 2112 gsname, (const char *)v);
2113 return; 2113 return;
2114 } 2114 }
2115 2115
2116 /* 2116 /*
2117 * hmm...i wonder if we have any generic hints? 2117 * hmm...i wonder if we have any generic hints?
2118 */ 2118 */
2119 switch (name[0]) { 2119 switch (name[0]) {
2120 case CTL_NET: 2120 case CTL_NET:
2121 sysctlperror("%s: use 'netstat' to view this information\n", 2121 sysctlperror("%s: use 'netstat' to view this information\n",
2122 sname); 2122 sname);
2123 break; 2123 break;
2124 case CTL_DEBUG: 2124 case CTL_DEBUG:
2125 sysctlperror("%s: missing 'options DEBUG' from kernel?\n", 2125 sysctlperror("%s: missing 'options DEBUG' from kernel?\n",
2126 sname); 2126 sname);
2127 break; 2127 break;
2128 case CTL_DDB: 2128 case CTL_DDB:
2129 sysctlperror("%s: missing 'options DDB' from kernel?\n", 2129 sysctlperror("%s: missing 'options DDB' from kernel?\n",
2130 sname); 2130 sname);
2131 break; 2131 break;
2132 case CTL_VENDOR: 2132 case CTL_VENDOR:
2133 sysctlperror("%s: no vendor extensions installed\n", 2133 sysctlperror("%s: no vendor extensions installed\n",
2134 sname); 2134 sname);
2135 break; 2135 break;
2136 } 2136 }
2137} 2137}
2138 2138
2139/*ARGSUSED*/ 2139/*ARGSUSED*/
2140static void 2140static void
2141kern_clockrate(HANDLER_ARGS) 2141kern_clockrate(HANDLER_ARGS)
2142{ 2142{
2143 struct clockinfo clkinfo; 2143 struct clockinfo clkinfo;
2144 size_t sz; 2144 size_t sz;
2145 int rc; 2145 int rc;
2146 2146
2147 sz = sizeof(clkinfo); 2147 sz = sizeof(clkinfo);
2148 rc = prog_sysctl(name, namelen, &clkinfo, &sz, NULL, 0); 2148 rc = prog_sysctl(name, namelen, &clkinfo, &sz, NULL, 0);
2149 if (rc == -1) { 2149 if (rc == -1) {
2150 sysctlerror(1); 2150 sysctlerror(1);
2151 return; 2151 return;
2152 } 2152 }
2153 if (sz != sizeof(clkinfo)) 2153 if (sz != sizeof(clkinfo))
2154 errx(1, "%s: !returned size wrong!", sname); 2154 errx(EXIT_FAILURE, "%s: !returned size wrong!", sname);
2155 2155
2156 if (xflag || rflag) { 2156 if (xflag || rflag) {
2157 display_struct(pnode, sname, &clkinfo, sz, 2157 display_struct(pnode, sname, &clkinfo, sz,
2158 DISPLAY_VALUE); 2158 DISPLAY_VALUE);
2159 return; 2159 return;
2160 } 2160 }
2161 else if (!nflag) 2161 else if (!nflag)
2162 printf("%s: ", sname); 2162 printf("%s: ", sname);
2163 printf("tick = %d, tickadj = %d, hz = %d, profhz = %d, stathz = %d\n", 2163 printf("tick = %d, tickadj = %d, hz = %d, profhz = %d, stathz = %d\n",
2164 clkinfo.tick, clkinfo.tickadj, 2164 clkinfo.tick, clkinfo.tickadj,
2165 clkinfo.hz, clkinfo.profhz, clkinfo.stathz); 2165 clkinfo.hz, clkinfo.profhz, clkinfo.stathz);
2166} 2166}
2167 2167
2168/*ARGSUSED*/ 2168/*ARGSUSED*/
2169static void 2169static void
2170kern_boottime(HANDLER_ARGS) 2170kern_boottime(HANDLER_ARGS)
2171{ 2171{
2172 struct timeval timeval; 2172 struct timeval timeval;
2173 time_t boottime; 2173 time_t boottime;
2174 size_t sz; 2174 size_t sz;
2175 int rc; 2175 int rc;
2176 2176
2177 sz = sizeof(timeval); 2177 sz = sizeof(timeval);
2178 rc = prog_sysctl(name, namelen, &timeval, &sz, NULL, 0); 2178 rc = prog_sysctl(name, namelen, &timeval, &sz, NULL, 0);
2179 if (rc == -1) { 2179 if (rc == -1) {
2180 sysctlerror(1); 2180 sysctlerror(1);
2181 return; 2181 return;
2182 } 2182 }
2183 if (sz != sizeof(timeval)) 2183 if (sz != sizeof(timeval))
2184 errx(1, "%s: !returned size wrong!", sname); 2184 errx(EXIT_FAILURE, "%s: !returned size wrong!", sname);
2185 2185
2186 boottime = timeval.tv_sec; 2186 boottime = timeval.tv_sec;
2187 if (xflag || rflag) 2187 if (xflag || rflag)
2188 display_struct(pnode, sname, &timeval, sz, 2188 display_struct(pnode, sname, &timeval, sz,
2189 DISPLAY_VALUE); 2189 DISPLAY_VALUE);
2190 else if (!nflag) 2190 else if (!nflag)
2191 /* ctime() provides the \n */ 2191 /* ctime() provides the \n */
2192 printf("%s%s%s", sname, eq, ctime(&boottime)); 2192 printf("%s%s%s", sname, eq, ctime(&boottime));
2193 else if (nflag == 1) 2193 else if (nflag == 1)
2194 printf("%ld\n", (long)boottime); 2194 printf("%ld\n", (long)boottime);
2195 else 2195 else
2196 printf("%ld.%06ld\n", (long)timeval.tv_sec, 2196 printf("%ld.%06ld\n", (long)timeval.tv_sec,
2197 (long)timeval.tv_usec); 2197 (long)timeval.tv_usec);
2198} 2198}
2199 2199
2200/*ARGSUSED*/ 2200/*ARGSUSED*/
2201static void 2201static void
2202kern_consdev(HANDLER_ARGS) 2202kern_consdev(HANDLER_ARGS)
2203{ 2203{
2204 dev_t cons; 2204 dev_t cons;
2205 size_t sz; 2205 size_t sz;
2206 int rc; 2206 int rc;
2207 2207
2208 sz = sizeof(cons); 2208 sz = sizeof(cons);
2209 rc = prog_sysctl(name, namelen, &cons, &sz, NULL, 0); 2209 rc = prog_sysctl(name, namelen, &cons, &sz, NULL, 0);
2210 if (rc == -1) { 2210 if (rc == -1) {
2211 sysctlerror(1); 2211 sysctlerror(1);
2212 return; 2212 return;
2213 } 2213 }
2214 if (sz != sizeof(cons)) 2214 if (sz != sizeof(cons))
2215 errx(1, "%s: !returned size wrong!", sname); 2215 errx(EXIT_FAILURE, "%s: !returned size wrong!", sname);
2216 2216
2217 if (xflag || rflag) 2217 if (xflag || rflag)
2218 display_struct(pnode, sname, &cons, sz, 2218 display_struct(pnode, sname, &cons, sz,
2219 DISPLAY_VALUE); 2219 DISPLAY_VALUE);
2220 else { 2220 else {
2221 if (!nflag) 2221 if (!nflag)
2222 printf("%s%s", sname, eq); 2222 printf("%s%s", sname, eq);
2223 if (nflag < 2 && (sname = devname(cons, S_IFCHR)) != NULL) 2223 if (nflag < 2 && (sname = devname(cons, S_IFCHR)) != NULL)
2224 printf("%s\n", sname); 2224 printf("%s\n", sname);
2225 else 2225 else
2226 printf("0x%llx\n", (unsigned long long)cons); 2226 printf("0x%llx\n", (unsigned long long)cons);
2227 } 2227 }
2228} 2228}
2229 2229
2230/*ARGSUSED*/ 2230/*ARGSUSED*/
2231static void 2231static void
2232kern_cp_time(HANDLER_ARGS) 2232kern_cp_time(HANDLER_ARGS)
2233{ 2233{
2234 u_int64_t *cp_time; 2234 u_int64_t *cp_time;
2235 size_t sz, osz; 2235 size_t sz, osz;
2236 int rc, i, n; 2236 int rc, i, n;
2237 char s[sizeof("kern.cp_time.nnnnnn")]; 2237 char s[sizeof("kern.cp_time.nnnnnn")];
2238 const char *tname; 2238 const char *tname;
2239 2239
2240 /* 2240 /*
2241 * three things to do here. 2241 * three things to do here.
2242 * case 1: get sum (no Aflag and namelen == 2) 2242 * case 1: get sum (no Aflag and namelen == 2)
2243 * case 2: get specific processor (namelen == 3) 2243 * case 2: get specific processor (namelen == 3)
2244 * case 3: get all processors (Aflag and namelen == 2) 2244 * case 3: get all processors (Aflag and namelen == 2)
2245 */ 2245 */
2246 2246
2247 if (namelen == 2 && Aflag) { 2247 if (namelen == 2 && Aflag) {
2248 sz = sizeof(n); 2248 sz = sizeof(n);
2249 rc = sysctlbyname("hw.ncpu", &n, &sz, NULL, 0); 2249 rc = sysctlbyname("hw.ncpu", &n, &sz, NULL, 0);
2250 if (rc != 0) 2250 if (rc != 0)
2251 return; /* XXX print an error, eh? */ 2251 return; /* XXX print an error, eh? */
2252 n++; /* Add on space for the sum. */ 2252 n++; /* Add on space for the sum. */
2253 sz = n * sizeof(u_int64_t) * CPUSTATES; 2253 sz = n * sizeof(u_int64_t) * CPUSTATES;
2254 } 2254 }
2255 else { 2255 else {
2256 n = -1; /* Just print one data set. */ 2256 n = -1; /* Just print one data set. */
2257 sz = sizeof(u_int64_t) * CPUSTATES; 2257 sz = sizeof(u_int64_t) * CPUSTATES;
2258 } 2258 }
2259 2259
2260 cp_time = malloc(sz); 2260 cp_time = malloc(sz);
2261 if (cp_time == NULL) { 2261 if (cp_time == NULL) {
2262 sysctlerror(1); 2262 sysctlerror(1);
2263 return; 2263 return;
2264 } 2264 }
2265 2265
2266 osz = sz; 2266 osz = sz;
2267 rc = prog_sysctl(name, namelen, cp_time + (n != -1) * CPUSTATES, &osz, 2267 rc = prog_sysctl(name, namelen, cp_time + (n != -1) * CPUSTATES, &osz,
2268 NULL, 0); 2268 NULL, 0);
2269 2269
2270 if (rc == -1) { 2270 if (rc == -1) {
2271 sysctlerror(1); 2271 sysctlerror(1);
2272 free(cp_time); 2272 free(cp_time);
2273 return; 2273 return;
2274 } 2274 }
2275 2275
2276 /* 2276 /*
2277 * Check, but account for space we'll occupy with the sum. 2277 * Check, but account for space we'll occupy with the sum.
2278 */ 2278 */
2279 if (osz != sz - (n != -1) * CPUSTATES * sizeof(u_int64_t)) 2279 if (osz != sz - (n != -1) * CPUSTATES * sizeof(u_int64_t))
2280 errx(1, "%s: !returned size wrong!", sname); 2280 errx(EXIT_FAILURE, "%s: !returned size wrong!", sname);
2281 2281
2282 /* 2282 /*
2283 * Compute the actual sum. Two calls would be easier (we 2283 * Compute the actual sum. Two calls would be easier (we
2284 * could just call ourselves recursively above), but the 2284 * could just call ourselves recursively above), but the
2285 * numbers wouldn't add up. 2285 * numbers wouldn't add up.
2286 */ 2286 */
2287 if (n != -1) { 2287 if (n != -1) {
2288 memset(cp_time, 0, sizeof(u_int64_t) * CPUSTATES); 2288 memset(cp_time, 0, sizeof(u_int64_t) * CPUSTATES);
2289 for (i = 1; i < n; i++) { 2289 for (i = 1; i < n; i++) {
2290 cp_time[CP_USER] += cp_time[i * CPUSTATES + CP_USER]; 2290 cp_time[CP_USER] += cp_time[i * CPUSTATES + CP_USER];
2291 cp_time[CP_NICE] += cp_time[i * CPUSTATES + CP_NICE]; 2291 cp_time[CP_NICE] += cp_time[i * CPUSTATES + CP_NICE];
2292 cp_time[CP_SYS] += cp_time[i * CPUSTATES + CP_SYS]; 2292 cp_time[CP_SYS] += cp_time[i * CPUSTATES + CP_SYS];
2293 cp_time[CP_INTR] += cp_time[i * CPUSTATES + CP_INTR]; 2293 cp_time[CP_INTR] += cp_time[i * CPUSTATES + CP_INTR];
2294 cp_time[CP_IDLE] += cp_time[i * CPUSTATES + CP_IDLE]; 2294 cp_time[CP_IDLE] += cp_time[i * CPUSTATES + CP_IDLE];
2295 } 2295 }
2296 } 2296 }
2297 2297
2298 tname = sname; 2298 tname = sname;
2299 for (i = 0; n == -1 || i < n; i++) { 2299 for (i = 0; n == -1 || i < n; i++) {
2300 if (i > 0) { 2300 if (i > 0) {
2301 (void)snprintf(s, sizeof(s), "%s%s%d", sname, sep, 2301 (void)snprintf(s, sizeof(s), "%s%s%d", sname, sep,
2302 i - 1); 2302 i - 1);
2303 tname = s; 2303 tname = s;
2304 } 2304 }
2305 if (xflag || rflag) 2305 if (xflag || rflag)
2306 display_struct(pnode, tname, cp_time + (i * CPUSTATES), 2306 display_struct(pnode, tname, cp_time + (i * CPUSTATES),
2307 sizeof(u_int64_t) * CPUSTATES, 2307 sizeof(u_int64_t) * CPUSTATES,
2308 DISPLAY_VALUE); 2308 DISPLAY_VALUE);
2309 else { 2309 else {
2310 if (!nflag) 2310 if (!nflag)
2311 printf("%s: ", tname); 2311 printf("%s: ", tname);
2312 printf("user = %" PRIu64 2312 printf("user = %" PRIu64
2313 ", nice = %" PRIu64 2313 ", nice = %" PRIu64
2314 ", sys = %" PRIu64 2314 ", sys = %" PRIu64
2315 ", intr = %" PRIu64 2315 ", intr = %" PRIu64
2316 ", idle = %" PRIu64 2316 ", idle = %" PRIu64
2317 "\n", 2317 "\n",
2318 cp_time[i * CPUSTATES + CP_USER], 2318 cp_time[i * CPUSTATES + CP_USER],
2319 cp_time[i * CPUSTATES + CP_NICE], 2319 cp_time[i * CPUSTATES + CP_NICE],
2320 cp_time[i * CPUSTATES + CP_SYS], 2320 cp_time[i * CPUSTATES + CP_SYS],
2321 cp_time[i * CPUSTATES + CP_INTR], 2321 cp_time[i * CPUSTATES + CP_INTR],
2322 cp_time[i * CPUSTATES + CP_IDLE]); 2322 cp_time[i * CPUSTATES + CP_IDLE]);
2323 } 2323 }
2324 /* 2324 /*
2325 * Just printing the one node. 2325 * Just printing the one node.
2326 */ 2326 */
2327 if (n == -1) 2327 if (n == -1)
2328 break; 2328 break;
2329 } 2329 }
2330 2330
2331 free(cp_time); 2331 free(cp_time);
2332} 2332}
2333 2333
2334/*ARGSUSED*/ 2334/*ARGSUSED*/
2335static void 2335static void
2336kern_drivers(HANDLER_ARGS) 2336kern_drivers(HANDLER_ARGS)
2337{ 2337{
2338 struct kinfo_drivers *kd; 2338 struct kinfo_drivers *kd;
2339 size_t sz, i; 2339 size_t sz, i;
2340 int rc; 2340 int rc;
2341 const char *comma; 2341 const char *comma;
2342 2342
2343 rc = prog_sysctl(name, namelen, NULL, &sz, NULL, 0); 2343 rc = prog_sysctl(name, namelen, NULL, &sz, NULL, 0);
2344 if (rc == -1) { 2344 if (rc == -1) {
2345 sysctlerror(1); 2345 sysctlerror(1);
2346 return; 2346 return;
2347 } 2347 }
2348 2348
2349 if (sz % sizeof(*kd)) 2349 if (sz % sizeof(*kd))
2350 err(1, "bad size %zu for kern.drivers", sz); 2350 err(EXIT_FAILURE, "bad size %zu for kern.drivers", sz);
2351 2351
2352 kd = malloc(sz); 2352 kd = malloc(sz);
2353 if (kd == NULL) { 2353 if (kd == NULL) {
2354 sysctlerror(1); 2354 sysctlerror(1);
2355 return; 2355 return;
2356 } 2356 }
2357 2357
2358 rc = prog_sysctl(name, namelen, kd, &sz, NULL, 0); 2358 rc = prog_sysctl(name, namelen, kd, &sz, NULL, 0);
2359 if (rc == -1) { 2359 if (rc == -1) {
2360 sysctlerror(1); 2360 sysctlerror(1);
2361 free(kd); 2361 free(kd);
2362 return; 2362 return;
2363 } 2363 }
2364 2364
2365 comma = ""; 2365 comma = "";
2366 if (!nflag) 2366 if (!nflag)
2367 printf("%s%s", sname, eq); 2367 printf("%s%s", sname, eq);
2368 for (i = 0, sz /= sizeof(*kd); i < sz; i++) { 2368 for (i = 0, sz /= sizeof(*kd); i < sz; i++) {
2369 (void)printf("%s[%d %d %s]", comma, kd[i].d_cmajor, 2369 (void)printf("%s[%d %d %s]", comma, kd[i].d_cmajor,
2370 kd[i].d_bmajor, kd[i].d_name); 2370 kd[i].d_bmajor, kd[i].d_name);
2371 comma = ", "; 2371 comma = ", ";
2372 } 2372 }
2373 (void)printf("\n"); 2373 (void)printf("\n");
2374 free(kd); 2374 free(kd);
2375} 2375}
2376 2376
2377/*ARGSUSED*/ 2377/*ARGSUSED*/
2378static void 2378static void
2379kern_cp_id(HANDLER_ARGS) 2379kern_cp_id(HANDLER_ARGS)
2380{ 2380{
2381 u_int64_t *cp_id; 2381 u_int64_t *cp_id;
2382 size_t sz, osz; 2382 size_t sz, osz;
2383 int rc, i, n; 2383 int rc, i, n;
2384 char s[sizeof("kern.cp_id.nnnnnn")]; 2384 char s[sizeof("kern.cp_id.nnnnnn")];
2385 const char *tname; 2385 const char *tname;
2386 struct sysctlnode node = *pnode; 2386 struct sysctlnode node = *pnode;
2387 2387
2388 /* 2388 /*
2389 * three things to do here. 2389 * three things to do here.
2390 * case 1: print a specific cpu id (namelen == 3) 2390 * case 1: print a specific cpu id (namelen == 3)
2391 * case 2: print all cpu ids separately (Aflag set) 2391 * case 2: print all cpu ids separately (Aflag set)
2392 * case 3: print all cpu ids on one line 2392 * case 3: print all cpu ids on one line
2393 */ 2393 */
2394 2394
2395 if (namelen == 2) { 2395 if (namelen == 2) {
2396 sz = sizeof(n); 2396 sz = sizeof(n);
2397 rc = sysctlbyname("hw.ncpu", &n, &sz, NULL, 0); 2397 rc = sysctlbyname("hw.ncpu", &n, &sz, NULL, 0);
2398 if (rc != 0) 2398 if (rc != 0)
2399 return; /* XXX print an error, eh? */ 2399 return; /* XXX print an error, eh? */
2400 sz = n * sizeof(u_int64_t); 2400 sz = n * sizeof(u_int64_t);
2401 } 2401 }
2402 else { 2402 else {
2403 n = -1; /* Just print one cpu id. */ 2403 n = -1; /* Just print one cpu id. */
2404 sz = sizeof(u_int64_t); 2404 sz = sizeof(u_int64_t);
2405 } 2405 }
2406 2406
2407 cp_id = malloc(sz); 2407 cp_id = malloc(sz);
2408 if (cp_id == NULL) { 2408 if (cp_id == NULL) {
2409 sysctlerror(1); 2409 sysctlerror(1);
2410 return; 2410 return;
2411 } 2411 }
2412 2412
2413 osz = sz; 2413 osz = sz;
2414 rc = prog_sysctl(name, namelen, cp_id, &osz, NULL, 0); 2414 rc = prog_sysctl(name, namelen, cp_id, &osz, NULL, 0);
2415 if (rc == -1) { 2415 if (rc == -1) {
2416 sysctlerror(1); 2416 sysctlerror(1);
2417 free(cp_id); 2417 free(cp_id);
2418 return; 2418 return;
2419 } 2419 }
2420 2420
2421 /* 2421 /*
2422 * Check that we got back what we asked for. 2422 * Check that we got back what we asked for.
2423 */ 2423 */
2424 if (osz != sz) 2424 if (osz != sz)
2425 errx(1, "%s: !returned size wrong!", sname); 2425 errx(EXIT_FAILURE, "%s: !returned size wrong!", sname);
2426 2426
2427 /* pretend for output purposes */ 2427 /* pretend for output purposes */
2428 node.sysctl_flags = SYSCTL_FLAGS(pnode->sysctl_flags) | 2428 node.sysctl_flags = SYSCTL_FLAGS(pnode->sysctl_flags) |
2429 SYSCTL_TYPE(CTLTYPE_QUAD); 2429 SYSCTL_TYPE(CTLTYPE_QUAD);
2430 2430
2431 tname = sname; 2431 tname = sname;
2432 if (namelen == 3) 2432 if (namelen == 3)
2433 display_number(&node, tname, cp_id, 2433 display_number(&node, tname, cp_id,
2434 sizeof(u_int64_t), 2434 sizeof(u_int64_t),
2435 DISPLAY_VALUE); 2435 DISPLAY_VALUE);
2436 else if (Aflag) { 2436 else if (Aflag) {
2437 for (i = 0; i < n; i++) 2437 for (i = 0; i < n; i++)
2438 (void)snprintf(s, sizeof(s), "%s%s%d", sname, sep, i); 2438 (void)snprintf(s, sizeof(s), "%s%s%d", sname, sep, i);
2439 tname = s; 2439 tname = s;
2440 display_number(&node, tname, &cp_id[i], 2440 display_number(&node, tname, &cp_id[i],
2441 sizeof(u_int64_t), 2441 sizeof(u_int64_t),
2442 DISPLAY_VALUE); 2442 DISPLAY_VALUE);
2443 } 2443 }
2444 else { 2444 else {
2445 if (xflag || rflag) 2445 if (xflag || rflag)
2446 display_struct(pnode, tname, cp_id, sz, DISPLAY_VALUE); 2446 display_struct(pnode, tname, cp_id, sz, DISPLAY_VALUE);
2447 else { 2447 else {
2448 if (!nflag) 2448 if (!nflag)
2449 printf("%s: ", tname); 2449 printf("%s: ", tname);
2450 for (i = 0; i < n; i++) { 2450 for (i = 0; i < n; i++) {
2451 if (i) 2451 if (i)
2452 printf(", "); 2452 printf(", ");
2453 printf("%d = %" PRIu64, i, cp_id[i]); 2453 printf("%d = %" PRIu64, i, cp_id[i]);
2454 } 2454 }
2455 printf("\n"); 2455 printf("\n");
2456 } 2456 }
2457 } 2457 }
2458 2458
2459 free(cp_id); 2459 free(cp_id);
2460} 2460}
2461 2461
2462/*ARGSUSED*/ 2462/*ARGSUSED*/
2463static void 2463static void
2464vm_loadavg(HANDLER_ARGS) 2464vm_loadavg(HANDLER_ARGS)
2465{ 2465{
2466 struct loadavg loadavg; 2466 struct loadavg loadavg;
2467 size_t sz; 2467 size_t sz;
2468 int rc; 2468 int rc;
2469 2469
2470 sz = sizeof(loadavg); 2470 sz = sizeof(loadavg);
2471 rc = prog_sysctl(name, namelen, &loadavg, &sz, NULL, 0); 2471 rc = prog_sysctl(name, namelen, &loadavg, &sz, NULL, 0);
2472 if (rc == -1) { 2472 if (rc == -1) {
2473 sysctlerror(1); 2473 sysctlerror(1);
2474 return; 2474 return;
2475 } 2475 }
2476 if (sz != sizeof(loadavg)) 2476 if (sz != sizeof(loadavg))
2477 errx(1, "%s: !returned size wrong!", sname); 2477 errx(EXIT_FAILURE, "%s: !returned size wrong!", sname);
2478 2478
2479 if (xflag || rflag) { 2479 if (xflag || rflag) {
2480 display_struct(pnode, sname, &loadavg, sz, 2480 display_struct(pnode, sname, &loadavg, sz,
2481 DISPLAY_VALUE); 2481 DISPLAY_VALUE);
2482 return; 2482 return;
2483 } 2483 }
2484 if (!nflag) 2484 if (!nflag)
2485 printf("%s: ", sname); 2485 printf("%s: ", sname);
2486 printf("%.2f %.2f %.2f\n", 2486 printf("%.2f %.2f %.2f\n",
2487 (double) loadavg.ldavg[0] / loadavg.fscale, 2487 (double) loadavg.ldavg[0] / loadavg.fscale,
2488 (double) loadavg.ldavg[1] / loadavg.fscale, 2488 (double) loadavg.ldavg[1] / loadavg.fscale,
2489 (double) loadavg.ldavg[2] / loadavg.fscale); 2489 (double) loadavg.ldavg[2] / loadavg.fscale);
2490} 2490}
2491 2491
2492/*ARGSUSED*/ 2492/*ARGSUSED*/
2493static void 2493static void
2494proc_limit(HANDLER_ARGS) 2494proc_limit(HANDLER_ARGS)
2495{ 2495{
2496 u_quad_t olim, *newp, nlim; 2496 u_quad_t olim, *newp, nlim;
2497 size_t osz, nsz; 2497 size_t osz, nsz;
2498 char *t; 2498 char *t;
2499 int rc; 2499 int rc;
2500 2500
2501 if (fn) 2501 if (fn)
2502 trim_whitespace(value, 3); 2502 trim_whitespace(value, 3);
2503 2503
2504 osz = sizeof(olim); 2504 osz = sizeof(olim);
2505 if (value != NULL) { 2505 if (value != NULL) {
2506 nsz = sizeof(nlim); 2506 nsz = sizeof(nlim);
2507 newp = &nlim; 2507 newp = &nlim;
2508 if (strcmp(value, "unlimited") == 0) 2508 if (strcmp(value, "unlimited") == 0)
2509 nlim = RLIM_INFINITY; 2509 nlim = RLIM_INFINITY;
2510 else { 2510 else {
2511 errno = 0; 2511 errno = 0;
2512 nlim = strtouq(value, &t, 0); 2512 nlim = strtouq(value, &t, 0);
2513 if (t == value || *t != '\0' || errno != 0) { 2513 if (t == value || *t != '\0' || errno != 0) {
2514 sysctlperror("%s: '%s' is not a valid limit\n", 2514 sysctlperror("%s: '%s' is not a valid limit\n",
2515 sname, value); 2515 sname, value);
2516 EXIT(1); 2516 EXIT(EXIT_FAILURE);
2517 } 2517 }
2518 } 2518 }
2519 } 2519 }
2520 else { 2520 else {
2521 nsz = 0; 2521 nsz = 0;
2522 newp = NULL; 2522 newp = NULL;
2523 } 2523 }
2524 2524
2525 rc = prog_sysctl(name, namelen, &olim, &osz, newp, nsz); 2525 rc = prog_sysctl(name, namelen, &olim, &osz, newp, nsz);
2526 if (rc == -1) { 2526 if (rc == -1) {
2527 sysctlerror(newp == NULL); 2527 sysctlerror(newp == NULL);
2528 return; 2528 return;
2529 } 2529 }
2530 2530
2531 if (newp && qflag) 2531 if (newp && qflag)
2532 return; 2532 return;
2533 2533
2534 if (rflag || xflag || olim != RLIM_INFINITY) 2534 if (rflag || xflag || olim != RLIM_INFINITY)
2535 display_number(pnode, sname, &olim, sizeof(olim), 2535 display_number(pnode, sname, &olim, sizeof(olim),
2536 newp ? DISPLAY_OLD : DISPLAY_VALUE); 2536 newp ? DISPLAY_OLD : DISPLAY_VALUE);
2537 else 2537 else
2538 display_string(pnode, sname, "unlimited", 10, 2538 display_string(pnode, sname, "unlimited", 10,
2539 newp ? DISPLAY_OLD : DISPLAY_VALUE); 2539 newp ? DISPLAY_OLD : DISPLAY_VALUE);
2540 2540
2541 if (newp) { 2541 if (newp) {
2542 if (rflag || xflag || nlim != RLIM_INFINITY) 2542 if (rflag || xflag || nlim != RLIM_INFINITY)
2543 display_number(pnode, sname, &nlim, sizeof(nlim), 2543 display_number(pnode, sname, &nlim, sizeof(nlim),
2544 DISPLAY_NEW); 2544 DISPLAY_NEW);
2545 else 2545 else
2546 display_string(pnode, sname, "unlimited", 10, 2546 display_string(pnode, sname, "unlimited", 10,
2547 DISPLAY_NEW); 2547 DISPLAY_NEW);
2548 } 2548 }
2549} 2549}
2550 2550
2551#ifdef CPU_DISKINFO 2551#ifdef CPU_DISKINFO
2552/*ARGSUSED*/ 2552/*ARGSUSED*/
2553static void 2553static void
2554machdep_diskinfo(HANDLER_ARGS) 2554machdep_diskinfo(HANDLER_ARGS)
2555{ 2555{
2556 struct disklist *dl; 2556 struct disklist *dl;
2557 struct biosdisk_info *bi; 2557 struct biosdisk_info *bi;
2558 struct nativedisk_info *ni; 2558 struct nativedisk_info *ni;
2559 int rc; 2559 int rc;
2560 size_t sz; 2560 size_t sz;
2561 uint i, b, lim; 2561 uint i, b, lim;
2562 2562
2563 rc = prog_sysctl(name, namelen, NULL, &sz, NULL, 0); 2563 rc = prog_sysctl(name, namelen, NULL, &sz, NULL, 0);
2564 if (rc == -1) { 2564 if (rc == -1) {
2565 sysctlerror(1); 2565 sysctlerror(1);
2566 return; 2566 return;
2567 } 2567 }
2568 dl = malloc(sz); 2568 dl = malloc(sz);
2569 if (dl == NULL) { 2569 if (dl == NULL) {
2570 sysctlerror(1); 2570 sysctlerror(1);
2571 return; 2571 return;
2572 } 2572 }
2573 rc = prog_sysctl(name, namelen, dl, &sz, NULL, 0); 2573 rc = prog_sysctl(name, namelen, dl, &sz, NULL, 0);
2574 if (rc == -1) { 2574 if (rc == -1) {
2575 sysctlerror(1); 2575 sysctlerror(1);
2576 return; 2576 return;
2577 } 2577 }
2578 2578
2579 if (!nflag) 2579 if (!nflag)
2580 printf("%s: ", sname); 2580 printf("%s: ", sname);
2581 lim = dl->dl_nbiosdisks; 2581 lim = dl->dl_nbiosdisks;
2582 if (lim > MAX_BIOSDISKS) 2582 if (lim > MAX_BIOSDISKS)
2583 lim = MAX_BIOSDISKS; 2583 lim = MAX_BIOSDISKS;
2584 for (bi = dl->dl_biosdisks, i = 0; i < lim; bi++, i++) 2584 for (bi = dl->dl_biosdisks, i = 0; i < lim; bi++, i++)
2585 printf("%x:%" PRIu64 "(%d/%d/%d),%x ", 2585 printf("%x:%" PRIu64 "(%d/%d/%d),%x ",
2586 bi->bi_dev, bi->bi_lbasecs, 2586 bi->bi_dev, bi->bi_lbasecs,
2587 bi->bi_cyl, bi->bi_head, bi->bi_sec, 2587 bi->bi_cyl, bi->bi_head, bi->bi_sec,
2588 bi->bi_flags); 2588 bi->bi_flags);
2589 lim = dl->dl_nnativedisks; 2589 lim = dl->dl_nnativedisks;
2590 ni = dl->dl_nativedisks; 2590 ni = dl->dl_nativedisks;
2591 bi = dl->dl_biosdisks; 2591 bi = dl->dl_biosdisks;
2592 /* LINTED -- pointer casts are tedious */ 2592 /* LINTED -- pointer casts are tedious */
2593 if ((char *)&ni[lim] != (char *)dl + sz) { 2593 if ((char *)&ni[lim] != (char *)dl + sz) {
2594 sysctlperror("%s: size mismatch\n", gsname); 2594 sysctlperror("%s: size mismatch\n", gsname);
2595 return; 2595 return;
2596 } 2596 }
2597 for (i = 0; i < lim; ni++, i++) { 2597 for (i = 0; i < lim; ni++, i++) {
2598 char t = ':'; 2598 char t = ':';
2599 printf(" %.*s", (int)sizeof ni->ni_devname, 2599 printf(" %.*s", (int)sizeof ni->ni_devname,
2600 ni->ni_devname); 2600 ni->ni_devname);
2601 for (b = 0; b < (unsigned int)ni->ni_nmatches; t = ',', b++) 2601 for (b = 0; b < (unsigned int)ni->ni_nmatches; t = ',', b++)
2602 printf("%c%x", t, 2602 printf("%c%x", t,
2603 bi[ni->ni_biosmatches[b]].bi_dev); 2603 bi[ni->ni_biosmatches[b]].bi_dev);
2604 } 2604 }
2605 printf("\n"); 2605 printf("\n");
2606 free(dl); 2606 free(dl);
2607} 2607}
2608#endif /* CPU_DISKINFO */ 2608#endif /* CPU_DISKINFO */
2609 2609
2610/*ARGSUSED*/ 2610/*ARGSUSED*/
2611static void 2611static void
2612mode_bits(HANDLER_ARGS) 2612mode_bits(HANDLER_ARGS)
2613{ 2613{
2614 char buf[12], outbuf[100]; 2614 char buf[12], outbuf[100];
2615 int o, m, *newp, rc; 2615 int o, m, *newp, rc;
2616 size_t osz, nsz; 2616 size_t osz, nsz;
2617 mode_t om, mm; 2617 mode_t om, mm;
2618 2618
2619 if (fn) 2619 if (fn)
2620 trim_whitespace(value, 3); 2620 trim_whitespace(value, 3);
2621 2621
2622 newp = NULL; 2622 newp = NULL;
2623 osz = sizeof(o); 2623 osz = sizeof(o);
2624 if (value != NULL) { 2624 if (value != NULL) {
2625 void *foo; 2625 void *foo;
2626 int tt; 2626 int tt;
2627 size_t ttsz = sizeof(tt); 2627 size_t ttsz = sizeof(tt);
2628 mode_t old_umask; 2628 mode_t old_umask;
2629 2629
2630 nsz = sizeof(m); 2630 nsz = sizeof(m);
2631 newp = &m; 2631 newp = &m;
2632 errno = 0; 2632 errno = 0;
2633 rc = prog_sysctl(name, namelen, &tt, &ttsz, NULL, 0); 2633 rc = prog_sysctl(name, namelen, &tt, &ttsz, NULL, 0);
2634 if (rc == -1) { 2634 if (rc == -1) {
2635 sysctlperror("%s: failed query\n", sname); 2635 sysctlperror("%s: failed query\n", sname);
2636 return; 2636 return;
2637 } 2637 }
2638 2638
2639 old_umask = umask(0); 2639 old_umask = umask(0);
2640 foo = setmode(value); 2640 foo = setmode(value);
2641 umask(old_umask); 2641 umask(old_umask);
2642 if (foo == NULL) { 2642 if (foo == NULL) {
2643 sysctlperror("%s: '%s' is an invalid mode\n", sname, 2643 sysctlperror("%s: '%s' is an invalid mode\n", sname,
2644 value); 2644 value);
2645 EXIT(1); 2645 EXIT(EXIT_FAILURE);
2646 } 2646 }
2647 old_umask = umask(0); 2647 old_umask = umask(0);
2648 m = getmode(foo, (mode_t)tt); 2648 m = getmode(foo, (mode_t)tt);
2649 umask(old_umask); 2649 umask(old_umask);
2650 if (errno) { 2650 if (errno) {
2651 sysctlperror("%s: '%s' is an invalid mode\n", sname, 2651 sysctlperror("%s: '%s' is an invalid mode\n", sname,
2652 value); 2652 value);
2653 EXIT(1); 2653 EXIT(EXIT_FAILURE);
2654 } 2654 }
2655 } 2655 }
2656 else { 2656 else {
2657 nsz = 0; 2657 nsz = 0;
2658 newp = NULL; 2658 newp = NULL;
2659 } 2659 }
2660 2660
2661 rc = prog_sysctl(name, namelen, &o, &osz, newp, nsz); 2661 rc = prog_sysctl(name, namelen, &o, &osz, newp, nsz);
2662 if (rc == -1) { 2662 if (rc == -1) {
2663 sysctlerror(newp == NULL); 2663 sysctlerror(newp == NULL);
2664 return; 2664 return;
2665 } 2665 }
2666 2666
2667 if (newp && qflag) 2667 if (newp && qflag)
2668 return; 2668 return;
2669 2669
2670 om = (mode_t)o; 2670 om = (mode_t)o;
2671 mm = (mode_t)m; 2671 mm = (mode_t)m;
2672 2672
2673 if (rflag || xflag) 2673 if (rflag || xflag)
2674 display_number(pnode, sname, &o, sizeof(o), 2674 display_number(pnode, sname, &o, sizeof(o),
2675 newp ? DISPLAY_OLD : DISPLAY_VALUE); 2675 newp ? DISPLAY_OLD : DISPLAY_VALUE);
2676 else { 2676 else {
2677 memset(buf, 0, sizeof(buf)); 2677 memset(buf, 0, sizeof(buf));
2678 strmode(om, buf); 2678 strmode(om, buf);
2679 rc = snprintf(outbuf, sizeof(outbuf), "%04o (%s)", om, buf + 1); 2679 rc = snprintf(outbuf, sizeof(outbuf), "%04o (%s)", om, buf + 1);
2680 display_string(pnode, sname, outbuf, rc, newp ? DISPLAY_OLD : DISPLAY_VALUE); 2680 display_string(pnode, sname, outbuf, rc, newp ? DISPLAY_OLD : DISPLAY_VALUE);
2681 } 2681 }
2682 2682
2683 if (newp) { 2683 if (newp) {
2684 if (rflag || xflag) 2684 if (rflag || xflag)
2685 display_number(pnode, sname, &m, sizeof(m), 2685 display_number(pnode, sname, &m, sizeof(m),
2686 DISPLAY_NEW); 2686 DISPLAY_NEW);
2687 else { 2687 else {
2688 memset(buf, 0, sizeof(buf)); 2688 memset(buf, 0, sizeof(buf));
2689 strmode(mm, buf); 2689 strmode(mm, buf);
2690 rc = snprintf(outbuf, sizeof(outbuf), "%04o (%s)", mm, buf + 1); 2690 rc = snprintf(outbuf, sizeof(outbuf), "%04o (%s)", mm, buf + 1);
2691 display_string(pnode, sname, outbuf, rc, DISPLAY_NEW); 2691 display_string(pnode, sname, outbuf, rc, DISPLAY_NEW);
2692 } 2692 }
2693 } 2693 }
2694} 2694}
2695 2695
2696typedef __BITMAP_TYPE(, uint32_t, 0x10000) bitmap; 2696typedef __BITMAP_TYPE(, uint32_t, 0x10000) bitmap;
2697 2697
2698static char * 2698static char *
2699bitmask_print(const bitmap *o) 2699bitmask_print(const bitmap *o)
2700{ 2700{
2701 char *s, *os; 2701 char *s, *os;
2702 2702
2703 s = os = NULL; 2703 s = os = NULL;
2704 for (size_t i = 0; i < MAXPORTS; i++) 2704 for (size_t i = 0; i < MAXPORTS; i++)
2705 if (__BITMAP_ISSET(i, o)) { 2705 if (__BITMAP_ISSET(i, o)) {
2706 int rv; 2706 int rv;
2707 2707
2708 if (os) 2708 if (os)
2709 rv = asprintf(&s, "%s,%zu", os, i); 2709 rv = asprintf(&s, "%s,%zu", os, i);
2710 else 2710 else
2711 rv = asprintf(&s, "%zu", i); 2711 rv = asprintf(&s, "%zu", i);
2712 if (rv == -1) 2712 if (rv == -1)
2713 err(1, "bitmask_print 1"); 2713 err(EXIT_FAILURE, "%s 1", __func__);
2714 free(os); 2714 free(os);
2715 os = s; 2715 os = s;
2716 } 2716 }
2717 if (s == NULL && (s = strdup("")) == NULL) 2717 if (s == NULL && (s = strdup("")) == NULL)
2718 err(1, "bitmask_print 2"); 2718 err(EXIT_FAILURE, "%s 2", __func__);
2719 return s; 2719 return s;
2720} 2720}
2721 2721
2722static void 2722static void
2723bitmask_scan(const void *v, bitmap *o) 2723bitmask_scan(const void *v, bitmap *o)
2724{ 2724{
2725 char *s = strdup(v); 2725 char *s = strdup(v);
2726 if (s == NULL) 2726 if (s == NULL)
2727 err(1, "bitmask_scan"); 2727 err(EXIT_FAILURE, "%s", __func__);
2728 2728
2729 __BITMAP_ZERO(o); 2729 __BITMAP_ZERO(o);
2730 for (s = strtok(s, ","); s; s = strtok(NULL, ",")) { 2730 for (s = strtok(s, ","); s; s = strtok(NULL, ",")) {
2731 char *e; 2731 char *e;
2732 errno = 0; 2732 errno = 0;
2733 unsigned long l = strtoul(s, &e, 0); 2733 unsigned long l = strtoul(s, &e, 0);
2734 if ((l == ULONG_MAX && errno == ERANGE) || s == e || *e) 2734 if ((l == ULONG_MAX && errno == ERANGE) || s == e || *e)
2735 errx(1, "Invalid port: %s", s); 2735 errx(EXIT_FAILURE, "Invalid port: %s", s);
2736 if (l >= MAXPORTS) 2736 if (l >= MAXPORTS)
2737 errx(1, "Port out of range: %s", s); 2737 errx(EXIT_FAILURE, "Port out of range: %s", s);
2738 __BITMAP_SET(l, o); 2738 __BITMAP_SET(l, o);
2739 } 2739 }
2740} 2740}
2741 2741
2742 2742
2743static void 2743static void
2744reserve(HANDLER_ARGS) 2744reserve(HANDLER_ARGS)
2745{ 2745{
2746 int rc; 2746 int rc;
2747 size_t osz, nsz; 2747 size_t osz, nsz;
2748 bitmap o, n; 2748 bitmap o, n;
2749 2749
2750 if (fn) 2750 if (fn)
2751 trim_whitespace(value, 3); 2751 trim_whitespace(value, 3);
2752 2752
2753 osz = sizeof(o); 2753 osz = sizeof(o);
2754 if (value) { 2754 if (value) {
2755 bitmask_scan(value, &n); 2755 bitmask_scan(value, &n);
2756 value = (char *)&n; 2756 value = (char *)&n;
2757 nsz = sizeof(n); 2757 nsz = sizeof(n);
2758 } else 2758 } else
2759 nsz = 0; 2759 nsz = 0;
2760 2760
2761 rc = prog_sysctl(name, namelen, &o, &osz, value, nsz); 2761 rc = prog_sysctl(name, namelen, &o, &osz, value, nsz);
2762 if (rc == -1) { 2762 if (rc == -1) {
2763 sysctlerror(value == NULL); 2763 sysctlerror(value == NULL);
2764 return; 2764 return;
2765 } 2765 }
2766 2766
2767 if (value && qflag) 2767 if (value && qflag)
2768 return; 2768 return;
2769 2769
2770 if (rflag || xflag) 2770 if (rflag || xflag)
2771 display_struct(pnode, sname, &o, sizeof(o), 2771 display_struct(pnode, sname, &o, sizeof(o),
2772 value ? DISPLAY_OLD : DISPLAY_VALUE); 2772 value ? DISPLAY_OLD : DISPLAY_VALUE);
2773 else { 2773 else {
2774 char *s = bitmask_print(&o); 2774 char *s = bitmask_print(&o);
2775 display_string(pnode, sname, s, strlen(s), 2775 display_string(pnode, sname, s, strlen(s),
2776 value ? DISPLAY_OLD : DISPLAY_VALUE); 2776 value ? DISPLAY_OLD : DISPLAY_VALUE);
2777 free(s); 2777 free(s);
2778 } 2778 }
2779 2779
2780 if (value) { 2780 if (value) {
2781 if (rflag || xflag) 2781 if (rflag || xflag)
2782 display_struct(pnode, sname, &n, sizeof(n), 2782 display_struct(pnode, sname, &n, sizeof(n),
2783 DISPLAY_NEW); 2783 DISPLAY_NEW);
2784 else { 2784 else {
2785 char *s = bitmask_print(&n); 2785 char *s = bitmask_print(&n);
2786 display_string(pnode, sname, s, strlen(s), DISPLAY_NEW); 2786 display_string(pnode, sname, s, strlen(s), DISPLAY_NEW);
2787 free(s); 2787 free(s);
2788 } 2788 }
2789 } 2789 }
2790} 2790}