xref: /csrg-svn/usr.sbin/sysctl/sysctl.c (revision 60426)
158888Smckusick /*
258888Smckusick  * Copyright (c) 1993 The Regents of the University of California.
358888Smckusick  * All rights reserved.
458888Smckusick  *
558888Smckusick  * %sccs.include.redist.c%
658888Smckusick  */
758888Smckusick 
858888Smckusick #ifndef lint
958888Smckusick char copyright[] =
1058888Smckusick "@(#) Copyright (c) 1993 The Regents of the University of California.\n\
1158888Smckusick  All rights reserved.\n";
1258888Smckusick #endif /* not lint */
1358888Smckusick 
1458888Smckusick #ifndef lint
15*60426Smckusick static char sccsid[] = "@(#)sysctl.c	5.12 (Berkeley) 05/26/93";
1658888Smckusick #endif /* not lint */
1758888Smckusick 
1859379Sbostic #include <sys/param.h>
1959658Smckusick #include <sys/gmon.h>
2058888Smckusick #include <sys/stat.h>
2158888Smckusick #include <sys/sysctl.h>
2258888Smckusick #include <sys/socket.h>
2358888Smckusick #include <vm/vm_param.h>
24*60426Smckusick #include <machine/cpu.h>
2559379Sbostic 
2659140Smckusick #include <netinet/in.h>
2759140Smckusick #include <netinet/in_systm.h>
2859140Smckusick #include <netinet/ip.h>
2959140Smckusick #include <netinet/ip_icmp.h>
3059140Smckusick #include <netinet/icmp_var.h>
3159311Smckusick #include <netinet/ip_var.h>
3259311Smckusick #include <netinet/udp.h>
3359311Smckusick #include <netinet/udp_var.h>
3459379Sbostic 
3558888Smckusick #include <errno.h>
3659379Sbostic #include <stdio.h>
3758888Smckusick #include <stdlib.h>
3858888Smckusick #include <string.h>
3958888Smckusick 
4059140Smckusick struct ctlname topname[] = CTL_NAMES;
4159140Smckusick struct ctlname kernname[] = CTL_KERN_NAMES;
4259140Smckusick struct ctlname vmname[] = CTL_VM_NAMES;
4359140Smckusick struct ctlname netname[] = CTL_NET_NAMES;
4459140Smckusick struct ctlname hwname[] = CTL_HW_NAMES;
4559719Sbostic struct ctlname username[] = CTL_USER_NAMES;
4659159Smckusick struct ctlname debugname[CTL_DEBUG_MAXID];
47*60426Smckusick #ifdef CTL_MACHDEP_NAMES
48*60426Smckusick struct ctlname machdepname[] = CTL_MACHDEP_NAMES;
49*60426Smckusick #endif
5059159Smckusick char names[BUFSIZ];
5158888Smckusick 
5258888Smckusick struct list {
5359140Smckusick 	struct	ctlname *list;
5458888Smckusick 	int	size;
5559140Smckusick };
5659140Smckusick struct list toplist = { topname, CTL_MAXID };
5759140Smckusick struct list secondlevel[] = {
5858888Smckusick 	{ 0, 0 },			/* CTL_UNSPEC */
5958888Smckusick 	{ kernname, KERN_MAXID },	/* CTL_KERN */
6058888Smckusick 	{ vmname, VM_MAXID },		/* CTL_VM */
6158888Smckusick 	{ 0, 0 },			/* CTL_FS */
6258888Smckusick 	{ netname, NET_MAXID },		/* CTL_NET */
6359159Smckusick 	{ 0, CTL_DEBUG_MAXID },		/* CTL_DEBUG */
6458888Smckusick 	{ hwname, HW_MAXID },		/* CTL_HW */
65*60426Smckusick #ifdef CTL_MACHDEP_NAMES
66*60426Smckusick 	{ machdepname, CPU_MAXID },	/* CTL_MACHDEP */
67*60426Smckusick #else
6858888Smckusick 	{ 0, 0 },			/* CTL_MACHDEP */
69*60426Smckusick #endif
7059719Sbostic 	{ username, USER_MAXID },	/* CTL_USER_NAMES */
7158888Smckusick };
7258888Smckusick 
7358910Smckusick int	Aflag, aflag, nflag, wflag;
7458888Smckusick 
75*60426Smckusick /*
76*60426Smckusick  * Variables requiring special processing.
77*60426Smckusick  */
78*60426Smckusick #define	CLOCK		0x00000001
79*60426Smckusick #define	BOOTTIME	0x00000002
80*60426Smckusick #define	CONSDEV		0x00000004
81*60426Smckusick 
8258888Smckusick int
8358888Smckusick main(argc, argv)
8458888Smckusick 	int argc;
8558888Smckusick 	char *argv[];
8658888Smckusick {
8758888Smckusick 	extern char *optarg;
8858888Smckusick 	extern int optind;
8958910Smckusick 	int ch, lvl1;
9058888Smckusick 
9158910Smckusick 	while ((ch = getopt(argc, argv, "Aanw")) != EOF) {
9258888Smckusick 		switch (ch) {
9358888Smckusick 
9458888Smckusick 		case 'A':
9558888Smckusick 			Aflag = 1;
9658888Smckusick 			break;
9758888Smckusick 
9858888Smckusick 		case 'a':
9958888Smckusick 			aflag = 1;
10058888Smckusick 			break;
10158888Smckusick 
10258910Smckusick 		case 'n':
10358910Smckusick 			nflag = 1;
10458910Smckusick 			break;
10558910Smckusick 
10658888Smckusick 		case 'w':
10758888Smckusick 			wflag = 1;
10858888Smckusick 			break;
10958888Smckusick 
11058888Smckusick 		default:
11158888Smckusick 			usage();
11258888Smckusick 		}
11358888Smckusick 	}
11458888Smckusick 	argc -= optind;
11558888Smckusick 	argv += optind;
11658888Smckusick 
11758888Smckusick 	if (Aflag || aflag) {
11859159Smckusick 		debuginit();
11958910Smckusick 		for (lvl1 = 1; lvl1 < CTL_MAXID; lvl1++)
12059140Smckusick 			listall(topname[lvl1].ctl_name, &secondlevel[lvl1]);
12158888Smckusick 		exit(0);
12258888Smckusick 	}
12358888Smckusick 	if (argc == 0)
12458888Smckusick 		usage();
12558888Smckusick 	while (argc-- > 0)
12658888Smckusick 		parse(*argv, 1);
12758888Smckusick 	exit(0);
12858888Smckusick }
12958888Smckusick 
13058888Smckusick /*
13158888Smckusick  * List all variables known to the system.
13258888Smckusick  */
13359140Smckusick listall(prefix, lp)
13459140Smckusick 	char *prefix;
13559140Smckusick 	struct list *lp;
13658888Smckusick {
13758910Smckusick 	int lvl2;
13858888Smckusick 	char *cp, name[BUFSIZ];
13958888Smckusick 
14058910Smckusick 	if (lp->list == 0)
14158910Smckusick 		return;
14259140Smckusick 	strcpy(name, prefix);
14358910Smckusick 	cp = &name[strlen(name)];
14458910Smckusick 	*cp++ = '.';
14559140Smckusick 	for (lvl2 = 0; lvl2 < lp->size; lvl2++) {
14659140Smckusick 		if (lp->list[lvl2].ctl_name == 0)
14759140Smckusick 			continue;
14859140Smckusick 		strcpy(cp, lp->list[lvl2].ctl_name);
14958910Smckusick 		parse(name, Aflag);
15058888Smckusick 	}
15158888Smckusick }
15258888Smckusick 
15358888Smckusick /*
15458888Smckusick  * Parse a name into a MIB entry.
15558888Smckusick  * Lookup and print out the MIB entry if it exists.
15658888Smckusick  * Set a new value if requested.
15758888Smckusick  */
15858888Smckusick parse(string, flags)
15958888Smckusick 	char *string;
16058888Smckusick 	int flags;
16158888Smckusick {
16259658Smckusick 	int indx, type, state, size, len;
163*60426Smckusick 	int special = 0;
16458888Smckusick 	void *newval = 0;
16558888Smckusick 	int intval, newsize = 0;
16659140Smckusick 	quad_t quadval;
16759140Smckusick 	struct list *lp;
16858888Smckusick 	int mib[CTL_MAXNAME];
16958888Smckusick 	char *cp, *bufp, buf[BUFSIZ], strval[BUFSIZ];
17058888Smckusick 
17158888Smckusick 	bufp = buf;
17258888Smckusick 	snprintf(buf, BUFSIZ, "%s", string);
17358888Smckusick 	if ((cp = strchr(string, '=')) != NULL) {
17458888Smckusick 		if (!wflag) {
17558888Smckusick 			fprintf(stderr, "Must specify -w to set variables\n");
17658888Smckusick 			exit(2);
17758888Smckusick 		}
17858888Smckusick 		*strchr(buf, '=') = '\0';
17958888Smckusick 		*cp++ = '\0';
18058888Smckusick 		while (isspace(*cp))
18158888Smckusick 			cp++;
18259140Smckusick 		newval = cp;
18359140Smckusick 		newsize = strlen(cp);
18458888Smckusick 	}
18559140Smckusick 	if ((indx = findname(string, "top", &bufp, &toplist)) == -1)
18658888Smckusick 		return;
18758888Smckusick 	mib[0] = indx;
18859159Smckusick 	if (indx == CTL_DEBUG)
18959159Smckusick 		debuginit();
19058888Smckusick 	lp = &secondlevel[indx];
19158888Smckusick 	if (lp->list == 0) {
19258888Smckusick 		fprintf(stderr, "%s: class is not implemented\n",
19358888Smckusick 		    topname[indx]);
19458888Smckusick 		return;
19558888Smckusick 	}
19658910Smckusick 	if (bufp == NULL) {
19759140Smckusick 		listall(topname[indx].ctl_name, lp);
19858910Smckusick 		return;
19958910Smckusick 	}
20058888Smckusick 	if ((indx = findname(string, "second", &bufp, lp)) == -1)
20158888Smckusick 		return;
20258888Smckusick 	mib[1] = indx;
20359140Smckusick 	type = lp->list[indx].ctl_type;
20459140Smckusick 	len = 2;
20558888Smckusick 	switch (mib[0]) {
20658888Smckusick 
20758888Smckusick 	case CTL_KERN:
20858888Smckusick 		switch (mib[1]) {
20959658Smckusick 		case KERN_PROF:
21059658Smckusick 			mib[2] = GPROF_STATE;
21159658Smckusick 			size = sizeof state;
21259658Smckusick 			if (sysctl(mib, 3, &state, &size, NULL, 0) < 0) {
21359658Smckusick 				if (flags == 0)
21459658Smckusick 					return;
21559658Smckusick 				if (!nflag)
21659658Smckusick 					fprintf(stdout, "%s: ", string);
21759658Smckusick 				fprintf(stderr,
21859658Smckusick 				    "kernel is not compiled for profiling\n");
21959658Smckusick 				return;
22059658Smckusick 			}
22159658Smckusick 			if (!nflag)
22259658Smckusick 				fprintf(stdout, "%s: %s\n", string,
22359658Smckusick 				    state == GMON_PROF_OFF ? "off" : "running");
22459658Smckusick 			return;
22558888Smckusick 		case KERN_VNODE:
22658888Smckusick 		case KERN_FILE:
22758888Smckusick 			if (flags == 0)
22858888Smckusick 				return;
22958888Smckusick 			fprintf(stderr,
23058888Smckusick 			    "Use pstat to view %s information\n", string);
23158888Smckusick 			return;
23258888Smckusick 		case KERN_PROC:
23358888Smckusick 			if (flags == 0)
23458888Smckusick 				return;
23558888Smckusick 			fprintf(stderr,
23658888Smckusick 			    "Use ps to view %s information\n", string);
23758888Smckusick 			return;
23858888Smckusick 		case KERN_CLOCKRATE:
239*60426Smckusick 			special |= CLOCK;
24058888Smckusick 			break;
24160154Smckusick 		case KERN_BOOTTIME:
242*60426Smckusick 			special |= BOOTTIME;
24360154Smckusick 			break;
24458888Smckusick 		}
24558888Smckusick 		break;
24658888Smckusick 
24758888Smckusick 	case CTL_HW:
24858888Smckusick 		break;
24958888Smckusick 
25058888Smckusick 	case CTL_VM:
25158888Smckusick 		if (mib[1] == VM_LOADAVG) {
25258888Smckusick 			double loads[3];
25358888Smckusick 
25458888Smckusick 			getloadavg(loads, 3);
25558910Smckusick 			if (!nflag)
25658910Smckusick 				fprintf(stdout, "%s: ", string);
25758910Smckusick 			fprintf(stdout, "%.2f %.2f %.2f\n",
25858888Smckusick 			    loads[0], loads[1], loads[2]);
25958888Smckusick 			return;
26058888Smckusick 		}
26158888Smckusick 		if (flags == 0)
26258888Smckusick 			return;
26358888Smckusick 		fprintf(stderr,
26458888Smckusick 		    "Use vmstat or systat to view %s information\n", string);
26558888Smckusick 		return;
26658888Smckusick 
26758888Smckusick 	case CTL_NET:
26859140Smckusick 		if (mib[1] == PF_INET) {
26959140Smckusick 			len = sysctl_inet(string, &bufp, mib, flags, &type);
27059140Smckusick 			if (len >= 0)
27159140Smckusick 				break;
27259140Smckusick 			return;
27359140Smckusick 		}
27458888Smckusick 		if (flags == 0)
27558888Smckusick 			return;
27658888Smckusick 		fprintf(stderr, "Use netstat to view %s information\n", string);
27758888Smckusick 		return;
27858888Smckusick 
27959159Smckusick 	case CTL_DEBUG:
28059159Smckusick 		mib[2] = CTL_DEBUG_VALUE;
28159159Smckusick 		len = 3;
28259159Smckusick 		break;
28359159Smckusick 
284*60426Smckusick 	case CTL_MACHDEP:
285*60426Smckusick #ifdef CPU_CONSDEV
286*60426Smckusick 		if (mib[1] == CPU_CONSDEV)
287*60426Smckusick 			special |= CONSDEV;
288*60426Smckusick #endif
289*60426Smckusick 		break;
290*60426Smckusick 
29158888Smckusick 	case CTL_FS:
29259719Sbostic 	case CTL_USER:
29358888Smckusick 		break;
29458888Smckusick 
29558888Smckusick 	default:
29658888Smckusick 		fprintf(stderr, "Illegal top level value: %d\n", mib[0]);
29758888Smckusick 		return;
29858888Smckusick 
29958888Smckusick 	}
30059140Smckusick 	if (bufp) {
30159140Smckusick 		fprintf(stderr, "name %s in %s is unknown\n", *bufp, string);
30259140Smckusick 		return;
30359140Smckusick 	}
30459140Smckusick 	if (newsize > 0) {
30559140Smckusick 		switch (type) {
30659140Smckusick 		case CTLTYPE_INT:
30759140Smckusick 			intval = atoi(newval);
30859140Smckusick 			newval = &intval;
30959140Smckusick 			newsize = sizeof intval;
31059140Smckusick 			break;
31158888Smckusick 
31259140Smckusick 		case CTLTYPE_QUAD:
31359140Smckusick 			sscanf(newval, "%qd", &quadval);
31459140Smckusick 			newval = &quadval;
31559140Smckusick 			newsize = sizeof quadval;
31659140Smckusick 			break;
31759140Smckusick 		}
31859140Smckusick 	}
31958888Smckusick 	size = BUFSIZ;
32059140Smckusick 	if (sysctl(mib, len, buf, &size, newsize ? newval : 0, newsize) == -1) {
32158888Smckusick 		if (flags == 0)
32258888Smckusick 			return;
32358888Smckusick 		switch (errno) {
32458888Smckusick 		case EOPNOTSUPP:
32558888Smckusick 			fprintf(stderr, "%s: value is not available\n", string);
32658888Smckusick 			return;
32758888Smckusick 		case ENOTDIR:
32858888Smckusick 			fprintf(stderr, "%s: specification is incomplete\n",
32958888Smckusick 			    string);
33058888Smckusick 			return;
33158888Smckusick 		case ENOMEM:
33258888Smckusick 			fprintf(stderr, "%s: type is unknown to this program\n",
33358888Smckusick 			    string);
33458888Smckusick 			return;
33558888Smckusick 		default:
33658888Smckusick 			perror(string);
33758888Smckusick 			return;
33858888Smckusick 		}
33958888Smckusick 	}
340*60426Smckusick 	if (special & CLOCK) {
34158888Smckusick 		struct clockinfo *clkp = (struct clockinfo *)buf;
34258888Smckusick 
34358910Smckusick 		if (!nflag)
34458910Smckusick 			fprintf(stdout, "%s: ", string);
34558888Smckusick 		fprintf(stdout,
34658910Smckusick 		    "hz = %d, tick = %d, profhz = %d, stathz = %d\n",
34758910Smckusick 		    clkp->hz, clkp->tick, clkp->profhz, clkp->stathz);
34858888Smckusick 		return;
34958888Smckusick 	}
350*60426Smckusick 	if (special & BOOTTIME) {
35160154Smckusick 		struct timeval *btp = (struct timeval *)buf;
35260154Smckusick 
35360154Smckusick 		if (!nflag)
35460154Smckusick 			fprintf(stdout, "%s = %s\n", string,
35560154Smckusick 			    ctime(&btp->tv_sec));
35660154Smckusick 		else
35760154Smckusick 			fprintf(stdout, "%d\n", btp->tv_sec);
35860154Smckusick 		return;
35960154Smckusick 	}
360*60426Smckusick 	if (special & CONSDEV) {
361*60426Smckusick 		dev_t dev = *(dev_t *)buf;
362*60426Smckusick 
363*60426Smckusick 		if (!nflag)
364*60426Smckusick 			fprintf(stdout, "%s = %s\n", string,
365*60426Smckusick 			    devname(dev, S_IFCHR));
366*60426Smckusick 		else
367*60426Smckusick 			fprintf(stdout, "0x%x\n", dev);
368*60426Smckusick 		return;
369*60426Smckusick 	}
37059140Smckusick 	switch (type) {
37159140Smckusick 	case CTLTYPE_INT:
37258910Smckusick 		if (newsize == 0) {
37358910Smckusick 			if (!nflag)
37458910Smckusick 				fprintf(stdout, "%s = ", string);
37558910Smckusick 			fprintf(stdout, "%d\n", *(int *)buf);
37658910Smckusick 		} else {
37758910Smckusick 			if (!nflag)
37858910Smckusick 				fprintf(stdout, "%s: %d -> ", string,
37958910Smckusick 				    *(int *)buf);
38058910Smckusick 			fprintf(stdout, "%d\n", *(int *)newval);
38158910Smckusick 		}
38259140Smckusick 		return;
38359140Smckusick 
38459140Smckusick 	case CTLTYPE_STRING:
38558910Smckusick 		if (newsize == 0) {
38658910Smckusick 			if (!nflag)
38758910Smckusick 				fprintf(stdout, "%s = ", string);
38858910Smckusick 			fprintf(stdout, "%s\n", buf);
38958910Smckusick 		} else {
39058910Smckusick 			if (!nflag)
39158910Smckusick 				fprintf(stdout, "%s: %s -> ", string, buf);
39258910Smckusick 			fprintf(stdout, "%s\n", newval);
39358910Smckusick 		}
39459140Smckusick 		return;
39559140Smckusick 
39659140Smckusick 	case CTLTYPE_QUAD:
39759140Smckusick 		if (newsize == 0) {
39859140Smckusick 			if (!nflag)
39959140Smckusick 				fprintf(stdout, "%s = ", string);
40059140Smckusick 			fprintf(stdout, "%qd\n", *(quad_t *)buf);
40159140Smckusick 		} else {
40259140Smckusick 			if (!nflag)
40359140Smckusick 				fprintf(stdout, "%s: %qd -> ", string,
40459140Smckusick 				    *(quad_t *)buf);
40559140Smckusick 			fprintf(stdout, "%qd\n", *(quad_t *)newval);
40659140Smckusick 		}
40759140Smckusick 		return;
40859140Smckusick 
40959140Smckusick 	case CTLTYPE_STRUCT:
41059140Smckusick 		fprintf(stderr, "%s: unknown structure returned\n",
41159140Smckusick 		    string);
41259140Smckusick 		return;
41359140Smckusick 
41459140Smckusick 	default:
41559140Smckusick 	case CTLTYPE_NODE:
41659140Smckusick 		fprintf(stderr, "%s: unknown type returned\n",
41759140Smckusick 		    string);
41859140Smckusick 		return;
41959140Smckusick 	}
42058888Smckusick }
42158888Smckusick 
42259159Smckusick /*
42359159Smckusick  * Initialize the set of debugging names
42459159Smckusick  */
42559159Smckusick debuginit()
42659159Smckusick {
42759159Smckusick 	int mib[3], size, loc, i;
42859159Smckusick 
42959159Smckusick 	if (secondlevel[CTL_DEBUG].list != 0)
43059159Smckusick 		return;
43159159Smckusick 	secondlevel[CTL_DEBUG].list = debugname;
43259159Smckusick 	mib[0] = CTL_DEBUG;
43359159Smckusick 	mib[2] = CTL_DEBUG_NAME;
43459159Smckusick 	for (loc = 0, i = 0; i < CTL_DEBUG_MAXID; i++) {
43559159Smckusick 		mib[1] = i;
43659159Smckusick 		size = BUFSIZ - loc;
43759159Smckusick 		if (sysctl(mib, 3, &names[loc], &size, NULL, 0) == -1)
43859159Smckusick 			continue;
43959159Smckusick 		debugname[i].ctl_name = &names[loc];
44059159Smckusick 		debugname[i].ctl_type = CTLTYPE_INT;
44159159Smckusick 		loc += size;
44259159Smckusick 	}
44359159Smckusick }
44459159Smckusick 
44559140Smckusick struct ctlname inetname[] = CTL_IPPROTO_NAMES;
44659140Smckusick struct ctlname ipname[] = IPCTL_NAMES;
44759140Smckusick struct ctlname icmpname[] = ICMPCTL_NAMES;
44859311Smckusick struct ctlname udpname[] = UDPCTL_NAMES;
44959140Smckusick struct list inetlist = { inetname, IPPROTO_MAXID };
45059140Smckusick struct list inetvars[] = {
45159311Smckusick 	{ ipname, IPCTL_MAXID },	/* ip */
45259311Smckusick 	{ icmpname, ICMPCTL_MAXID },	/* icmp */
45359311Smckusick 	{ 0, 0 },			/* igmp */
45459311Smckusick 	{ 0, 0 },			/* ggmp */
45559311Smckusick 	{ 0, 0 },
45659311Smckusick 	{ 0, 0 },
45759311Smckusick 	{ 0, 0 },			/* tcp */
45859311Smckusick 	{ 0, 0 },
45959311Smckusick 	{ 0, 0 },			/* egp */
46059311Smckusick 	{ 0, 0 },
46159311Smckusick 	{ 0, 0 },
46259311Smckusick 	{ 0, 0 },
46359311Smckusick 	{ 0, 0 },			/* pup */
46459311Smckusick 	{ 0, 0 },
46559311Smckusick 	{ 0, 0 },
46659311Smckusick 	{ 0, 0 },
46759311Smckusick 	{ 0, 0 },
46859311Smckusick 	{ udpname, UDPCTL_MAXID },	/* udp */
46959140Smckusick };
47059140Smckusick 
47158888Smckusick /*
47259140Smckusick  * handle internet requests
47359140Smckusick  */
47459140Smckusick sysctl_inet(string, bufpp, mib, flags, typep)
47559140Smckusick 	char *string;
47659140Smckusick 	char **bufpp;
47759140Smckusick 	int mib[];
47859140Smckusick 	int flags;
47959140Smckusick 	int *typep;
48059140Smckusick {
48159140Smckusick 	struct list *lp;
48259140Smckusick 	int indx;
48359140Smckusick 
48459140Smckusick 	if (*bufpp == NULL) {
48559140Smckusick 		listall(string, &inetlist);
48659140Smckusick 		return (-1);
48759140Smckusick 	}
48859140Smckusick 	if ((indx = findname(string, "third", bufpp, &inetlist)) == -1)
48959140Smckusick 		return (-1);
49059140Smckusick 	mib[2] = indx;
49159311Smckusick 	if (indx <= IPPROTO_UDP && inetvars[indx].list != NULL)
49259140Smckusick 		lp = &inetvars[indx];
49359140Smckusick 	else if (!flags)
49459140Smckusick 		return (-1);
49559140Smckusick 	else {
49659140Smckusick 		fprintf(stderr, "%s: no variables defined for this protocol\n",
49759140Smckusick 		    string);
49859140Smckusick 		return (-1);
49959140Smckusick 	}
50059140Smckusick 	if (*bufpp == NULL) {
50159140Smckusick 		listall(string, lp);
50259140Smckusick 		return (-1);
50359140Smckusick 	}
50459140Smckusick 	if ((indx = findname(string, "fourth", bufpp, lp)) == -1)
50559140Smckusick 		return (-1);
50659140Smckusick 	mib[3] = indx;
50759140Smckusick 	*typep = lp->list[indx].ctl_type;
50859140Smckusick 	return (4);
50959140Smckusick }
51059140Smckusick 
51159140Smckusick /*
51258888Smckusick  * Scan a list of names searching for a particular name.
51358888Smckusick  */
51458888Smckusick findname(string, level, bufp, namelist)
51558888Smckusick 	char *string;
51658888Smckusick 	char *level;
51758888Smckusick 	char **bufp;
51858888Smckusick 	struct list *namelist;
51958888Smckusick {
52058888Smckusick 	char *name;
52158888Smckusick 	int i;
52258888Smckusick 
52358888Smckusick 	if (namelist->list == 0 || (name = strsep(bufp, ".")) == NULL) {
52458888Smckusick 		fprintf(stderr, "%s: incomplete specification\n", string);
52558888Smckusick 		return (-1);
52658888Smckusick 	}
52758888Smckusick 	for (i = 0; i < namelist->size; i++)
52859252Storek 		if (namelist->list[i].ctl_name != NULL &&
52959252Storek 		    strcmp(name, namelist->list[i].ctl_name) == 0)
53058888Smckusick 			break;
53158888Smckusick 	if (i == namelist->size) {
53258888Smckusick 		fprintf(stderr, "%s level name %s in %s is invalid\n",
53358888Smckusick 		    level, name, string);
53458888Smckusick 		return (-1);
53558888Smckusick 	}
53658888Smckusick 	return (i);
53758888Smckusick }
53858888Smckusick 
53958888Smckusick usage()
54058888Smckusick {
54158888Smckusick 
54258911Smckusick 	(void)fprintf(stderr, "usage:\t%s\n\t%s\n\t%s\n\t%s\n",
54358911Smckusick 	    "sysctl [-n] variable ...", "sysctl [-n] -w variable=value ...",
54458911Smckusick 	    "sysctl [-n] -a", "sysctl [-n] -A");
54558888Smckusick 	exit(1);
54658888Smckusick }
547