source: rtems-libbsd/freebsd/sbin/sysctl/sysctl.c @ f575822

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since f575822 was 83eb07c, checked in by Chris Johns <chrisj@…>, on 05/06/16 at 05:06:08

Add sbin/sysctl

  • Property mode set to 100644
File size: 17.2 KB
Line 
1#include <machine/rtems-bsd-user-space.h>
2
3/*
4 * Copyright (c) 1993
5 *      The Regents of the University of California.  All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 *    notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 *    notice, this list of conditions and the following disclaimer in the
14 *    documentation and/or other materials provided with the distribution.
15 * 4. Neither the name of the University nor the names of its contributors
16 *    may be used to endorse or promote products derived from this software
17 *    without specific prior written permission.
18 *
19 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
29 * SUCH DAMAGE.
30 */
31
32#ifndef lint
33static const char copyright[] =
34"@(#) Copyright (c) 1993\n\
35        The Regents of the University of California.  All rights reserved.\n";
36#endif /* not lint */
37
38#ifndef lint
39#if 0
40static char sccsid[] = "@(#)from: sysctl.c      8.1 (Berkeley) 6/6/93";
41#endif
42static const char rcsid[] =
43  "$FreeBSD$";
44#endif /* not lint */
45#ifdef __rtems__
46#define __need_getopt_newlib
47#include <getopt.h>
48#include <machine/rtems-bsd-program.h>
49#include <machine/rtems-bsd-commands.h>
50#endif /* __rtems__ */
51
52#include <rtems/bsd/sys/param.h>
53#include <rtems/bsd/sys/time.h>
54#include <rtems/bsd/sys/resource.h>
55#include <sys/stat.h>
56#include <sys/sysctl.h>
57#include <sys/vmmeter.h>
58
59#include <ctype.h>
60#include <err.h>
61#include <errno.h>
62#include <inttypes.h>
63#include <locale.h>
64#include <stdio.h>
65#include <stdlib.h>
66#include <string.h>
67#include <unistd.h>
68
69static int      aflag, bflag, dflag, eflag, hflag, iflag;
70static int      Nflag, nflag, oflag, qflag, xflag, warncount;
71
72static int      oidfmt(int *, int, char *, u_int *);
73static void     parse(const char *);
74static int      show_var(int *, int);
75static int      sysctl_all(int *oid, int len);
76static int      name2oid(char *, int *);
77
78static int      set_IK(const char *, int *);
79
80static void
81usage(void)
82{
83
84        (void)fprintf(stderr, "%s\n%s\n",
85            "usage: sysctl [-bdehiNnoqx] name[=value] ...",
86            "       sysctl [-bdehNnoqx] -a");
87        exit(1);
88}
89
90#ifdef __rtems__
91static int main(int argc, char **argv);
92
93int rtems_bsd_command_sysctl(int argc, char *argv[])
94{
95        int exit_code;
96
97        rtems_bsd_program_lock();
98
99        aflag = bflag = dflag = eflag = hflag = iflag = 0;
100        Nflag = nflag = oflag = qflag = xflag = warncount = 0;
101
102        exit_code = rtems_bsd_program_call_main("sysctl", main, argc, argv);
103
104        rtems_bsd_program_unlock();
105
106        return exit_code;
107}
108#endif /* __rtems__ */
109
110int
111main(int argc, char **argv)
112{
113        int ch;
114
115#ifdef __rtems__
116        struct getopt_data getopt_data;
117        memset(&getopt_data, 0, sizeof(getopt_data));
118#define optind getopt_data.optind
119#define optarg getopt_data.optarg
120#define opterr getopt_data.opterr
121#define optopt getopt_data.optopt
122#define getopt(argc, argv, opt) getopt_r(argc, argv, "+" opt, &getopt_data)
123#endif /* __rtems__ */
124
125#ifndef __rtems__
126        setlocale(LC_NUMERIC, "");
127        setbuf(stdout,0);
128        setbuf(stderr,0);
129#endif /* __rtems__ */
130
131        while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) {
132                switch (ch) {
133                case 'A':
134                        /* compatibility */
135                        aflag = oflag = 1;
136                        break;
137                case 'a':
138                        aflag = 1;
139                        break;
140                case 'b':
141                        bflag = 1;
142                        break;
143                case 'd':
144                        dflag = 1;
145                        break;
146                case 'e':
147                        eflag = 1;
148                        break;
149                case 'h':
150                        hflag = 1;
151                        break;
152                case 'i':
153                        iflag = 1;
154                        break;
155                case 'N':
156                        Nflag = 1;
157                        break;
158                case 'n':
159                        nflag = 1;
160                        break;
161                case 'o':
162                        oflag = 1;
163                        break;
164                case 'q':
165                        qflag = 1;
166                        break;
167                case 'w':
168                        /* compatibility */
169                        /* ignored */
170                        break;
171                case 'X':
172                        /* compatibility */
173                        aflag = xflag = 1;
174                        break;
175                case 'x':
176                        xflag = 1;
177                        break;
178                default:
179                        usage();
180                }
181        }
182        argc -= optind;
183        argv += optind;
184
185        if (Nflag && nflag)
186                usage();
187        if (aflag && argc == 0)
188                exit(sysctl_all(0, 0));
189        if (argc == 0)
190                usage();
191
192        warncount = 0;
193        while (argc-- > 0)
194                parse(*argv++);
195        exit(warncount);
196}
197
198/*
199 * Parse a name into a MIB entry.
200 * Lookup and print out the MIB entry if it exists.
201 * Set a new value if requested.
202 */
203static void
204parse(const char *string)
205{
206        int len, i, j;
207        void *newval = 0;
208        int intval;
209        unsigned int uintval;
210        long longval;
211        unsigned long ulongval;
212        size_t newsize = 0;
213        int64_t i64val;
214        uint64_t u64val;
215        int mib[CTL_MAXNAME];
216        char *cp, *bufp, buf[BUFSIZ], *endptr, fmt[BUFSIZ];
217        u_int kind;
218
219        cp = buf;
220        if (snprintf(buf, BUFSIZ, "%s", string) >= BUFSIZ)
221                errx(1, "oid too long: '%s'", string);
222        bufp = strsep(&cp, "=");
223        if (cp != NULL) {
224                while (isspace(*cp))
225                        cp++;
226                newval = cp;
227                newsize = strlen(cp);
228        }
229        len = name2oid(bufp, mib);
230
231        if (len < 0) {
232                if (iflag)
233                        return;
234                if (qflag)
235                        exit(1);
236                else
237                        errx(1, "unknown oid '%s'", bufp);
238        }
239
240        if (oidfmt(mib, len, fmt, &kind))
241                err(1, "couldn't find format of oid '%s'", bufp);
242
243        if (newval == NULL || dflag) {
244                if ((kind & CTLTYPE) == CTLTYPE_NODE) {
245                        if (dflag) {
246                                i = show_var(mib, len);
247                                if (!i && !bflag)
248                                        putchar('\n');
249                        }
250                        sysctl_all(mib, len);
251                } else {
252                        i = show_var(mib, len);
253                        if (!i && !bflag)
254                                putchar('\n');
255                }
256        } else {
257                if ((kind & CTLTYPE) == CTLTYPE_NODE)
258                        errx(1, "oid '%s' isn't a leaf node", bufp);
259
260                if (!(kind & CTLFLAG_WR)) {
261                        if (kind & CTLFLAG_TUN) {
262                                warnx("oid '%s' is a read only tunable", bufp);
263                                errx(1, "Tunable values are set in /boot/loader.conf");
264                        } else {
265                                errx(1, "oid '%s' is read only", bufp);
266                        }
267                }
268
269                if ((kind & CTLTYPE) == CTLTYPE_INT ||
270                    (kind & CTLTYPE) == CTLTYPE_UINT ||
271                    (kind & CTLTYPE) == CTLTYPE_LONG ||
272                    (kind & CTLTYPE) == CTLTYPE_ULONG ||
273                    (kind & CTLTYPE) == CTLTYPE_S64 ||
274                    (kind & CTLTYPE) == CTLTYPE_U64) {
275                        if (strlen(newval) == 0)
276                                errx(1, "empty numeric value");
277                }
278
279                switch (kind & CTLTYPE) {
280                        case CTLTYPE_INT:
281                                if (strcmp(fmt, "IK") == 0) {
282                                        if (!set_IK(newval, &intval))
283                                                errx(1, "invalid value '%s'",
284                                                    (char *)newval);
285                                } else {
286                                        intval = (int)strtol(newval, &endptr,
287                                            0);
288                                        if (endptr == newval || *endptr != '\0')
289                                                errx(1, "invalid integer '%s'",
290                                                    (char *)newval);
291                                }
292                                newval = &intval;
293                                newsize = sizeof(intval);
294                                break;
295                        case CTLTYPE_UINT:
296                                uintval = (int) strtoul(newval, &endptr, 0);
297                                if (endptr == newval || *endptr != '\0')
298                                        errx(1, "invalid unsigned integer '%s'",
299                                            (char *)newval);
300                                newval = &uintval;
301                                newsize = sizeof(uintval);
302                                break;
303                        case CTLTYPE_LONG:
304                                longval = strtol(newval, &endptr, 0);
305                                if (endptr == newval || *endptr != '\0')
306                                        errx(1, "invalid long integer '%s'",
307                                            (char *)newval);
308                                newval = &longval;
309                                newsize = sizeof(longval);
310                                break;
311                        case CTLTYPE_ULONG:
312                                ulongval = strtoul(newval, &endptr, 0);
313                                if (endptr == newval || *endptr != '\0')
314                                        errx(1, "invalid unsigned long integer"
315                                            " '%s'", (char *)newval);
316                                newval = &ulongval;
317                                newsize = sizeof(ulongval);
318                                break;
319                        case CTLTYPE_STRING:
320                                break;
321                        case CTLTYPE_S64:
322                                i64val = strtoimax(newval, &endptr, 0);
323                                if (endptr == newval || *endptr != '\0')
324                                        errx(1, "invalid int64_t '%s'",
325                                            (char *)newval);
326                                newval = &i64val;
327                                newsize = sizeof(i64val);
328                                break;
329                        case CTLTYPE_U64:
330                                u64val = strtoumax(newval, &endptr, 0);
331                                if (endptr == newval || *endptr != '\0')
332                                        errx(1, "invalid uint64_t '%s'",
333                                            (char *)newval);
334                                newval = &u64val;
335                                newsize = sizeof(u64val);
336                                break;
337                        case CTLTYPE_OPAQUE:
338                                /* FALLTHROUGH */
339                        default:
340                                errx(1, "oid '%s' is type %d,"
341                                        " cannot set that", bufp,
342                                        kind & CTLTYPE);
343                }
344
345                i = show_var(mib, len);
346                if (sysctl(mib, len, 0, 0, newval, newsize) == -1) {
347                        if (!i && !bflag)
348                                putchar('\n');
349                        switch (errno) {
350                        case EOPNOTSUPP:
351                                errx(1, "%s: value is not available",
352                                        string);
353                        case ENOTDIR:
354                                errx(1, "%s: specification is incomplete",
355                                        string);
356                        case ENOMEM:
357                                errx(1, "%s: type is unknown to this program",
358                                        string);
359                        default:
360                                warn("%s", string);
361                                warncount++;
362                                return;
363                        }
364                }
365                if (!bflag)
366                        printf(" -> ");
367                i = nflag;
368                nflag = 1;
369                j = show_var(mib, len);
370                if (!j && !bflag)
371                        putchar('\n');
372                nflag = i;
373        }
374}
375
376/* These functions will dump out various interesting structures. */
377
378static int
379S_clockinfo(int l2, void *p)
380{
381#ifndef __rtems__
382        struct clockinfo *ci = (struct clockinfo*)p;
383
384        if (l2 != sizeof(*ci)) {
385                warnx("S_clockinfo %d != %zu", l2, sizeof(*ci));
386                return (1);
387        }
388        printf(hflag ? "{ hz = %'d, tick = %'d, profhz = %'d, stathz = %'d }" :
389                "{ hz = %d, tick = %d, profhz = %d, stathz = %d }",
390                ci->hz, ci->tick, ci->profhz, ci->stathz);
391#endif /* __rtems__ */
392        return (0);
393}
394
395static int
396S_loadavg(int l2, void *p)
397{
398        struct loadavg *tv = (struct loadavg*)p;
399
400        if (l2 != sizeof(*tv)) {
401                warnx("S_loadavg %d != %zu", l2, sizeof(*tv));
402                return (1);
403        }
404        printf(hflag ? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
405                (double)tv->ldavg[0]/(double)tv->fscale,
406                (double)tv->ldavg[1]/(double)tv->fscale,
407                (double)tv->ldavg[2]/(double)tv->fscale);
408        return (0);
409}
410
411static int
412S_timeval(int l2, void *p)
413{
414        struct timeval *tv = (struct timeval*)p;
415        time_t tv_sec;
416        char *p1, *p2;
417
418        if (l2 != sizeof(*tv)) {
419                warnx("S_timeval %d != %zu", l2, sizeof(*tv));
420                return (1);
421        }
422        printf(hflag ? "{ sec = %'jd, usec = %'ld } " :
423                "{ sec = %jd, usec = %ld } ",
424                (intmax_t)tv->tv_sec, tv->tv_usec);
425        tv_sec = tv->tv_sec;
426        p1 = strdup(ctime(&tv_sec));
427        for (p2=p1; *p2 ; p2++)
428                if (*p2 == '\n')
429                        *p2 = '\0';
430        fputs(p1, stdout);
431        free(p1);
432        return (0);
433}
434
435static int
436S_vmtotal(int l2, void *p)
437{
438        struct vmtotal *v = (struct vmtotal *)p;
439        int pageKilo = getpagesize() / 1024;
440
441        if (l2 != sizeof(*v)) {
442                warnx("S_vmtotal %d != %zu", l2, sizeof(*v));
443                return (1);
444        }
445
446        printf(
447            "\nSystem wide totals computed every five seconds:"
448            " (values in kilobytes)\n");
449        printf("===============================================\n");
450        printf(
451            "Processes:\t\t(RUNQ: %hd Disk Wait: %hd Page Wait: "
452            "%hd Sleep: %hd)\n",
453            v->t_rq, v->t_dw, v->t_pw, v->t_sl);
454        printf(
455            "Virtual Memory:\t\t(Total: %dK Active: %dK)\n",
456            v->t_vm * pageKilo, v->t_avm * pageKilo);
457        printf("Real Memory:\t\t(Total: %dK Active: %dK)\n",
458            v->t_rm * pageKilo, v->t_arm * pageKilo);
459        printf("Shared Virtual Memory:\t(Total: %dK Active: %dK)\n",
460            v->t_vmshr * pageKilo, v->t_avmshr * pageKilo);
461        printf("Shared Real Memory:\t(Total: %dK Active: %dK)\n",
462            v->t_rmshr * pageKilo, v->t_armshr * pageKilo);
463        printf("Free Memory:\t%dK\n", v->t_free * pageKilo);
464
465        return (0);
466}
467
468static int
469set_IK(const char *str, int *val)
470{
471        float temp;
472        int len, kelv;
473        const char *p;
474        char *endptr;
475
476        if ((len = strlen(str)) == 0)
477                return (0);
478        p = &str[len - 1];
479        if (*p == 'C' || *p == 'F') {
480                temp = strtof(str, &endptr);
481                if (endptr == str || endptr != p)
482                        return (0);
483                if (*p == 'F')
484                        temp = (temp - 32) * 5 / 9;
485                kelv = temp * 10 + 2732;
486        } else {
487                kelv = (int)strtol(str, &endptr, 10);
488                if (endptr == str || *endptr != '\0')
489                        return (0);
490        }
491        *val = kelv;
492        return (1);
493}
494
495/*
496 * These functions uses a presently undocumented interface to the kernel
497 * to walk the tree and get the type so it can print the value.
498 * This interface is under work and consideration, and should probably
499 * be killed with a big axe by the first person who can find the time.
500 * (be aware though, that the proper interface isn't as obvious as it
501 * may seem, there are various conflicting requirements.
502 */
503
504static int
505name2oid(char *name, int *oidp)
506{
507        int oid[2];
508        int i;
509        size_t j;
510
511        oid[0] = 0;
512        oid[1] = 3;
513
514        j = CTL_MAXNAME * sizeof(int);
515        i = sysctl(oid, 2, oidp, &j, name, strlen(name));
516        if (i < 0)
517                return (i);
518        j /= sizeof(int);
519        return (j);
520}
521
522static int
523oidfmt(int *oid, int len, char *fmt, u_int *kind)
524{
525        int qoid[CTL_MAXNAME+2];
526        u_char buf[BUFSIZ];
527        int i;
528        size_t j;
529
530        qoid[0] = 0;
531        qoid[1] = 4;
532        memcpy(qoid + 2, oid, len * sizeof(int));
533
534        j = sizeof(buf);
535        i = sysctl(qoid, len + 2, buf, &j, 0, 0);
536        if (i)
537                err(1, "sysctl fmt %d %zu %d", i, j, errno);
538
539        if (kind)
540                *kind = *(u_int *)buf;
541
542        if (fmt)
543                strcpy(fmt, (char *)(buf + sizeof(u_int)));
544        return (0);
545}
546
547static int ctl_sign[CTLTYPE+1] = {
548        [CTLTYPE_INT] = 1,
549        [CTLTYPE_LONG] = 1,
550        [CTLTYPE_S64] = 1,
551};
552
553static int ctl_size[CTLTYPE+1] = {
554        [CTLTYPE_INT] = sizeof(int),
555        [CTLTYPE_UINT] = sizeof(u_int),
556        [CTLTYPE_LONG] = sizeof(long),
557        [CTLTYPE_ULONG] = sizeof(u_long),
558        [CTLTYPE_S64] = sizeof(int64_t),
559        [CTLTYPE_U64] = sizeof(int64_t),
560};
561
562/*
563 * This formats and outputs the value of one variable
564 *
565 * Returns zero if anything was actually output.
566 * Returns one if didn't know what to do with this.
567 * Return minus one if we had errors.
568 */
569static int
570show_var(int *oid, int nlen)
571{
572        u_char buf[BUFSIZ], *val, *oval, *p;
573        char name[BUFSIZ], *fmt;
574        const char *sep, *sep1;
575        int qoid[CTL_MAXNAME+2];
576        uintmax_t umv;
577        intmax_t mv;
578        int i, hexlen, sign, ctltype;
579        size_t intlen;
580        size_t j, len;
581        u_int kind;
582        int (*func)(int, void *);
583
584        /* Silence GCC. */
585        umv = mv = intlen = 0;
586
587        bzero(buf, BUFSIZ);
588        bzero(name, BUFSIZ);
589        qoid[0] = 0;
590        memcpy(qoid + 2, oid, nlen * sizeof(int));
591
592        qoid[1] = 1;
593        j = sizeof(name);
594        i = sysctl(qoid, nlen + 2, name, &j, 0, 0);
595        if (i || !j)
596                err(1, "sysctl name %d %zu %d", i, j, errno);
597
598        if (Nflag) {
599                printf("%s", name);
600                return (0);
601        }
602
603        if (eflag)
604                sep = "=";
605        else
606                sep = ": ";
607
608        if (dflag) {    /* just print description */
609                qoid[1] = 5;
610                j = sizeof(buf);
611                i = sysctl(qoid, nlen + 2, buf, &j, 0, 0);
612                if (!nflag)
613                        printf("%s%s", name, sep);
614                printf("%s", buf);
615                return (0);
616        }
617        /* find an estimate of how much we need for this var */
618        j = 0;
619        i = sysctl(oid, nlen, 0, &j, 0, 0);
620        j += j; /* we want to be sure :-) */
621
622        val = oval = malloc(j + 1);
623        if (val == NULL) {
624                warnx("malloc failed");
625                return (1);
626        }
627        len = j;
628        i = sysctl(oid, nlen, val, &len, 0, 0);
629        if (i || !len) {
630                free(oval);
631                return (1);
632        }
633
634        if (bflag) {
635                fwrite(val, 1, len, stdout);
636                free(oval);
637                return (0);
638        }
639        val[len] = '\0';
640        fmt = buf;
641        oidfmt(oid, nlen, fmt, &kind);
642        p = val;
643        ctltype = (kind & CTLTYPE);
644        sign = ctl_sign[ctltype];
645        intlen = ctl_size[ctltype];
646
647        switch (ctltype) {
648        case CTLTYPE_STRING:
649                if (!nflag)
650                        printf("%s%s", name, sep);
651                printf("%.*s", (int)len, p);
652                free(oval);
653                return (0);
654
655        case CTLTYPE_INT:
656        case CTLTYPE_UINT:
657        case CTLTYPE_LONG:
658        case CTLTYPE_ULONG:
659        case CTLTYPE_S64:
660        case CTLTYPE_U64:
661                if (!nflag)
662                        printf("%s%s", name, sep);
663                hexlen = 2 + (intlen * CHAR_BIT + 3) / 4;
664                sep1 = "";
665                while (len >= intlen) {
666                        switch (kind & CTLTYPE) {
667                        case CTLTYPE_INT:
668                        case CTLTYPE_UINT:
669                                umv = *(u_int *)p;
670                                mv = *(int *)p;
671                                break;
672                        case CTLTYPE_LONG:
673                        case CTLTYPE_ULONG:
674                                umv = *(u_long *)p;
675                                mv = *(long *)p;
676                                break;
677                        case CTLTYPE_S64:
678                        case CTLTYPE_U64:
679                                umv = *(uint64_t *)p;
680                                mv = *(int64_t *)p;
681                                break;
682                        }
683                        fputs(sep1, stdout);
684                        if (xflag)
685                                printf("%#0*jx", hexlen, umv);
686                        else if (!sign)
687                                printf(hflag ? "%'ju" : "%ju", umv);
688                        else if (fmt[1] == 'K') {
689                                if (mv < 0)
690                                        printf("%jd", mv);
691                                else
692                                        printf("%.1fC", (mv - 2732.0) / 10);
693                        } else
694                                printf(hflag ? "%'jd" : "%jd", mv);
695                        sep1 = " ";
696                        len -= intlen;
697                        p += intlen;
698                }
699                free(oval);
700                return (0);
701
702        case CTLTYPE_OPAQUE:
703                i = 0;
704                if (strcmp(fmt, "S,clockinfo") == 0)
705                        func = S_clockinfo;
706                else if (strcmp(fmt, "S,timeval") == 0)
707                        func = S_timeval;
708                else if (strcmp(fmt, "S,loadavg") == 0)
709                        func = S_loadavg;
710                else if (strcmp(fmt, "S,vmtotal") == 0)
711                        func = S_vmtotal;
712                else
713                        func = NULL;
714                if (func) {
715                        if (!nflag)
716                                printf("%s%s", name, sep);
717                        i = (*func)(len, p);
718                        free(oval);
719                        return (i);
720                }
721                /* FALLTHROUGH */
722        default:
723                if (!oflag && !xflag) {
724                        free(oval);
725                        return (1);
726                }
727                if (!nflag)
728                        printf("%s%s", name, sep);
729                printf("Format:%s Length:%zu Dump:0x", fmt, len);
730                while (len-- && (xflag || p < val + 16))
731                        printf("%02x", *p++);
732                if (!xflag && len > 16)
733                        printf("...");
734                free(oval);
735                return (0);
736        }
737        free(oval);
738        return (1);
739}
740
741static int
742sysctl_all(int *oid, int len)
743{
744        int name1[22], name2[22];
745        int i, j;
746        size_t l1, l2;
747
748        name1[0] = 0;
749        name1[1] = 2;
750        l1 = 2;
751        if (len) {
752                memcpy(name1+2, oid, len * sizeof(int));
753                l1 += len;
754        } else {
755                name1[2] = 1;
756                l1++;
757        }
758        for (;;) {
759                l2 = sizeof(name2);
760                j = sysctl(name1, l1, name2, &l2, 0, 0);
761                if (j < 0) {
762                        if (errno == ENOENT)
763                                return (0);
764                        else
765                                err(1, "sysctl(getnext) %d %zu", j, l2);
766                }
767
768                l2 /= sizeof(int);
769
770                if (len < 0 || l2 < (unsigned int)len)
771                        return (0);
772
773                for (i = 0; i < len; i++)
774                        if (name2[i] != oid[i])
775                                return (0);
776
777                i = show_var(name2, l2);
778                if (!i && !bflag)
779                        putchar('\n');
780
781                memcpy(name1+2, name2, l2 * sizeof(int));
782                l1 = 2 + l2;
783        }
784}
Note: See TracBrowser for help on using the repository browser.