Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 23 Jul 2001 00:40:34 +0300
From:      Peter Pentchev <roam@orbitel.bg>
To:        arch@FreeBSD.org
Cc:        audit@FreeBSD.org
Subject:   sysctl(8) enhancement: display sysctl MIB's
Message-ID:  <20010723004034.I882@ringworld.oblivion.bg>

next in thread | raw e-mail | index | archive | help
Hi,

During the testing of the kern_sysctl.c patches for PR xxxxx,
I came across a feature missing from the sysctl user interface -
there was no easy way to obtain a list of sysctl's and their MIB's
to see if the PR submitter was actually correct that there were
cases when dynamic sysctl's were placed amidst static ones.

sysctl(8), the logical place to look for such an interface, turned
out to have none.  Attached is a patch which adds a new command-line
flag, -m, to display MIB's before names.

Since the MIB's are of arbitrary length, there is no easy way to
line them up, short of buffering the entire sysctl output to determine
the maximum size.  Since this is only of limited use (debugging new
sysctl entries' placement), people who use it could be bothered to
use a standalone formatter (Perl and awk come to mind ;) to prettify
the output.

Comments?  Yep, I know that this is only of limited use, but still,
it turned out to be useful in at least one case.

G'luck,
Peter

-- 
I am jealous of the first word in this sentence.

Index: src/sbin/sysctl/sysctl.8
===================================================================
RCS file: /home/ncvs/src/sbin/sysctl/sysctl.8,v
retrieving revision 1.36
diff -u -r1.36 sysctl.8
--- src/sbin/sysctl/sysctl.8	2001/07/13 09:09:48	1.36
+++ src/sbin/sysctl/sysctl.8	2001/07/22 21:36:26
@@ -40,7 +40,7 @@
 .Nd get or set kernel state
 .Sh SYNOPSIS
 .Nm
-.Op Fl bNnox
+.Op Fl bmNnox
 .Ar name Ns Op = Ns Ar value
 .Ar ...
 .Nm
@@ -71,6 +71,11 @@
 Force the value of the variable(s) to be output in raw, binary format.
 No names are printed and no terminating newlines are output.
 This is mostly useful with a single variable.
+.It Fl m
+Specify that the MIB numerical value should be printed before the name.
+This flag only takes effect if
+.Fl n
+is not specified.
 .It Fl N
 Show only variable names, not their values.
 This is particularly useful with shells that offer programmable
Index: src/sbin/sysctl/sysctl.c
===================================================================
RCS file: /home/ncvs/src/sbin/sysctl/sysctl.c,v
retrieving revision 1.37
diff -u -r1.37 sysctl.c
--- src/sbin/sysctl/sysctl.c	2001/06/18 21:06:24	1.37
+++ src/sbin/sysctl/sysctl.c	2001/07/22 21:36:28
@@ -58,10 +58,11 @@
 #include <string.h>
 #include <unistd.h>
 
-static int	aflag, bflag, Nflag, nflag, oflag, xflag;
+static int	aflag, bflag, mflag, Nflag, nflag, oflag, xflag;
 
 static int	oidfmt(int *, int, char *, u_int *);
 static void	parse(char *);
+static int	show_varname(const char *, const int *, int);
 static int	show_var(int *, int);
 static int	sysctl_all (int *oid, int len);
 static int	name2oid(char *, int *);
@@ -71,8 +72,8 @@
 {
 
 	(void)fprintf(stderr, "%s\n%s\n",
-	    "usage: sysctl [-bNnox] variable[=value] ...",
-	    "       sysctl [-bNnox] -a");
+	    "usage: sysctl [-bmNnox] variable[=value] ...",
+	    "       sysctl [-bmNnox] -a");
 	exit(1);
 }
 
@@ -83,7 +84,7 @@
 	setbuf(stdout,0);
 	setbuf(stderr,0);
 
-	while ((ch = getopt(argc, argv, "AabNnowxX")) != -1) {
+	while ((ch = getopt(argc, argv, "AabmNnowxX")) != -1) {
 		switch (ch) {
 		case 'A':
 			/* compatibility */
@@ -95,6 +96,9 @@
 		case 'b':
 			bflag = 1;
 			break;
+		case 'm':
+			mflag = 1;
+			break;
 		case 'N':
 			Nflag = 1;
 			break;
@@ -369,6 +373,33 @@
 }
 
 /*
+ * This formats and outputs the name of one variable.
+ * If the -m command-line flag was specified, the MIB value
+ * is also printed out.
+ *
+ * Returns zero on success.
+ * No error conditions yet (XXX: check printf() return value? :)
+ */
+
+static int
+show_varname(const char *name, const int *oid, int len)
+{
+	int i;
+
+	if (nflag)
+		return (0);
+
+	if (mflag) {
+		for (i = 0; i < len-1; i++)
+			printf("%X.", oid[i]);
+		printf("%X ", oid[i]);
+	}
+
+	printf("%s: ", name);
+	return (0);
+}
+
+/*
  * This formats and outputs the value of one variable
  *
  * Returns zero if anything was actually output.
@@ -397,7 +428,7 @@
 		err(1, "sysctl name %d %d %d", i, j, errno);
 
 	if (Nflag) {
-		printf("%s", name);
+		show_varname(name, oid, nlen);
 		return (0);
 	}
 
@@ -430,14 +461,12 @@
 	p = val;
 	switch (*fmt) {
 	case 'A':
-		if (!nflag)
-			printf("%s: ", name);
+		show_varname(name, oid, nlen);
 		printf("%s", p);
 		return (0);
 		
 	case 'I':
-		if (!nflag)
-			printf("%s: ", name);
+		show_varname(name, oid, nlen);
 		fmt++;
 		val = "";
 		while (len >= sizeof(int)) {
@@ -452,8 +481,7 @@
 		return (0);
 
 	case 'L':
-		if (!nflag)
-			printf("%s: ", name);
+		show_varname(name, oid, nlen);
 		fmt++;
 		val = "";
 		while (len >= sizeof(long)) {
@@ -468,8 +496,7 @@
 		return (0);
 
 	case 'P':
-		if (!nflag)
-			printf("%s: ", name);
+		show_varname(name, oid, nlen);
 		printf("%p", *(void **)p);
 		return (0);
 
@@ -487,16 +514,14 @@
 		else
 			func = NULL;
 		if (func) {
-			if (!nflag)
-				printf("%s: ", name);
+			show_varname(name, oid, nlen);
 			return ((*func)(len, p));
 		}
 		/* FALL THROUGH */
 	default:
 		if (!oflag && !xflag)
 			return (1);
-		if (!nflag)
-			printf("%s: ", name);
+		show_varname(name, oid, nlen);
 		printf("Format:%s Length:%d Dump:0x", fmt, len);
 		while (len-- && (xflag || p < val + 16))
 			printf("%02x", *p++);

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-audit" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010723004034.I882>