sysctl: implement --pattern option
Useful for e.g network hook scripts together with --system to only apply sysctls for a specific network interface. Signed-off-by: Ludwig Nussel <ludwig.nussel@suse.de> Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
100959274c
commit
7393599f73
16
sysctl.8
16
sysctl.8
@ -80,6 +80,13 @@ Load settings from all system configuration files.
|
|||||||
.br
|
.br
|
||||||
/etc/sysctl.conf
|
/etc/sysctl.conf
|
||||||
.TP
|
.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
|
\fB\-A\fR
|
||||||
Alias of \fB\-a\fR
|
Alias of \fB\-a\fR
|
||||||
.TP
|
.TP
|
||||||
@ -111,12 +118,21 @@ Display version information and exit.
|
|||||||
/sbin/sysctl \-w kernel.domainname="example.com"
|
/sbin/sysctl \-w kernel.domainname="example.com"
|
||||||
.br
|
.br
|
||||||
/sbin/sysctl \-p /etc/sysctl.conf
|
/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
|
.SH FILES
|
||||||
.I /proc/sys
|
.I /proc/sys
|
||||||
.br
|
.br
|
||||||
.I /etc/sysctl.conf
|
.I /etc/sysctl.conf
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.BR sysctl.conf (5)
|
.BR sysctl.conf (5)
|
||||||
|
.BR regex (7)
|
||||||
.SH AUTHOR
|
.SH AUTHOR
|
||||||
.UR staikos\@0wned.org
|
.UR staikos\@0wned.org
|
||||||
George Staikos
|
George Staikos
|
||||||
|
40
sysctl.c
40
sysctl.c
@ -27,6 +27,7 @@
|
|||||||
#include <getopt.h>
|
#include <getopt.h>
|
||||||
#include <libgen.h>
|
#include <libgen.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
#include <regex.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -53,6 +54,7 @@ static bool PrintName;
|
|||||||
static bool PrintNewline;
|
static bool PrintNewline;
|
||||||
static bool IgnoreError;
|
static bool IgnoreError;
|
||||||
static bool Quiet;
|
static bool Quiet;
|
||||||
|
static char *pattern;
|
||||||
|
|
||||||
/* error messages */
|
/* error messages */
|
||||||
static const char ERR_MALFORMED_SETTING[] = "error: Malformed setting \"%s\"\n";
|
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 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 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){
|
static void slashdot(char *restrict p, char old, char new){
|
||||||
p = strpbrk(p,"/.");
|
p = strpbrk(p,"/.");
|
||||||
@ -99,8 +102,10 @@ static void __attribute__ ((__noreturn__))
|
|||||||
" -N, --names print variable names without values\n"
|
" -N, --names print variable names without values\n"
|
||||||
" -n, --values print only values of a variables\n"
|
" -n, --values print only values of a variables\n"
|
||||||
" -p, --load[=<file>] read values from file\n"
|
" -p, --load[=<file>] read values from file\n"
|
||||||
" --system read values from all system directories\n"
|
|
||||||
" -f alias of -p\n"
|
" -f alias of -p\n"
|
||||||
|
" --system read values from all system directories\n"
|
||||||
|
" -r, --pattern <expression>\n"
|
||||||
|
" select setting that match expression\n"
|
||||||
" -q, --quiet do not echo variable set\n"
|
" -q, --quiet do not echo variable set\n"
|
||||||
" -w, --write enable writing a value to variable\n"
|
" -w, --write enable writing a value to variable\n"
|
||||||
" -o does nothing\n"
|
" -o does nothing\n"
|
||||||
@ -156,6 +161,15 @@ static int ReadSetting(const char *restrict const name) {
|
|||||||
return -1;
|
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 */
|
/* used to open the file */
|
||||||
tmpname = malloc(strlen(name)+strlen(PROC_PATH)+2);
|
tmpname = malloc(strlen(name)+strlen(PROC_PATH)+2);
|
||||||
strcpy(tmpname, PROC_PATH);
|
strcpy(tmpname, PROC_PATH);
|
||||||
@ -412,7 +426,21 @@ out:
|
|||||||
return rc;
|
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
|
* Preload the sysctl's from the conf file
|
||||||
@ -456,6 +484,10 @@ static int Preload(const char *restrict const filename) {
|
|||||||
|
|
||||||
StripLeadingAndTrailingSpaces(name);
|
StripLeadingAndTrailingSpaces(name);
|
||||||
|
|
||||||
|
if (pattern && !pattern_match(name, pattern)){
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
value = strtok(NULL, "\n\r");
|
value = strtok(NULL, "\n\r");
|
||||||
if (!value || !*value) {
|
if (!value || !*value) {
|
||||||
fprintf(stderr, WARN_BAD_LINE, filename, n);
|
fprintf(stderr, WARN_BAD_LINE, filename, n);
|
||||||
@ -573,6 +605,7 @@ int main(int argc, char *argv[])
|
|||||||
{"quiet", no_argument, NULL, 'q'},
|
{"quiet", no_argument, NULL, 'q'},
|
||||||
{"write", no_argument, NULL, 'w'},
|
{"write", no_argument, NULL, 'w'},
|
||||||
{"system", no_argument, NULL, SYSTEM_OPTION},
|
{"system", no_argument, NULL, SYSTEM_OPTION},
|
||||||
|
{"pattern", required_argument, NULL, 'r'},
|
||||||
{"help", no_argument, NULL, 'h'},
|
{"help", no_argument, NULL, 'h'},
|
||||||
{"version", no_argument, NULL, 'V'},
|
{"version", no_argument, NULL, 'V'},
|
||||||
{NULL, 0, NULL, 0}
|
{NULL, 0, NULL, 0}
|
||||||
@ -588,7 +621,7 @@ int main(int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
while ((c =
|
while ((c =
|
||||||
getopt_long(argc, argv, "bneNwfpqoxaAXVdh", longopts,
|
getopt_long(argc, argv, "bneNwfp::qoxaAXr:Vdh", longopts,
|
||||||
NULL)) != -1)
|
NULL)) != -1)
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case 'b':
|
case 'b':
|
||||||
@ -633,6 +666,9 @@ int main(int argc, char *argv[])
|
|||||||
case SYSTEM_OPTION:
|
case SYSTEM_OPTION:
|
||||||
IgnoreError = true;
|
IgnoreError = true;
|
||||||
return PreloadSystem();
|
return PreloadSystem();
|
||||||
|
case 'r':
|
||||||
|
pattern = strdup(optarg);
|
||||||
|
break;
|
||||||
case 'V':
|
case 'V':
|
||||||
fprintf(stdout, "sysctl (%s)\n",procps_version);
|
fprintf(stdout, "sysctl (%s)\n",procps_version);
|
||||||
exit(0);
|
exit(0);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user