Deleted Added
full compact
sysctl.c (77332) sysctl.c (77567)
1/*
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char copyright[] =
36"@(#) Copyright (c) 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93";
43#endif
44static const char rcsid[] =
1/*
2 * Copyright (c) 1993
3 * The Regents of the University of California. All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 * 3. All advertising materials mentioning features or use of this software
14 * must display the following acknowledgement:
15 * This product includes software developed by the University of
16 * California, Berkeley and its contributors.
17 * 4. Neither the name of the University nor the names of its contributors
18 * may be used to endorse or promote products derived from this software
19 * without specific prior written permission.
20 *
21 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
22 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 */
33
34#ifndef lint
35static const char copyright[] =
36"@(#) Copyright (c) 1993\n\
37 The Regents of the University of California. All rights reserved.\n";
38#endif /* not lint */
39
40#ifndef lint
41#if 0
42static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93";
43#endif
44static const char rcsid[] =
45 "$FreeBSD: head/sbin/sysctl/sysctl.c 77332 2001-05-28 12:35:40Z des $";
45 "$FreeBSD: head/sbin/sysctl/sysctl.c 77567 2001-06-01 02:58:09Z dd $";
46#endif /* not lint */
47
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <sys/sysctl.h>
51#include <sys/resource.h>
52
53#include <ctype.h>
54#include <err.h>
55#include <errno.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59#include <unistd.h>
60
61static int aflag, bflag, Nflag, nflag, oflag, xflag;
62
63static int oidfmt(int *, int, char *, u_int *);
64static void parse(char *);
65static int show_var(int *, int);
66static int sysctl_all (int *oid, int len);
67static int name2oid(char *, int *);
68
69static void
70usage(void)
71{
72
73 (void)fprintf(stderr, "%s\n%s\n",
74 "usage: sysctl [-bNnox] variable[=value] ...",
75 " sysctl [-bNnox] -a");
76 exit(1);
77}
78
79int
80main(int argc, char **argv)
81{
82 int ch;
83 setbuf(stdout,0);
84 setbuf(stderr,0);
85
86 while ((ch = getopt(argc, argv, "AabNnowxX")) != -1) {
87 switch (ch) {
88 case 'A':
89 /* compatibility */
90 aflag = oflag = 1;
91 break;
92 case 'a':
93 aflag = 1;
94 break;
95 case 'b':
96 bflag = 1;
97 break;
98 case 'N':
99 Nflag = 1;
100 break;
101 case 'n':
102 nflag = 1;
103 break;
104 case 'o':
105 oflag = 1;
106 break;
107 case 'w':
108 /* compatibility */
109 /* ignored */
110 break;
111 case 'X':
112 /* compatibility */
113 aflag = xflag = 1;
114 break;
115 case 'x':
116 xflag = 1;
117 break;
118 default:
119 usage();
120 }
121 }
122 argc -= optind;
123 argv += optind;
124
125 if (Nflag && nflag)
126 usage();
127 if (aflag && argc == 0)
128 exit(sysctl_all(0, 0));
129 if (argc == 0)
130 usage();
131 while (argc-- > 0)
132 parse(*argv++);
133 exit(0);
134}
135
136/*
137 * Parse a name into a MIB entry.
138 * Lookup and print out the MIB entry if it exists.
139 * Set a new value if requested.
140 */
141static void
142parse(char *string)
143{
144 int len, i, j;
145 void *newval = 0;
146 int intval, newsize = 0;
147 quad_t quadval;
148 int mib[CTL_MAXNAME];
149 char *cp, *bufp, buf[BUFSIZ];
150 u_int kind;
151
152 bufp = buf;
153 snprintf(buf, BUFSIZ, "%s", string);
154 if ((cp = strchr(string, '=')) != NULL) {
155 *strchr(buf, '=') = '\0';
156 *cp++ = '\0';
157 while (isspace(*cp))
158 cp++;
159 newval = cp;
160 newsize = strlen(cp);
161 }
162 len = name2oid(bufp, mib);
163
164 if (len < 0)
165 errx(1, "unknown oid '%s'", bufp);
166
167 if (oidfmt(mib, len, 0, &kind))
168 err(1, "couldn't find format of oid '%s'", bufp);
169
170 if (newval == NULL) {
171 if ((kind & CTLTYPE) == CTLTYPE_NODE) {
172 sysctl_all(mib, len);
173 } else {
174 i = show_var(mib, len);
175 if (!i && !bflag)
176 putchar('\n');
177 }
178 } else {
179 if ((kind & CTLTYPE) == CTLTYPE_NODE)
180 errx(1, "oid '%s' isn't a leaf node", bufp);
181
182 if (!(kind&CTLFLAG_WR))
183 errx(1, "oid '%s' is read only", bufp);
184
185 switch (kind & CTLTYPE) {
186 case CTLTYPE_INT:
187 intval = (int) strtol(newval, NULL, 0);
188 newval = &intval;
189 newsize = sizeof intval;
190 break;
191 break;
192 case CTLTYPE_STRING:
193 break;
194 case CTLTYPE_QUAD:
195 break;
196 sscanf(newval, "%qd", &quadval);
197 newval = &quadval;
198 newsize = sizeof quadval;
199 break;
200 default:
201 errx(1, "oid '%s' is type %d,"
202 " cannot set that", bufp,
203 kind & CTLTYPE);
204 }
205
206 i = show_var(mib, len);
207 if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
208 if (!i && !bflag)
209 putchar('\n');
210 switch (errno) {
211 case EOPNOTSUPP:
212 errx(1, "%s: value is not available",
213 string);
214 case ENOTDIR:
215 errx(1, "%s: specification is incomplete",
216 string);
217 case ENOMEM:
218 errx(1, "%s: type is unknown to this program",
219 string);
220 default:
221 warn("%s", string);
222 return;
223 }
224 }
225 if (!bflag)
226 printf(" -> ");
227 i = nflag;
228 nflag = 1;
229 j = show_var(mib, len);
230 if (!j && !bflag)
231 putchar('\n');
232 nflag = i;
233 }
234}
235
236/* These functions will dump out various interesting structures. */
237
238static int
239S_clockinfo(int l2, void *p)
240{
241 struct clockinfo *ci = (struct clockinfo*)p;
242 if (l2 != sizeof *ci)
243 err(1, "S_clockinfo %d != %d", l2, sizeof *ci);
244 printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
245 ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
246 return (0);
247}
248
249static int
250S_loadavg(int l2, void *p)
251{
252 struct loadavg *tv = (struct loadavg*)p;
253
254 if (l2 != sizeof *tv)
255 err(1, "S_loadavg %d != %d", l2, sizeof *tv);
256
257 printf("{ %.2f %.2f %.2f }",
258 (double)tv->ldavg[0]/(double)tv->fscale,
259 (double)tv->ldavg[1]/(double)tv->fscale,
260 (double)tv->ldavg[2]/(double)tv->fscale);
261 return (0);
262}
263
264static int
265S_timeval(int l2, void *p)
266{
267 struct timeval *tv = (struct timeval*)p;
268 time_t tv_sec;
269 char *p1, *p2;
270
271 if (l2 != sizeof *tv)
272 err(1, "S_timeval %d != %d", l2, sizeof *tv);
273 printf("{ sec = %ld, usec = %ld } ",
274 tv->tv_sec, tv->tv_usec);
275 tv_sec = tv->tv_sec;
276 p1 = strdup(ctime(&tv_sec));
277 for (p2=p1; *p2 ; p2++)
278 if (*p2 == '\n')
279 *p2 = '\0';
280 fputs(p1, stdout);
281 return (0);
282}
283
284static int
285T_dev_t(int l2, void *p)
286{
287 dev_t *d = (dev_t *)p;
288 if (l2 != sizeof *d)
289 err(1, "T_dev_T %d != %d", l2, sizeof *d);
290 if ((int)(*d) != -1) {
291 if (minor(*d) > 255 || minor(*d) < 0)
292 printf("{ major = %d, minor = 0x%x }",
293 major(*d), minor(*d));
294 else
295 printf("{ major = %d, minor = %d }",
296 major(*d), minor(*d));
297 }
298 return (0);
299}
300
301/*
302 * These functions uses a presently undocumented interface to the kernel
303 * to walk the tree and get the type so it can print the value.
304 * This interface is under work and consideration, and should probably
305 * be killed with a big axe by the first person who can find the time.
306 * (be aware though, that the proper interface isn't as obvious as it
307 * may seem, there are various conflicting requirements.
308 */
309
310static int
311name2oid(char *name, int *oidp)
312{
313 int oid[2];
314 int i;
315 size_t j;
316
317 oid[0] = 0;
318 oid[1] = 3;
319
320 j = CTL_MAXNAME * sizeof (int);
321 i = sysctl(oid, 2, oidp, &j, name, strlen(name));
322 if (i < 0)
323 return i;
324 j /= sizeof (int);
325 return (j);
326}
327
328static int
329oidfmt(int *oid, int len, char *fmt, u_int *kind)
330{
331 int qoid[CTL_MAXNAME+2];
332 u_char buf[BUFSIZ];
333 int i;
334 size_t j;
335
336 qoid[0] = 0;
337 qoid[1] = 4;
338 memcpy(qoid + 2, oid, len * sizeof(int));
339
340 j = sizeof buf;
341 i = sysctl(qoid, len + 2, buf, &j, 0, 0);
342 if (i)
343 err(1, "sysctl fmt %d %d %d", i, j, errno);
344
345 if (kind)
346 *kind = *(u_int *)buf;
347
348 if (fmt)
349 strcpy(fmt, (char *)(buf + sizeof(u_int)));
350 return 0;
351}
352
353/*
354 * This formats and outputs the value of one variable
355 *
356 * Returns zero if anything was actually output.
357 * Returns one if didn't know what to do with this.
358 * Return minus one if we had errors.
359 */
360
361static int
362show_var(int *oid, int nlen)
363{
364 u_char buf[BUFSIZ], *val, *p;
46#endif /* not lint */
47
48#include <sys/types.h>
49#include <sys/stat.h>
50#include <sys/sysctl.h>
51#include <sys/resource.h>
52
53#include <ctype.h>
54#include <err.h>
55#include <errno.h>
56#include <stdio.h>
57#include <stdlib.h>
58#include <string.h>
59#include <unistd.h>
60
61static int aflag, bflag, Nflag, nflag, oflag, xflag;
62
63static int oidfmt(int *, int, char *, u_int *);
64static void parse(char *);
65static int show_var(int *, int);
66static int sysctl_all (int *oid, int len);
67static int name2oid(char *, int *);
68
69static void
70usage(void)
71{
72
73 (void)fprintf(stderr, "%s\n%s\n",
74 "usage: sysctl [-bNnox] variable[=value] ...",
75 " sysctl [-bNnox] -a");
76 exit(1);
77}
78
79int
80main(int argc, char **argv)
81{
82 int ch;
83 setbuf(stdout,0);
84 setbuf(stderr,0);
85
86 while ((ch = getopt(argc, argv, "AabNnowxX")) != -1) {
87 switch (ch) {
88 case 'A':
89 /* compatibility */
90 aflag = oflag = 1;
91 break;
92 case 'a':
93 aflag = 1;
94 break;
95 case 'b':
96 bflag = 1;
97 break;
98 case 'N':
99 Nflag = 1;
100 break;
101 case 'n':
102 nflag = 1;
103 break;
104 case 'o':
105 oflag = 1;
106 break;
107 case 'w':
108 /* compatibility */
109 /* ignored */
110 break;
111 case 'X':
112 /* compatibility */
113 aflag = xflag = 1;
114 break;
115 case 'x':
116 xflag = 1;
117 break;
118 default:
119 usage();
120 }
121 }
122 argc -= optind;
123 argv += optind;
124
125 if (Nflag && nflag)
126 usage();
127 if (aflag && argc == 0)
128 exit(sysctl_all(0, 0));
129 if (argc == 0)
130 usage();
131 while (argc-- > 0)
132 parse(*argv++);
133 exit(0);
134}
135
136/*
137 * Parse a name into a MIB entry.
138 * Lookup and print out the MIB entry if it exists.
139 * Set a new value if requested.
140 */
141static void
142parse(char *string)
143{
144 int len, i, j;
145 void *newval = 0;
146 int intval, newsize = 0;
147 quad_t quadval;
148 int mib[CTL_MAXNAME];
149 char *cp, *bufp, buf[BUFSIZ];
150 u_int kind;
151
152 bufp = buf;
153 snprintf(buf, BUFSIZ, "%s", string);
154 if ((cp = strchr(string, '=')) != NULL) {
155 *strchr(buf, '=') = '\0';
156 *cp++ = '\0';
157 while (isspace(*cp))
158 cp++;
159 newval = cp;
160 newsize = strlen(cp);
161 }
162 len = name2oid(bufp, mib);
163
164 if (len < 0)
165 errx(1, "unknown oid '%s'", bufp);
166
167 if (oidfmt(mib, len, 0, &kind))
168 err(1, "couldn't find format of oid '%s'", bufp);
169
170 if (newval == NULL) {
171 if ((kind & CTLTYPE) == CTLTYPE_NODE) {
172 sysctl_all(mib, len);
173 } else {
174 i = show_var(mib, len);
175 if (!i && !bflag)
176 putchar('\n');
177 }
178 } else {
179 if ((kind & CTLTYPE) == CTLTYPE_NODE)
180 errx(1, "oid '%s' isn't a leaf node", bufp);
181
182 if (!(kind&CTLFLAG_WR))
183 errx(1, "oid '%s' is read only", bufp);
184
185 switch (kind & CTLTYPE) {
186 case CTLTYPE_INT:
187 intval = (int) strtol(newval, NULL, 0);
188 newval = &intval;
189 newsize = sizeof intval;
190 break;
191 break;
192 case CTLTYPE_STRING:
193 break;
194 case CTLTYPE_QUAD:
195 break;
196 sscanf(newval, "%qd", &quadval);
197 newval = &quadval;
198 newsize = sizeof quadval;
199 break;
200 default:
201 errx(1, "oid '%s' is type %d,"
202 " cannot set that", bufp,
203 kind & CTLTYPE);
204 }
205
206 i = show_var(mib, len);
207 if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
208 if (!i && !bflag)
209 putchar('\n');
210 switch (errno) {
211 case EOPNOTSUPP:
212 errx(1, "%s: value is not available",
213 string);
214 case ENOTDIR:
215 errx(1, "%s: specification is incomplete",
216 string);
217 case ENOMEM:
218 errx(1, "%s: type is unknown to this program",
219 string);
220 default:
221 warn("%s", string);
222 return;
223 }
224 }
225 if (!bflag)
226 printf(" -> ");
227 i = nflag;
228 nflag = 1;
229 j = show_var(mib, len);
230 if (!j && !bflag)
231 putchar('\n');
232 nflag = i;
233 }
234}
235
236/* These functions will dump out various interesting structures. */
237
238static int
239S_clockinfo(int l2, void *p)
240{
241 struct clockinfo *ci = (struct clockinfo*)p;
242 if (l2 != sizeof *ci)
243 err(1, "S_clockinfo %d != %d", l2, sizeof *ci);
244 printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
245 ci->hz, ci->tick, ci->tickadj, ci->profhz, ci->stathz);
246 return (0);
247}
248
249static int
250S_loadavg(int l2, void *p)
251{
252 struct loadavg *tv = (struct loadavg*)p;
253
254 if (l2 != sizeof *tv)
255 err(1, "S_loadavg %d != %d", l2, sizeof *tv);
256
257 printf("{ %.2f %.2f %.2f }",
258 (double)tv->ldavg[0]/(double)tv->fscale,
259 (double)tv->ldavg[1]/(double)tv->fscale,
260 (double)tv->ldavg[2]/(double)tv->fscale);
261 return (0);
262}
263
264static int
265S_timeval(int l2, void *p)
266{
267 struct timeval *tv = (struct timeval*)p;
268 time_t tv_sec;
269 char *p1, *p2;
270
271 if (l2 != sizeof *tv)
272 err(1, "S_timeval %d != %d", l2, sizeof *tv);
273 printf("{ sec = %ld, usec = %ld } ",
274 tv->tv_sec, tv->tv_usec);
275 tv_sec = tv->tv_sec;
276 p1 = strdup(ctime(&tv_sec));
277 for (p2=p1; *p2 ; p2++)
278 if (*p2 == '\n')
279 *p2 = '\0';
280 fputs(p1, stdout);
281 return (0);
282}
283
284static int
285T_dev_t(int l2, void *p)
286{
287 dev_t *d = (dev_t *)p;
288 if (l2 != sizeof *d)
289 err(1, "T_dev_T %d != %d", l2, sizeof *d);
290 if ((int)(*d) != -1) {
291 if (minor(*d) > 255 || minor(*d) < 0)
292 printf("{ major = %d, minor = 0x%x }",
293 major(*d), minor(*d));
294 else
295 printf("{ major = %d, minor = %d }",
296 major(*d), minor(*d));
297 }
298 return (0);
299}
300
301/*
302 * These functions uses a presently undocumented interface to the kernel
303 * to walk the tree and get the type so it can print the value.
304 * This interface is under work and consideration, and should probably
305 * be killed with a big axe by the first person who can find the time.
306 * (be aware though, that the proper interface isn't as obvious as it
307 * may seem, there are various conflicting requirements.
308 */
309
310static int
311name2oid(char *name, int *oidp)
312{
313 int oid[2];
314 int i;
315 size_t j;
316
317 oid[0] = 0;
318 oid[1] = 3;
319
320 j = CTL_MAXNAME * sizeof (int);
321 i = sysctl(oid, 2, oidp, &j, name, strlen(name));
322 if (i < 0)
323 return i;
324 j /= sizeof (int);
325 return (j);
326}
327
328static int
329oidfmt(int *oid, int len, char *fmt, u_int *kind)
330{
331 int qoid[CTL_MAXNAME+2];
332 u_char buf[BUFSIZ];
333 int i;
334 size_t j;
335
336 qoid[0] = 0;
337 qoid[1] = 4;
338 memcpy(qoid + 2, oid, len * sizeof(int));
339
340 j = sizeof buf;
341 i = sysctl(qoid, len + 2, buf, &j, 0, 0);
342 if (i)
343 err(1, "sysctl fmt %d %d %d", i, j, errno);
344
345 if (kind)
346 *kind = *(u_int *)buf;
347
348 if (fmt)
349 strcpy(fmt, (char *)(buf + sizeof(u_int)));
350 return 0;
351}
352
353/*
354 * This formats and outputs the value of one variable
355 *
356 * Returns zero if anything was actually output.
357 * Returns one if didn't know what to do with this.
358 * Return minus one if we had errors.
359 */
360
361static int
362show_var(int *oid, int nlen)
363{
364 u_char buf[BUFSIZ], *val, *p;
365 char name[BUFSIZ], descr[BUFSIZ], *fmt;
365 char name[BUFSIZ], *fmt;
366 int qoid[CTL_MAXNAME+2];
367 int i;
368 size_t j, len;
369 u_int kind;
370 int (*func)(int, void *);
371
372 qoid[0] = 0;
373 memcpy(qoid + 2, oid, nlen * sizeof(int));
374
375 qoid[1] = 1;
376 j = sizeof name;
377 i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
378 if (i || !j)
379 err(1, "sysctl name %d %d %d", i, j, errno);
380
381 if (Nflag) {
382 printf("%s", name);
383 return (0);
384 }
385
386 /* find an estimate of how much we need for this var */
387 j = 0;
388 i = sysctl(oid, nlen, 0, &j, 0, 0);
389 j += j; /* we want to be sure :-) */
390
391 val = alloca(j);
392 len = j;
393 i = sysctl(oid, nlen, val, &len, 0, 0);
394 if (i || !len)
395 return (1);
396
397 if (bflag) {
398 fwrite(val, 1, len, stdout);
399 return (0);
400 }
401
402 qoid[1] = 4;
403 j = sizeof buf;
404 i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
405 if (i || !j)
406 err(1, "sysctl fmt %d %d %d", i, j, errno);
407
408 kind = *(u_int *)buf;
409
410 fmt = (char *)(buf + sizeof(u_int));
411
412 p = val;
413 switch (*fmt) {
414 case 'A':
415 if (!nflag)
416 printf("%s: ", name);
417 printf("%s", p);
418 return (0);
419
420 case 'I':
421 if (!nflag)
422 printf("%s: ", name);
423 fmt++;
424 val = "";
425 while (len >= sizeof(int)) {
426 if(*fmt == 'U')
427 printf("%s%u", val, *(unsigned int *)p);
428 else
429 printf("%s%d", val, *(int *)p);
430 val = " ";
431 len -= sizeof(int);
432 p += sizeof(int);
433 }
434 return (0);
435
436 case 'L':
437 if (!nflag)
438 printf("%s: ", name);
439 fmt++;
440 val = "";
441 while (len >= sizeof(long)) {
442 if(*fmt == 'U')
443 printf("%s%lu", val, *(unsigned long *)p);
444 else
445 printf("%s%ld", val, *(long *)p);
446 val = " ";
447 len -= sizeof(long);
448 p += sizeof(long);
449 }
450 return (0);
451
452 case 'P':
453 if (!nflag)
454 printf("%s: ", name);
455 printf("%p", *(void **)p);
456 return (0);
457
458 case 'T':
459 case 'S':
460 i = 0;
461 if (strcmp(fmt, "S,clockinfo") == 0)
462 func = S_clockinfo;
463 else if (strcmp(fmt, "S,timeval") == 0)
464 func = S_timeval;
465 else if (strcmp(fmt, "S,loadavg") == 0)
466 func = S_loadavg;
467 else if (strcmp(fmt, "T,dev_t") == 0)
468 func = T_dev_t;
469 else
470 func = NULL;
471 if (func) {
472 if (!nflag)
473 printf("%s: ", name);
474 return ((*func)(len, p));
475 }
476 /* FALL THROUGH */
477 default:
478 if (!oflag && !xflag)
479 return (1);
480 if (!nflag)
481 printf("%s: ", name);
482 printf("Format:%s Length:%d Dump:0x", fmt, len);
483 while (len-- && (xflag || p < val + 16))
484 printf("%02x", *p++);
485 if (!xflag && len > 16)
486 printf("...");
487 return (0);
488 }
489 return (1);
490}
491
492static int
493sysctl_all (int *oid, int len)
494{
495 int name1[22], name2[22];
496 int i, j;
497 size_t l1, l2;
498
499 name1[0] = 0;
500 name1[1] = 2;
501 l1 = 2;
502 if (len) {
503 memcpy(name1+2, oid, len*sizeof (int));
504 l1 += len;
505 } else {
506 name1[2] = 1;
507 l1++;
508 }
509 for (;;) {
510 l2 = sizeof name2;
511 j = sysctl(name1, l1, name2, &l2, 0, 0);
512 if (j < 0) {
513 if (errno == ENOENT)
514 return 0;
515 else
516 err(1, "sysctl(getnext) %d %d", j, l2);
517 }
518
519 l2 /= sizeof (int);
520
521 if (l2 < len)
522 return 0;
523
524 for (i = 0; i < len; i++)
525 if (name2[i] != oid[i])
526 return 0;
527
528 i = show_var(name2, l2);
529 if (!i && !bflag)
530 putchar('\n');
531
532 memcpy(name1+2, name2, l2*sizeof (int));
533 l1 = 2 + l2;
534 }
535}
366 int qoid[CTL_MAXNAME+2];
367 int i;
368 size_t j, len;
369 u_int kind;
370 int (*func)(int, void *);
371
372 qoid[0] = 0;
373 memcpy(qoid + 2, oid, nlen * sizeof(int));
374
375 qoid[1] = 1;
376 j = sizeof name;
377 i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
378 if (i || !j)
379 err(1, "sysctl name %d %d %d", i, j, errno);
380
381 if (Nflag) {
382 printf("%s", name);
383 return (0);
384 }
385
386 /* find an estimate of how much we need for this var */
387 j = 0;
388 i = sysctl(oid, nlen, 0, &j, 0, 0);
389 j += j; /* we want to be sure :-) */
390
391 val = alloca(j);
392 len = j;
393 i = sysctl(oid, nlen, val, &len, 0, 0);
394 if (i || !len)
395 return (1);
396
397 if (bflag) {
398 fwrite(val, 1, len, stdout);
399 return (0);
400 }
401
402 qoid[1] = 4;
403 j = sizeof buf;
404 i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
405 if (i || !j)
406 err(1, "sysctl fmt %d %d %d", i, j, errno);
407
408 kind = *(u_int *)buf;
409
410 fmt = (char *)(buf + sizeof(u_int));
411
412 p = val;
413 switch (*fmt) {
414 case 'A':
415 if (!nflag)
416 printf("%s: ", name);
417 printf("%s", p);
418 return (0);
419
420 case 'I':
421 if (!nflag)
422 printf("%s: ", name);
423 fmt++;
424 val = "";
425 while (len >= sizeof(int)) {
426 if(*fmt == 'U')
427 printf("%s%u", val, *(unsigned int *)p);
428 else
429 printf("%s%d", val, *(int *)p);
430 val = " ";
431 len -= sizeof(int);
432 p += sizeof(int);
433 }
434 return (0);
435
436 case 'L':
437 if (!nflag)
438 printf("%s: ", name);
439 fmt++;
440 val = "";
441 while (len >= sizeof(long)) {
442 if(*fmt == 'U')
443 printf("%s%lu", val, *(unsigned long *)p);
444 else
445 printf("%s%ld", val, *(long *)p);
446 val = " ";
447 len -= sizeof(long);
448 p += sizeof(long);
449 }
450 return (0);
451
452 case 'P':
453 if (!nflag)
454 printf("%s: ", name);
455 printf("%p", *(void **)p);
456 return (0);
457
458 case 'T':
459 case 'S':
460 i = 0;
461 if (strcmp(fmt, "S,clockinfo") == 0)
462 func = S_clockinfo;
463 else if (strcmp(fmt, "S,timeval") == 0)
464 func = S_timeval;
465 else if (strcmp(fmt, "S,loadavg") == 0)
466 func = S_loadavg;
467 else if (strcmp(fmt, "T,dev_t") == 0)
468 func = T_dev_t;
469 else
470 func = NULL;
471 if (func) {
472 if (!nflag)
473 printf("%s: ", name);
474 return ((*func)(len, p));
475 }
476 /* FALL THROUGH */
477 default:
478 if (!oflag && !xflag)
479 return (1);
480 if (!nflag)
481 printf("%s: ", name);
482 printf("Format:%s Length:%d Dump:0x", fmt, len);
483 while (len-- && (xflag || p < val + 16))
484 printf("%02x", *p++);
485 if (!xflag && len > 16)
486 printf("...");
487 return (0);
488 }
489 return (1);
490}
491
492static int
493sysctl_all (int *oid, int len)
494{
495 int name1[22], name2[22];
496 int i, j;
497 size_t l1, l2;
498
499 name1[0] = 0;
500 name1[1] = 2;
501 l1 = 2;
502 if (len) {
503 memcpy(name1+2, oid, len*sizeof (int));
504 l1 += len;
505 } else {
506 name1[2] = 1;
507 l1++;
508 }
509 for (;;) {
510 l2 = sizeof name2;
511 j = sysctl(name1, l1, name2, &l2, 0, 0);
512 if (j < 0) {
513 if (errno == ENOENT)
514 return 0;
515 else
516 err(1, "sysctl(getnext) %d %d", j, l2);
517 }
518
519 l2 /= sizeof (int);
520
521 if (l2 < len)
522 return 0;
523
524 for (i = 0; i < len; i++)
525 if (name2[i] != oid[i])
526 return 0;
527
528 i = show_var(name2, l2);
529 if (!i && !bflag)
530 putchar('\n');
531
532 memcpy(name1+2, name2, l2*sizeof (int));
533 l1 = 2 + l2;
534 }
535}