]>
git.saurik.com Git - apple/system_cmds.git/blob - sysctl.tproj/sysctl.c
2 * Copyright (c) 1999-2005 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * "Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7 * Reserved. This file contains Original Code and/or Modifications of
8 * Original Code as defined in and that are subject to the Apple Public
9 * Source License Version 1.0 (the 'License'). You may not use this file
10 * except in compliance with the License. Please obtain a copy of the
11 * License at http://www.apple.com/publicsource and read it before using
14 * The Original Code and all software distributed under the License are
15 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19 * License for the specific language governing rights and limitations
22 * @APPLE_LICENSE_HEADER_END@
26 * The Regents of the University of California. All rights reserved.
28 * Redistribution and use in source and binary forms, with or without
29 * modification, are permitted provided that the following conditions
31 * 1. Redistributions of source code must retain the above copyright
32 * notice, this list of conditions and the following disclaimer.
33 * 2. Redistributions in binary form must reproduce the above copyright
34 * notice, this list of conditions and the following disclaimer in the
35 * documentation and/or other materials provided with the distribution.
36 * 3. All advertising materials mentioning features or use of this software
37 * must display the following acknowledgement:
38 * This product includes software developed by the University of
39 * California, Berkeley and its contributors.
40 * 4. Neither the name of the University nor the names of its contributors
41 * may be used to endorse or promote products derived from this software
42 * without specific prior written permission.
44 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
45 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
46 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
47 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
48 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
49 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
50 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
51 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
52 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
53 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 Modified November 1, 2000, by Ryan Rempel, ryan.rempel@utoronto.ca
60 The Darwin sysctl mechanism is in a state of flux. Parts of the kernel use the old
61 style of BSD sysctl definition, and other parts use the new style. The sysctl (8)
62 command that shipped with Darwin 1.2 (OS X PB) did not allow you to access
63 all possible sysctl values. In particular, it did not permit access to sysctl values
64 created by kernel extensions--hence my particular interest. The freeBSD sysctl (8)
65 command compiled and ran under Darwin 1.2, and it did permit access to
66 sysctl values created by kernel extensions, as well as several others. However, it
67 did not permit access to many other values which the Darwin 1.2 sysctl could access.
69 What I have done is merge the Darwin 1.2 sysctl and the freeBSD sysctl. Essentially,
70 there are two points of merger. When showing all values (i.e. -a, -A, or -X), sysctl now
71 runs the Darwin 1.2 routine to show all values, and then the freeBSD routine. This does
72 result in some duplication. When getting or setting a particular value, sysctl now tries
73 the freeBSD way first. If it cannot find the value, then it tries the Darwin 1.2 way.
75 There are a few oddities which this creates (aside from some duplication with -a, -A,
76 and -X). The freeBSD version of sysctl now supports two extra options, -b and -X.
77 In this syctl, those options are supported where the value is retrieved by the freeBSD
78 routine, and have no effect where the value is retrieved by the Darwin 1.2 routine.
79 The freeBSD sysctl uses a ':' to separate the name and the value, whereas Darwin 1.2's
80 sysctl uses a '='. I have left this way, as it lets you know which routine was used,
83 I have also fixed several lines which gave warnings previously, one of which appears
84 to have been an actual bug (bufp was dereferenced when it shouldn't have been).
85 I have also incoporated my previous patch to permit setting kern.hostid as an unsigned
86 integer. In the freeBSD side of the code, I have incorporated a general fix for
87 setting values where the format is specified as unsigned integer.
90 #include <sys/cdefs.h>
92 __unused
static char copyright
[] =
93 "@(#) Copyright (c) 1993\n\
94 The Regents of the University of California. All rights reserved.\n";
98 __unused
static char sccsid
[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95";
101 #include <sys/param.h>
102 #include <sys/gmon.h>
103 #include <sys/mount.h>
104 #include <sys/stat.h>
105 #include <sys/sysctl.h>
106 #include <sys/socket.h>
108 #include <mach/machine/vm_param.h>
109 #include <mach/machine/vm_types.h>
110 #include <mach/mach_types.h>
112 #include <vm/vm_param.h>
113 #endif /* __APPLE__ */
122 #include <sys/types.h>
123 #include <sys/resource.h>
126 struct ctlname topname
[] = CTL_NAMES
;
127 struct ctlname kernname
[] = CTL_KERN_NAMES
;
128 struct ctlname vmname
[] = CTL_VM_NAMES
;
129 struct ctlname hwname
[] = CTL_HW_NAMES
;
130 struct ctlname username
[] = CTL_USER_NAMES
;
131 struct ctlname debugname
[CTL_DEBUG_MAXID
];
132 struct ctlname
*vfsname
;
133 #ifdef CTL_MACHDEP_NAMES
134 struct ctlname machdepname
[] = CTL_MACHDEP_NAMES
;
140 struct ctlname
*list
;
143 struct list toplist
= { topname
, CTL_MAXID
};
144 struct list secondlevel
[] = {
145 { 0, 0 }, /* CTL_UNSPEC */
146 { kernname
, KERN_MAXID
}, /* CTL_KERN */
147 { vmname
, VM_MAXID
}, /* CTL_VM */
148 { 0, 0 }, /* CTL_VFS */
149 { 0, 0 }, /* CTL_NET */
150 { 0, CTL_DEBUG_MAXID
}, /* CTL_DEBUG */
151 { hwname
, HW_MAXID
}, /* CTL_HW */
152 #ifdef CTL_MACHDEP_NAMES
153 { machdepname
, CPU_MAXID
}, /* CTL_MACHDEP */
155 { 0, 0 }, /* CTL_MACHDEP */
157 { username
, USER_MAXID
}, /* CTL_USER_NAMES */
160 static int Aflag
, aflag
, bflag
, nflag
, wflag
, Xflag
;
161 static int foundSome
= 0;
162 static int invalid_name_used
= 0;
164 void listall(char *prefix
, struct list
*lp
);
165 void old_parse(char *string
, int flags
);
168 int findname(char *string
, char *level
, char **bufp
, struct list
*namelist
);
171 static void parse(char *string
, int flags
);
172 static int oidfmt(int *, int, char *, u_int
*);
173 static int show_var(int *, int, int);
174 static int sysctl_all (int *oid
, int len
);
175 static int name2oid(char *, int *);
178 * Variables requiring special processing.
180 #define CLOCK 0x00000001
181 #define BOOTTIME 0x00000002
182 #define CONSDEV 0x00000004
189 // extern char *optarg; // unused
193 while ((ch
= getopt(argc
, argv
, "AabnwX")) != EOF
) {
195 case 'A': Aflag
= 1; break;
196 case 'a': aflag
= 1; break;
197 case 'b': bflag
= 1; break;
198 case 'n': nflag
= 1; break;
199 case 'w': wflag
= 1; break;
200 case 'X': Xflag
= Aflag
= 1; break;
207 if (argc
== 0 && (Aflag
|| aflag
)) {
210 for (lvl1
= 1; lvl1
< CTL_MAXID
; lvl1
++)
211 listall(topname
[lvl1
].ctl_name
, &secondlevel
[lvl1
]);
212 exit (sysctl_all(0, 0));
216 for (; *argv
!= NULL
; ++argv
)
218 exit(invalid_name_used
? 1 : 0);
222 * List all variables known to the system.
230 char *cp
, name
[BUFSIZ
];
234 strcpy(name
, prefix
);
235 cp
= &name
[strlen(name
)];
237 for (lvl2
= 0; lvl2
< lp
->size
; lvl2
++) {
238 if (lp
->list
[lvl2
].ctl_name
== 0)
240 strcpy(cp
, lp
->list
[lvl2
].ctl_name
);
241 old_parse(name
, Aflag
);
246 * Parse a name into a MIB entry.
247 * Lookup and print out the MIB entry if it exists.
248 * Set a new value if requested.
251 old_parse(string
, flags
)
255 int indx
, type
, state
, len
;
259 int intval
, newsize
= 0;
260 unsigned int uintval
;
261 int useUnsignedInt
= 0;
265 int mib
[CTL_MAXNAME
];
266 char *cp
, *bufp
, buf
[BUFSIZ
] /*, strval[BUFSIZ] */ ;
269 snprintf(buf
, BUFSIZ
, "%s", string
);
270 if ((cp
= strchr(string
, '=')) != NULL
) {
272 fprintf(stderr
, "Must specify -w to set variables\n");
275 *strchr(buf
, '=') = '\0';
280 newsize
= strlen(cp
);
282 if ((indx
= findname(string
, "top", &bufp
, &toplist
)) == -1)
287 if (indx
== CTL_DEBUG
)
289 lp
= &secondlevel
[indx
];
291 if (!foundSome
) fprintf(stderr
, "%s: class is not implemented\n",
292 topname
[indx
].ctl_name
);
296 listall(topname
[indx
].ctl_name
, lp
);
299 if ((indx
= findname(string
, "second", &bufp
, lp
)) == -1)
302 type
= lp
->list
[indx
].ctl_type
;
309 mib
[2] = GPROF_STATE
;
311 if (sysctl(mib
, 3, &state
, &size
, NULL
, 0) < 0) {
315 fprintf(stdout
, "%s: ", string
);
317 "kernel is not compiled for profiling\n");
321 fprintf(stdout
, "%s: %s\n", string
,
322 state
== GMON_PROF_OFF
? "off" : "running");
329 "Use pstat to view %s information\n", string
);
335 "Use ps to view %s information\n", string
);
354 #if 0 /* XXX Handled by the new sysctl mechanism */
356 case VM_LOADAVG
: { /* XXX this is bogus */
359 getloadavg(loads
, 3);
361 fprintf(stdout
, "%s: ", string
);
362 fprintf(stdout
, "%.2f %.2f %.2f\n",
363 loads
[0], loads
[1], loads
[2]);
367 struct xsw_usage xsu
;
371 if (sysctl(mib
, 2, &xsu
, &size
, NULL
, 0) != 0) {
376 fprintf(stderr
, "%s: ", string
);
377 fprintf(stderr
, "sysctl(VM_SWAPUSAGE): %s\n",
378 strerror(saved_errno
));
383 fprintf(stdout
, "%s: ", string
);
385 "total = %.2fM used = %.2fM free = %.2fM %s\n",
386 ((double) xsu
.xsu_total
) / (1024.0 * 1024.0),
387 ((double) xsu
.xsu_used
) / (1024.0 * 1024.0),
388 ((double) xsu
.xsu_avail
) / (1024.0 * 1024.0),
389 xsu
.xsu_encrypted
? "(encrypted)" : "");
396 "Use vmstat or systat to view %s information\n", string
);
401 mib
[2] = CTL_DEBUG_VALUE
;
407 if (mib
[1] == CPU_CONSDEV
)
414 mib
[1] = VFS_GENERIC
;
418 if (sysctl(mib
, 4, &vfc
, &size
, (void *)0, (size_t)0) < 0) {
422 if (flags
== 0 && vfc
.vfc_refcount
== 0)
425 fprintf(stdout
, "%s has %d mounted instance%s\n",
426 string
, vfc
.vfc_refcount
,
427 vfc
.vfc_refcount
!= 1 ? "s" : "");
429 fprintf(stdout
, "%d\n", vfc
.vfc_refcount
);
436 fprintf(stderr
, "Illegal top level value: %d\n", mib
[0]);
441 fprintf(stderr
, "name %s in %s is unknown\n", bufp
, string
);
447 if (useUnsignedInt
) {
448 uintval
= strtoul(newval
, NULL
, 0);
449 if ((uintval
== 0) && (errno
== EINVAL
)) {
450 fprintf(stderr
, "invalid argument: %s\n",
455 newsize
= sizeof uintval
;
457 intval
= strtol(newval
, NULL
, 0);
458 if ((intval
== 0) && (errno
== EINVAL
)) {
459 fprintf(stderr
, "invalid argument: %s\n",
464 newsize
= sizeof intval
;
469 quadval
= strtoq(newval
, NULL
, 0);
470 if ((quadval
== 0) && (errno
== EINVAL
)) {
471 fprintf(stderr
, "invalid argument: %s\n",
476 newsize
= sizeof quadval
;
481 if (sysctl(mib
, len
, buf
, &size
, newsize
? newval
: 0, newsize
) == -1) {
486 fprintf(stderr
, "%s: value is not available\n", string
);
489 fprintf(stderr
, "%s: specification is incomplete\n",
493 fprintf(stderr
, "%s: type is unknown to this program\n",
501 if (special
& CLOCK
) {
502 struct clockinfo
*clkp
= (struct clockinfo
*)buf
;
505 fprintf(stdout
, "%s: ", string
);
507 "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
508 clkp
->hz
, clkp
->tick
, clkp
->profhz
, clkp
->stathz
);
511 if (special
& BOOTTIME
) {
512 struct timeval
*btp
= (struct timeval
*)buf
;
515 fprintf(stdout
, "%s = %s\n", string
,
516 ctime((time_t *) &btp
->tv_sec
));
518 fprintf(stdout
, "%ld\n", btp
->tv_sec
);
521 if (special
& CONSDEV
) {
522 dev_t dev
= *(dev_t
*)buf
;
525 fprintf(stdout
, "%s = %s\n", string
,
526 devname(dev
, S_IFCHR
));
528 fprintf(stdout
, "0x%x\n", dev
);
535 fprintf(stdout
, "%s = ", string
);
536 fprintf(stdout
, useUnsignedInt
? "%u\n" : "%d\n", *(int *)buf
);
539 fprintf(stdout
, useUnsignedInt
? "%s: %u -> " : "%s: %d -> ",
540 string
, *(int *)buf
);
541 fprintf(stdout
, useUnsignedInt
? "%u\n" : "%d\n", *(int *)newval
);
548 fprintf(stdout
, "%s = ", string
);
549 fprintf(stdout
, "%s\n", buf
);
552 fprintf(stdout
, "%s: %s -> ", string
, buf
);
553 fprintf(stdout
, "%s\n", (char *) newval
);
560 fprintf(stdout
, "%s = ", string
);
561 fprintf(stdout
, "%qd\n", *(quad_t
*)buf
);
564 fprintf(stdout
, "%s: %qd -> ", string
,
566 fprintf(stdout
, "%qd\n", *(quad_t
*)newval
);
575 fprintf(stderr
, "%s: unknown type returned\n",
582 * Initialize the set of debugging names
589 if (secondlevel
[CTL_DEBUG
].list
!= 0)
591 secondlevel
[CTL_DEBUG
].list
= debugname
;
593 mib
[2] = CTL_DEBUG_NAME
;
594 for (loc
= lastused
, i
= 0; i
< CTL_DEBUG_MAXID
; i
++) {
597 if (sysctl(mib
, 3, &names
[loc
], &size
, NULL
, 0) == -1)
599 debugname
[i
].ctl_name
= &names
[loc
];
600 debugname
[i
].ctl_type
= CTLTYPE_INT
;
607 * Initialize the set of filesystem names
611 int mib
[4], maxtypenum
, cnt
, loc
, size
;
615 if (secondlevel
[CTL_VFS
].list
!= 0)
618 mib
[1] = VFS_GENERIC
;
619 mib
[2] = VFS_MAXTYPENUM
;
621 if (sysctl(mib
, 3, &maxtypenum
, &buflen
, (void *)0, (size_t)0) < 0)
623 if ((vfsname
= malloc(maxtypenum
* sizeof(*vfsname
))) == 0)
625 memset(vfsname
, 0, maxtypenum
* sizeof(*vfsname
));
628 for (loc
= lastused
, cnt
= 0; cnt
< maxtypenum
; cnt
++) {
630 if (sysctl(mib
, 4, &vfc
, &buflen
, (void *)0, (size_t)0) < 0) {
631 if (errno
== ENOTSUP
)
637 strcat(&names
[loc
], vfc
.vfc_name
);
638 vfsname
[cnt
].ctl_name
= &names
[loc
];
639 vfsname
[cnt
].ctl_type
= CTLTYPE_INT
;
640 size
= strlen(vfc
.vfc_name
) + 1;
644 secondlevel
[CTL_VFS
].list
= vfsname
;
645 secondlevel
[CTL_VFS
].size
= maxtypenum
;
650 * Scan a list of names searching for a particular name.
653 findname(string
, level
, bufp
, namelist
)
657 struct list
*namelist
;
662 /* Make 'sysctl kern.' style behave the same as 'sysctl kern' 3360872*/
663 if (bufp
[0][strlen(*bufp
)-1] == '.')
664 bufp
[0][strlen(*bufp
)-1]='\0';
665 if (namelist
->list
== 0 || (name
= strsep(bufp
, ".")) == NULL
) {
666 fprintf(stderr
, "%s: incomplete specification\n", string
);
667 invalid_name_used
= 1;
670 for (i
= 0; i
< namelist
->size
; i
++)
671 if (namelist
->list
[i
].ctl_name
!= NULL
&&
672 strcmp(name
, namelist
->list
[i
].ctl_name
) == 0)
674 if (i
== namelist
->size
) {
675 fprintf(stderr
, "%s level name %s in %s is invalid\n",
676 level
, name
, string
);
677 invalid_name_used
= 1;
686 (void)fprintf(stderr
, "%s\n%s\n%s\n%s\n%s\n",
687 "usage: sysctl [-bn] variable ...",
688 " sysctl [-bn] -w variable=value ...",
696 * Parse a name into a MIB entry.
697 * Lookup and print out the MIB entry if it exists.
698 * Set a new value if requested.
701 parse(char *string
, int flags
)
705 int intval
, newsize
= 0;
706 unsigned int uintval
;
708 int mib
[CTL_MAXNAME
];
709 char *cp
, *bufp
, buf
[BUFSIZ
], fmt
[BUFSIZ
];
713 snprintf(buf
, BUFSIZ
, "%s", string
);
714 if ((cp
= strchr(string
, '=')) != NULL
) {
716 errx(2, "must specify -w to set variables");
717 *strchr(buf
, '=') = '\0';
722 newsize
= strlen(cp
);
727 len
= name2oid(bufp
, mib
);
731 while (*cp
!= '\0') cp
--;
734 old_parse (string
, flags
);
738 if (oidfmt(mib
, len
, fmt
, &kind
))
739 err(1, "couldn't find format of oid '%s'", bufp
);
742 if ((kind
& CTLTYPE
) == CTLTYPE_NODE
) {
743 sysctl_all(mib
, len
);
745 old_parse (string
, flags
);
747 i
= show_var(mib
, len
, 1);
752 if ((kind
& CTLTYPE
) == CTLTYPE_NODE
)
753 errx(1, "oid '%s' isn't a leaf node", bufp
);
755 if (!(kind
&CTLFLAG_WR
))
756 errx(1, "oid '%s' is read only", bufp
);
758 switch (kind
& CTLTYPE
) {
760 if ((*fmt
== 'I') && (*(fmt
+ 1) == 'U')) {
761 uintval
= (unsigned int) strtoul (newval
, NULL
, 0);
762 if ((uintval
== 0) &&
764 errx(1, "invalid argument: %s",
769 newsize
= sizeof uintval
;
771 intval
= (int) strtol(newval
, NULL
, 0);
774 errx(1, "invalid argument: %s",
779 newsize
= sizeof intval
;
785 quadval
= strtoq(newval
, NULL
, 0);
786 if ((quadval
== 0) && (errno
== EINVAL
)) {
787 errx(1, "invalid argument %s", newval
);
791 newsize
= sizeof quadval
;
794 errx(1, "oid '%s' is type %d,"
795 " cannot set that", bufp
,
799 i
= show_var(mib
, len
, 1);
800 if (sysctl(mib
, len
, 0, 0, newval
, newsize
) == -1) {
805 errx(1, "%s: value is not available",
808 errx(1, "%s: specification is incomplete",
811 errx(1, "%s: type is unknown to this program",
822 j
= show_var(mib
, len
, 1);
829 /* These functions will dump out various interesting structures. */
832 S_clockinfo(int l2
, void *p
)
834 struct clockinfo
*ci
= (struct clockinfo
*)p
;
835 if (l2
!= sizeof *ci
)
836 err(1, "S_clockinfo %d != %d", l2
, sizeof *ci
);
837 printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
838 ci
->hz
, ci
->tick
, ci
->tickadj
, ci
->profhz
, ci
->stathz
);
843 S_loadavg(int l2
, void *p
)
845 struct loadavg
*tv
= (struct loadavg
*)p
;
847 if (l2
!= sizeof *tv
)
848 err(1, "S_loadavg %d != %d", l2
, sizeof *tv
);
850 printf("{ %.2f %.2f %.2f }",
851 (double)tv
->ldavg
[0]/(double)tv
->fscale
,
852 (double)tv
->ldavg
[1]/(double)tv
->fscale
,
853 (double)tv
->ldavg
[2]/(double)tv
->fscale
);
858 S_timeval(int l2
, void *p
)
860 struct timeval
*tv
= (struct timeval
*)p
;
864 if (l2
!= sizeof *tv
)
865 err(1, "S_timeval %d != %d", l2
, sizeof *tv
);
866 printf("{ sec = %ld, usec = %ld } ",
867 (long) tv
->tv_sec
, (long) tv
->tv_usec
);
869 p1
= strdup(ctime(&tv_sec
));
870 for (p2
=p1
; *p2
; p2
++)
878 S_xswusage(int l2
, void *p
)
880 struct xsw_usage
*xsu
= (struct xsw_usage
*)p
;
882 if(l2
!= sizeof (*xsu
))
883 err(1, "S_xswusage %d != %d", l2
, sizeof *xsu
);
886 "total = %.2fM used = %.2fM free = %.2fM %s",
887 ((double) xsu
->xsu_total
) / (1024.0 * 1024.0),
888 ((double) xsu
->xsu_used
) / (1024.0 * 1024.0),
889 ((double) xsu
->xsu_avail
) / (1024.0 * 1024.0),
890 xsu
->xsu_encrypted
? "(encrypted)" : "");
895 T_dev_t(int l2
, void *p
)
897 dev_t
*d
= (dev_t
*)p
;
899 err(1, "T_dev_T %d != %d", l2
, sizeof *d
);
900 if ((int)(*d
) != -1) {
901 if (minor(*d
) > 255 || minor(*d
) < 0)
902 printf("{ major = %d, minor = 0x%x }",
903 major(*d
), minor(*d
));
905 printf("{ major = %d, minor = %d }",
906 major(*d
), minor(*d
));
912 * These functions uses a presently undocumented interface to the kernel
913 * to walk the tree and get the type so it can print the value.
914 * This interface is under work and consideration, and should probably
915 * be killed with a big axe by the first person who can find the time.
916 * (be aware though, that the proper interface isn't as obvious as it
917 * may seem, there are various conflicting requirements.
921 name2oid(char *name
, int *oidp
)
930 j
= CTL_MAXNAME
* sizeof (int);
931 i
= sysctl(oid
, 2, oidp
, &j
, name
, strlen(name
));
939 oidfmt(int *oid
, int len
, char *fmt
, u_int
*kind
)
941 int qoid
[CTL_MAXNAME
+2];
948 memcpy(qoid
+ 2, oid
, len
* sizeof(int));
951 i
= sysctl(qoid
, len
+ 2, buf
, &j
, 0, 0);
953 err(1, "sysctl fmt %d %d %d", i
, j
, errno
);
956 *kind
= *(u_int
*)buf
;
959 strcpy(fmt
, (char *)(buf
+ sizeof(u_int
)));
964 * This formats and outputs the value of one variable
966 * Returns zero if anything was actually output.
967 * Returns one if didn't know what to do with this.
968 * Return minus one if we had errors.
972 show_var(int *oid
, int nlen
, int show_masked
)
974 u_char buf
[BUFSIZ
], *val
, *mval
, *p
;
975 char name
[BUFSIZ
], /* descr[BUFSIZ], */ *fmt
;
976 int qoid
[CTL_MAXNAME
+2];
981 int (*func
)(int, void *) = 0;
984 memcpy(qoid
+ 2, oid
, nlen
* sizeof(int));
988 i
= sysctl(qoid
, nlen
+ 2, name
, &j
, 0, 0);
990 err(1, "sysctl name %d %d %d", i
, j
, errno
);
992 /* find an estimate of how much we need for this var */
994 i
= sysctl(oid
, nlen
, 0, &j
, 0, 0);
995 j
+= j
; /* we want to be sure :-) */
997 val
= mval
= malloc(j
);
999 i
= sysctl(oid
, nlen
, val
, &len
, 0, 0);
1006 fwrite(val
, 1, len
, stdout
);
1013 i
= sysctl(qoid
, nlen
+ 2, buf
, &j
, 0, 0);
1015 err(1, "sysctl fmt %d %d %d", i
, j
, errno
);
1017 kind
= *(u_int
*)buf
;
1018 if (!show_masked
&& (kind
& CTLFLAG_MASKED
)) {
1023 fmt
= (char *)(buf
+ sizeof(u_int
));
1028 /* deprecated, do not print */
1035 printf("%s: ", name
);
1042 printf("%s: ", name
);
1044 val
= (unsigned char *)"";
1045 while (len
>= sizeof(int)) {
1047 printf("%s%u", val
, *(unsigned int *)p
);
1049 printf("%s%d", val
, *(int *)p
);
1050 val
= (unsigned char *)" ";
1051 len
-= sizeof (int);
1059 printf("%s: ", name
);
1061 val
= (unsigned char *)"";
1062 while (len
>= sizeof(long)) {
1064 printf("%s%lu", val
, *(unsigned long *)p
);
1066 printf("%s%ld", val
, *(long *)p
);
1067 val
= (unsigned char *)" ";
1068 len
-= sizeof (long);
1076 printf("%s: ", name
);
1077 printf("%p", *(void **)p
);
1083 printf("%s: ", name
);
1085 val
= (unsigned char *)"";
1086 while (len
>= sizeof(long long)) {
1088 printf("%s%llu", val
, *(unsigned long long *)p
);
1090 printf("%s%lld", val
, *(long long *)p
);
1091 val
= (unsigned char *)" ";
1092 len
-= sizeof (long long);
1093 p
+= sizeof (long long);
1102 if (!strcmp(fmt
, "S,clockinfo")) func
= S_clockinfo
;
1103 else if (!strcmp(fmt
, "S,timeval")) func
= S_timeval
;
1104 else if (!strcmp(fmt
, "S,loadavg")) func
= S_loadavg
;
1105 else if (!strcmp(fmt
, "S,xsw_usage")) func
= S_xswusage
;
1106 else if (!strcmp(fmt
, "T,dev_t")) func
= T_dev_t
;
1109 printf("%s: ", name
);
1110 retval
= (*func
)(len
, p
);
1120 printf("%s: ", name
);
1121 printf("Format:%s Length:%ld Dump:0x", fmt
, len
);
1123 printf("%02x", *p
++);
1124 if (Xflag
|| p
< val
+16)
1140 sysctl_all (int *oid
, int len
)
1142 int name1
[22], name2
[22];
1150 memcpy(name1
+2, oid
, len
*sizeof (int));
1158 j
= sysctl(name1
, l1
, name2
, &l2
, 0, 0);
1160 if (errno
== ENOENT
)
1163 err(1, "sysctl(getnext) %d %d", j
, l2
);
1171 for (i
= 0; i
< len
; i
++)
1172 if (name2
[i
] != oid
[i
])
1175 i
= show_var(name2
, l2
, 0);
1179 memcpy(name1
+2, name2
, l2
*sizeof (int));