From owner-freebsd-audit Sun Jul 22 14:41:39 2001 Delivered-To: freebsd-audit@freebsd.org Received: from ringworld.nanolink.com (discworld.nanolink.com [195.24.48.189]) by hub.freebsd.org (Postfix) with SMTP id 9572337B406 for ; Sun, 22 Jul 2001 14:41:20 -0700 (PDT) (envelope-from roam@ringworld.nanolink.com) Received: (qmail 3493 invoked by uid 1000); 22 Jul 2001 21:40:34 -0000 Date: Mon, 23 Jul 2001 00:40:34 +0300 From: Peter Pentchev To: arch@FreeBSD.org Cc: audit@FreeBSD.org Subject: sysctl(8) enhancement: display sysctl MIB's Message-ID: <20010723004034.I882@ringworld.oblivion.bg> Mail-Followup-To: arch@FreeBSD.org, audit@FreeBSD.org Mime-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.2.5i Sender: owner-freebsd-audit@FreeBSD.ORG Precedence: bulk List-ID: List-Archive: (Web Archive) List-Help: (List Instructions) List-Subscribe: List-Unsubscribe: X-Loop: FreeBSD.ORG 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 #include -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