]>
git.saurik.com Git - apple/system_cmds.git/blob - sysctl.tproj/sysctl.c
2 * Copyright (c) 1999-2010 Apple Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
21 * @APPLE_LICENSE_HEADER_END@
25 * The Regents of the University of California. All rights reserved.
27 * Redistribution and use in source and binary forms, with or without
28 * modification, are permitted provided that the following conditions
30 * 1. Redistributions of source code must retain the above copyright
31 * notice, this list of conditions and the following disclaimer.
32 * 2. Redistributions in binary form must reproduce the above copyright
33 * notice, this list of conditions and the following disclaimer in the
34 * documentation and/or other materials provided with the distribution.
35 * 4. Neither the name of the University nor the names of its contributors
36 * may be used to endorse or promote products derived from this software
37 * without specific prior written permission.
39 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
40 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
41 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
42 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
43 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
44 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
45 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
46 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
47 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
48 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
53 Modified November 1, 2000, by Ryan Rempel, ryan.rempel@utoronto.ca
55 The Darwin sysctl mechanism is in a state of flux. Parts of the kernel use the old
56 style of BSD sysctl definition, and other parts use the new style. The sysctl (8)
57 command that shipped with Darwin 1.2 (OS X PB) did not allow you to access
58 all possible sysctl values. In particular, it did not permit access to sysctl values
59 created by kernel extensions--hence my particular interest. The freeBSD sysctl (8)
60 command compiled and ran under Darwin 1.2, and it did permit access to
61 sysctl values created by kernel extensions, as well as several others. However, it
62 did not permit access to many other values which the Darwin 1.2 sysctl could access.
64 What I have done is merge the Darwin 1.2 sysctl and the freeBSD sysctl. Essentially,
65 there are two points of merger. When showing all values (i.e. -a, -A, or -X), sysctl now
66 runs the Darwin 1.2 routine to show all values, and then the freeBSD routine. This does
67 result in some duplication. When getting or setting a particular value, sysctl now tries
68 the freeBSD way first. If it cannot find the value, then it tries the Darwin 1.2 way.
70 There are a few oddities which this creates (aside from some duplication with -a, -A,
71 and -X). The freeBSD version of sysctl now supports two extra options, -b and -X.
72 In this syctl, those options are supported where the value is retrieved by the freeBSD
73 routine, and have no effect where the value is retrieved by the Darwin 1.2 routine.
74 The freeBSD sysctl uses a ':' to separate the name and the value, whereas Darwin 1.2's
75 sysctl uses a '='. I have left this way, as it lets you know which routine was used,
78 I have also fixed several lines which gave warnings previously, one of which appears
79 to have been an actual bug (bufp was dereferenced when it shouldn't have been).
80 I have also incoporated my previous patch to permit setting kern.hostid as an unsigned
81 integer. In the freeBSD side of the code, I have incorporated a general fix for
82 setting values where the format is specified as unsigned integer.
85 #include <sys/cdefs.h>
87 __unused
static char copyright
[] =
88 "@(#) Copyright (c) 1993\n\
89 The Regents of the University of California. All rights reserved.\n";
93 __unused
static char sccsid
[] = "@(#)sysctl.c 8.5 (Berkeley) 5/9/95";
96 #include <sys/param.h>
98 #include <sys/mount.h>
100 #include <sys/sysctl.h>
101 #include <sys/socket.h>
103 #include <mach/machine/vm_param.h>
104 #include <mach/machine/vm_types.h>
105 #include <mach/mach_types.h>
107 #include <vm/vm_param.h>
108 #endif /* __APPLE__ */
117 #include <sys/types.h>
118 #include <sys/resource.h>
121 struct ctlname topname
[] = CTL_NAMES
;
122 struct ctlname kernname
[] = CTL_KERN_NAMES
;
123 struct ctlname vmname
[] = CTL_VM_NAMES
;
124 struct ctlname hwname
[] = CTL_HW_NAMES
;
125 struct ctlname username
[] = CTL_USER_NAMES
;
126 struct ctlname debugname
[CTL_DEBUG_MAXID
];
127 struct ctlname
*vfsname
;
128 #ifdef CTL_MACHDEP_NAMES
129 struct ctlname machdepname
[] = CTL_MACHDEP_NAMES
;
135 struct ctlname
*list
;
138 struct list toplist
= { topname
, CTL_MAXID
};
139 struct list secondlevel
[] = {
140 { 0, 0 }, /* CTL_UNSPEC */
141 { kernname
, KERN_MAXID
}, /* CTL_KERN */
142 { vmname
, VM_MAXID
}, /* CTL_VM */
143 { 0, 0 }, /* CTL_VFS */
144 { 0, 0 }, /* CTL_NET */
145 { 0, CTL_DEBUG_MAXID
}, /* CTL_DEBUG */
146 { hwname
, HW_MAXID
}, /* CTL_HW */
147 #ifdef CTL_MACHDEP_NAMES
148 { machdepname
, CPU_MAXID
}, /* CTL_MACHDEP */
150 { 0, 0 }, /* CTL_MACHDEP */
152 { username
, USER_MAXID
}, /* CTL_USER_NAMES */
155 static int Aflag
, aflag
, bflag
, hflag
, nflag
, wflag
, Xflag
;
156 static int foundSome
= 0;
157 static int invalid_name_used
= 0;
159 void listall(char *prefix
, struct list
*lp
);
160 void old_parse(char *string
, int flags
);
163 int findname(char *string
, char *level
, char **bufp
, struct list
*namelist
);
166 static void parse(char *string
, int flags
);
167 static int oidfmt(int *, int, char *, u_int
*);
168 static int show_var(int *, int, int);
169 static int sysctl_all (int *oid
, int len
);
170 static int name2oid(char *, int *);
173 * Variables requiring special processing.
175 #define CLOCK 0x00000001
176 #define BOOTTIME 0x00000002
177 #define CONSDEV 0x00000004
184 // extern char *optarg; // unused
188 while ((ch
= getopt(argc
, argv
, "AabnwX")) != EOF
) {
190 case 'A': Aflag
= 1; break;
191 case 'a': aflag
= 1; break;
192 case 'b': bflag
= 1; break;
193 case 'h': hflag
= 1; break;
194 case 'n': nflag
= 1; break;
195 case 'w': wflag
= 1; break;
196 case 'X': Xflag
= Aflag
= 1; break;
203 if (argc
== 0 && (Aflag
|| aflag
)) {
206 for (lvl1
= 1; lvl1
< CTL_MAXID
; lvl1
++)
207 listall(topname
[lvl1
].ctl_name
, &secondlevel
[lvl1
]);
208 exit (sysctl_all(0, 0));
212 for (; *argv
!= NULL
; ++argv
)
214 exit(invalid_name_used
? 1 : 0);
218 * List all variables known to the system.
226 char *cp
, name
[BUFSIZ
];
230 strcpy(name
, prefix
);
231 cp
= &name
[strlen(name
)];
233 for (lvl2
= 0; lvl2
< lp
->size
; lvl2
++) {
234 if (lp
->list
[lvl2
].ctl_name
== 0)
236 strcpy(cp
, lp
->list
[lvl2
].ctl_name
);
237 old_parse(name
, Aflag
);
242 * Parse a name into a MIB entry.
243 * Lookup and print out the MIB entry if it exists.
244 * Set a new value if requested.
247 old_parse(string
, flags
)
251 int indx
, type
, state
, len
;
255 int intval
, newsize
= 0;
256 unsigned int uintval
;
257 int useUnsignedInt
= 0;
261 int mib
[CTL_MAXNAME
];
262 char *cp
, *bufp
, buf
[BUFSIZ
] /*, strval[BUFSIZ] */ ;
265 snprintf(buf
, BUFSIZ
, "%s", string
);
266 if ((cp
= strchr(string
, '=')) != NULL
) {
268 fprintf(stderr
, "Must specify -w to set variables\n");
271 *strchr(buf
, '=') = '\0';
276 newsize
= strlen(cp
);
278 if ((indx
= findname(string
, "top", &bufp
, &toplist
)) == -1)
283 if (indx
== CTL_DEBUG
)
285 lp
= &secondlevel
[indx
];
287 if (!foundSome
) fprintf(stderr
, "%s: class is not implemented\n",
288 topname
[indx
].ctl_name
);
292 listall(topname
[indx
].ctl_name
, lp
);
295 if ((indx
= findname(string
, "second", &bufp
, lp
)) == -1)
298 type
= lp
->list
[indx
].ctl_type
;
305 mib
[2] = GPROF_STATE
;
307 if (sysctl(mib
, 3, &state
, &size
, NULL
, 0) < 0) {
311 fprintf(stdout
, "%s: ", string
);
313 "kernel is not compiled for profiling\n");
317 fprintf(stdout
, "%s: %s\n", string
,
318 state
== GMON_PROF_OFF
? "off" : "running");
325 "Use pstat to view %s information\n", string
);
331 "Use ps to view %s information\n", string
);
350 #if 0 /* XXX Handled by the new sysctl mechanism */
352 case VM_LOADAVG
: { /* XXX this is bogus */
355 getloadavg(loads
, 3);
357 fprintf(stdout
, "%s: ", string
);
358 fprintf(stdout
, "%.2f %.2f %.2f\n",
359 loads
[0], loads
[1], loads
[2]);
363 struct xsw_usage xsu
;
367 if (sysctl(mib
, 2, &xsu
, &size
, NULL
, 0) != 0) {
372 fprintf(stderr
, "%s: ", string
);
373 fprintf(stderr
, "sysctl(VM_SWAPUSAGE): %s\n",
374 strerror(saved_errno
));
379 fprintf(stdout
, "%s: ", string
);
381 "total = %.2fM used = %.2fM free = %.2fM %s\n",
382 ((double) xsu
.xsu_total
) / (1024.0 * 1024.0),
383 ((double) xsu
.xsu_used
) / (1024.0 * 1024.0),
384 ((double) xsu
.xsu_avail
) / (1024.0 * 1024.0),
385 xsu
.xsu_encrypted
? "(encrypted)" : "");
392 "Use vmstat or systat to view %s information\n", string
);
397 mib
[2] = CTL_DEBUG_VALUE
;
403 if (mib
[1] == CPU_CONSDEV
)
410 mib
[1] = VFS_GENERIC
;
414 if (sysctl(mib
, 4, &vfc
, &size
, (void *)0, (size_t)0) < 0) {
418 if (flags
== 0 && vfc
.vfc_refcount
== 0)
421 fprintf(stdout
, "%s has %d mounted instance%s\n",
422 string
, vfc
.vfc_refcount
,
423 vfc
.vfc_refcount
!= 1 ? "s" : "");
425 fprintf(stdout
, "%d\n", vfc
.vfc_refcount
);
432 fprintf(stderr
, "Illegal top level value: %d\n", mib
[0]);
437 fprintf(stderr
, "name %s in %s is unknown\n", bufp
, string
);
443 if (useUnsignedInt
) {
444 uintval
= strtoul(newval
, NULL
, 0);
445 if ((uintval
== 0) && (errno
== EINVAL
)) {
446 fprintf(stderr
, "invalid argument: %s\n",
451 newsize
= sizeof uintval
;
453 intval
= strtol(newval
, NULL
, 0);
454 if ((intval
== 0) && (errno
== EINVAL
)) {
455 fprintf(stderr
, "invalid argument: %s\n",
460 newsize
= sizeof intval
;
465 quadval
= strtoq(newval
, NULL
, 0);
466 if ((quadval
== 0) && (errno
== EINVAL
)) {
467 fprintf(stderr
, "invalid argument: %s\n",
472 newsize
= sizeof quadval
;
477 if (sysctl(mib
, len
, buf
, &size
, newsize
? newval
: 0, newsize
) == -1) {
482 fprintf(stderr
, "%s: value is not available\n", string
);
485 fprintf(stderr
, "%s: specification is incomplete\n",
489 fprintf(stderr
, "%s: type is unknown to this program\n",
493 fprintf(stderr
, "%s: no such MIB\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
) {
667 fprintf(stderr
, "%s: incomplete specification\n", string
);
668 invalid_name_used
= 1;
672 for (i
= 0; i
< namelist
->size
; i
++)
673 if (namelist
->list
[i
].ctl_name
!= NULL
&&
674 strcmp(name
, namelist
->list
[i
].ctl_name
) == 0)
676 if (i
== namelist
->size
) {
678 fprintf(stderr
, "%s level name %s in %s is invalid\n",
679 level
, name
, string
);
680 invalid_name_used
= 1;
690 (void)fprintf(stderr
, "%s\n%s\n%s\n%s\n%s\n",
691 "usage: sysctl [-bn] variable ...",
692 " sysctl [-bn] -w variable=value ...",
700 * Parse a name into a MIB entry.
701 * Lookup and print out the MIB entry if it exists.
702 * Set a new value if requested.
705 parse(char *string
, int flags
)
709 int intval
, newsize
= 0;
710 unsigned int uintval
;
712 int mib
[CTL_MAXNAME
];
713 char *cp
, *bufp
, buf
[BUFSIZ
], fmt
[BUFSIZ
];
717 if (snprintf(buf
, BUFSIZ
, "%s", string
) >= BUFSIZ
)
718 errx(1, "MIB too long");
719 snprintf(buf
, BUFSIZ
, "%s", string
);
720 if ((cp
= strchr(string
, '=')) != NULL
) {
722 errx(2, "must specify -w to set variables");
723 *strchr(buf
, '=') = '\0';
728 newsize
= strlen(cp
);
733 len
= name2oid(bufp
, mib
);
737 while (*cp
!= '\0') cp
--;
740 old_parse (string
, flags
);
745 * An non-zero return here is an OID space containing parameters which
746 * needs to be ignored in the interests of backward compatibility with
747 * pre-newsysctl sysctls.
749 if (oidfmt(mib
, len
, fmt
, &kind
))
753 if ((kind
& CTLTYPE
) == CTLTYPE_NODE
) {
754 sysctl_all(mib
, len
);
756 old_parse (string
, flags
);
758 i
= show_var(mib
, len
, 1);
763 if ((kind
& CTLTYPE
) == CTLTYPE_NODE
)
764 errx(1, "oid '%s' isn't a leaf node", bufp
);
766 if (!(kind
&CTLFLAG_WR
))
767 errx(1, "oid '%s' is read only", bufp
);
769 switch (kind
& CTLTYPE
) {
771 if ((*fmt
== 'I') && (*(fmt
+ 1) == 'U')) {
772 uintval
= (unsigned int) strtoul (newval
, NULL
, 0);
773 if ((uintval
== 0) &&
775 errx(1, "invalid argument: %s",
780 newsize
= sizeof uintval
;
782 intval
= (int) strtol(newval
, NULL
, 0);
785 errx(1, "invalid argument: %s",
790 newsize
= sizeof intval
;
796 quadval
= strtoq(newval
, NULL
, 0);
797 if ((quadval
== 0) && (errno
== EINVAL
)) {
798 errx(1, "invalid argument %s", (char *)newval
);
802 newsize
= sizeof(quadval
);
805 errx(1, "oid '%s' is type %d,"
806 " cannot set that", bufp
,
810 i
= show_var(mib
, len
, 1);
811 if (sysctl(mib
, len
, 0, 0, newval
, newsize
) == -1) {
816 errx(1, "%s: value is not available",
819 errx(1, "%s: specification is incomplete",
822 errx(1, "%s: type is unknown to this program",
833 j
= show_var(mib
, len
, 1);
840 /* These functions will dump out various interesting structures. */
843 S_clockinfo(int l2
, void *p
)
845 struct clockinfo
*ci
= (struct clockinfo
*)p
;
847 if (l2
!= sizeof(*ci
)) {
848 warnx("S_clockinfo %d != %ld", l2
, sizeof(*ci
));
851 printf(hflag
? "{ hz = %'d, tick = %'d, tickadj = %'d, profhz = %'d, stathz = %'d }" :
852 "{ hz = %d, tick = %d, tickadj = %d, profhz = %d, stathz = %d }",
853 ci
->hz
, ci
->tick
, ci
->tickadj
, ci
->profhz
, ci
->stathz
);
858 S_loadavg(int l2
, void *p
)
860 struct loadavg
*tv
= (struct loadavg
*)p
;
862 if (l2
!= sizeof(*tv
)) {
863 warnx("S_loadavg %d != %ld", l2
, sizeof(*tv
));
866 printf(hflag
? "{ %'.2f %'.2f %'.2f }" : "{ %.2f %.2f %.2f }",
867 (double)tv
->ldavg
[0]/(double)tv
->fscale
,
868 (double)tv
->ldavg
[1]/(double)tv
->fscale
,
869 (double)tv
->ldavg
[2]/(double)tv
->fscale
);
874 S_timeval(int l2
, void *p
)
876 struct timeval
*tv
= (struct timeval
*)p
;
880 if (l2
!= sizeof(*tv
)) {
881 warnx("S_timeval %d != %ld", l2
, sizeof(*tv
));
884 printf(hflag
? "{ sec = %'jd, usec = %'ld } " :
885 "{ sec = %jd, usec = %ld } ",
886 (intmax_t)tv
->tv_sec
, (long)tv
->tv_usec
);
888 p1
= strdup(ctime(&tv_sec
));
889 for (p2
=p1
; *p2
; p2
++)
898 S_xswusage(int l2
, void *p
)
900 struct xsw_usage
*xsu
= (struct xsw_usage
*)p
;
902 if (l2
!= sizeof(*xsu
)) {
903 warnx("S_xswusage %d != %ld", l2
, sizeof(*xsu
));
907 "total = %.2fM used = %.2fM free = %.2fM %s",
908 ((double)xsu
->xsu_total
) / (1024.0 * 1024.0),
909 ((double)xsu
->xsu_used
) / (1024.0 * 1024.0),
910 ((double)xsu
->xsu_avail
) / (1024.0 * 1024.0),
911 xsu
->xsu_encrypted
? "(encrypted)" : "");
916 T_dev_t(int l2
, void *p
)
918 dev_t
*d
= (dev_t
*)p
;
920 if (l2
!= sizeof(*d
)) {
921 warnx("T_dev_T %d != %ld", l2
, sizeof(*d
));
924 if ((int)(*d
) != -1) {
925 if (minor(*d
) > 255 || minor(*d
) < 0)
926 printf("{ major = %d, minor = 0x%x }",
927 major(*d
), minor(*d
));
929 printf("{ major = %d, minor = %d }",
930 major(*d
), minor(*d
));
936 * These functions uses a presently undocumented interface to the kernel
937 * to walk the tree and get the type so it can print the value.
938 * This interface is under work and consideration, and should probably
939 * be killed with a big axe by the first person who can find the time.
940 * (be aware though, that the proper interface isn't as obvious as it
941 * may seem, there are various conflicting requirements.
945 name2oid(char *name
, int *oidp
)
954 j
= CTL_MAXNAME
* sizeof (int);
955 i
= sysctl(oid
, 2, oidp
, &j
, name
, strlen(name
));
963 oidfmt(int *oid
, int len
, char *fmt
, u_int
*kind
)
965 int qoid
[CTL_MAXNAME
+2];
972 memcpy(qoid
+ 2, oid
, len
* sizeof(int));
975 i
= sysctl(qoid
, len
+ 2, buf
, &j
, 0, 0);
978 * An ENOENT error return indicates that the OID in question
979 * is a node OID followed not by additional OID elements, but
980 * by integer parameters. We really do not want to support
981 * this type of thing going forward, but we alow it here for
982 * historical compatibility. Eventually, this will go away.
986 err(1, "sysctl fmt %d %ld %d", i
, j
, errno
);
990 *kind
= *(u_int
*)buf
;
993 strcpy(fmt
, (char *)(buf
+ sizeof(u_int
)));
998 * This formats and outputs the value of one variable
1000 * Returns zero if anything was actually output.
1001 * Returns one if didn't know what to do with this.
1002 * Return minus one if we had errors.
1006 show_var(int *oid
, int nlen
, int show_masked
)
1008 u_char buf
[BUFSIZ
], *val
, *mval
, *p
;
1009 char name
[BUFSIZ
], /* descr[BUFSIZ], */ *fmt
;
1010 int qoid
[CTL_MAXNAME
+2];
1015 int (*func
)(int, void *) = 0;
1018 memcpy(qoid
+ 2, oid
, nlen
* sizeof(int));
1022 i
= sysctl(qoid
, nlen
+ 2, name
, &j
, 0, 0);
1024 err(1, "sysctl name %d %ld %d", i
, j
, errno
);
1026 /* find an estimate of how much we need for this var */
1028 i
= sysctl(oid
, nlen
, 0, &j
, 0, 0);
1029 j
+= j
; /* we want to be sure :-) */
1031 val
= mval
= malloc(j
);
1033 i
= sysctl(oid
, nlen
, val
, &len
, 0, 0);
1040 fwrite(val
, 1, len
, stdout
);
1047 i
= sysctl(qoid
, nlen
+ 2, buf
, &j
, 0, 0);
1049 * An ENOENT error return indicates that the OID in question
1050 * is a node OID followed not by additional OID elements, but
1051 * by integer parameters. We really do not want to support
1052 * this type of thing going forward, but we alow it here for
1053 * historical compatibility. Eventially, this will go away.
1055 if (i
&& errno
== ENOENT
) {
1061 err(1, "sysctl fmt %d %ld %d", i
, j
, errno
);
1063 kind
= *(u_int
*)buf
;
1064 if (!show_masked
&& (kind
& CTLFLAG_MASKED
)) {
1069 fmt
= (char *)(buf
+ sizeof(u_int
));
1074 /* deprecated, do not print */
1081 printf("%s: ", name
);
1088 printf("%s: ", name
);
1090 val
= (unsigned char *)"";
1091 while (len
>= sizeof(int)) {
1093 printf("%s%u", val
, *(unsigned int *)p
);
1095 printf("%s%d", val
, *(int *)p
);
1096 val
= (unsigned char *)" ";
1097 len
-= sizeof (int);
1105 printf("%s: ", name
);
1107 val
= (unsigned char *)"";
1108 while (len
>= sizeof(long)) {
1110 printf("%s%lu", val
, *(unsigned long *)p
);
1112 printf("%s%ld", val
, *(long *)p
);
1113 val
= (unsigned char *)" ";
1114 len
-= sizeof (long);
1122 printf("%s: ", name
);
1123 printf("%p", *(void **)p
);
1129 printf("%s: ", name
);
1131 val
= (unsigned char *)"";
1132 while (len
>= sizeof(long long)) {
1134 printf("%s%llu", val
, *(unsigned long long *)p
);
1136 printf("%s%lld", val
, *(long long *)p
);
1137 val
= (unsigned char *)" ";
1138 len
-= sizeof (long long);
1139 p
+= sizeof (long long);
1148 if (!strcmp(fmt
, "S,clockinfo")) func
= S_clockinfo
;
1149 else if (!strcmp(fmt
, "S,timeval")) func
= S_timeval
;
1150 else if (!strcmp(fmt
, "S,loadavg")) func
= S_loadavg
;
1151 else if (!strcmp(fmt
, "S,xsw_usage")) func
= S_xswusage
;
1152 else if (!strcmp(fmt
, "T,dev_t")) func
= T_dev_t
;
1155 printf("%s: ", name
);
1156 retval
= (*func
)(len
, p
);
1166 printf("%s: ", name
);
1167 printf("Format:%s Length:%ld Dump:0x", fmt
, len
);
1169 printf("%02x", *p
++);
1170 if (Xflag
|| p
< val
+16)
1186 sysctl_all (int *oid
, int len
)
1188 int name1
[22], name2
[22];
1196 memcpy(name1
+2, oid
, len
*sizeof (int));
1204 j
= sysctl(name1
, l1
, name2
, &l2
, 0, 0);
1206 if (errno
== ENOENT
)
1209 err(1, "sysctl(getnext) %d %ld", j
, l2
);
1217 for (i
= 0; i
< len
; i
++)
1218 if (name2
[i
] != oid
[i
])
1221 i
= show_var(name2
, l2
, 0);
1225 memcpy(name1
+2, name2
, l2
*sizeof (int));