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

55-freebsd-126-freebsd-12freebsd-9.3
Last change on this file since 21abaef was 21abaef, checked in by Christian Mauderer <Christian.Mauderer@…>, on Jul 15, 2016 at 5:32:56 AM

freebsd: Don't use new wrappers for old ports.

Some of the commands have been adapted manually. So the wrapper
currently don't necessarily work as expected. For example ifconfig calls
malloc outside of the program call.

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