1 /*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
4 This file is part of systemd.
6 Copyright 2010 Lennart Poettering
8 systemd is free software; you can redistribute it and/or modify it
9 under the terms of the GNU General Public License as published by
10 the Free Software Foundation; either version 2 of the License, or
11 (at your option) any later version.
13 systemd is distributed in the hope that it will be useful, but
14 WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with systemd; If not, see <http://www.gnu.org/licenses/>.
35 #define PROC_SYS_PREFIX "/proc/sys/"
37 static char **arg_prefixes = NULL;
39 static int apply_sysctl(const char *property, const char *value) {
43 log_debug("Setting '%s' to '%s'", property, value);
45 p = new(char, sizeof(PROC_SYS_PREFIX) + strlen(property));
47 log_error("Out of memory");
51 n = stpcpy(p, PROC_SYS_PREFIX);
58 if (!strv_isempty(arg_prefixes)) {
62 STRV_FOREACH(i, arg_prefixes)
63 if (path_startswith(p, *i)) {
69 log_debug("Skipping %s", p);
75 k = write_one_line_file(p, value);
78 log_full(k == -ENOENT ? LOG_DEBUG : LOG_WARNING,
79 "Failed to write '%s' to '%s': %s", value, p, strerror(-k));
81 if (k != -ENOENT && r == 0)
90 static int apply_file(const char *path, bool ignore_enoent) {
96 if (!(f = fopen(path, "re"))) {
97 if (ignore_enoent && errno == ENOENT)
100 log_error("Failed to open file '%s', ignoring: %m", path);
104 log_debug("apply: %s\n", path);
106 char l[LINE_MAX], *p, *value;
109 if (!fgets(l, sizeof(l), f)) {
113 log_error("Failed to read file '%s', ignoring: %m", path);
123 if (strchr(COMMENTS, *p))
126 if (!(value = strchr(p, '='))) {
127 log_error("Line is not an assignment in file '%s': %s", path, value);
137 if ((k = apply_sysctl(strstrip(p), strstrip(value))) < 0 && r == 0)
147 static int help(void) {
149 printf("%s [OPTIONS...] [CONFIGURATION FILE...]\n\n"
150 "Applies kernel sysctl settings.\n\n"
151 " -h --help Show this help\n"
152 " --prefix=PATH Only apply rules that apply to paths with the specified prefix\n",
153 program_invocation_short_name);
158 static int parse_argv(int argc, char *argv[]) {
164 static const struct option options[] = {
165 { "help", no_argument, NULL, 'h' },
166 { "prefix", required_argument, NULL, ARG_PREFIX },
175 while ((c = getopt_long(argc, argv, "h", options, NULL)) >= 0) {
187 for (p = optarg; *p; p++)
191 l = strv_append(arg_prefixes, optarg);
193 log_error("Out of memory");
197 strv_free(arg_prefixes);
207 log_error("Unknown option code %c", c);
215 int main(int argc, char *argv[]) {
218 r = parse_argv(argc, argv);
220 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
222 if (argc-optind > 1) {
223 log_error("This program expects one or no arguments.");
227 log_set_target(LOG_TARGET_AUTO);
228 log_parse_environment();
234 r = apply_file(argv[optind], false);
238 r = conf_files_list(&files, ".conf",
241 "/usr/local/lib/sysctl.d",
246 log_error("Failed to enumerate sysctl.d files: %s", strerror(-r));
250 STRV_FOREACH(f, files) {
253 k = apply_file(*f, true);
258 apply_file("/etc/sysctl.conf", true);
263 strv_free(arg_prefixes);
265 return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;