Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 19 Dec 2012 18:59:17 -0500
From:      Mark Johnston <markjdb@gmail.com>
To:        Brooks Davis <brooks@FreeBSD.org>
Cc:        Ian Lepore <freebsd@damnhippie.dyndns.org>, "src-committers@freebsd.org" <src-committers@FreeBSD.org>, d@delphij.net, Jilles Tjoelker <jilles@stack.nl>, Garrett Cooper <yanegomi@gmail.com>, "svn-src-all@freebsd.org" <svn-src-all@FreeBSD.org>, Alfred Perlstein <bright@mu.org>, Xin LI <delphij@FreeBSD.org>, "svn-src-head@freebsd.org" <svn-src-head@FreeBSD.org>, Andrey Zonov <zont@FreeBSD.org>
Subject:   Re: svn commit: r244198 - in head: etc/rc.d sbin/sysctl
Message-ID:  <20121219235917.GD8399@oddish>
In-Reply-To: <20121219232140.GA40927@lor.one-eyed-alien.net>
References:  <05CC5BAD-B968-4A7A-8097-A3344D970D63@mu.org> <1355932607.1198.206.camel@revolution.hippie.lan> <F158CD10-B65B-4BBA-BCAD-6A52BC5C8FDF@mu.org> <50D2128A.7030205@delphij.net> <20121219210418.GA83983@stack.nl> <CAGH67wRTdBCZLq1R8-yqD6EBZ%2B=F228-0o_8TvU3b0KZD6vUfg@mail.gmail.com> <CAGH67wT1L_9ia7-hdHST6q8iCdtmFifZcHixCQhBTiZEH8YAcw@mail.gmail.com> <50D23961.7090803@delphij.net> <20121219225854.GA8399@oddish> <20121219232140.GA40927@lor.one-eyed-alien.net>

next in thread | previous in thread | raw e-mail | index | archive | help
On Wed, Dec 19, 2012 at 05:21:40PM -0600, Brooks Davis wrote:
> On Wed, Dec 19, 2012 at 05:58:54PM -0500, Mark Johnston wrote:
> > On Wed, Dec 19, 2012 at 02:02:09PM -0800, Xin Li wrote:
> > > -----BEGIN PGP SIGNED MESSAGE-----
> > > Hash: SHA256
> > > 
> > > On 12/19/12 13:12, Garrett Cooper wrote:
> > > > On Wed, Dec 19, 2012 at 1:10 PM, Garrett Cooper
> > > > <yanegomi@gmail.com> wrote:
> > > > 
> > > > ...
> > > > 
> > > >> find -exec / echo | xargs ? Seems like there's a better way to
> > > >> solve this.
> > > > 
> > > > Of course we also might be overengineering the problem (my 
> > > > suggestion definitely was overengineered). Why not pass in the 
> > > > appropriate arguments via sysctl_args in /etc/rc.conf ? Thanks,
> > > 
> > > Irrelevant.  Consider this (extreme) situation: someone distributes
> > > several sets of sysctl values tuned for certain situations, like
> > > tcp.conf, supermicro.conf, ... and wants to put them together in a
> > > directory, it's useful to source from the directory without having to
> > > do a generation of command line on boot, so when something goes wrong,
> > > they just remove the pack rather than changing /etc/rc.conf.
> > 
> > At work I've changed the -f flag of syslogd and newsyslog to accept a
> > directory which gets non-recursively searched for input files. This way
> > we can have a directory, say /etc/syslog.d, into which package install
> > scripts can easily drop config files.
> > 
> > For something like sysctl this might be a bit much, but it's just a
> > thought. The example diff below is what I have in mind.
> 
> I don't have a strong opinion about the usefulness of this feature.  It
> seems useful particularly in conjunction with supporting multiple -f's.

I don't really either. Just thought I'd suggest it.

> 
> I do have a few comments on the implementation below.
> 

Thanks! I didn't know about openat(). Here's the regenerated diff.

diff --git a/sbin/sysctl/sysctl.c b/sbin/sysctl/sysctl.c
index 8fad089..9e453f6 100644
--- a/sbin/sysctl/sysctl.c
+++ b/sbin/sysctl/sysctl.c
@@ -42,6 +42,7 @@ static const char rcsid[] =
 #endif /* not lint */
 
 #include <sys/param.h>
+#include <sys/types.h>
 #include <sys/time.h>
 #include <sys/resource.h>
 #include <sys/stat.h>
@@ -49,8 +50,11 @@ static const char rcsid[] =
 #include <sys/vmmeter.h>
 
 #include <ctype.h>
+#include <dirent.h>
 #include <err.h>
 #include <errno.h>
+#include <fcntl.h>
+#include <fnmatch.h>
 #include <inttypes.h>
 #include <locale.h>
 #include <stdio.h>
@@ -64,8 +68,9 @@ static const char *conffile;
 static int	aflag, bflag, dflag, eflag, hflag, iflag;
 static int	Nflag, nflag, oflag, qflag, Tflag, Wflag, xflag;
 
+static int	handlefile(const char *);
 static int	oidfmt(int *, int, char *, u_int *);
-static int	parsefile(const char *);
+static int	parsefile(int);
 static int	parse(const char *, int);
 static int	show_var(int *, int);
 static int	sysctl_all(int *oid, int len);
@@ -165,7 +170,7 @@ main(int argc, char **argv)
 
 	warncount = 0;
 	if (conffile != NULL)
-		warncount += parsefile(conffile);
+		warncount += handlefile(conffile);
 
 	while (argc-- > 0)
 		warncount += parse(*argv++, 0);
@@ -402,15 +407,55 @@ parse(const char *string, int lineno)
 }
 
 static int
-parsefile(const char *filename)
+handlefile(const char *filename)
+{
+	DIR *dir;
+	struct dirent *de;
+	struct stat sb;
+	int fd, warncount = 0;
+
+	fd = open(filename, O_RDONLY);
+	if (fd < 0)
+		err(EX_NOINPUT, "%s", filename);
+	if (fstat(fd, &sb))
+		err(EX_NOINPUT, "%s", filename);
+
+	if (S_ISREG(sb.st_mode)) {
+		return (parsefile(fd));
+	} else if (!S_ISDIR(sb.st_mode))
+		errx(EX_USAGE, "invalid input file '%s'", filename);
+
+	dir = fdopendir(fd);
+	if (dir == NULL)
+		err(EX_NOINPUT, "%s", filename);
+	while ((de = readdir(dir)) != NULL) {
+		if (fnmatch("*.conf", de->d_name, 0) != 0)
+			continue;
+		fd = openat(fd, de->d_name, O_RDONLY);
+		if (fd < 0 || fstat(fd, &sb) != 0) {
+			warn("%s", de->d_name);
+			continue;
+		} else if (!S_ISREG(sb.st_mode))
+			continue;
+
+		warncount += parsefile(fd);
+		close(fd);
+	}
+	closedir(dir);
+
+	return (warncount);
+}
+
+static int
+parsefile(int fd)
 {
 	FILE *file;
 	char line[BUFSIZ], *p, *pq, *pdq;
 	int warncount = 0, lineno = 0;
 
-	file = fopen(filename, "r");
+	file = fdopen(fd, "r");
 	if (file == NULL)
-		err(EX_NOINPUT, "%s", filename);
+		err(EX_OSERR, "fdopen()");
 	while (fgets(line, sizeof(line), file) != NULL) {
 		lineno++;
 		p = line;
@@ -446,7 +491,6 @@ parsefile(const char *filename)
 		else
 			warncount += parse(p, lineno);
 	}
-	fclose(file);
 
 	return (warncount);
 }



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