ubase

suckless linux base utils
git clone git://git.2f30.org/ubase
Log | Files | Refs | README | LICENSE

commit 191cc71cee5846e680ef12b3e1707f13bf4e0832
parent db0ea785f0231be4315aa4c5af37e64841ce48f2
Author: sin <sin@2f30.org>
Date:   Fri, 13 Jun 2014 15:20:21 +0100

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

Diffstat:
Msysctl.8 | 6+++++-
Msysctl.c | 119++++++++++++++++++++++++++++++++++++++++++++++++++-----------------------------
2 files changed, 81 insertions(+), 44 deletions(-)

diff --git a/sysctl.8 b/sysctl.8 @@ -2,8 +2,12 @@ .SH NAME \fBsysctl\fR - Configure kernel parameters at runtime .SH SYNOPSIS -\fBsysctl\fR \fIvariable\fR[=\fIvalue\fR]... +\fBsysctl\fR [\fB-p\fR \fIfile\fR] \fIvariable\fR[=\fIvalue\fR]... .SH DESCRIPTION \fBsysctl\fR modifies kernel parameters at runtime. The parameters available 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. +.SH OPTIONS +.TP +\fB-p\fR +Load the sysctl key:value pairs from \fIfile\fR. diff --git a/sysctl.c b/sysctl.c @@ -108,68 +108,101 @@ setsysctl(char *variable, char *value) 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 usage(void) { - eprintf("usage: %s variable[=value]...\n", argv0); + eprintf("usage: %s [-p file] variable[=value]...\n", argv0); } int main(int argc, char *argv[]) { - char *variable; - char *value; - char *p; + FILE *fp; + char buf[BUFSIZ], *p; + char *file = NULL; int i; int r = EXIT_SUCCESS; - argv0 = argv[0]; - argv++; - argc--; - - if (argc < 1) + ARGBEGIN { + case 'p': + file = EARGF(usage()); + break; + default: usage(); + } ARGEND; - for (i = 0; i < argc; i++) { - for (p = argv[i]; *p; p++) { - if (p[0] == '.' && p[1] == '.') { - r = EXIT_FAILURE; - weprintf("malformed input: %s\n", argv[i]); - break; - } - } - if (*p != '\0') - continue; - p = strchr(argv[i], '='); - if (p) { - if (p[1] == '\0') { - r = EXIT_FAILURE; - weprintf("malformed input: %s\n", argv[i]); - continue; - } - *p = '\0'; - value = &p[1]; - } else { - value = NULL; - } - variable = argv[i]; + if (!file && argc < 1) + usage(); - if (value) { - if (setsysctl(variable, value) < 0) { + if (!file) { + for (i = 0; i < argc; i++) + if (parsepair(argv[i]) < 0) r = EXIT_FAILURE; - weprintf("failed to set sysctl for %s\n", variable); + } else { + fp = fopen(file, "r"); + if (!fp) + eprintf("fopen %s:", file); + while (fgets(buf, sizeof(buf), fp)) { + p = buf; + for (p = buf; *p == ' ' || *p == '\t'; p++) + ; + if (*p == '#' || *p == '\n') continue; + for (p = buf; *p; p++) { + if (*p == '\n') { + *p = '\0'; + break; + } } - } - else { - if (getsysctl(variable, &value) < 0) { + p = buf; + if (parsepair(p) < 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;