]>
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",
497 fprintf(stderr
, "%s: no such MIB\n",
505 if (special
& CLOCK
) {
506 struct clockinfo
*clkp
= (struct clockinfo
*)buf
;
509 fprintf(stdout
, "%s: ", string
);
511 "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
512 clkp
->hz
, clkp
->tick
, clkp
->profhz
, clkp
->stathz
);
515 if (special
& BOOTTIME
) {
516 struct timeval
*btp
= (struct timeval
*)buf
;
519 fprintf(stdout
, "%s = %s\n", string
,
520 ctime((time_t *) &btp
->tv_sec
));
522 fprintf(stdout
, "%ld\n", btp
->tv_sec
);
525 if (special
& CONSDEV
) {
526 dev_t dev
= *(dev_t
*)buf
;
529 fprintf(stdout
, "%s = %s\n", string
,
530 devname(dev
, S_IFCHR
));
532 fprintf(stdout
, "0x%x\n", dev
);
539 fprintf(stdout
, "%s = ", string
);
540 fprintf(stdout
, useUnsignedInt
? "%u\n" : "%d\n", *(int *)buf
);
543 fprintf(stdout
, useUnsignedInt
? "%s: %u -> " : "%s: %d -> ",
544 string
, *(int *)buf
);
545 fprintf(stdout
, useUnsignedInt
? "%u\n" : "%d\n", *(int *)newval
);
552 fprintf(stdout
, "%s = ", string
);
553 fprintf(stdout
, "%s\n", buf
);
556 fprintf(stdout
, "%s: %s -> ", string
, buf
);
557 fprintf(stdout
, "%s\n", (char *) newval
);
564 fprintf(stdout
, "%s = ", string
);
565 fprintf(stdout
, "%qd\n", *(quad_t
*)buf
);
568 fprintf(stdout
, "%s: %qd -> ", string
,
570 fprintf(stdout
, "%qd\n", *(quad_t
*)newval
);
579 fprintf(stderr
, "%s: unknown type returned\n",
586 * Initialize the set of debugging names
593 if (secondlevel
[CTL_DEBUG
].list
!= 0)
595 secondlevel
[CTL_DEBUG
].list
= debugname
;
597 mib
[2] = CTL_DEBUG_NAME
;
598 for (loc
= lastused
, i
= 0; i
< CTL_DEBUG_MAXID
; i
++) {
601 if (sysctl(mib
, 3, &names
[loc
], &size
, NULL
, 0) == -1)
603 debugname
[i
].ctl_name
= &names
[loc
];
604 debugname
[i
].ctl_type
= CTLTYPE_INT
;
611 * Initialize the set of filesystem names
615 int mib
[4], maxtypenum
, cnt
, loc
, size
;
619 if (secondlevel
[CTL_VFS
].list
!= 0)
622 mib
[1] = VFS_GENERIC
;
623 mib
[2] = VFS_MAXTYPENUM
;
625 if (sysctl(mib
, 3, &maxtypenum
, &buflen
, (void *)0, (size_t)0) < 0)
627 if ((vfsname
= malloc(maxtypenum
* sizeof(*vfsname
))) == 0)
629 memset(vfsname
, 0, maxtypenum
* sizeof(*vfsname
));
632 for (loc
= lastused
, cnt
= 0; cnt
< maxtypenum
; cnt
++) {
634 if (sysctl(mib
, 4, &vfc
, &buflen
, (void *)0, (size_t)0) < 0) {
635 if (errno
== ENOTSUP
)
641 strcat(&names
[loc
], vfc
.vfc_name
);
642 vfsname
[cnt
].ctl_name
= &names
[loc
];
643 vfsname
[cnt
].ctl_type
= CTLTYPE_INT
;
644 size
= strlen(vfc
.vfc_name
) + 1;
648 secondlevel
[CTL_VFS
].list
= vfsname
;
649 secondlevel
[CTL_VFS
].size
= maxtypenum
;
654 * Scan a list of names searching for a particular name.
657 findname(string
, level
, bufp
, namelist
)
661 struct list
*namelist
;
666 /* Make 'sysctl kern.' style behave the same as 'sysctl kern' 3360872*/
667 if (bufp
[0][strlen(*bufp
)-1] == '.')
668 bufp
[0][strlen(*bufp
)-1]='\0';
669 if (namelist
->list
== 0 || (name
= strsep(bufp
, ".")) == NULL
) {
671 fprintf(stderr
, "%s: incomplete specification\n", string
);
672 invalid_name_used
= 1;
676 for (i
= 0; i
< namelist
->size
; i
++)
677 if (namelist
->list
[i
].ctl_name
!= NULL
&&
678 strcmp(name
, namelist
->list
[i
].ctl_name
) == 0)
680 if (i
== namelist
->size
) {
682 fprintf(stderr
, "%s level name %s in %s is invalid\n",
683 level
, name
, string
);
684 invalid_name_used
= 1;
694 (void)fprintf(stderr
, "%s\n%s\n%s\n%s\n%s\n",
695 "usage: sysctl [-bn] variable ...",
696 " sysctl [-bn] -w variable=value ...",
704 * Parse a name into a MIB entry.
705 * Lookup and print out the MIB entry if it exists.
706 * Set a new value if requested.
709 parse(char *string
, int flags
)
713 int intval
, newsize
= 0;
714 unsigned int uintval
;
716 int mib
[CTL_MAXNAME
];
717 char *cp
, *bufp
, buf
[BUFSIZ
], fmt
[BUFSIZ
];
721 if (snprintf(buf
, BUFSIZ
, "%s", string
) >= BUFSIZ
)
722 errx(1, "MIB too long");
723 snprintf(buf
, BUFSIZ
, "%s", string
);
724 if ((cp
= strchr(string
, '=')) != NULL
) {
726 errx(2, "must specify -w to set variables");
727 *strchr(buf
, '=') = '\0';
732 newsize
= strlen(cp
);
737 len
= name2oid(bufp
, mib
);
741 while (*cp
!= '\0') cp
--;
744 old_parse (string
, flags
);
748 if (oidfmt(mib
, len
, fmt
, &kind
))
749 err(1, "couldn't find format of oid '%s'", bufp
);
752 if ((kind
& CTLTYPE
) == CTLTYPE_NODE
) {
753 sysctl_all(mib
, len
);
755 old_parse (string
, flags
);
757 i
= show_var(mib
, len
, 1);
762 if ((kind
& CTLTYPE
) == CTLTYPE_NODE
)
763 errx(1, "oid '%s' isn't a leaf node", bufp
);
765 if (!(kind
&CTLFLAG_WR
))
766 errx(1, "oid '%s' is read only", bufp
);
768 switch (kind
& CTLTYPE
) {
770 if ((*fmt
== 'I') && (*(fmt
+ 1) == 'U')) {
771 uintval
= (unsigned int) strtoul (newval
, NULL
, 0);
772 if ((uintval
== 0) &&
774 errx(1, "invalid argument: %s",
779 newsize
= sizeof uintval
;
781 intval
= (int) strtol(newval
, NULL
, 0);
784 errx(1, "invalid argument: %s",
789 newsize
= sizeof intval
;
795 quadval
= strtoq(newval
, NULL
, 0);
796 if ((quadval
== 0) && (errno
== EINVAL
)) {
797 errx(1, "invalid argument %s", newval
);
801 newsize
= sizeof quadval
;
804 errx(1, "oid '%s' is type %d,"
805 " cannot set that", bufp
,
809 i
= show_var(mib
, len
, 1);
810 if (sysctl(mib
, len
, 0, 0, newval
, newsize
) == -1) {
815 errx(1, "%s: value is not available",
818 errx(1, "%s: specification is incomplete",
821 errx(1, "%s: type is unknown to this program",
832 j
= show_var(mib
, len
, 1);
839 /* These functions will dump out various interesting structures. */
842 S_clockinfo(int l2
, void *p
)
844 struct clockinfo
*ci
= (struct clockinfo
*)p
;
845 if (l2
!= sizeof *ci
)
846 err(1, "S_clockinfo %d != %d", l2
, sizeof *ci
);
847 printf("{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
848 ci
->hz
, ci
->tick
, ci
->tickadj
, ci
->profhz
, ci
->stathz
);
853 S_loadavg(int l2
, void *p
)
855 struct loadavg
*tv
= (struct loadavg
*)p
;
857 if (l2
!= sizeof *tv
)
858 err(1, "S_loadavg %d != %d", l2
, sizeof *tv
);
860 printf("{ %.2f %.2f %.2f }",
861 (double)tv
->ldavg
[0]/(double)tv
->fscale
,
862 (double)tv
->ldavg
[1]/(double)tv
->fscale
,
863 (double)tv
->ldavg
[2]/(double)tv
->fscale
);
868 S_timeval(int l2
, void *p
)
870 struct timeval
*tv
= (struct timeval
*)p
;
874 if (l2
!= sizeof *tv
)
875 err(1, "S_timeval %d != %d", l2
, sizeof *tv
);
876 printf("{ sec = %ld, usec = %ld } ",
877 (long) tv
->tv_sec
, (long) tv
->tv_usec
);
879 p1
= strdup(ctime(&tv_sec
));
880 for (p2
=p1
; *p2
; p2
++)
888 S_xswusage(int l2
, void *p
)
890 struct xsw_usage
*xsu
= (struct xsw_usage
*)p
;
892 if(l2
!= sizeof (*xsu
))
893 err(1, "S_xswusage %d != %d", l2
, sizeof *xsu
);
896 "total = %.2fM used = %.2fM free = %.2fM %s",
897 ((double) xsu
->xsu_total
) / (1024.0 * 1024.0),
898 ((double) xsu
->xsu_used
) / (1024.0 * 1024.0),
899 ((double) xsu
->xsu_avail
) / (1024.0 * 1024.0),
900 xsu
->xsu_encrypted
? "(encrypted)" : "");
905 T_dev_t(int l2
, void *p
)
907 dev_t
*d
= (dev_t
*)p
;
909 err(1, "T_dev_T %d != %d", l2
, sizeof *d
);
910 if ((int)(*d
) != -1) {
911 if (minor(*d
) > 255 || minor(*d
) < 0)
912 printf("{ major = %d, minor = 0x%x }",
913 major(*d
), minor(*d
));
915 printf("{ major = %d, minor = %d }",
916 major(*d
), minor(*d
));
922 * These functions uses a presently undocumented interface to the kernel
923 * to walk the tree and get the type so it can print the value.
924 * This interface is under work and consideration, and should probably
925 * be killed with a big axe by the first person who can find the time.
926 * (be aware though, that the proper interface isn't as obvious as it
927 * may seem, there are various conflicting requirements.
931 name2oid(char *name
, int *oidp
)
940 j
= CTL_MAXNAME
* sizeof (int);
941 i
= sysctl(oid
, 2, oidp
, &j
, name
, strlen(name
));
949 oidfmt(int *oid
, int len
, char *fmt
, u_int
*kind
)
951 int qoid
[CTL_MAXNAME
+2];
958 memcpy(qoid
+ 2, oid
, len
* sizeof(int));
961 i
= sysctl(qoid
, len
+ 2, buf
, &j
, 0, 0);
963 err(1, "sysctl fmt %d %d %d", i
, j
, errno
);
966 *kind
= *(u_int
*)buf
;
969 strcpy(fmt
, (char *)(buf
+ sizeof(u_int
)));
974 * This formats and outputs the value of one variable
976 * Returns zero if anything was actually output.
977 * Returns one if didn't know what to do with this.
978 * Return minus one if we had errors.
982 show_var(int *oid
, int nlen
, int show_masked
)
984 u_char buf
[BUFSIZ
], *val
, *mval
, *p
;
985 char name
[BUFSIZ
], /* descr[BUFSIZ], */ *fmt
;
986 int qoid
[CTL_MAXNAME
+2];
991 int (*func
)(int, void *) = 0;
994 memcpy(qoid
+ 2, oid
, nlen
* sizeof(int));
998 i
= sysctl(qoid
, nlen
+ 2, name
, &j
, 0, 0);
1000 err(1, "sysctl name %d %d %d", i
, j
, errno
);
1002 /* find an estimate of how much we need for this var */
1004 i
= sysctl(oid
, nlen
, 0, &j
, 0, 0);
1005 j
+= j
; /* we want to be sure :-) */
1007 val
= mval
= malloc(j
);
1009 i
= sysctl(oid
, nlen
, val
, &len
, 0, 0);
1016 fwrite(val
, 1, len
, stdout
);
1023 i
= sysctl(qoid
, nlen
+ 2, buf
, &j
, 0, 0);
1025 err(1, "sysctl fmt %d %d %d", i
, j
, errno
);
1027 kind
= *(u_int
*)buf
;
1028 if (!show_masked
&& (kind
& CTLFLAG_MASKED
)) {
1033 fmt
= (char *)(buf
+ sizeof(u_int
));
1038 /* deprecated, do not print */
1045 printf("%s: ", name
);
1052 printf("%s: ", name
);
1054 val
= (unsigned char *)"";
1055 while (len
>= sizeof(int)) {
1057 printf("%s%u", val
, *(unsigned int *)p
);
1059 printf("%s%d", val
, *(int *)p
);
1060 val
= (unsigned char *)" ";
1061 len
-= sizeof (int);
1069 printf("%s: ", name
);
1071 val
= (unsigned char *)"";
1072 while (len
>= sizeof(long)) {
1074 printf("%s%lu", val
, *(unsigned long *)p
);
1076 printf("%s%ld", val
, *(long *)p
);
1077 val
= (unsigned char *)" ";
1078 len
-= sizeof (long);
1086 printf("%s: ", name
);
1087 printf("%p", *(void **)p
);
1093 printf("%s: ", name
);
1095 val
= (unsigned char *)"";
1096 while (len
>= sizeof(long long)) {
1098 printf("%s%llu", val
, *(unsigned long long *)p
);
1100 printf("%s%lld", val
, *(long long *)p
);
1101 val
= (unsigned char *)" ";
1102 len
-= sizeof (long long);
1103 p
+= sizeof (long long);
1112 if (!strcmp(fmt
, "S,clockinfo")) func
= S_clockinfo
;
1113 else if (!strcmp(fmt
, "S,timeval")) func
= S_timeval
;
1114 else if (!strcmp(fmt
, "S,loadavg")) func
= S_loadavg
;
1115 else if (!strcmp(fmt
, "S,xsw_usage")) func
= S_xswusage
;
1116 else if (!strcmp(fmt
, "T,dev_t")) func
= T_dev_t
;
1119 printf("%s: ", name
);
1120 retval
= (*func
)(len
, p
);
1130 printf("%s: ", name
);
1131 printf("Format:%s Length:%ld Dump:0x", fmt
, len
);
1133 printf("%02x", *p
++);
1134 if (Xflag
|| p
< val
+16)
1150 sysctl_all (int *oid
, int len
)
1152 int name1
[22], name2
[22];
1160 memcpy(name1
+2, oid
, len
*sizeof (int));
1168 j
= sysctl(name1
, l1
, name2
, &l2
, 0, 0);
1170 if (errno
== ENOENT
)
1173 err(1, "sysctl(getnext) %d %d", j
, l2
);
1181 for (i
= 0; i
< len
; i
++)
1182 if (name2
[i
] != oid
[i
])
1185 i
= show_var(name2
, l2
, 0);
1189 memcpy(name1
+2, name2
, l2
*sizeof (int));