From owner-freebsd-current@FreeBSD.ORG Sun Dec 2 03:32:02 2012 Return-Path: Delivered-To: current@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 64DCA176; Sun, 2 Dec 2012 03:32:02 +0000 (UTC) (envelope-from mureninc@gmail.com) Received: from mail-ie0-f182.google.com (mail-ie0-f182.google.com [209.85.223.182]) by mx1.freebsd.org (Postfix) with ESMTP id 0FC058FC0C; Sun, 2 Dec 2012 03:32:01 +0000 (UTC) Received: by mail-ie0-f182.google.com with SMTP id s9so3238579iec.13 for ; Sat, 01 Dec 2012 19:32:01 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20120113; h=mime-version:in-reply-to:references:date:message-id:subject:from:to :cc:content-type; bh=cZtvEVfNn/+hFORpgLQVXdrWH9gUOIwIMkcldhkPzNQ=; b=EMkTfREC5PhR8IxrVYsKWxn3LbjcHzc5R/pmyky7Gc3AWO6ecsbc5j4k1eplxLQu05 ag/BoqFwDJXuepBoSJT3BiEobFXikCzhyVUUDjOjuZcYtn2ZakzhmHkIhbN4yasSwfWv yKGLAgS0DZVJI1xG0VSch2VV40OOpBPjKOlb8QF2gteSplkNYfuygbBKtr+fTubvaSsB Ue0lghdWjYBJDRyDJkHGFs5gDfGKdXNyHwpYSrgfuOqe4ZdHvWNbRd2C/FOdPKnckkXh uJ5iZbCQ6W/0pK1fOkh/veypnd31DWNPYTXexFTts0kY9iHvnfr7OMUbqGJwjr12omqJ t2Xg== MIME-Version: 1.0 Received: by 10.50.152.236 with SMTP id vb12mr2919192igb.15.1354419120951; Sat, 01 Dec 2012 19:32:00 -0800 (PST) Received: by 10.64.166.66 with HTTP; Sat, 1 Dec 2012 19:32:00 -0800 (PST) In-Reply-To: References: <20121202.015048.1122480556487090170.hrs@allbsd.org> <20121202.082150.896017277887885294.hrs@allbsd.org> <20121201233756.GS3013@kib.kiev.ua> Date: Sat, 1 Dec 2012 19:32:00 -0800 Message-ID: Subject: Re: RFC: sysctl -f filename From: "Constantine A. Murenin" To: Garrett Cooper Content-Type: text/plain; charset=ISO-8859-1 Cc: Konstantin Belousov , rc@freebsd.org, current@freebsd.org X-BeenThere: freebsd-current@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: Discussions about the use of FreeBSD-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sun, 02 Dec 2012 03:32:02 -0000 On 1 December 2012 16:30, Garrett Cooper wrote: > On Sat, Dec 1, 2012 at 3:37 PM, Konstantin Belousov wrote: >> On Sun, Dec 02, 2012 at 08:21:50AM +0900, Hiroki Sato wrote: >>> Garrett Cooper wrote >>> in : >>> >>> ya> On Sat, Dec 1, 2012 at 2:10 PM, Garrett Cooper wrote: >>> ya> > Why change the tool when we can change the rc script to do the >>> ya> > right thing? I have a patch I'm working on to resolve this (you hit an >>> ya> > itch I've been meaning to scratch for a little while). >>> ya> >>> ya> This should work. I also refactored the script to get it down to >>> ya> 80 columns. I've attached the debug output and the diff for the debug >>> ya> version of the script. >>> >>> You will find out the following test case does not work (this is one >>> of the test strings I used): >>> >>> kern.domainname="c$EDITOR.\"\ hoge\ \"\#hoge2\\$ \# h$$\#oge"# >>> >>> The reason why I changed sysctl(8) was that the rc.d/sysctl script >>> was too complex and slow even if it could support meta characters in >>> shell script syntax. I created several prototypes as script but >>> noticed that keeping consistency was quite difficult and >>> maintainability was poor due to tricky handling of variables. >>> >>> Although my patch in the previous email does not support meta >>> characters completely, I still think it is more reasonable to >>> implement this functionality on the sysctl(8) side. >> >> I fully agree with the proposal to add the -f switch to the sysctl(8). >> This is consistent with several other administrative tools. Putting >> the ability to parse and apply arbitrary sysctl.conf-like file into >> the rc script is weird. > > The point was to augment rc.d/sysctl to do the right thing in most > sane cases. What's shown above frankly doesn't make sense for a domain > name, and while I agree that it's a good negative test, it seems a bit > on the insane side for a real world example. > I was trying to provide an alternative using an existing > functioning system, instead of having to go and hack a widely used > utility to function in a way that isn't standard. Since when sysctl(8) is standard and the "-f file" option is not? http://man.NetBSD.org/man/sysctl+8 I also agree with the proposal that adding "-f file" directly to sysctl(8) sounds like a much better approach than going through the non-standard (and slow) rc.d route. > With that in mind, reviewing the original proposed code... > > ... > > +.It Fl f Ar filename I think this might be s/filename/file/, e.g. as in at(1), apmd(8), boot0cfg(8), bsdlabel(8), devd(8), restore(8), pfctl(8) etc. > +Specify a file which contains a pair of name and value in each line. > +.Nm > +reads and processes the specified file first and then processes the name > +and value pairs in the command line argument. > > gcooper> This doesn't discuss the file format in complete, gory > detail, and no examples were added to aid the reader in how things can > be done in the new world order. +1. Also, note that NetBSD's sysctl(8) supports line continuation with "\"; is this something that would at all be useful for sysctl? Then it should probably be implemented and documented from the start, to ensure that we don't have to needlessly break backwards compatibility with a future change. > > .It Fl h > Format output for human, rather than machine, readability. > .It Fl i > Index: sbin/sysctl/sysctl.c > =================================================================== > --- sbin/sysctl/sysctl.c (revision 243756) > +++ sbin/sysctl/sysctl.c (working copy) > @@ -56,13 +56,16 @@ > #include > #include > #include > +#include > #include > > +static const char *conffile; > static int aflag, bflag, dflag, eflag, hflag, iflag; > -static int Nflag, nflag, oflag, qflag, xflag, warncount; > +static int Nflag, nflag, oflag, qflag, xflag; > > static int oidfmt(int *, int, char *, u_int *); > -static void parse(char *); > +static int parsefile(const char *); > +static int parse(char *, int); > static int show_var(int *, int); > static int sysctl_all(int *oid, int len); > static int name2oid(char *, int *); > @@ -74,7 +77,7 @@ > { > > (void)fprintf(stderr, "%s\n%s\n", > - "usage: sysctl [-bdehiNnoqx] name[=value] ...", > + "usage: sysctl [-bdehiNnoqx] [-f filename] name[=value] ...", I think the "-f file" should be a separate usage paradigm here, and, most likely, it should not be possible to use both "-f file" and "name[=value]". > " sysctl [-bdehNnoqx] -a"); > exit(1); > } > @@ -83,12 +86,13 @@ > main(int argc, char **argv) > { > int ch; > + int warncount = 0; > > gcooper> style bug. > > setlocale(LC_NUMERIC, ""); > setbuf(stdout,0); > setbuf(stderr,0); > > - while ((ch = getopt(argc, argv, "AabdehiNnoqwxX")) != -1) { > + while ((ch = getopt(argc, argv, "Aabdef:hiNnoqwxX")) != -1) { > switch (ch) { > case 'A': > /* compatibility */ > @@ -106,6 +110,9 @@ > case 'e': > eflag = 1; > break; > + case 'f': > + conffile = strdup(optarg); > > gcooper> Not checking for != NULL. > > ... > > /* > @@ -160,8 +169,8 @@ > * Lookup and print out the MIB entry if it exists. > * Set a new value if requested. > */ > -static void > -parse(char *string) > +static int > +parse(char *string, int lineno) > > gcooper> Since this is being modified, could string be changed to > const char * for completeness? > > ... > > @@ -191,15 +213,20 @@ > > if (len < 0) { > if (iflag) > - return; > - if (qflag) > + return (1); > > gcooper> This should be return (0); > > + if (qflag) > exit(1); > else > - errx(1, "unknown oid '%s'", bufp); > + errx(1, "unknown oid '%s'%s", bufp, line); > } > > - if (oidfmt(mib, len, fmt, &kind)) > - err(1, "couldn't find format of oid '%s'", bufp); > + if (oidfmt(mib, len, fmt, &kind)) { > + warn("couldn't find format of oid '%s'%s", bufp, line); > + if (!iflag) > + exit(1); > + else > + return (1); > > gcooper> This should be arguably be `return (0);` too. > > ... > > +static int > +parsefile(const char *filename) > +{ > + FILE *file; > + char line[BUFSIZ], *p; > + int warncount = 0, lineno = 0; > > gcooper> Style bugs (declaring and initializing on the same line). Not according to style(9): http://www.freebsd.org/cgi/man.cgi?query=style&sektion=9&manpath=FreeBSD+9.0-RELEASE << Be careful to not obfuscate the code by initializing variables in the declarations. Use this feature only thoughtfully. DO NOT use function calls in initializers. >> I think the above initialisations are just fine and used thoughtfully. C. > > + > + file = fopen(filename, "r"); > + if (file == NULL) > + err(EX_NOINPUT, "%s", filename); > + while (fgets(line, sizeof(line), file) != NULL) { > + lineno++; > + p = line; > + /* Replace the first # with \0. */ > + while((p = strchr(p, '#')) != NULL) { > > gcooper> Style bug (needs space between `while` and `(`). > > + if (p == line || *(p-1) != '\\') { > > gcooper> Why are you allowing '\#' ? > > + *p = '\0'; > > ... > > static int > Index: etc/rc.d/sysctl > =================================================================== > --- etc/rc.d/sysctl (revision 243756) > +++ etc/rc.d/sysctl (working copy) > @@ -8,51 +8,27 @@ > . /etc/rc.subr > > name="sysctl" > +command=/sbin/sysctl > > gcooper> Please quote this for consistency with the bulk majority of > rc.d scripts.