Bernhard Reutner-Fischer | e15d757 | 2006-06-02 20:56:16 +0000 | [diff] [blame] | 1 | /* vi: set sw=4 ts=4: */ |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 2 | /* |
| 3 | * Sysctl 1.01 - A utility to read and manipulate the sysctl parameters |
| 4 | * |
Rob Landley | 8b1f11d | 2006-04-17 21:49:34 +0000 | [diff] [blame] | 5 | * Copyright 1999 George Staikos |
Bernhard Reutner-Fischer | cb44816 | 2006-04-12 07:35:12 +0000 | [diff] [blame] | 6 | * |
| 7 | * Licensed under GPLv2 or later, see file LICENSE in this tarball for details. |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 8 | * |
| 9 | * Changelog: |
| 10 | * v1.01: |
| 11 | * - added -p <preload> to preload values from a file |
| 12 | * v1.01.1 |
| 13 | * - busybox applet aware by <solar@gentoo.org> |
Eric Andersen | c7bda1c | 2004-03-15 08:29:22 +0000 | [diff] [blame] | 14 | * |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 15 | */ |
| 16 | |
Denis Vlasenko | b6adbf1 | 2007-05-26 19:00:18 +0000 | [diff] [blame] | 17 | #include "libbb.h" |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 18 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 19 | static int sysctl_read_setting(const char *setting); |
| 20 | static int sysctl_write_setting(const char *setting); |
| 21 | static int sysctl_display_all(const char *path); |
| 22 | static int sysctl_preload_file_and_exit(const char *filename); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 23 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 24 | static const char ETC_SYSCTL_CONF[] ALIGN1 = "/etc/sysctl.conf"; |
| 25 | static const char PROC_SYS[] ALIGN1 = "/proc/sys/"; |
| 26 | enum { strlen_PROC_SYS = sizeof(PROC_SYS) - 1 }; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 27 | |
| 28 | /* error messages */ |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 29 | static const char ERR_MALFORMED_SETTING[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 30 | "error: malformed setting '%s'"; |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 31 | static const char ERR_NO_EQUALS[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 32 | "error: '%s' must be of the form name=value"; |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 33 | static const char ERR_INVALID_KEY[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 34 | "error: '%s' is an unknown key"; |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 35 | static const char ERR_UNKNOWN_WRITING[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 36 | "error setting key '%s'"; |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 37 | static const char ERR_UNKNOWN_READING[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 38 | "error reading key '%s'"; |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 39 | static const char ERR_PERMISSION_DENIED[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 40 | "error: permission denied on key '%s'"; |
Denis Vlasenko | 6ca409e | 2007-08-12 20:58:27 +0000 | [diff] [blame] | 41 | static const char WARN_BAD_LINE[] ALIGN1 = |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 42 | "warning: %s(%d): invalid syntax, continuing"; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 43 | |
| 44 | |
Glenn L McGrath | ab82154 | 2003-12-26 02:19:34 +0000 | [diff] [blame] | 45 | static void dwrite_str(int fd, const char *buf) |
| 46 | { |
| 47 | write(fd, buf, strlen(buf)); |
| 48 | } |
| 49 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 50 | enum { |
| 51 | FLAG_SHOW_KEYS = 1 << 0, |
| 52 | FLAG_SHOW_KEY_ERRORS = 1 << 1, |
| 53 | FLAG_TABLE_FORMAT = 1 << 2, /* not implemented */ |
| 54 | FLAG_SHOW_ALL = 1 << 3, |
| 55 | FLAG_PRELOAD_FILE = 1 << 4, |
| 56 | FLAG_WRITE = 1 << 5, |
| 57 | }; |
| 58 | |
Denis Vlasenko | 9b49a5e | 2007-10-11 10:05:36 +0000 | [diff] [blame] | 59 | int sysctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 60 | int sysctl_main(int argc, char **argv) |
| 61 | { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 62 | int retval; |
| 63 | int opt; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 64 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 65 | opt = getopt32(argv, "+neAapw"); /* '+' - stop on first non-option */ |
| 66 | argv += optind; |
| 67 | opt ^= (FLAG_SHOW_KEYS | FLAG_SHOW_KEY_ERRORS); |
| 68 | option_mask32 ^= (FLAG_SHOW_KEYS | FLAG_SHOW_KEY_ERRORS); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 69 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 70 | if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL)) |
| 71 | return sysctl_display_all(PROC_SYS); |
| 72 | if (opt & FLAG_PRELOAD_FILE) |
| 73 | return sysctl_preload_file_and_exit(*argv ? *argv : ETC_SYSCTL_CONF); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 74 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 75 | retval = 0; |
| 76 | while (*argv) { |
| 77 | if (opt & FLAG_WRITE) |
| 78 | retval |= sysctl_write_setting(*argv); |
| 79 | else |
| 80 | retval |= sysctl_read_setting(*argv); |
| 81 | argv++; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 82 | } |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 83 | |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 84 | return retval; |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 85 | } /* end sysctl_main() */ |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 86 | |
| 87 | /* |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 88 | * preload the sysctl's from a conf file |
| 89 | * - we parse the file and then reform it (strip out whitespace) |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 90 | */ |
Glenn L McGrath | ab82154 | 2003-12-26 02:19:34 +0000 | [diff] [blame] | 91 | #define PRELOAD_BUF 256 |
| 92 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 93 | static int sysctl_preload_file_and_exit(const char *filename) |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 94 | { |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 95 | int lineno; |
Glenn L McGrath | ab82154 | 2003-12-26 02:19:34 +0000 | [diff] [blame] | 96 | char oneline[PRELOAD_BUF]; |
| 97 | char buffer[PRELOAD_BUF]; |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 98 | char *name, *value; |
| 99 | FILE *fp; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 100 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 101 | fp = xfopen(filename, "r"); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 102 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 103 | lineno = 0; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 104 | while (fgets(oneline, sizeof(oneline) - 1, fp)) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 105 | lineno++; |
| 106 | trim(oneline); |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 107 | if (oneline[0] == '#' || oneline[0] == ';') |
| 108 | continue; |
| 109 | if (!oneline[0] || !oneline[1]) |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 110 | continue; |
| 111 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 112 | name = strtok(oneline, "="); |
| 113 | if (!name) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 114 | bb_error_msg(WARN_BAD_LINE, filename, lineno); |
| 115 | continue; |
| 116 | } |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 117 | trim(name); |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 118 | if (!*name) { |
| 119 | bb_error_msg(WARN_BAD_LINE, filename, lineno); |
| 120 | continue; |
| 121 | } |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 122 | |
| 123 | value = strtok(NULL, "\n\r"); |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 124 | if (!value) { |
| 125 | bb_error_msg(WARN_BAD_LINE, filename, lineno); |
| 126 | continue; |
| 127 | } |
| 128 | while (*value == ' ' || *value == '\t') |
| 129 | value++; |
| 130 | if (!*value) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 131 | bb_error_msg(WARN_BAD_LINE, filename, lineno); |
| 132 | continue; |
| 133 | } |
| 134 | |
Denis Vlasenko | 9cac521 | 2006-09-09 12:24:19 +0000 | [diff] [blame] | 135 | /* safe because sizeof(oneline) == sizeof(buffer) */ |
| 136 | sprintf(buffer, "%s=%s", name, value); |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 137 | sysctl_write_setting(buffer); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 138 | } |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 139 | if (ENABLE_FEATURE_CLEAN_UP) |
| 140 | fclose(fp); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 141 | return 0; |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 142 | } /* end sysctl_preload_file_and_exit() */ |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 143 | |
| 144 | /* |
| 145 | * Write a single sysctl setting |
| 146 | */ |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 147 | static int sysctl_write_setting(const char *setting) |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 148 | { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 149 | int retval; |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 150 | const char *name; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 151 | const char *value; |
| 152 | const char *equals; |
| 153 | char *tmpname, *outname, *cptr; |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 154 | int fd; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 155 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 156 | name = setting; |
| 157 | equals = strchr(setting, '='); |
| 158 | if (!equals) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 159 | bb_error_msg(ERR_NO_EQUALS, setting); |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 160 | return EXIT_FAILURE; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 161 | } |
| 162 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 163 | value = equals + 1; /* point to the value in name=value */ |
| 164 | if (name == equals || !*value) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 165 | bb_error_msg(ERR_MALFORMED_SETTING, setting); |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 166 | return EXIT_FAILURE; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 167 | } |
| 168 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 169 | tmpname = xasprintf("%s%.*s", PROC_SYS, (int)(equals - name), name); |
| 170 | outname = xstrdup(tmpname + strlen_PROC_SYS); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 171 | |
| 172 | while ((cptr = strchr(tmpname, '.')) != NULL) |
| 173 | *cptr = '/'; |
| 174 | |
| 175 | while ((cptr = strchr(outname, '/')) != NULL) |
| 176 | *cptr = '.'; |
| 177 | |
Denis Vlasenko | 50f7f44 | 2007-04-11 23:20:53 +0000 | [diff] [blame] | 178 | fd = open(tmpname, O_WRONLY | O_CREAT | O_TRUNC, 0666); |
| 179 | if (fd < 0) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 180 | switch (errno) { |
| 181 | case ENOENT: |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 182 | if (option_mask32 & FLAG_SHOW_KEY_ERRORS) |
| 183 | bb_error_msg(ERR_INVALID_KEY, outname); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 184 | break; |
| 185 | case EACCES: |
| 186 | bb_perror_msg(ERR_PERMISSION_DENIED, outname); |
| 187 | break; |
| 188 | default: |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 189 | bb_perror_msg(ERR_UNKNOWN_WRITING, outname); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 190 | break; |
| 191 | } |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 192 | retval = EXIT_FAILURE; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 193 | } else { |
Glenn L McGrath | ab82154 | 2003-12-26 02:19:34 +0000 | [diff] [blame] | 194 | dwrite_str(fd, value); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 195 | close(fd); |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 196 | if (option_mask32 & FLAG_SHOW_KEYS) { |
| 197 | printf("%s = ", outname); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 198 | } |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 199 | puts(value); |
| 200 | retval = EXIT_SUCCESS; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 201 | } |
| 202 | |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 203 | free(tmpname); |
| 204 | free(outname); |
| 205 | return retval; |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 206 | } /* end sysctl_write_setting() */ |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 207 | |
| 208 | /* |
Eric Andersen | c7bda1c | 2004-03-15 08:29:22 +0000 | [diff] [blame] | 209 | * Read a sysctl setting |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 210 | */ |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 211 | static int sysctl_read_setting(const char *name) |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 212 | { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 213 | int retval; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 214 | char *tmpname, *outname, *cptr; |
| 215 | char inbuf[1025]; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 216 | FILE *fp; |
| 217 | |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 218 | if (!*name) { |
| 219 | if (option_mask32 & FLAG_SHOW_KEY_ERRORS) |
| 220 | bb_error_msg(ERR_INVALID_KEY, name); |
| 221 | return -1; |
| 222 | } |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 223 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 224 | tmpname = concat_path_file(PROC_SYS, name); |
| 225 | outname = xstrdup(tmpname + strlen_PROC_SYS); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 226 | |
| 227 | while ((cptr = strchr(tmpname, '.')) != NULL) |
| 228 | *cptr = '/'; |
| 229 | while ((cptr = strchr(outname, '/')) != NULL) |
| 230 | *cptr = '.'; |
| 231 | |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 232 | fp = fopen(tmpname, "r"); |
| 233 | if (fp == NULL) { |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 234 | switch (errno) { |
| 235 | case ENOENT: |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 236 | if (option_mask32 & FLAG_SHOW_KEY_ERRORS) |
| 237 | bb_error_msg(ERR_INVALID_KEY, outname); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 238 | break; |
| 239 | case EACCES: |
| 240 | bb_error_msg(ERR_PERMISSION_DENIED, outname); |
| 241 | break; |
| 242 | default: |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 243 | bb_perror_msg(ERR_UNKNOWN_READING, outname); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 244 | break; |
| 245 | } |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 246 | retval = EXIT_FAILURE; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 247 | } else { |
| 248 | while (fgets(inbuf, sizeof(inbuf) - 1, fp)) { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 249 | if (option_mask32 & FLAG_SHOW_KEYS) { |
| 250 | printf("%s = ", outname); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 251 | } |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 252 | fputs(inbuf, stdout); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 253 | } |
| 254 | fclose(fp); |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 255 | retval = EXIT_SUCCESS; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 256 | } |
| 257 | |
| 258 | free(tmpname); |
| 259 | free(outname); |
| 260 | return retval; |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 261 | } /* end sysctl_read_setting() */ |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 262 | |
| 263 | /* |
Eric Andersen | c7bda1c | 2004-03-15 08:29:22 +0000 | [diff] [blame] | 264 | * Display all the sysctl settings |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 265 | */ |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 266 | static int sysctl_display_all(const char *path) |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 267 | { |
| 268 | int retval = 0; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 269 | DIR *dp; |
| 270 | struct dirent *de; |
| 271 | char *tmpdir; |
| 272 | struct stat ts; |
| 273 | |
Denis Vlasenko | 51742f4 | 2007-04-12 00:32:05 +0000 | [diff] [blame] | 274 | dp = opendir(path); |
| 275 | if (!dp) { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 276 | return EXIT_FAILURE; |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 277 | } |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 278 | while ((de = readdir(dp)) != NULL) { |
| 279 | tmpdir = concat_subpath_file(path, de->d_name); |
| 280 | if (tmpdir == NULL) |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 281 | continue; /* . or .. */ |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 282 | if (stat(tmpdir, &ts) != 0) { |
| 283 | bb_perror_msg(tmpdir); |
| 284 | } else if (S_ISDIR(ts.st_mode)) { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 285 | retval |= sysctl_display_all(tmpdir); |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 286 | } else { |
Denis Vlasenko | 64309f8 | 2007-11-29 06:40:28 +0000 | [diff] [blame] | 287 | retval |= sysctl_read_setting(tmpdir + strlen_PROC_SYS); |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 288 | } |
| 289 | free(tmpdir); |
| 290 | } /* end while */ |
| 291 | closedir(dp); |
Eric Andersen | b905028 | 2003-12-24 06:02:11 +0000 | [diff] [blame] | 292 | |
| 293 | return retval; |
Denis Vlasenko | 5a28a25 | 2007-10-29 19:22:13 +0000 | [diff] [blame] | 294 | } /* end sysctl_display_all() */ |