Mercurial > hg > toybox
comparison toys/other/sysctl.c @ 1285:1a8108bda4c1 draft
Promote sysctl from pending to other, default y.
author | Rob Landley <rob@landley.net> |
---|---|
date | Thu, 15 May 2014 05:34:08 -0500 |
parents | toys/pending/sysctl.c@5c1bd5b94541 |
children | 58d9f1b61f0a |
comparison
equal
deleted
inserted
replaced
1284:5c1bd5b94541 | 1285:1a8108bda4c1 |
---|---|
1 /* sysctl.c - A utility to read and manipulate the sysctl parameters. | |
2 * | |
3 * Copyright 2014 Bilal Qureshi <bilal.jmi@gmail.com> | |
4 * Copyright 2014 Kyungwan Han <asura321@gmail.com> | |
5 * | |
6 * No Standard | |
7 | |
8 USE_SYSCTL(NEWTOY(sysctl, "^neNqwpaA[!ap][!aq][!aw][+aA]", TOYFLAG_USR|TOYFLAG_BIN)) | |
9 | |
10 config SYSCTL | |
11 bool "sysctl" | |
12 default y | |
13 help | |
14 usage: sysctl [-aAeNnqw] [-p [FILE] | KEY[=VALUE]...] | |
15 | |
16 Read/write system control data (under /proc/sys). | |
17 | |
18 -a,A Show all values | |
19 -e Don't warn about unknown keys | |
20 -N Don't print key values | |
21 -n Don't print key names | |
22 -p [FILE] Read values from FILE (default /etc/sysctl.conf) | |
23 -q Don't show value after write | |
24 -w Only write values (object to reading) | |
25 */ | |
26 #define FOR_sysctl | |
27 #include "toys.h" | |
28 | |
29 // Null terminate at =, return value | |
30 static char *split_key(char *key) | |
31 { | |
32 char *value = strchr(key, '='); | |
33 | |
34 if (value) *(value++)=0; | |
35 | |
36 return value; | |
37 } | |
38 | |
39 static void replace_char(char *str, char old, char new) | |
40 { | |
41 for (; *str; str++) if (*str == old) *str = new; | |
42 } | |
43 | |
44 static void key_error(char *key) | |
45 { | |
46 if (errno == ENOENT) { | |
47 if (!(toys.optflags & FLAG_e)) error_msg("unknown key '%s'", key); | |
48 } else perror_msg("key '%s'", key); | |
49 } | |
50 | |
51 static int write_key(char *path, char *key, char *value) | |
52 { | |
53 int fd = open(path, O_WRONLY);; | |
54 | |
55 if (fd < 0) { | |
56 key_error(key); | |
57 | |
58 return 0; | |
59 } | |
60 xwrite(fd, value, strlen(value)); | |
61 xclose(fd); | |
62 | |
63 return 1; | |
64 } | |
65 | |
66 // Display all keys under a path | |
67 static int do_show_keys(struct dirtree *dt) | |
68 { | |
69 char *path, *data, *key; | |
70 | |
71 if (!dirtree_notdotdot(dt)) return 0; // Skip . and .. | |
72 if (S_ISDIR(dt->st.st_mode)) return DIRTREE_RECURSE; | |
73 | |
74 path = dirtree_path(dt, 0); | |
75 data = readfile(path, 0, 0); | |
76 replace_char(key = path + 10, '/', '.'); // skip "/proc/sys/" | |
77 if (!data) key_error(key); | |
78 else { | |
79 // Print the parts that aren't switched off by flags. | |
80 if (!(toys.optflags & FLAG_n)) xprintf("%s", key); | |
81 if (!(toys.optflags & (FLAG_N|FLAG_n))) xprintf(" = "); | |
82 for (key = data+strlen(data); key > data && isspace(*--key); *key = 0); | |
83 if (!(toys.optflags & FLAG_N)) xprintf("%s", data); | |
84 if ((toys.optflags & (FLAG_N|FLAG_n)) != (FLAG_N|FLAG_n)) xputc('\n'); | |
85 } | |
86 | |
87 free(data); | |
88 free(path); | |
89 | |
90 return 0; | |
91 } | |
92 | |
93 // Read/write entries under a key. Accepts "key=value" in key if !value | |
94 static void process_key(char *key, char *value) | |
95 { | |
96 char *path; | |
97 | |
98 if (!value) value = split_key(key); | |
99 if ((toys.optflags & FLAG_w) && !value) { | |
100 error_msg("'%s' not key=value"); | |
101 | |
102 return; | |
103 } | |
104 | |
105 path = xmprintf("/proc/sys/%s", key); | |
106 replace_char(path, '.', '/'); | |
107 // Note: failure to assign to a non-leaf node suppresses the display. | |
108 if (!(value && (!write_key(path, key, value) || (toys.optflags & FLAG_q)))) { | |
109 if (!access(path, R_OK)) dirtree_read(path, do_show_keys); | |
110 else key_error(key); | |
111 } | |
112 free(path); | |
113 } | |
114 | |
115 void sysctl_main() | |
116 { | |
117 char **args = 0; | |
118 | |
119 // Display all keys | |
120 if (toys.optflags & FLAG_a) dirtree_read("/proc/sys", do_show_keys); | |
121 | |
122 // read file | |
123 else if (toys.optflags & FLAG_p) { | |
124 FILE *fp = xfopen(*toys.optargs ? *toys.optargs : "/etc/sysctl.conf", "r"); | |
125 size_t len; | |
126 | |
127 for (;;) { | |
128 char *line = 0, *key, *val; | |
129 | |
130 if (-1 == (len = getline(&line, &len, fp))) break; | |
131 key = line; | |
132 while (isspace(*key)) key++; | |
133 if (*key == '#' || *key == ';' || !*key) continue; | |
134 while (len && isspace(line[len-1])) line[--len] = 0; | |
135 if (!(val = split_key(line))) { | |
136 error_msg("'%s' not key=value", line); | |
137 continue; | |
138 } | |
139 | |
140 // Trim whitespace around = | |
141 len = (val-line)-1; | |
142 while (len && isspace(line[len-1])) line[--len] = 0; | |
143 while (isspace(*val)) val++;; | |
144 | |
145 process_key(key, val); | |
146 free(line); | |
147 } | |
148 fclose(fp); | |
149 | |
150 // Loop through arguments, displaying or assigning as appropriate | |
151 } else for (args = toys.optargs; *args; args++) process_key(*args, 0); | |
152 } |