sysctl: Add support for loading key:value pairs from file

This commit is contained in:
sin 2014-06-13 15:20:21 +01:00
parent db0ea785f0
commit 191cc71cee
2 changed files with 81 additions and 44 deletions

View File

@ -2,8 +2,12 @@
.SH NAME .SH NAME
\fBsysctl\fR - Configure kernel parameters at runtime \fBsysctl\fR - Configure kernel parameters at runtime
.SH SYNOPSIS .SH SYNOPSIS
\fBsysctl\fR \fIvariable\fR[=\fIvalue\fR]... \fBsysctl\fR [\fB-p\fR \fIfile\fR] \fIvariable\fR[=\fIvalue\fR]...
.SH DESCRIPTION .SH DESCRIPTION
\fBsysctl\fR modifies kernel parameters at runtime. The parameters available \fBsysctl\fR modifies kernel parameters at runtime. The parameters available
are those listed under \fI/proc/sys/\fR. Procfs is required for sysctl support are those listed under \fI/proc/sys/\fR. Procfs is required for sysctl support
in Linux. You can use \fBsysctl\fR to both read and write sysctl data. in Linux. You can use \fBsysctl\fR to both read and write sysctl data.
.SH OPTIONS
.TP
\fB-p\fR
Load the sysctl key:value pairs from \fIfile\fR.

119
sysctl.c
View File

@ -108,68 +108,101 @@ setsysctl(char *variable, char *value)
return 0; return 0;
} }
static int
parsepair(char *pair)
{
char *p;
char *variable;
char *value;
for (p = pair; *p; p++) {
if (p[0] == '.' && p[1] == '.') {
weprintf("malformed input: %s\n", pair);
return -1;
}
}
p = strchr(pair, '=');
if (p) {
if (p[1] == '\0') {
weprintf("malformed input: %s\n", pair);
return -1;
}
*p = '\0';
value = &p[1];
} else {
value = NULL;
}
variable = pair;
if (value) {
if (setsysctl(variable, value) < 0) {
weprintf("failed to set sysctl for %s\n", variable);
return -1;
}
} else {
if (getsysctl(variable, &value) < 0) {
weprintf("failed to get sysctl for %s\n", variable);
return -1;
}
printf("%s = %s\n", variable, value);
free(value);
}
return 0;
}
static void static void
usage(void) usage(void)
{ {
eprintf("usage: %s variable[=value]...\n", argv0); eprintf("usage: %s [-p file] variable[=value]...\n", argv0);
} }
int int
main(int argc, char *argv[]) main(int argc, char *argv[])
{ {
char *variable; FILE *fp;
char *value; char buf[BUFSIZ], *p;
char *p; char *file = NULL;
int i; int i;
int r = EXIT_SUCCESS; int r = EXIT_SUCCESS;
argv0 = argv[0]; ARGBEGIN {
argv++; case 'p':
argc--; file = EARGF(usage());
break;
default:
usage();
} ARGEND;
if (argc < 1) if (!file && argc < 1)
usage(); usage();
for (i = 0; i < argc; i++) { if (!file) {
for (p = argv[i]; *p; p++) { for (i = 0; i < argc; i++)
if (p[0] == '.' && p[1] == '.') { if (parsepair(argv[i]) < 0)
r = EXIT_FAILURE; r = EXIT_FAILURE;
weprintf("malformed input: %s\n", argv[i]); } else {
break; fp = fopen(file, "r");
} if (!fp)
} eprintf("fopen %s:", file);
if (*p != '\0') while (fgets(buf, sizeof(buf), fp)) {
continue; p = buf;
p = strchr(argv[i], '='); for (p = buf; *p == ' ' || *p == '\t'; p++)
if (p) { ;
if (p[1] == '\0') { if (*p == '#' || *p == '\n')
r = EXIT_FAILURE;
weprintf("malformed input: %s\n", argv[i]);
continue; continue;
for (p = buf; *p; p++) {
if (*p == '\n') {
*p = '\0';
break;
}
} }
*p = '\0'; p = buf;
value = &p[1]; if (parsepair(p) < 0)
} else {
value = NULL;
}
variable = argv[i];
if (value) {
if (setsysctl(variable, value) < 0) {
r = EXIT_FAILURE; r = EXIT_FAILURE;
weprintf("failed to set sysctl for %s\n", variable);
continue;
}
}
else {
if (getsysctl(variable, &value) < 0) {
r = EXIT_FAILURE;
weprintf("failed to get sysctl for %s\n", variable);
continue;
}
printf("%s = %s\n", variable, value);
free(value);
} }
if (ferror(fp))
eprintf("%s: read error:", file);
fclose(fp);
} }
return r; return r;