diff --git a/sysctl.8 b/sysctl.8 index bc3a8db7..9e4b9b75 100644 --- a/sysctl.8 +++ b/sysctl.8 @@ -80,6 +80,13 @@ Load settings from all system configuration files. .br /etc/sysctl.conf .TP +\fB\-\-pattern\fR \fIpattern\fR +Only apply settings that match +.IR pattern . +The +.I pattern +uses extended regular expression syntax. +.TP \fB\-A\fR Alias of \fB\-a\fR .TP @@ -111,12 +118,21 @@ Display version information and exit. /sbin/sysctl \-w kernel.domainname="example.com" .br /sbin/sysctl \-p /etc/sysctl.conf +.br +/sbin/sysctl \-a \-\-pattern forward +.br +/sbin/sysctl \-a \-\-pattern forward$ +.br +/sbin/sysctl \-a \-\-pattern 'net.ipv4.conf.(eth|wlan)0.arp' +.br +/sbin/sysctl \-\-system \-\-pattern '^net.ipv6' .SH FILES .I /proc/sys .br .I /etc/sysctl.conf .SH SEE ALSO .BR sysctl.conf (5) +.BR regex (7) .SH AUTHOR .UR staikos\@0wned.org George Staikos diff --git a/sysctl.c b/sysctl.c index 37c256a9..311d4b9a 100644 --- a/sysctl.c +++ b/sysctl.c @@ -27,6 +27,7 @@ #include #include #include +#include #include #include #include @@ -53,6 +54,7 @@ static bool PrintName; static bool PrintNewline; static bool IgnoreError; static bool Quiet; +static char *pattern; /* error messages */ static const char ERR_MALFORMED_SETTING[] = "error: Malformed setting \"%s\"\n"; @@ -65,6 +67,7 @@ static const char ERR_OPENING_DIR[] = "error: unable to open directory \"%s\"\n" static const char ERR_PRELOAD_FILE[] = "error: unable to open preload file \"%s\"\n"; static const char WARN_BAD_LINE[] = "warning: %s(%d): invalid syntax, continuing...\n"; +static int pattern_match(const char *string, const char *pattern); static void slashdot(char *restrict p, char old, char new){ p = strpbrk(p,"/."); @@ -99,8 +102,10 @@ static void __attribute__ ((__noreturn__)) " -N, --names print variable names without values\n" " -n, --values print only values of a variables\n" " -p, --load[=] read values from file\n" - " --system read values from all system directories\n" " -f alias of -p\n" + " --system read values from all system directories\n" + " -r, --pattern \n" + " select setting that match expression\n" " -q, --quiet do not echo variable set\n" " -w, --write enable writing a value to variable\n" " -o does nothing\n" @@ -156,6 +161,15 @@ static int ReadSetting(const char *restrict const name) { return -1; } + /* used to display the output */ + outname = strdup(name); + slashdot(outname,'/','.'); /* change / to . */ + + if (pattern && !pattern_match(outname, pattern)){ + free(outname); + return 0; + } + /* used to open the file */ tmpname = malloc(strlen(name)+strlen(PROC_PATH)+2); strcpy(tmpname, PROC_PATH); @@ -412,7 +426,21 @@ out: return rc; } +static int pattern_match(const char *string, const char *pattern) +{ + int status; + regex_t re; + if (regcomp(&re, pattern, REG_EXTENDED | REG_NOSUB) != 0) { + return (0); /* Report error. */ + } + status = regexec(&re, string, (size_t) 0, NULL, 0); + regfree(&re); + if (status != 0) { + return (0); /* Report error. */ + } + return (1); +} /* * Preload the sysctl's from the conf file @@ -456,6 +484,10 @@ static int Preload(const char *restrict const filename) { StripLeadingAndTrailingSpaces(name); + if (pattern && !pattern_match(name, pattern)){ + continue; + } + value = strtok(NULL, "\n\r"); if (!value || !*value) { fprintf(stderr, WARN_BAD_LINE, filename, n); @@ -573,6 +605,7 @@ int main(int argc, char *argv[]) {"quiet", no_argument, NULL, 'q'}, {"write", no_argument, NULL, 'w'}, {"system", no_argument, NULL, SYSTEM_OPTION}, + {"pattern", required_argument, NULL, 'r'}, {"help", no_argument, NULL, 'h'}, {"version", no_argument, NULL, 'V'}, {NULL, 0, NULL, 0} @@ -588,7 +621,7 @@ int main(int argc, char *argv[]) } while ((c = - getopt_long(argc, argv, "bneNwfpqoxaAXVdh", longopts, + getopt_long(argc, argv, "bneNwfp::qoxaAXr:Vdh", longopts, NULL)) != -1) switch (c) { case 'b': @@ -633,6 +666,9 @@ int main(int argc, char *argv[]) case SYSTEM_OPTION: IgnoreError = true; return PreloadSystem(); + case 'r': + pattern = strdup(optarg); + break; case 'V': fprintf(stdout, "sysctl (%s)\n",procps_version); exit(0);