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