1 | #include <machine/rtems-bsd-user-space.h> |
---|
2 | |
---|
3 | #ifdef __rtems__ |
---|
4 | #include "rtems-bsd-sysctl-namespace.h" |
---|
5 | #endif /* __rtems__ */ |
---|
6 | |
---|
7 | /* |
---|
8 | * Copyright (c) 1993 |
---|
9 | * The Regents of the University of California. All rights reserved. |
---|
10 | * |
---|
11 | * Redistribution and use in source and binary forms, with or without |
---|
12 | * modification, are permitted provided that the following conditions |
---|
13 | * are met: |
---|
14 | * 1. Redistributions of source code must retain the above copyright |
---|
15 | * notice, this list of conditions and the following disclaimer. |
---|
16 | * 2. Redistributions in binary form must reproduce the above copyright |
---|
17 | * notice, this list of conditions and the following disclaimer in the |
---|
18 | * documentation and/or other materials provided with the distribution. |
---|
19 | * 4. Neither the name of the University nor the names of its contributors |
---|
20 | * may be used to endorse or promote products derived from this software |
---|
21 | * without specific prior written permission. |
---|
22 | * |
---|
23 | * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND |
---|
24 | * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE |
---|
25 | * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE |
---|
26 | * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE |
---|
27 | * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL |
---|
28 | * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS |
---|
29 | * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) |
---|
30 | * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
---|
31 | * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY |
---|
32 | * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF |
---|
33 | * SUCH DAMAGE. |
---|
34 | */ |
---|
35 | |
---|
36 | #ifndef lint |
---|
37 | static const char copyright[] = |
---|
38 | "@(#) Copyright (c) 1993\n\ |
---|
39 | The Regents of the University of California. All rights reserved.\n"; |
---|
40 | #endif /* not lint */ |
---|
41 | |
---|
42 | #ifndef lint |
---|
43 | #if 0 |
---|
44 | static char sccsid[] = "@(#)from: sysctl.c 8.1 (Berkeley) 6/6/93"; |
---|
45 | #endif |
---|
46 | static const char rcsid[] = |
---|
47 | "$FreeBSD$"; |
---|
48 | #endif /* not lint */ |
---|
49 | |
---|
50 | #ifdef __rtems__ |
---|
51 | #define __need_getopt_newlib |
---|
52 | #include <getopt.h> |
---|
53 | #include <machine/rtems-bsd-program.h> |
---|
54 | #include <machine/rtems-bsd-commands.h> |
---|
55 | #endif /* __rtems__ */ |
---|
56 | #include <rtems/bsd/sys/param.h> |
---|
57 | #include <sys/time.h> |
---|
58 | #include <rtems/bsd/sys/resource.h> |
---|
59 | #include <sys/stat.h> |
---|
60 | #include <sys/sysctl.h> |
---|
61 | #include <sys/vmmeter.h> |
---|
62 | |
---|
63 | #ifdef __amd64__ |
---|
64 | #include <sys/efi.h> |
---|
65 | #include <machine/metadata.h> |
---|
66 | #endif |
---|
67 | |
---|
68 | #if defined(__amd64__) || defined(__i386__) |
---|
69 | #include <machine/pc/bios.h> |
---|
70 | #endif |
---|
71 | |
---|
72 | #include <assert.h> |
---|
73 | #include <ctype.h> |
---|
74 | #include <err.h> |
---|
75 | #include <errno.h> |
---|
76 | #include <inttypes.h> |
---|
77 | #include <locale.h> |
---|
78 | #include <stdio.h> |
---|
79 | #include <stdlib.h> |
---|
80 | #include <string.h> |
---|
81 | #include <sysexits.h> |
---|
82 | #include <unistd.h> |
---|
83 | #ifdef __rtems__ |
---|
84 | #include "rtems-bsd-sysctl-sysctl-data.h" |
---|
85 | #endif /* __rtems__ */ |
---|
86 | |
---|
87 | static const char *conffile; |
---|
88 | |
---|
89 | static int aflag, bflag, Bflag, dflag, eflag, hflag, iflag; |
---|
90 | static int Nflag, nflag, oflag, qflag, tflag, Tflag, Wflag, xflag; |
---|
91 | |
---|
92 | static int oidfmt(int *, int, char *, u_int *); |
---|
93 | static int parsefile(const char *); |
---|
94 | static int parse(const char *, int); |
---|
95 | static int show_var(int *, int); |
---|
96 | static int sysctl_all(int *oid, int len); |
---|
97 | static int name2oid(const char *, int *); |
---|
98 | |
---|
99 | static int strIKtoi(const char *, char **, const char *); |
---|
100 | |
---|
101 | static int ctl_sign[CTLTYPE+1] = { |
---|
102 | [CTLTYPE_INT] = 1, |
---|
103 | [CTLTYPE_LONG] = 1, |
---|
104 | [CTLTYPE_S8] = 1, |
---|
105 | [CTLTYPE_S16] = 1, |
---|
106 | [CTLTYPE_S32] = 1, |
---|
107 | [CTLTYPE_S64] = 1, |
---|
108 | }; |
---|
109 | |
---|
110 | static int ctl_size[CTLTYPE+1] = { |
---|
111 | [CTLTYPE_INT] = sizeof(int), |
---|
112 | [CTLTYPE_UINT] = sizeof(u_int), |
---|
113 | [CTLTYPE_LONG] = sizeof(long), |
---|
114 | [CTLTYPE_ULONG] = sizeof(u_long), |
---|
115 | [CTLTYPE_S8] = sizeof(int8_t), |
---|
116 | [CTLTYPE_S16] = sizeof(int16_t), |
---|
117 | [CTLTYPE_S32] = sizeof(int32_t), |
---|
118 | [CTLTYPE_S64] = sizeof(int64_t), |
---|
119 | [CTLTYPE_U8] = sizeof(uint8_t), |
---|
120 | [CTLTYPE_U16] = sizeof(uint16_t), |
---|
121 | [CTLTYPE_U32] = sizeof(uint32_t), |
---|
122 | [CTLTYPE_U64] = sizeof(uint64_t), |
---|
123 | }; |
---|
124 | |
---|
125 | static const char *ctl_typename[CTLTYPE+1] = { |
---|
126 | [CTLTYPE_INT] = "integer", |
---|
127 | [CTLTYPE_UINT] = "unsigned integer", |
---|
128 | [CTLTYPE_LONG] = "long integer", |
---|
129 | [CTLTYPE_ULONG] = "unsigned long", |
---|
130 | [CTLTYPE_U8] = "uint8_t", |
---|
131 | [CTLTYPE_U16] = "uint16_t", |
---|
132 | [CTLTYPE_U32] = "uint32_t", |
---|
133 | [CTLTYPE_U64] = "uint64_t", |
---|
134 | [CTLTYPE_S8] = "int8_t", |
---|
135 | [CTLTYPE_S16] = "int16_t", |
---|
136 | [CTLTYPE_S32] = "int32_t", |
---|
137 | [CTLTYPE_S64] = "int64_t", |
---|
138 | [CTLTYPE_NODE] = "node", |
---|
139 | [CTLTYPE_STRING] = "string", |
---|
140 | [CTLTYPE_OPAQUE] = "opaque", |
---|
141 | }; |
---|
142 | |
---|
143 | static void |
---|
144 | usage(void) |
---|
145 | { |
---|
146 | |
---|
147 | (void)fprintf(stderr, "%s\n%s\n", |
---|
148 | "usage: sysctl [-bdehiNnoqTtWx] [ -B <bufsize> ] [-f filename] name[=value] ...", |
---|
149 | " sysctl [-bdehNnoqTtWx] [ -B <bufsize> ] -a"); |
---|
150 | exit(1); |
---|
151 | } |
---|
152 | |
---|
153 | #ifdef __rtems__ |
---|
154 | static int main(int argc, char *argv[]); |
---|
155 | |
---|
156 | RTEMS_LINKER_RWSET(bsd_prog_sysctl, char); |
---|
157 | |
---|
158 | int |
---|
159 | rtems_bsd_command_sysctl(int argc, char *argv[]) |
---|
160 | { |
---|
161 | int exit_code; |
---|
162 | void *data_begin; |
---|
163 | size_t data_size; |
---|
164 | |
---|
165 | data_begin = RTEMS_LINKER_SET_BEGIN(bsd_prog_sysctl); |
---|
166 | data_size = RTEMS_LINKER_SET_SIZE(bsd_prog_sysctl); |
---|
167 | |
---|
168 | rtems_bsd_program_lock(); |
---|
169 | exit_code = rtems_bsd_program_call_main_with_data_restore("sysctl", |
---|
170 | main, argc, argv, data_begin, data_size); |
---|
171 | rtems_bsd_program_unlock(); |
---|
172 | |
---|
173 | return exit_code; |
---|
174 | } |
---|
175 | #endif /* __rtems__ */ |
---|
176 | int |
---|
177 | main(int argc, char **argv) |
---|
178 | { |
---|
179 | int ch; |
---|
180 | int warncount = 0; |
---|
181 | #ifdef __rtems__ |
---|
182 | struct getopt_data getopt_data; |
---|
183 | memset(&getopt_data, 0, sizeof(getopt_data)); |
---|
184 | #define optind getopt_data.optind |
---|
185 | #define optarg getopt_data.optarg |
---|
186 | #define opterr getopt_data.opterr |
---|
187 | #define optopt getopt_data.optopt |
---|
188 | #define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data) |
---|
189 | #endif /* __rtems__ */ |
---|
190 | |
---|
191 | setlocale(LC_NUMERIC, ""); |
---|
192 | setbuf(stdout,0); |
---|
193 | setbuf(stderr,0); |
---|
194 | |
---|
195 | while ((ch = getopt(argc, argv, "AabB:def:hiNnoqtTwWxX")) != -1) { |
---|
196 | switch (ch) { |
---|
197 | case 'A': |
---|
198 | /* compatibility */ |
---|
199 | aflag = oflag = 1; |
---|
200 | break; |
---|
201 | case 'a': |
---|
202 | aflag = 1; |
---|
203 | break; |
---|
204 | case 'b': |
---|
205 | bflag = 1; |
---|
206 | break; |
---|
207 | case 'B': |
---|
208 | Bflag = strtol(optarg, NULL, 0); |
---|
209 | break; |
---|
210 | case 'd': |
---|
211 | dflag = 1; |
---|
212 | break; |
---|
213 | case 'e': |
---|
214 | eflag = 1; |
---|
215 | break; |
---|
216 | case 'f': |
---|
217 | conffile = optarg; |
---|
218 | break; |
---|
219 | case 'h': |
---|
220 | hflag = 1; |
---|
221 | break; |
---|
222 | case 'i': |
---|
223 | iflag = 1; |
---|
224 | break; |
---|
225 | case 'N': |
---|
226 | Nflag = 1; |
---|
227 | break; |
---|
228 | case 'n': |
---|
229 | nflag = 1; |
---|
230 | break; |
---|
231 | case 'o': |
---|
232 | oflag = 1; |
---|
233 | break; |
---|
234 | case 'q': |
---|
235 | qflag = 1; |
---|
236 | break; |
---|
237 | case 't': |
---|
238 | tflag = 1; |
---|
239 | break; |
---|
240 | case 'T': |
---|
241 | Tflag = 1; |
---|
242 | break; |
---|
243 | case 'w': |
---|
244 | /* compatibility */ |
---|
245 | /* ignored */ |
---|
246 | break; |
---|
247 | case 'W': |
---|
248 | Wflag = 1; |
---|
249 | break; |
---|
250 | case 'X': |
---|
251 | /* compatibility */ |
---|
252 | aflag = xflag = 1; |
---|
253 | break; |
---|
254 | case 'x': |
---|
255 | xflag = 1; |
---|
256 | break; |
---|
257 | default: |
---|
258 | usage(); |
---|
259 | } |
---|
260 | } |
---|
261 | argc -= optind; |
---|
262 | argv += optind; |
---|
263 | |
---|
264 | if (Nflag && nflag) |
---|
265 | usage(); |
---|
266 | if (aflag && argc == 0) |
---|
267 | exit(sysctl_all(0, 0)); |
---|
268 | if (argc == 0 && conffile == NULL) |
---|
269 | usage(); |
---|
270 | |
---|
271 | warncount = 0; |
---|
272 | if (conffile != NULL) |
---|
273 | warncount += parsefile(conffile); |
---|
274 | |
---|
275 | while (argc-- > 0) |
---|
276 | warncount += parse(*argv++, 0); |
---|
277 | |
---|
278 | return (warncount); |
---|
279 | } |
---|
280 | |
---|
281 | /* |
---|
282 | * Parse a name into a MIB entry. |
---|
283 | * Lookup and print out the MIB entry if it exists. |
---|
284 | * Set a new value if requested. |
---|
285 | */ |
---|
286 | static int |
---|
287 | parse(const char *string, int lineno) |
---|
288 | { |
---|
289 | int len, i, j; |
---|
290 | const void *newval; |
---|
291 | const char *newvalstr = NULL; |
---|
292 | int8_t i8val; |
---|
293 | uint8_t u8val; |
---|
294 | int16_t i16val; |
---|
295 | uint16_t u16val; |
---|
296 | int32_t i32val; |
---|
297 | uint32_t u32val; |
---|
298 | int intval; |
---|
299 | unsigned int uintval; |
---|
300 | long longval; |
---|
301 | unsigned long ulongval; |
---|
302 | size_t newsize = Bflag; |
---|
303 | int64_t i64val; |
---|
304 | uint64_t u64val; |
---|
305 | int mib[CTL_MAXNAME]; |
---|
306 | char *cp, *bufp, buf[BUFSIZ], *endptr = NULL, fmt[BUFSIZ], line[BUFSIZ]; |
---|
307 | u_int kind; |
---|
308 | |
---|
309 | if (lineno) |
---|
310 | snprintf(line, sizeof(line), " at line %d", lineno); |
---|
311 | else |
---|
312 | line[0] = '\0'; |
---|
313 | |
---|
314 | cp = buf; |
---|
315 | if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ) { |
---|
316 | warnx("oid too long: '%s'%s", string, line); |
---|
317 | return (1); |
---|
318 | } |
---|
319 | bufp = strsep(&cp, "=:"); |
---|
320 | if (cp != NULL) { |
---|
321 | /* Tflag just lists tunables, do not allow assignment */ |
---|
322 | if (Tflag || Wflag) { |
---|
323 | warnx("Can't set variables when using -T or -W"); |
---|
324 | usage(); |
---|
325 | } |
---|
326 | while (isspace(*cp)) |
---|
327 | cp++; |
---|
328 | /* Strip a pair of " or ' if any. */ |
---|
329 | switch (*cp) { |
---|
330 | case '\"': |
---|
331 | case '\'': |
---|
332 | if (cp[strlen(cp) - 1] == *cp) |
---|
333 | cp[strlen(cp) - 1] = '\0'; |
---|
334 | cp++; |
---|
335 | } |
---|
336 | newvalstr = cp; |
---|
337 | newsize = strlen(cp); |
---|
338 | } |
---|
339 | /* Trim spaces */ |
---|
340 | cp = bufp + strlen(bufp) - 1; |
---|
341 | while (cp >= bufp && isspace((int)*cp)) { |
---|
342 | *cp = '\0'; |
---|
343 | cp--; |
---|
344 | } |
---|
345 | len = name2oid(bufp, mib); |
---|
346 | |
---|
347 | if (len < 0) { |
---|
348 | if (iflag) |
---|
349 | return (0); |
---|
350 | if (qflag) |
---|
351 | return (1); |
---|
352 | else { |
---|
353 | if (errno == ENOENT) { |
---|
354 | warnx("unknown oid '%s'%s", bufp, line); |
---|
355 | } else { |
---|
356 | warn("unknown oid '%s'%s", bufp, line); |
---|
357 | } |
---|
358 | return (1); |
---|
359 | } |
---|
360 | } |
---|
361 | |
---|
362 | if (oidfmt(mib, len, fmt, &kind)) { |
---|
363 | warn("couldn't find format of oid '%s'%s", bufp, line); |
---|
364 | if (iflag) |
---|
365 | return (1); |
---|
366 | else |
---|
367 | exit(1); |
---|
368 | } |
---|
369 | |
---|
370 | if (newvalstr == NULL || dflag) { |
---|
371 | if ((kind & CTLTYPE) == CTLTYPE_NODE) { |
---|
372 | if (dflag) { |
---|
373 | i = show_var(mib, len); |
---|
374 | if (!i && !bflag) |
---|
375 | putchar('\n'); |
---|
376 | } |
---|
377 | sysctl_all(mib, len); |
---|
378 | } else { |
---|
379 | i = show_var(mib, len); |
---|
380 | if (!i && !bflag) |
---|
381 | putchar('\n'); |
---|
382 | } |
---|
383 | } else { |
---|
384 | if ((kind & CTLTYPE) == CTLTYPE_NODE) { |
---|
385 | warnx("oid '%s' isn't a leaf node%s", bufp, line); |
---|
386 | return (1); |
---|
387 | } |
---|
388 | |
---|
389 | if (!(kind & CTLFLAG_WR)) { |
---|
390 | if (kind & CTLFLAG_TUN) { |
---|
391 | warnx("oid '%s' is a read only tunable%s", bufp, line); |
---|
392 | warnx("Tunable values are set in /boot/loader.conf"); |
---|
393 | } else |
---|
394 | warnx("oid '%s' is read only%s", bufp, line); |
---|
395 | return (1); |
---|
396 | } |
---|
397 | |
---|
398 | switch (kind & CTLTYPE) { |
---|
399 | case CTLTYPE_INT: |
---|
400 | case CTLTYPE_UINT: |
---|
401 | case CTLTYPE_LONG: |
---|
402 | case CTLTYPE_ULONG: |
---|
403 | case CTLTYPE_S8: |
---|
404 | case CTLTYPE_S16: |
---|
405 | case CTLTYPE_S32: |
---|
406 | case CTLTYPE_S64: |
---|
407 | case CTLTYPE_U8: |
---|
408 | case CTLTYPE_U16: |
---|
409 | case CTLTYPE_U32: |
---|
410 | case CTLTYPE_U64: |
---|
411 | if (strlen(newvalstr) == 0) { |
---|
412 | warnx("empty numeric value"); |
---|
413 | return (1); |
---|
414 | } |
---|
415 | /* FALLTHROUGH */ |
---|
416 | case CTLTYPE_STRING: |
---|
417 | break; |
---|
418 | default: |
---|
419 | warnx("oid '%s' is type %d," |
---|
420 | " cannot set that%s", bufp, |
---|
421 | kind & CTLTYPE, line); |
---|
422 | return (1); |
---|
423 | } |
---|
424 | |
---|
425 | errno = 0; |
---|
426 | |
---|
427 | switch (kind & CTLTYPE) { |
---|
428 | case CTLTYPE_INT: |
---|
429 | if (strncmp(fmt, "IK", 2) == 0) |
---|
430 | intval = strIKtoi(newvalstr, &endptr, fmt); |
---|
431 | else |
---|
432 | intval = (int)strtol(newvalstr, &endptr, |
---|
433 | 0); |
---|
434 | newval = &intval; |
---|
435 | newsize = sizeof(intval); |
---|
436 | break; |
---|
437 | case CTLTYPE_UINT: |
---|
438 | uintval = (int) strtoul(newvalstr, &endptr, 0); |
---|
439 | newval = &uintval; |
---|
440 | newsize = sizeof(uintval); |
---|
441 | break; |
---|
442 | case CTLTYPE_LONG: |
---|
443 | longval = strtol(newvalstr, &endptr, 0); |
---|
444 | newval = &longval; |
---|
445 | newsize = sizeof(longval); |
---|
446 | break; |
---|
447 | case CTLTYPE_ULONG: |
---|
448 | ulongval = strtoul(newvalstr, &endptr, 0); |
---|
449 | newval = &ulongval; |
---|
450 | newsize = sizeof(ulongval); |
---|
451 | break; |
---|
452 | case CTLTYPE_STRING: |
---|
453 | newval = newvalstr; |
---|
454 | break; |
---|
455 | case CTLTYPE_S8: |
---|
456 | i8val = (int8_t)strtol(newvalstr, &endptr, 0); |
---|
457 | newval = &i8val; |
---|
458 | newsize = sizeof(i8val); |
---|
459 | break; |
---|
460 | case CTLTYPE_S16: |
---|
461 | i16val = (int16_t)strtol(newvalstr, &endptr, |
---|
462 | 0); |
---|
463 | newval = &i16val; |
---|
464 | newsize = sizeof(i16val); |
---|
465 | break; |
---|
466 | case CTLTYPE_S32: |
---|
467 | i32val = (int32_t)strtol(newvalstr, &endptr, |
---|
468 | 0); |
---|
469 | newval = &i32val; |
---|
470 | newsize = sizeof(i32val); |
---|
471 | break; |
---|
472 | case CTLTYPE_S64: |
---|
473 | i64val = strtoimax(newvalstr, &endptr, 0); |
---|
474 | newval = &i64val; |
---|
475 | newsize = sizeof(i64val); |
---|
476 | break; |
---|
477 | case CTLTYPE_U8: |
---|
478 | u8val = (uint8_t)strtoul(newvalstr, &endptr, 0); |
---|
479 | newval = &u8val; |
---|
480 | newsize = sizeof(u8val); |
---|
481 | break; |
---|
482 | case CTLTYPE_U16: |
---|
483 | u16val = (uint16_t)strtoul(newvalstr, &endptr, |
---|
484 | 0); |
---|
485 | newval = &u16val; |
---|
486 | newsize = sizeof(u16val); |
---|
487 | break; |
---|
488 | case CTLTYPE_U32: |
---|
489 | u32val = (uint32_t)strtoul(newvalstr, &endptr, |
---|
490 | 0); |
---|
491 | newval = &u32val; |
---|
492 | newsize = sizeof(u32val); |
---|
493 | break; |
---|
494 | case CTLTYPE_U64: |
---|
495 | u64val = strtoumax(newvalstr, &endptr, 0); |
---|
496 | newval = &u64val; |
---|
497 | newsize = sizeof(u64val); |
---|
498 | break; |
---|
499 | default: |
---|
500 | /* NOTREACHED */ |
---|
501 | abort(); |
---|
502 | } |
---|
503 | |
---|
504 | if (errno != 0 || endptr == newvalstr || |
---|
505 | (endptr != NULL && *endptr != '\0')) { |
---|
506 | warnx("invalid %s '%s'%s", ctl_typename[kind & CTLTYPE], |
---|
507 | newvalstr, line); |
---|
508 | return (1); |
---|
509 | } |
---|
510 | |
---|
511 | i = show_var(mib, len); |
---|
512 | if (sysctl(mib, len, 0, 0, newval, newsize) == -1) { |
---|
513 | if (!i && !bflag) |
---|
514 | putchar('\n'); |
---|
515 | switch (errno) { |
---|
516 | case EOPNOTSUPP: |
---|
517 | warnx("%s: value is not available%s", |
---|
518 | string, line); |
---|
519 | return (1); |
---|
520 | case ENOTDIR: |
---|
521 | warnx("%s: specification is incomplete%s", |
---|
522 | string, line); |
---|
523 | return (1); |
---|
524 | case ENOMEM: |
---|
525 | warnx("%s: type is unknown to this program%s", |
---|
526 | string, line); |
---|
527 | return (1); |
---|
528 | default: |
---|
529 | warn("%s%s", string, line); |
---|
530 | return (1); |
---|
531 | } |
---|
532 | } |
---|
533 | if (!bflag) |
---|
534 | printf(" -> "); |
---|
535 | i = nflag; |
---|
536 | nflag = 1; |
---|
537 | j = show_var(mib, len); |
---|
538 | if (!j && !bflag) |
---|
539 | putchar('\n'); |
---|
540 | nflag = i; |
---|
541 | } |
---|
542 | |
---|
543 | return (0); |
---|
544 | } |
---|
545 | |
---|
546 | static int |
---|
547 | parsefile(const char *filename) |
---|
548 | { |
---|
549 | FILE *file; |
---|
550 | char line[BUFSIZ], *p, *pq, *pdq; |
---|
551 | int warncount = 0, lineno = 0; |
---|
552 | |
---|
553 | file = fopen(filename, "r"); |
---|
554 | if (file == NULL) |
---|
555 | err(EX_NOINPUT, "%s", filename); |
---|
556 | while (fgets(line, sizeof(line), file) != NULL) { |
---|
557 | lineno++; |
---|
558 | p = line; |
---|
559 | pq = strchr(line, '\''); |
---|
560 | pdq = strchr(line, '\"'); |
---|
561 | /* Replace the first # with \0. */ |
---|
562 | while((p = strchr(p, '#')) != NULL) { |
---|
563 | if (pq != NULL && p > pq) { |
---|
564 | if ((p = strchr(pq+1, '\'')) != NULL) |
---|
565 | *(++p) = '\0'; |
---|
566 | break; |
---|
567 | } else if (pdq != NULL && p > pdq) { |
---|
568 | if ((p = strchr(pdq+1, '\"')) != NULL) |
---|
569 | *(++p) = '\0'; |
---|
570 | break; |
---|
571 | } else if (p == line || *(p-1) != '\\') { |
---|
572 | *p = '\0'; |
---|
573 | break; |
---|
574 | } |
---|
575 | p++; |
---|
576 | } |
---|
577 | /* Trim spaces */ |
---|
578 | p = line + strlen(line) - 1; |
---|
579 | while (p >= line && isspace((int)*p)) { |
---|
580 | *p = '\0'; |
---|
581 | p--; |
---|
582 | } |
---|
583 | p = line; |
---|
584 | while (isspace((int)*p)) |
---|
585 | p++; |
---|
586 | if (*p == '\0') |
---|
587 | continue; |
---|
588 | else |
---|
589 | warncount += parse(p, lineno); |
---|
590 | } |
---|
591 | fclose(file); |
---|
592 | |
---|
593 | return (warncount); |
---|
594 | } |
---|
595 | |
---|
596 | /* These functions will dump out various interesting structures. */ |
---|
597 | |
---|
598 | #ifndef __rtems__ |
---|
599 | static int |
---|
600 | S_clockinfo(size_t l2, void *p) |
---|
601 | { |
---|
602 | struct clockinfo *ci = (struct clockinfo*)p; |
---|
603 | |
---|
604 | if (l2 != sizeof(*ci)) { |
---|
605 | warnx("S_clockinfo %zu != %zu", l2, sizeof(*ci)); |
---|
606 | return (1); |
---|
607 | } |
---|
608 | printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" : |
---|
609 | "{ hz = %d, tick = %d, profhz = %d, stathz = %d }", |
---|
610 | ci->hz, ci->tick, ci->profhz, ci->stathz); |
---|
611 | return (0); |
---|
612 | } |
---|
613 | #endif /* __rtems__ */ |
---|
614 | |
---|
615 | static int |
---|
616 | S_loadavg(size_t l2, void *p) |
---|
617 | { |
---|
618 | struct loadavg *tv = (struct loadavg*)p; |
---|
619 | |
---|
620 | if (l2 != sizeof(*tv)) { |
---|
621 | warnx("S_loadavg %zu != %zu", l2, sizeof(*tv)); |
---|
622 | return (1); |
---|
623 | } |
---|
624 | printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }", |
---|
625 | (double)tv->ldavg[0]/(double)tv->fscale, |
---|
626 | (double)tv->ldavg[1]/(double)tv->fscale, |
---|
627 | (double)tv->ldavg[2]/(double)tv->fscale); |
---|
628 | return (0); |
---|
629 | } |
---|
630 | |
---|
631 | static int |
---|
632 | S_timeval(size_t l2, void *p) |
---|
633 | { |
---|
634 | struct timeval *tv = (struct timeval*)p; |
---|
635 | time_t tv_sec; |
---|
636 | char *p1, *p2; |
---|
637 | |
---|
638 | if (l2 != sizeof(*tv)) { |
---|
639 | warnx("S_timeval %zu != %zu", l2, sizeof(*tv)); |
---|
640 | return (1); |
---|
641 | } |
---|
642 | printf(hflag ? "{ sec = %'jd, usec = %'ld } " : |
---|
643 | "{ sec = %jd, usec = %ld } ", |
---|
644 | (intmax_t)tv->tv_sec, tv->tv_usec); |
---|
645 | tv_sec = tv->tv_sec; |
---|
646 | p1 = strdup(ctime(&tv_sec)); |
---|
647 | for (p2=p1; *p2 ; p2++) |
---|
648 | if (*p2 == '\n') |
---|
649 | *p2 = '\0'; |
---|
650 | fputs(p1, stdout); |
---|
651 | free(p1); |
---|
652 | return (0); |
---|
653 | } |
---|
654 | |
---|
655 | static int |
---|
656 | S_vmtotal(size_t l2, void *p) |
---|
657 | { |
---|
658 | struct vmtotal *v = (struct vmtotal *)p; |
---|
659 | int pageKilo = getpagesize() / 1024; |
---|
660 | |
---|
661 | if (l2 != sizeof(*v)) { |
---|
662 | warnx("S_vmtotal %zu != %zu", l2, sizeof(*v)); |
---|
663 | return (1); |
---|
664 | } |
---|
665 | |
---|
666 | printf( |
---|
667 | "\nSystem wide totals computed every five seconds:" |
---|
668 | " (values in kilobytes)\n"); |
---|
669 | printf("===============================================\n"); |
---|
670 | printf( |
---|
671 | "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: " |
---|
672 | "%hd Sleep: %hd)\n", |
---|
673 | v->t_rq, v->t_dw, v->t_pw, v->t_sl); |
---|
674 | printf( |
---|
675 | "Virtual Memory:\t\t(Total: %jdK Active: %jdK)\n", |
---|
676 | (intmax_t)v->t_vm * pageKilo, (intmax_t)v->t_avm * pageKilo); |
---|
677 | printf("Real Memory:\t\t(Total: %jdK Active: %jdK)\n", |
---|
678 | (intmax_t)v->t_rm * pageKilo, (intmax_t)v->t_arm * pageKilo); |
---|
679 | printf("Shared Virtual Memory:\t(Total: %jdK Active: %jdK)\n", |
---|
680 | (intmax_t)v->t_vmshr * pageKilo, (intmax_t)v->t_avmshr * pageKilo); |
---|
681 | printf("Shared Real Memory:\t(Total: %jdK Active: %jdK)\n", |
---|
682 | (intmax_t)v->t_rmshr * pageKilo, (intmax_t)v->t_armshr * pageKilo); |
---|
683 | printf("Free Memory:\t%jdK", (intmax_t)v->t_free * pageKilo); |
---|
684 | |
---|
685 | return (0); |
---|
686 | } |
---|
687 | |
---|
688 | #ifdef __amd64__ |
---|
689 | static int |
---|
690 | S_efi_map(size_t l2, void *p) |
---|
691 | { |
---|
692 | struct efi_map_header *efihdr; |
---|
693 | struct efi_md *map; |
---|
694 | const char *type; |
---|
695 | size_t efisz; |
---|
696 | int ndesc, i; |
---|
697 | |
---|
698 | static const char *types[] = { |
---|
699 | "Reserved", |
---|
700 | "LoaderCode", |
---|
701 | "LoaderData", |
---|
702 | "BootServicesCode", |
---|
703 | "BootServicesData", |
---|
704 | "RuntimeServicesCode", |
---|
705 | "RuntimeServicesData", |
---|
706 | "ConventionalMemory", |
---|
707 | "UnusableMemory", |
---|
708 | "ACPIReclaimMemory", |
---|
709 | "ACPIMemoryNVS", |
---|
710 | "MemoryMappedIO", |
---|
711 | "MemoryMappedIOPortSpace", |
---|
712 | "PalCode" |
---|
713 | }; |
---|
714 | |
---|
715 | /* |
---|
716 | * Memory map data provided by UEFI via the GetMemoryMap |
---|
717 | * Boot Services API. |
---|
718 | */ |
---|
719 | if (l2 < sizeof(*efihdr)) { |
---|
720 | warnx("S_efi_map length less than header"); |
---|
721 | return (1); |
---|
722 | } |
---|
723 | efihdr = p; |
---|
724 | efisz = (sizeof(struct efi_map_header) + 0xf) & ~0xf; |
---|
725 | map = (struct efi_md *)((uint8_t *)efihdr + efisz); |
---|
726 | |
---|
727 | if (efihdr->descriptor_size == 0) |
---|
728 | return (0); |
---|
729 | if (l2 != efisz + efihdr->memory_size) { |
---|
730 | warnx("S_efi_map length mismatch %zu vs %zu", l2, efisz + |
---|
731 | efihdr->memory_size); |
---|
732 | return (1); |
---|
733 | } |
---|
734 | ndesc = efihdr->memory_size / efihdr->descriptor_size; |
---|
735 | |
---|
736 | printf("\n%23s %12s %12s %8s %4s", |
---|
737 | "Type", "Physical", "Virtual", "#Pages", "Attr"); |
---|
738 | |
---|
739 | for (i = 0; i < ndesc; i++, |
---|
740 | map = efi_next_descriptor(map, efihdr->descriptor_size)) { |
---|
741 | if (map->md_type <= EFI_MD_TYPE_PALCODE) |
---|
742 | type = types[map->md_type]; |
---|
743 | else |
---|
744 | type = "<INVALID>"; |
---|
745 | printf("\n%23s %012lx %12p %08lx ", type, map->md_phys, |
---|
746 | map->md_virt, map->md_pages); |
---|
747 | if (map->md_attr & EFI_MD_ATTR_UC) |
---|
748 | printf("UC "); |
---|
749 | if (map->md_attr & EFI_MD_ATTR_WC) |
---|
750 | printf("WC "); |
---|
751 | if (map->md_attr & EFI_MD_ATTR_WT) |
---|
752 | printf("WT "); |
---|
753 | if (map->md_attr & EFI_MD_ATTR_WB) |
---|
754 | printf("WB "); |
---|
755 | if (map->md_attr & EFI_MD_ATTR_UCE) |
---|
756 | printf("UCE "); |
---|
757 | if (map->md_attr & EFI_MD_ATTR_WP) |
---|
758 | printf("WP "); |
---|
759 | if (map->md_attr & EFI_MD_ATTR_RP) |
---|
760 | printf("RP "); |
---|
761 | if (map->md_attr & EFI_MD_ATTR_XP) |
---|
762 | printf("XP "); |
---|
763 | if (map->md_attr & EFI_MD_ATTR_RT) |
---|
764 | printf("RUNTIME"); |
---|
765 | } |
---|
766 | return (0); |
---|
767 | } |
---|
768 | #endif |
---|
769 | |
---|
770 | #if defined(__amd64__) || defined(__i386__) |
---|
771 | static int |
---|
772 | S_bios_smap_xattr(size_t l2, void *p) |
---|
773 | { |
---|
774 | struct bios_smap_xattr *smap, *end; |
---|
775 | |
---|
776 | if (l2 % sizeof(*smap) != 0) { |
---|
777 | warnx("S_bios_smap_xattr %zu is not a multiple of %zu", l2, |
---|
778 | sizeof(*smap)); |
---|
779 | return (1); |
---|
780 | } |
---|
781 | |
---|
782 | end = (struct bios_smap_xattr *)((char *)p + l2); |
---|
783 | for (smap = p; smap < end; smap++) |
---|
784 | printf("\nSMAP type=%02x, xattr=%02x, base=%016jx, len=%016jx", |
---|
785 | smap->type, smap->xattr, (uintmax_t)smap->base, |
---|
786 | (uintmax_t)smap->length); |
---|
787 | return (0); |
---|
788 | } |
---|
789 | #endif |
---|
790 | |
---|
791 | static int |
---|
792 | strIKtoi(const char *str, char **endptrp, const char *fmt) |
---|
793 | { |
---|
794 | int kelv; |
---|
795 | float temp; |
---|
796 | size_t len; |
---|
797 | const char *p; |
---|
798 | int prec, i; |
---|
799 | |
---|
800 | assert(errno == 0); |
---|
801 | |
---|
802 | len = strlen(str); |
---|
803 | /* caller already checked this */ |
---|
804 | assert(len > 0); |
---|
805 | |
---|
806 | /* |
---|
807 | * A format of "IK" is in deciKelvin. A format of "IK3" is in |
---|
808 | * milliKelvin. The single digit following IK is log10 of the |
---|
809 | * multiplying factor to convert Kelvin into the untis of this sysctl, |
---|
810 | * or the dividing factor to convert the sysctl value to Kelvin. Numbers |
---|
811 | * larger than 6 will run into precision issues with 32-bit integers. |
---|
812 | * Characters that aren't ASCII digits after the 'K' are ignored. No |
---|
813 | * localization is present because this is an interface from the kernel |
---|
814 | * to this program (eg not an end-user interface), so isdigit() isn't |
---|
815 | * used here. |
---|
816 | */ |
---|
817 | if (fmt[2] != '\0' && fmt[2] >= '0' && fmt[2] <= '9') |
---|
818 | prec = fmt[2] - '0'; |
---|
819 | else |
---|
820 | prec = 1; |
---|
821 | p = &str[len - 1]; |
---|
822 | if (*p == 'C' || *p == 'F' || *p == 'K') { |
---|
823 | temp = strtof(str, endptrp); |
---|
824 | if (*endptrp != str && *endptrp == p && errno == 0) { |
---|
825 | if (*p == 'F') |
---|
826 | temp = (temp - 32) * 5 / 9; |
---|
827 | *endptrp = NULL; |
---|
828 | if (*p != 'K') |
---|
829 | temp += 273.15; |
---|
830 | for (i = 0; i < prec; i++) |
---|
831 | temp *= 10.0; |
---|
832 | return ((int)(temp + 0.5)); |
---|
833 | } |
---|
834 | } else { |
---|
835 | /* No unit specified -> treat it as a raw number */ |
---|
836 | kelv = (int)strtol(str, endptrp, 10); |
---|
837 | if (*endptrp != str && *endptrp == p && errno == 0) { |
---|
838 | *endptrp = NULL; |
---|
839 | return (kelv); |
---|
840 | } |
---|
841 | } |
---|
842 | |
---|
843 | errno = ERANGE; |
---|
844 | return (0); |
---|
845 | } |
---|
846 | |
---|
847 | /* |
---|
848 | * These functions uses a presently undocumented interface to the kernel |
---|
849 | * to walk the tree and get the type so it can print the value. |
---|
850 | * This interface is under work and consideration, and should probably |
---|
851 | * be killed with a big axe by the first person who can find the time. |
---|
852 | * (be aware though, that the proper interface isn't as obvious as it |
---|
853 | * may seem, there are various conflicting requirements. |
---|
854 | */ |
---|
855 | |
---|
856 | static int |
---|
857 | name2oid(const char *name, int *oidp) |
---|
858 | { |
---|
859 | int oid[2]; |
---|
860 | int i; |
---|
861 | size_t j; |
---|
862 | |
---|
863 | oid[0] = 0; |
---|
864 | oid[1] = 3; |
---|
865 | |
---|
866 | j = CTL_MAXNAME * sizeof(int); |
---|
867 | i = sysctl(oid, 2, oidp, &j, name, strlen(name)); |
---|
868 | if (i < 0) |
---|
869 | return (i); |
---|
870 | j /= sizeof(int); |
---|
871 | return (j); |
---|
872 | } |
---|
873 | |
---|
874 | static int |
---|
875 | oidfmt(int *oid, int len, char *fmt, u_int *kind) |
---|
876 | { |
---|
877 | int qoid[CTL_MAXNAME+2]; |
---|
878 | u_char buf[BUFSIZ]; |
---|
879 | int i; |
---|
880 | size_t j; |
---|
881 | |
---|
882 | qoid[0] = 0; |
---|
883 | qoid[1] = 4; |
---|
884 | memcpy(qoid + 2, oid, len * sizeof(int)); |
---|
885 | |
---|
886 | j = sizeof(buf); |
---|
887 | i = sysctl(qoid, len + 2, buf, &j, 0, 0); |
---|
888 | if (i) |
---|
889 | err(1, "sysctl fmt %d %zu %d", i, j, errno); |
---|
890 | |
---|
891 | if (kind) |
---|
892 | *kind = *(u_int *)buf; |
---|
893 | |
---|
894 | if (fmt) |
---|
895 | strcpy(fmt, (char *)(buf + sizeof(u_int))); |
---|
896 | return (0); |
---|
897 | } |
---|
898 | |
---|
899 | /* |
---|
900 | * This formats and outputs the value of one variable |
---|
901 | * |
---|
902 | * Returns zero if anything was actually output. |
---|
903 | * Returns one if didn't know what to do with this. |
---|
904 | * Return minus one if we had errors. |
---|
905 | */ |
---|
906 | static int |
---|
907 | show_var(int *oid, int nlen) |
---|
908 | { |
---|
909 | u_char buf[BUFSIZ], *val, *oval, *p; |
---|
910 | char name[BUFSIZ], fmt[BUFSIZ]; |
---|
911 | const char *sep, *sep1, *prntype; |
---|
912 | int qoid[CTL_MAXNAME+2]; |
---|
913 | uintmax_t umv; |
---|
914 | intmax_t mv; |
---|
915 | int i, hexlen, sign, ctltype; |
---|
916 | size_t intlen; |
---|
917 | size_t j, len; |
---|
918 | u_int kind; |
---|
919 | float base; |
---|
920 | int (*func)(size_t, void *); |
---|
921 | int prec; |
---|
922 | |
---|
923 | /* Silence GCC. */ |
---|
924 | umv = mv = intlen = 0; |
---|
925 | |
---|
926 | bzero(buf, BUFSIZ); |
---|
927 | bzero(fmt, BUFSIZ); |
---|
928 | bzero(name, BUFSIZ); |
---|
929 | qoid[0] = 0; |
---|
930 | memcpy(qoid + 2, oid, nlen * sizeof(int)); |
---|
931 | |
---|
932 | qoid[1] = 1; |
---|
933 | j = sizeof(name); |
---|
934 | i = sysctl(qoid, nlen + 2, name, &j, 0, 0); |
---|
935 | if (i || !j) |
---|
936 | err(1, "sysctl name %d %zu %d", i, j, errno); |
---|
937 | |
---|
938 | oidfmt(oid, nlen, fmt, &kind); |
---|
939 | /* if Wflag then only list sysctls that are writeable and not stats. */ |
---|
940 | if (Wflag && ((kind & CTLFLAG_WR) == 0 || (kind & CTLFLAG_STATS) != 0)) |
---|
941 | return 1; |
---|
942 | |
---|
943 | /* if Tflag then only list sysctls that are tuneables. */ |
---|
944 | if (Tflag && (kind & CTLFLAG_TUN) == 0) |
---|
945 | return 1; |
---|
946 | |
---|
947 | if (Nflag) { |
---|
948 | printf("%s", name); |
---|
949 | return (0); |
---|
950 | } |
---|
951 | |
---|
952 | if (eflag) |
---|
953 | sep = "="; |
---|
954 | else |
---|
955 | sep = ": "; |
---|
956 | |
---|
957 | ctltype = (kind & CTLTYPE); |
---|
958 | if (tflag || dflag) { |
---|
959 | if (!nflag) |
---|
960 | printf("%s%s", name, sep); |
---|
961 | if (ctl_typename[ctltype] != NULL) |
---|
962 | prntype = ctl_typename[ctltype]; |
---|
963 | else |
---|
964 | prntype = "unknown"; |
---|
965 | if (tflag && dflag) |
---|
966 | printf("%s%s", prntype, sep); |
---|
967 | else if (tflag) { |
---|
968 | printf("%s", prntype); |
---|
969 | return (0); |
---|
970 | } |
---|
971 | qoid[1] = 5; |
---|
972 | j = sizeof(buf); |
---|
973 | i = sysctl(qoid, nlen + 2, buf, &j, 0, 0); |
---|
974 | printf("%s", buf); |
---|
975 | return (0); |
---|
976 | } |
---|
977 | /* find an estimate of how much we need for this var */ |
---|
978 | if (Bflag) |
---|
979 | j = Bflag; |
---|
980 | else { |
---|
981 | j = 0; |
---|
982 | i = sysctl(oid, nlen, 0, &j, 0, 0); |
---|
983 | j += j; /* we want to be sure :-) */ |
---|
984 | } |
---|
985 | |
---|
986 | val = oval = malloc(j + 1); |
---|
987 | if (val == NULL) { |
---|
988 | warnx("malloc failed"); |
---|
989 | return (1); |
---|
990 | } |
---|
991 | len = j; |
---|
992 | i = sysctl(oid, nlen, val, &len, 0, 0); |
---|
993 | if (i != 0 || (len == 0 && ctltype != CTLTYPE_STRING)) { |
---|
994 | free(oval); |
---|
995 | return (1); |
---|
996 | } |
---|
997 | |
---|
998 | if (bflag) { |
---|
999 | fwrite(val, 1, len, stdout); |
---|
1000 | free(oval); |
---|
1001 | return (0); |
---|
1002 | } |
---|
1003 | val[len] = '\0'; |
---|
1004 | p = val; |
---|
1005 | sign = ctl_sign[ctltype]; |
---|
1006 | intlen = ctl_size[ctltype]; |
---|
1007 | |
---|
1008 | switch (ctltype) { |
---|
1009 | case CTLTYPE_STRING: |
---|
1010 | if (!nflag) |
---|
1011 | printf("%s%s", name, sep); |
---|
1012 | printf("%.*s", (int)len, p); |
---|
1013 | free(oval); |
---|
1014 | return (0); |
---|
1015 | |
---|
1016 | case CTLTYPE_INT: |
---|
1017 | case CTLTYPE_UINT: |
---|
1018 | case CTLTYPE_LONG: |
---|
1019 | case CTLTYPE_ULONG: |
---|
1020 | case CTLTYPE_S8: |
---|
1021 | case CTLTYPE_S16: |
---|
1022 | case CTLTYPE_S32: |
---|
1023 | case CTLTYPE_S64: |
---|
1024 | case CTLTYPE_U8: |
---|
1025 | case CTLTYPE_U16: |
---|
1026 | case CTLTYPE_U32: |
---|
1027 | case CTLTYPE_U64: |
---|
1028 | if (!nflag) |
---|
1029 | printf("%s%s", name, sep); |
---|
1030 | hexlen = 2 + (intlen * CHAR_BIT + 3) / 4; |
---|
1031 | sep1 = ""; |
---|
1032 | while (len >= intlen) { |
---|
1033 | switch (kind & CTLTYPE) { |
---|
1034 | case CTLTYPE_INT: |
---|
1035 | case CTLTYPE_UINT: |
---|
1036 | umv = *(u_int *)p; |
---|
1037 | mv = *(int *)p; |
---|
1038 | break; |
---|
1039 | case CTLTYPE_LONG: |
---|
1040 | case CTLTYPE_ULONG: |
---|
1041 | umv = *(u_long *)p; |
---|
1042 | mv = *(long *)p; |
---|
1043 | break; |
---|
1044 | case CTLTYPE_S8: |
---|
1045 | case CTLTYPE_U8: |
---|
1046 | umv = *(uint8_t *)p; |
---|
1047 | mv = *(int8_t *)p; |
---|
1048 | break; |
---|
1049 | case CTLTYPE_S16: |
---|
1050 | case CTLTYPE_U16: |
---|
1051 | umv = *(uint16_t *)p; |
---|
1052 | mv = *(int16_t *)p; |
---|
1053 | break; |
---|
1054 | case CTLTYPE_S32: |
---|
1055 | case CTLTYPE_U32: |
---|
1056 | umv = *(uint32_t *)p; |
---|
1057 | mv = *(int32_t *)p; |
---|
1058 | break; |
---|
1059 | case CTLTYPE_S64: |
---|
1060 | case CTLTYPE_U64: |
---|
1061 | umv = *(uint64_t *)p; |
---|
1062 | mv = *(int64_t *)p; |
---|
1063 | break; |
---|
1064 | } |
---|
1065 | fputs(sep1, stdout); |
---|
1066 | if (xflag) |
---|
1067 | printf("%#0*jx", hexlen, umv); |
---|
1068 | else if (!sign) |
---|
1069 | printf(hflag ? "%'ju" : "%ju", umv); |
---|
1070 | else if (fmt[1] == 'K') { |
---|
1071 | if (mv < 0) |
---|
1072 | printf("%jd", mv); |
---|
1073 | else { |
---|
1074 | /* |
---|
1075 | * See strIKtoi for details on fmt. |
---|
1076 | */ |
---|
1077 | prec = 1; |
---|
1078 | if (fmt[2] != '\0') |
---|
1079 | prec = fmt[2] - '0'; |
---|
1080 | base = 1.0; |
---|
1081 | for (int i = 0; i < prec; i++) |
---|
1082 | base *= 10.0; |
---|
1083 | printf("%.*fC", prec, |
---|
1084 | (float)mv / base - 273.15); |
---|
1085 | } |
---|
1086 | } else |
---|
1087 | printf(hflag ? "%'jd" : "%jd", mv); |
---|
1088 | sep1 = " "; |
---|
1089 | len -= intlen; |
---|
1090 | p += intlen; |
---|
1091 | } |
---|
1092 | free(oval); |
---|
1093 | return (0); |
---|
1094 | |
---|
1095 | case CTLTYPE_OPAQUE: |
---|
1096 | i = 0; |
---|
1097 | if (strcmp(fmt, "S,clockinfo") == 0) |
---|
1098 | #ifndef __rtems__ |
---|
1099 | func = S_clockinfo; |
---|
1100 | #else /* __rtems__ */ |
---|
1101 | func = NULL; |
---|
1102 | #endif /* __rtems__ */ |
---|
1103 | else if (strcmp(fmt, "S,timeval") == 0) |
---|
1104 | func = S_timeval; |
---|
1105 | else if (strcmp(fmt, "S,loadavg") == 0) |
---|
1106 | func = S_loadavg; |
---|
1107 | else if (strcmp(fmt, "S,vmtotal") == 0) |
---|
1108 | func = S_vmtotal; |
---|
1109 | #ifdef __amd64__ |
---|
1110 | else if (strcmp(fmt, "S,efi_map_header") == 0) |
---|
1111 | func = S_efi_map; |
---|
1112 | #endif |
---|
1113 | #if defined(__amd64__) || defined(__i386__) |
---|
1114 | else if (strcmp(fmt, "S,bios_smap_xattr") == 0) |
---|
1115 | func = S_bios_smap_xattr; |
---|
1116 | #endif |
---|
1117 | else |
---|
1118 | func = NULL; |
---|
1119 | if (func) { |
---|
1120 | if (!nflag) |
---|
1121 | printf("%s%s", name, sep); |
---|
1122 | i = (*func)(len, p); |
---|
1123 | free(oval); |
---|
1124 | return (i); |
---|
1125 | } |
---|
1126 | /* FALLTHROUGH */ |
---|
1127 | default: |
---|
1128 | if (!oflag && !xflag) { |
---|
1129 | free(oval); |
---|
1130 | return (1); |
---|
1131 | } |
---|
1132 | if (!nflag) |
---|
1133 | printf("%s%s", name, sep); |
---|
1134 | printf("Format:%s Length:%zu Dump:0x", fmt, len); |
---|
1135 | while (len-- && (xflag || p < val + 16)) |
---|
1136 | printf("%02x", *p++); |
---|
1137 | if (!xflag && len > 16) |
---|
1138 | printf("..."); |
---|
1139 | free(oval); |
---|
1140 | return (0); |
---|
1141 | } |
---|
1142 | free(oval); |
---|
1143 | return (1); |
---|
1144 | } |
---|
1145 | |
---|
1146 | static int |
---|
1147 | sysctl_all(int *oid, int len) |
---|
1148 | { |
---|
1149 | int name1[22], name2[22]; |
---|
1150 | int i, j; |
---|
1151 | size_t l1, l2; |
---|
1152 | |
---|
1153 | name1[0] = 0; |
---|
1154 | name1[1] = 2; |
---|
1155 | l1 = 2; |
---|
1156 | if (len) { |
---|
1157 | memcpy(name1+2, oid, len * sizeof(int)); |
---|
1158 | l1 += len; |
---|
1159 | } else { |
---|
1160 | name1[2] = 1; |
---|
1161 | l1++; |
---|
1162 | } |
---|
1163 | for (;;) { |
---|
1164 | l2 = sizeof(name2); |
---|
1165 | j = sysctl(name1, l1, name2, &l2, 0, 0); |
---|
1166 | if (j < 0) { |
---|
1167 | if (errno == ENOENT) |
---|
1168 | return (0); |
---|
1169 | else |
---|
1170 | err(1, "sysctl(getnext) %d %zu", j, l2); |
---|
1171 | } |
---|
1172 | |
---|
1173 | l2 /= sizeof(int); |
---|
1174 | |
---|
1175 | if (len < 0 || l2 < (unsigned int)len) |
---|
1176 | return (0); |
---|
1177 | |
---|
1178 | for (i = 0; i < len; i++) |
---|
1179 | if (name2[i] != oid[i]) |
---|
1180 | return (0); |
---|
1181 | |
---|
1182 | i = show_var(name2, l2); |
---|
1183 | if (!i && !bflag) |
---|
1184 | putchar('\n'); |
---|
1185 | |
---|
1186 | memcpy(name1+2, name2, l2 * sizeof(int)); |
---|
1187 | l1 = 2 + l2; |
---|
1188 | } |
---|
1189 | } |
---|