From b73ff507f616c74ac94e7b1bef2ce51fa9bb2806 Mon Sep 17 00:00:00 2001 From: Ludwig Nussel Date: Wed, 18 May 2011 08:20:09 +0200 Subject: [PATCH procps 2/3] implement --pattern option Useful for e.g network hook scripts together with --system to only apply sysctls for a specific network interface. --- sysctl.8 | 14 ++++++++++++++ sysctl.c | 52 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 66 insertions(+), 0 deletions(-) diff --git a/sysctl.8 b/sysctl.8 index e26c4fb..9f6de65 100644 --- a/sysctl.8 +++ b/sysctl.8 @@ -64,6 +64,16 @@ Display all values currently available. .TP .B "-A" Display all values currently available in table form. +.TP +.B "--system" +Load settings from system configuration files (/lib/sysctl.d/*.conf, +/usr/lib/sysctl.d/*.conf, /usr/local/lib/sysctl.d/*.conf, +/etc/sysctl.d/*.conf, /etc/sysctl.conf) +.TP +.B "--pattern" PATTERN +Ignore settings that don't patch PATTERN. A star '*' is recognized +as wildcard. It matches strings until the next dot. '**' at the end +of the pattern matches until the end of the string. .SH EXAMPLES .TP /sbin/sysctl -a @@ -73,6 +83,10 @@ Display all values currently available in table form. /sbin/sysctl -w kernel.domainname="example.com" .TP /sbin/sysctl -p /etc/sysctl.conf +.TP +/sbin/sysctl --pattern 'net.ipv4.conf.*.forwarding' -a +.TP +/sbin/sysctl --pattern 'net.ipv6.**' --system .SH FILES .I /proc/sys .I /etc/sysctl.conf diff --git a/sysctl.c b/sysctl.c index 3445efe..b68170b 100644 --- a/sysctl.c +++ b/sysctl.c @@ -50,6 +50,7 @@ static bool PrintName; static bool PrintNewline; static bool IgnoreError; static bool Quiet; +static char* pattern; /* error messages */ static const char ERR_UNKNOWN_PARAMETER[] = "error: Unknown parameter \"%s\"\n"; @@ -63,6 +64,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* name); static void slashdot(char *restrict p, char old, char new){ p = strpbrk(p,"/."); @@ -145,6 +147,10 @@ static int ReadSetting(const char *restrict const name) { outname = strdup(name); slashdot(outname,'/','.'); /* change / to . */ + if (pattern && !pattern_match(outname)){ + goto out; + } + if (stat(tmpname, &ts) < 0) { if (!IgnoreError) { perror(tmpname); @@ -391,7 +397,39 @@ out: return rc; } +static int pattern_match(const char* name) { + const char* p = pattern; + if (!p || !name) + return 0; + + while (*p && *name) { + if (*p == '*') { + ++p; + // collapse stars. if at end match rest of string + while (*p == '*') { + ++p; + if (!*p) + return 1; + } + while (*name) { + if (*name == '.') { + break; + } + ++name; + } + continue; + } + if (*p != *name) + return 0; + ++p; + ++name; + continue; + } + if (!*p && !*name) + return 1; + return 0; +} /* * Preload the sysctl's from the conf file @@ -435,6 +473,10 @@ static int Preload(const char *restrict const filename) { StripLeadingAndTrailingSpaces(name); + if (pattern && !pattern_match(name)){ + continue; + } + value = strtok(NULL, "\n\r"); if (!value || !*value) { fprintf(stderr, WARN_BAD_LINE, filename, n); @@ -523,6 +565,16 @@ int main(int argc, char *argv[]) { IgnoreError = true; return PreloadSystem(); } + if (!strcmp("--pattern",*argv)) { + ++argv; + if (*argv && **argv) { + pattern = strdup(*argv); + continue; + } else { + fprintf(stderr, "error: --pattern requires an argument\n"); + return 1; + } + } fprintf(stderr, ERR_UNKNOWN_PARAMETER, *argv); return Usage(me); } -- 1.7.3.4