procps/procps-3.2.8-implement-pattern-option.diff
Cristian Rodríguez a082bb1e4a Accepting request 71353 from home:lnussel:branches:Base:System
- load sysctls earlier (bnc#664550)
- move distro defaults to /lib/sysctl.d to avoid .rpmnew files
- enable IPv6 privacy by default (bnc#678066)

I've sent the --system and --pattern path upstream but they weren't accepted
yet. So this is tentative but we need the /lib/sysctl.d feature to be able to
provide distro defaults in a sane way.

OBS-URL: https://build.opensuse.org/request/show/71353
OBS-URL: https://build.opensuse.org/package/show/Base:System/procps?expand=0&rev=46
2011-05-28 20:50:18 +00:00

147 lines
4.2 KiB
Diff

From b73ff507f616c74ac94e7b1bef2ce51fa9bb2806 Mon Sep 17 00:00:00 2001
From: Ludwig Nussel <ludwig.nussel@suse.de>
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