aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2007-11-29 06:40:28 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2007-11-29 06:40:28 +0000
commit64309f8669f08f2c3c16a3b5bf82d9cae84ec388 (patch)
treef71b0a8578a8cdfa8b610b98f2e4a2a8ed4a37e5
parent745cd17926a9d75cdd6482d5ce58227b492d1ebe (diff)
downloadbusybox-w32-64309f8669f08f2c3c16a3b5bf82d9cae84ec388.tar.gz
busybox-w32-64309f8669f08f2c3c16a3b5bf82d9cae84ec388.tar.bz2
busybox-w32-64309f8669f08f2c3c16a3b5bf82d9cae84ec388.zip
sysctl: add -e: supress warnings about invalid key (Jeremy Kerr <jk@ozlabs.org>)
code shrink: text data bss dec hex filename 775565 929 9100 785594 bfcba busybox_old 775296 929 9100 785325 bfbad busybox_unstripped
-rw-r--r--include/usage.h11
-rw-r--r--procps/sysctl.c168
2 files changed, 77 insertions, 102 deletions
diff --git a/include/usage.h b/include/usage.h
index d910e2bf6..0ae819a1a 100644
--- a/include/usage.h
+++ b/include/usage.h
@@ -3505,16 +3505,17 @@ USE_FEATURE_RUN_PARTS_FANCY("\n -l Prints names of all matching files even when
3505 "Configure kernel parameters at runtime" \ 3505 "Configure kernel parameters at runtime" \
3506 "\n\nOptions:\n" \ 3506 "\n\nOptions:\n" \
3507 " -n Disable printing of key names\n" \ 3507 " -n Disable printing of key names\n" \
3508 " -e Don't warn about unknown keys\n" \
3508 " -w Change sysctl setting\n" \ 3509 " -w Change sysctl setting\n" \
3509 " -p FILE Load sysctl settings from FILE (default /etc/sysctl.conf)\n" \ 3510 " -p FILE Load sysctl settings from FILE (default /etc/sysctl.conf)\n" \
3510 " -a Display all values\n" \ 3511 " -a Display all values\n" \
3511 " -A Display all values in table form" 3512 " -A Display all values in table form"
3512#define sysctl_example_usage \ 3513#define sysctl_example_usage \
3513 "sysctl [-n] variable...\n" \ 3514 "sysctl [-n] [-e] variable...\n" \
3514 "sysctl [-n] -w variable=value...\n" \ 3515 "sysctl [-n] [-e] -w variable=value...\n" \
3515 "sysctl [-n] -a\n" \ 3516 "sysctl [-n] [-e] -a\n" \
3516 "sysctl [-n] -p file (default /etc/sysctl.conf)\n" \ 3517 "sysctl [-n] [-e] -p file (default /etc/sysctl.conf)\n" \
3517 "sysctl [-n] -A\n" 3518 "sysctl [-n] [-e] -A\n"
3518 3519
3519#define syslogd_trivial_usage \ 3520#define syslogd_trivial_usage \
3520 "[OPTION]..." 3521 "[OPTION]..."
diff --git a/procps/sysctl.c b/procps/sysctl.c
index a12948017..3a0af02d2 100644
--- a/procps/sysctl.c
+++ b/procps/sysctl.c
@@ -16,24 +16,16 @@
16 16
17#include "libbb.h" 17#include "libbb.h"
18 18
19/* 19static int sysctl_read_setting(const char *setting);
20 * Function Prototypes 20static int sysctl_write_setting(const char *setting);
21 */ 21static int sysctl_display_all(const char *path);
22static int sysctl_read_setting(const char *setting, int output); 22static int sysctl_preload_file_and_exit(const char *filename);
23static int sysctl_write_setting(const char *setting, int output);
24static int sysctl_preload_file(const char *filename, int output);
25static int sysctl_display_all(const char *path, int output, int show_table);
26 23
27/*
28 * Globals...
29 */
30static const char ETC_SYSCTL_CONF[] ALIGN1 = "/etc/sysctl.conf"; 24static const char ETC_SYSCTL_CONF[] ALIGN1 = "/etc/sysctl.conf";
31static const char PROC_SYS[] ALIGN1 = "/proc/sys/"; 25static const char PROC_SYS[] ALIGN1 = "/proc/sys/";
32enum { strlen_PROC_SYS = sizeof(PROC_SYS) - 1 }; 26enum { strlen_PROC_SYS = sizeof(PROC_SYS) - 1 };
33 27
34/* error messages */ 28/* error messages */
35static const char ERR_UNKNOWN_PARAMETER[] ALIGN1 =
36 "error: unknown parameter '%s'";
37static const char ERR_MALFORMED_SETTING[] ALIGN1 = 29static const char ERR_MALFORMED_SETTING[] ALIGN1 =
38 "error: malformed setting '%s'"; 30 "error: malformed setting '%s'";
39static const char ERR_NO_EQUALS[] ALIGN1 = 31static const char ERR_NO_EQUALS[] ALIGN1 =
@@ -46,8 +38,6 @@ static const char ERR_UNKNOWN_READING[] ALIGN1 =
46 "error reading key '%s'"; 38 "error reading key '%s'";
47static const char ERR_PERMISSION_DENIED[] ALIGN1 = 39static const char ERR_PERMISSION_DENIED[] ALIGN1 =
48 "error: permission denied on key '%s'"; 40 "error: permission denied on key '%s'";
49static const char ERR_PRELOAD_FILE[] ALIGN1 =
50 "error: cannot open preload file '%s'";
51static const char WARN_BAD_LINE[] ALIGN1 = 41static const char WARN_BAD_LINE[] ALIGN1 =
52 "warning: %s(%d): invalid syntax, continuing"; 42 "warning: %s(%d): invalid syntax, continuing";
53 43
@@ -57,66 +47,50 @@ static void dwrite_str(int fd, const char *buf)
57 write(fd, buf, strlen(buf)); 47 write(fd, buf, strlen(buf));
58} 48}
59 49
60/* 50enum {
61 * sysctl_main()... 51 FLAG_SHOW_KEYS = 1 << 0,
62 */ 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
63int sysctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE; 59int sysctl_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
64int sysctl_main(int argc, char **argv) 60int sysctl_main(int argc, char **argv)
65{ 61{
66 int retval = 0; 62 int retval;
67 int output = 1; 63 int opt;
68 int write_mode = 0; 64
69 int switches_allowed = 1; 65 opt = getopt32(argv, "+neAapw"); /* '+' - stop on first non-option */
70 66 argv += optind;
71 if (argc < 2) 67 opt ^= (FLAG_SHOW_KEYS | FLAG_SHOW_KEY_ERRORS);
72 bb_show_usage(); 68 option_mask32 ^= (FLAG_SHOW_KEYS | FLAG_SHOW_KEY_ERRORS);
73 69
74 argv++; 70 if (opt & (FLAG_TABLE_FORMAT | FLAG_SHOW_ALL))
75 71 return sysctl_display_all(PROC_SYS);
76 for (; *argv /*&& **argv*/; argv++) { 72 if (opt & FLAG_PRELOAD_FILE)
77 if (switches_allowed && **argv == '-') { /* we have a switch */ 73 return sysctl_preload_file_and_exit(*argv ? *argv : ETC_SYSCTL_CONF);
78 switch ((*argv)[1]) { 74
79 case 'n': 75 retval = 0;
80 output = 0; 76 while (*argv) {
81 break; 77 if (opt & FLAG_WRITE)
82 case 'w': 78 retval |= sysctl_write_setting(*argv);
83 write_mode = 1; 79 else
84 switches_allowed = 0; 80 retval |= sysctl_read_setting(*argv);
85 break; 81 argv++;
86 case 'p':
87 argv++;
88 return sysctl_preload_file(((*argv /*&& **argv*/) ? *argv : ETC_SYSCTL_CONF),
89 output);
90 case 'a':
91 case 'A':
92 return sysctl_display_all(PROC_SYS, output,
93 ((*argv)[1] == 'A'));
94 default:
95 bb_error_msg(ERR_UNKNOWN_PARAMETER, *argv);
96 /* fall through */
97 //case 'h':
98 //case '?':
99 bb_show_usage();
100 }
101 } else {
102 switches_allowed = 0;
103 if (write_mode)
104 retval |= sysctl_write_setting(*argv, output);
105 else
106 sysctl_read_setting(*argv, output);
107 }
108 } 82 }
83
109 return retval; 84 return retval;
110} /* end sysctl_main() */ 85} /* end sysctl_main() */
111 86
112/* 87/*
113 * sysctl_preload_file
114 * preload the sysctl's from a conf file 88 * preload the sysctl's from a conf file
115 * - we parse the file and then reform it (strip out whitespace) 89 * - we parse the file and then reform it (strip out whitespace)
116 */ 90 */
117#define PRELOAD_BUF 256 91#define PRELOAD_BUF 256
118 92
119static int sysctl_preload_file(const char *filename, int output) 93static int sysctl_preload_file_and_exit(const char *filename)
120{ 94{
121 int lineno; 95 int lineno;
122 char oneline[PRELOAD_BUF]; 96 char oneline[PRELOAD_BUF];
@@ -124,10 +98,7 @@ static int sysctl_preload_file(const char *filename, int output)
124 char *name, *value; 98 char *name, *value;
125 FILE *fp; 99 FILE *fp;
126 100
127 fp = fopen(filename, "r"); 101 fp = xfopen(filename, "r");
128 if (fp == NULL) {
129 bb_error_msg_and_die(ERR_PRELOAD_FILE, filename);
130 }
131 102
132 lineno = 0; 103 lineno = 0;
133 while (fgets(oneline, sizeof(oneline) - 1, fp)) { 104 while (fgets(oneline, sizeof(oneline) - 1, fp)) {
@@ -163,35 +134,36 @@ static int sysctl_preload_file(const char *filename, int output)
163 134
164 /* safe because sizeof(oneline) == sizeof(buffer) */ 135 /* safe because sizeof(oneline) == sizeof(buffer) */
165 sprintf(buffer, "%s=%s", name, value); 136 sprintf(buffer, "%s=%s", name, value);
166 sysctl_write_setting(buffer, output); 137 sysctl_write_setting(buffer);
167 } 138 }
168 fclose(fp); 139 if (ENABLE_FEATURE_CLEAN_UP)
140 fclose(fp);
169 return 0; 141 return 0;
170} /* end sysctl_preload_file() */ 142} /* end sysctl_preload_file_and_exit() */
171 143
172/* 144/*
173 * Write a single sysctl setting 145 * Write a single sysctl setting
174 */ 146 */
175static int sysctl_write_setting(const char *setting, int output) 147static int sysctl_write_setting(const char *setting)
176{ 148{
177 int retval = 0; 149 int retval;
178 const char *name; 150 const char *name;
179 const char *value; 151 const char *value;
180 const char *equals; 152 const char *equals;
181 char *tmpname, *outname, *cptr; 153 char *tmpname, *outname, *cptr;
182 int fd = -1; 154 int fd;
183 155
184 name = setting; 156 name = setting;
185 equals = strchr(setting, '='); 157 equals = strchr(setting, '=');
186 if (!equals) { 158 if (!equals) {
187 bb_error_msg(ERR_NO_EQUALS, setting); 159 bb_error_msg(ERR_NO_EQUALS, setting);
188 return -1; 160 return EXIT_FAILURE;
189 } 161 }
190 162
191 value = equals + 1; /* point to the value in name=value */ 163 value = equals + 1; /* point to the value in name=value */
192 if (name == equals || !*value) { 164 if (name == equals || !*value) {
193 bb_error_msg(ERR_MALFORMED_SETTING, setting); 165 bb_error_msg(ERR_MALFORMED_SETTING, setting);
194 return -2; 166 return EXIT_FAILURE;
195 } 167 }
196 168
197 tmpname = xasprintf("%s%.*s", PROC_SYS, (int)(equals - name), name); 169 tmpname = xasprintf("%s%.*s", PROC_SYS, (int)(equals - name), name);
@@ -207,7 +179,8 @@ static int sysctl_write_setting(const char *setting, int output)
207 if (fd < 0) { 179 if (fd < 0) {
208 switch (errno) { 180 switch (errno) {
209 case ENOENT: 181 case ENOENT:
210 bb_error_msg(ERR_INVALID_KEY, outname); 182 if (option_mask32 & FLAG_SHOW_KEY_ERRORS)
183 bb_error_msg(ERR_INVALID_KEY, outname);
211 break; 184 break;
212 case EACCES: 185 case EACCES:
213 bb_perror_msg(ERR_PERMISSION_DENIED, outname); 186 bb_perror_msg(ERR_PERMISSION_DENIED, outname);
@@ -216,16 +189,15 @@ static int sysctl_write_setting(const char *setting, int output)
216 bb_perror_msg(ERR_UNKNOWN_WRITING, outname); 189 bb_perror_msg(ERR_UNKNOWN_WRITING, outname);
217 break; 190 break;
218 } 191 }
219 retval = -1; 192 retval = EXIT_FAILURE;
220 } else { 193 } else {
221 dwrite_str(fd, value); 194 dwrite_str(fd, value);
222 close(fd); 195 close(fd);
223 if (output) { 196 if (option_mask32 & FLAG_SHOW_KEYS) {
224 dwrite_str(STDOUT_FILENO, outname); 197 printf("%s = ", outname);
225 dwrite_str(STDOUT_FILENO, " = ");
226 } 198 }
227 dwrite_str(STDOUT_FILENO, value); 199 puts(value);
228 dwrite_str(STDOUT_FILENO, "\n"); 200 retval = EXIT_SUCCESS;
229 } 201 }
230 202
231 free(tmpname); 203 free(tmpname);
@@ -236,18 +208,19 @@ static int sysctl_write_setting(const char *setting, int output)
236/* 208/*
237 * Read a sysctl setting 209 * Read a sysctl setting
238 */ 210 */
239static int sysctl_read_setting(const char *setting, int output) 211static int sysctl_read_setting(const char *name)
240{ 212{
241 int retval = 0; 213 int retval;
242 char *tmpname, *outname, *cptr; 214 char *tmpname, *outname, *cptr;
243 char inbuf[1025]; 215 char inbuf[1025];
244 const char *name;
245 FILE *fp; 216 FILE *fp;
246 217
247 if (!*setting) 218 if (!*name) {
248 bb_error_msg(ERR_INVALID_KEY, setting); 219 if (option_mask32 & FLAG_SHOW_KEY_ERRORS)
220 bb_error_msg(ERR_INVALID_KEY, name);
221 return -1;
222 }
249 223
250 name = setting;
251 tmpname = concat_path_file(PROC_SYS, name); 224 tmpname = concat_path_file(PROC_SYS, name);
252 outname = xstrdup(tmpname + strlen_PROC_SYS); 225 outname = xstrdup(tmpname + strlen_PROC_SYS);
253 226
@@ -260,7 +233,8 @@ static int sysctl_read_setting(const char *setting, int output)
260 if (fp == NULL) { 233 if (fp == NULL) {
261 switch (errno) { 234 switch (errno) {
262 case ENOENT: 235 case ENOENT:
263 bb_error_msg(ERR_INVALID_KEY, outname); 236 if (option_mask32 & FLAG_SHOW_KEY_ERRORS)
237 bb_error_msg(ERR_INVALID_KEY, outname);
264 break; 238 break;
265 case EACCES: 239 case EACCES:
266 bb_error_msg(ERR_PERMISSION_DENIED, outname); 240 bb_error_msg(ERR_PERMISSION_DENIED, outname);
@@ -269,16 +243,16 @@ static int sysctl_read_setting(const char *setting, int output)
269 bb_perror_msg(ERR_UNKNOWN_READING, outname); 243 bb_perror_msg(ERR_UNKNOWN_READING, outname);
270 break; 244 break;
271 } 245 }
272 retval = -1; 246 retval = EXIT_FAILURE;
273 } else { 247 } else {
274 while (fgets(inbuf, sizeof(inbuf) - 1, fp)) { 248 while (fgets(inbuf, sizeof(inbuf) - 1, fp)) {
275 if (output) { 249 if (option_mask32 & FLAG_SHOW_KEYS) {
276 dwrite_str(STDOUT_FILENO, outname); 250 printf("%s = ", outname);
277 dwrite_str(STDOUT_FILENO, " = ");
278 } 251 }
279 dwrite_str(STDOUT_FILENO, inbuf); 252 fputs(inbuf, stdout);
280 } 253 }
281 fclose(fp); 254 fclose(fp);
255 retval = EXIT_SUCCESS;
282 } 256 }
283 257
284 free(tmpname); 258 free(tmpname);
@@ -289,7 +263,7 @@ static int sysctl_read_setting(const char *setting, int output)
289/* 263/*
290 * Display all the sysctl settings 264 * Display all the sysctl settings
291 */ 265 */
292static int sysctl_display_all(const char *path, int output, int show_table) 266static int sysctl_display_all(const char *path)
293{ 267{
294 int retval = 0; 268 int retval = 0;
295 DIR *dp; 269 DIR *dp;
@@ -299,18 +273,18 @@ static int sysctl_display_all(const char *path, int output, int show_table)
299 273
300 dp = opendir(path); 274 dp = opendir(path);
301 if (!dp) { 275 if (!dp) {
302 return -1; 276 return EXIT_FAILURE;
303 } 277 }
304 while ((de = readdir(dp)) != NULL) { 278 while ((de = readdir(dp)) != NULL) {
305 tmpdir = concat_subpath_file(path, de->d_name); 279 tmpdir = concat_subpath_file(path, de->d_name);
306 if (tmpdir == NULL) 280 if (tmpdir == NULL)
307 continue; 281 continue; /* . or .. */
308 if (stat(tmpdir, &ts) != 0) { 282 if (stat(tmpdir, &ts) != 0) {
309 bb_perror_msg(tmpdir); 283 bb_perror_msg(tmpdir);
310 } else if (S_ISDIR(ts.st_mode)) { 284 } else if (S_ISDIR(ts.st_mode)) {
311 sysctl_display_all(tmpdir, output, show_table); 285 retval |= sysctl_display_all(tmpdir);
312 } else { 286 } else {
313 retval |= sysctl_read_setting(tmpdir + strlen_PROC_SYS, output); 287 retval |= sysctl_read_setting(tmpdir + strlen_PROC_SYS);
314 } 288 }
315 free(tmpdir); 289 free(tmpdir);
316 } /* end while */ 290 } /* end while */