diff --git a/sysctl.8 b/sysctl.8 index e1f6cb07..fc1c9dd3 100644 --- a/sysctl.8 +++ b/sysctl.8 @@ -12,6 +12,8 @@ sysctl \- configure kernel parameters at runtime .SH SYNOPSIS .B sysctl [\fIoptions\fR] [\fIvariable\fR[\fI=value\fR]] [...] +.BR +.B sysctl \-p [file or regexp] [...] .SH DESCRIPTION .B sysctl is used to modify kernel parameters at runtime. The parameters available @@ -58,6 +60,10 @@ Use this option when you want to change a sysctl setting. \fB\-p\fR[\fIFILE\fR], \fB\-\-load\fR[=\fIFILE\fR] Load in sysctl settings from the file specified or /etc/sysctl.conf if none given. Specifying \- as filename means reading data from standard input. +Using this option will mean arguments to +.B sysctl +are files, which are read in order they are specified. The file argument can +may be specified as reqular expression. .TP \fB\-a\fR, \fB\-\-all\fR Display all values currently available. diff --git a/sysctl.c b/sysctl.c index 587e26d9..92351706 100644 --- a/sysctl.c +++ b/sysctl.c @@ -29,6 +29,7 @@ #include #include #include +#include #include #include #include @@ -492,53 +493,61 @@ static int Preload(const char *restrict const filename) int n = 0; int rc = 0; char *name, *value; + glob_t globbuf; + int globerr; + int j; - fp = (filename[0] == '-' && !filename[1]) - ? stdin : fopen(filename, "r"); + globerr = glob(filename, GLOB_NOCHECK | GLOB_TILDE, NULL, &globbuf); + if (globerr != 0 && globerr != GLOB_NOMATCH) + xerr(EXIT_FAILURE, _("glob failed")); - if (!fp) { - xwarn(_("cannot open \"%s\""), filename); - return -1; - } - - while (fgets(oneline, sizeof oneline, fp)) { - n++; - t = StripLeadingAndTrailingSpaces(oneline); - - if (strlen(t) < 2) - continue; - - if (*t == '#' || *t == ';') - continue; - - name = strtok(t, "="); - if (!name || !*name) { - xwarnx(_("%s(%d): invalid syntax, continuing..."), - filename, n); - continue; + for (j = 0; j < globbuf.gl_pathc; j++) { + fp = (globbuf.gl_pathv[j][0] == '-' && !globbuf.gl_pathv[j][1]) + ? stdin : fopen(globbuf.gl_pathv[j], "r"); + if (!fp) { + xwarn(_("cannot open \"%s\""), globbuf.gl_pathv[j]); + return -1; } - StripLeadingAndTrailingSpaces(name); + while (fgets(oneline, sizeof oneline, fp)) { + n++; + t = StripLeadingAndTrailingSpaces(oneline); - if (pattern && !pattern_match(name, pattern)) - continue; + if (strlen(t) < 2) + continue; - value = strtok(NULL, "\n\r"); - if (!value || !*value) { - xwarnx(_("%s(%d): invalid syntax, continuing..."), - filename, n); - continue; + if (*t == '#' || *t == ';') + continue; + + name = strtok(t, "="); + if (!name || !*name) { + xwarnx(_("%s(%d): invalid syntax, continuing..."), + globbuf.gl_pathv[j], n); + continue; + } + + StripLeadingAndTrailingSpaces(name); + + if (pattern && !pattern_match(name, pattern)) + continue; + + value = strtok(NULL, "\n\r"); + if (!value || !*value) { + xwarnx(_("%s(%d): invalid syntax, continuing..."), + globbuf.gl_pathv[j], n); + continue; + } + + while ((*value == ' ' || *value == '\t') && *value != 0) + value++; + + /* should NameOnly affect this? */ + sprintf(buffer, "%s=%s", name, value); + rc |= WriteSetting(buffer); } - while ((*value == ' ' || *value == '\t') && *value != 0) - value++; - - /* should NameOnly affect this? */ - sprintf(buffer, "%s=%s", name, value); - rc |= WriteSetting(buffer); + fclose(fp); } - - fclose(fp); return rc; } @@ -641,7 +650,7 @@ int main(int argc, char *argv[]) bool preloadfileOpt = false; int ReturnCode = 0; int c; - const char *preloadfile = DEFAULT_PRELOAD; + const char *preloadfile = NULL; enum { DEPRECATED_OPTION = CHAR_MAX + 1, @@ -744,14 +753,28 @@ int main(int argc, char *argv[]) } } - if (DisplayAllOpt) - return DisplayAll(PROC_PATH); - if (preloadfileOpt) - return Preload(preloadfile); - argc -= optind; argv += optind; + if (DisplayAllOpt) + return DisplayAll(PROC_PATH); + + if (preloadfileOpt) { + int ret = EXIT_SUCCESS, i; + if (!preloadfile) { + if (!argc) { + ret != Preload(DEFAULT_PRELOAD); + } + } else { + /* This happens when -pfile option is + * used without space. */ + Preload(preloadfile); + } + for (i = 0; i < argc; i++) + Preload(argv[i]); + return ret; + } + if (argc < 1) xerrx(EXIT_FAILURE, _("no variables specified\n" "Try `%s --help' for more information."),