aboutsummaryrefslogtreecommitdiff
path: root/util-linux/mdev.c
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2008-07-26 18:35:10 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2008-07-26 18:35:10 +0000
commitdf96df9c7c78d0f19c8d1ac1aa3d8d80abbe16bb (patch)
tree7f8641e7a6fb7da86cac5b0a3dc0ca4456eecd95 /util-linux/mdev.c
parent48a9971bd41a6ad7fc2ee52dcc885b25012b5561 (diff)
downloadbusybox-w32-df96df9c7c78d0f19c8d1ac1aa3d8d80abbe16bb.tar.gz
busybox-w32-df96df9c7c78d0f19c8d1ac1aa3d8d80abbe16bb.tar.bz2
busybox-w32-df96df9c7c78d0f19c8d1ac1aa3d8d80abbe16bb.zip
mdev: do not complain if mdev.conf does not exist;
use #if to prevent gcc from generating dead code (sadly, it's more ugly this way)
Diffstat (limited to 'util-linux/mdev.c')
-rw-r--r--util-linux/mdev.c293
1 files changed, 155 insertions, 138 deletions
diff --git a/util-linux/mdev.c b/util-linux/mdev.c
index 461d3c8c1..f6440b190 100644
--- a/util-linux/mdev.c
+++ b/util-linux/mdev.c
@@ -25,6 +25,7 @@ struct globals {
25/* We use additional 64+ bytes in make_device() */ 25/* We use additional 64+ bytes in make_device() */
26#define SCRATCH_SIZE 80 26#define SCRATCH_SIZE 80
27 27
28#if ENABLE_FEATURE_MDEV_RENAME
28/* Builds an alias path. 29/* Builds an alias path.
29 * This function potentionally reallocates the alias parameter. 30 * This function potentionally reallocates the alias parameter.
30 */ 31 */
@@ -48,6 +49,7 @@ static char *build_alias(char *alias, const char *device_name)
48 49
49 return alias; 50 return alias;
50} 51}
52#endif
51 53
52/* mknod in /dev based on a path like "/sys/block/hda/hda1" */ 54/* mknod in /dev based on a path like "/sys/block/hda/hda1" */
53/* NB: "mdev -s" may call us many times, do not leak memory/fds! */ 55/* NB: "mdev -s" may call us many times, do not leak memory/fds! */
@@ -56,12 +58,20 @@ static void make_device(char *path, int delete)
56 const char *device_name; 58 const char *device_name;
57 int major, minor, type, len; 59 int major, minor, type, len;
58 int mode = 0660; 60 int mode = 0660;
61#if ENABLE_FEATURE_MDEV_CONF
59 uid_t uid = 0; 62 uid_t uid = 0;
60 gid_t gid = 0; 63 gid_t gid = 0;
61 char *dev_maj_min = path + strlen(path); 64 parser_t *parser;
65 char *tokens[5];
66#endif
67#if ENABLE_FEATURE_MDEV_EXEC
62 char *command = NULL; 68 char *command = NULL;
69#endif
70#if ENABLE_FEATURE_MDEV_RENAME
63 char *alias = NULL; 71 char *alias = NULL;
64 char aliaslink = aliaslink; /* for compiler */ 72 char aliaslink = aliaslink; /* for compiler */
73#endif
74 char *dev_maj_min = path + strlen(path);
65 75
66 /* Force the configuration file settings exactly. */ 76 /* Force the configuration file settings exactly. */
67 umask(0); 77 umask(0);
@@ -93,148 +103,149 @@ static void make_device(char *path, int delete)
93 if (strstr(path, "/block/")) 103 if (strstr(path, "/block/"))
94 type = S_IFBLK; 104 type = S_IFBLK;
95 105
96 if (ENABLE_FEATURE_MDEV_CONF) { 106#if ENABLE_FEATURE_MDEV_CONF
97 parser_t *parser = config_open("/etc/mdev.conf"); 107 parser = config_open2("/etc/mdev.conf", fopen_for_read);
98 char *tokens[5]; 108
99 109 /* If we have config file, look up user settings */
100 /* If we have config file, look up user settings */ 110 if (!parser)
101 if (!parser) 111 goto end_parse;
102 goto end_parse; 112
103 113 while (config_read(parser, tokens, 4, 3, "# \t", PARSE_LAST_IS_GREEDY)) {
104 while (config_read(parser, tokens, 4, 3, "# \t", PARSE_LAST_IS_GREEDY)) { 114 regmatch_t off[1 + 9*ENABLE_FEATURE_MDEV_RENAME_REGEXP];
105 regmatch_t off[1+9*ENABLE_FEATURE_MDEV_RENAME_REGEXP]; 115 char *val;
106 char *val; 116
107 117 /* Fields: regex uid:gid mode [alias] [cmd] */
108 /* Fields: regex uid:gid mode [alias] [cmd] */ 118
109 119 /* 1st field: regex to match this device */
110 /* 1st field: regex to match this device */ 120 {
111 { 121 regex_t match;
112 regex_t match; 122 int result;
113 int result; 123
114 124 /* Is this it? */
115 /* Is this it? */ 125 xregcomp(&match, tokens[0], REG_EXTENDED);
116 xregcomp(&match, tokens[0], REG_EXTENDED); 126 result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0);
117 result = regexec(&match, device_name, ARRAY_SIZE(off), off, 0); 127 regfree(&match);
118 regfree(&match); 128
119 129 //bb_error_msg("matches:");
120 //bb_error_msg("matches:"); 130 //for (int i = 0; i < ARRAY_SIZE(off); i++) {
121 //for (int i = 0; i < ARRAY_SIZE(off); i++) { 131 // if (off[i].rm_so < 0) continue;
122 // if (off[i].rm_so < 0) continue; 132 // bb_error_msg("match %d: '%.*s'\n", i,
123 // bb_error_msg("match %d: '%.*s'\n", i, 133 // (int)(off[i].rm_eo - off[i].rm_so),
124 // (int)(off[i].rm_eo - off[i].rm_so), 134 // device_name + off[i].rm_so);
125 // device_name + off[i].rm_so); 135 //}
126 //} 136
127 137 /* If not this device, skip rest of line */
128 /* If not this device, skip rest of line */ 138 /* (regexec returns whole pattern as "range" 0) */
129 /* (regexec returns whole pattern as "range" 0) */ 139 if (result || off[0].rm_so
130 if (result || off[0].rm_so 140 || ((int)off[0].rm_eo != (int)strlen(device_name))
131 || ((int)off[0].rm_eo != (int)strlen(device_name)) 141 ) {
132 ) { 142 continue;
133 continue;
134 }
135 } 143 }
144 }
136 145
137 /* This line matches: stop parsing the file 146 /* This line matches: stop parsing the file
138 * after parsing the rest of fields */ 147 * after parsing the rest of fields */
139 148
140 /* 2nd field: uid:gid - device ownership */ 149 /* 2nd field: uid:gid - device ownership */
141 { 150 {
142 struct passwd *pass; 151 struct passwd *pass;
143 struct group *grp; 152 struct group *grp;
144 char *str_uid = tokens[1]; 153 char *str_uid = tokens[1];
145 char *str_gid = strchrnul(str_uid, ':'); 154 char *str_gid = strchrnul(str_uid, ':');
146 155
147 if (*str_gid) 156 if (*str_gid)
148 *str_gid++ = '\0'; 157 *str_gid++ = '\0';
149 /* Parse UID */ 158 /* Parse UID */
150 pass = getpwnam(str_uid); 159 pass = getpwnam(str_uid);
151 if (pass) 160 if (pass)
152 uid = pass->pw_uid; 161 uid = pass->pw_uid;
153 else 162 else
154 uid = strtoul(str_uid, NULL, 10); 163 uid = strtoul(str_uid, NULL, 10);
155 /* Parse GID */ 164 /* Parse GID */
156 grp = getgrnam(str_gid); 165 grp = getgrnam(str_gid);
157 if (grp) 166 if (grp)
158 gid = grp->gr_gid; 167 gid = grp->gr_gid;
159 else 168 else
160 gid = strtoul(str_gid, NULL, 10); 169 gid = strtoul(str_gid, NULL, 10);
161 } 170 }
162 171
163 /* 3rd field: mode - device permissions */ 172 /* 3rd field: mode - device permissions */
164 mode = strtoul(tokens[2], NULL, 8); 173 mode = strtoul(tokens[2], NULL, 8);
165 174
166 val = tokens[3]; 175 val = tokens[3];
167 /* 4th field (opt): >alias */ 176 /* 4th field (opt): >alias */
168#if ENABLE_FEATURE_MDEV_RENAME 177#if ENABLE_FEATURE_MDEV_RENAME
169 if (!val) 178 if (!val)
170 break; 179 break;
171 aliaslink = *val; 180 aliaslink = *val;
172 if (aliaslink == '>' || aliaslink == '=') { 181 if (aliaslink == '>' || aliaslink == '=') {
173 char *s; 182 char *s;
174#if ENABLE_FEATURE_MDEV_RENAME_REGEXP 183#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
175 char *p; 184 char *p;
176 unsigned i, n; 185 unsigned i, n;
177#endif 186#endif
178 char *a = val; 187 char *a = val;
179 s = strchr(val, ' '); 188 s = strchr(val, ' ');
180 val = (s && s[1]) ? s+1 : NULL; 189 val = (s && s[1]) ? s+1 : NULL;
181#if ENABLE_FEATURE_MDEV_RENAME_REGEXP 190#if ENABLE_FEATURE_MDEV_RENAME_REGEXP
182 /* substitute %1..9 with off[1..9], if any */ 191 /* substitute %1..9 with off[1..9], if any */
183 n = 0; 192 n = 0;
184 s = a; 193 s = a;
185 while (*s) 194 while (*s)
186 if (*s++ == '%') 195 if (*s++ == '%')
187 n++; 196 n++;
188 197
189 p = alias = xzalloc(strlen(a) + n * strlen(device_name)); 198 p = alias = xzalloc(strlen(a) + n * strlen(device_name));
190 s = a + 1; 199 s = a + 1;
191 while (*s) { 200 while (*s) {
192 *p = *s; 201 *p = *s;
193 if ('%' == *s) { 202 if ('%' == *s) {
194 i = (s[1] - '0'); 203 i = (s[1] - '0');
195 if (i <= 9 && off[i].rm_so >= 0) { 204 if (i <= 9 && off[i].rm_so >= 0) {
196 n = off[i].rm_eo - off[i].rm_so; 205 n = off[i].rm_eo - off[i].rm_so;
197 strncpy(p, device_name + off[i].rm_so, n); 206 strncpy(p, device_name + off[i].rm_so, n);
198 p += n - 1; 207 p += n - 1;
199 s++; 208 s++;
200 }
201 } 209 }
202 p++;
203 s++;
204 } 210 }
211 p++;
212 s++;
213 }
205#else 214#else
206 alias = xstrdup(a + 1); 215 alias = xstrdup(a + 1);
207#endif 216#endif
208 } 217 }
209#endif /* ENABLE_FEATURE_MDEV_RENAME */ 218#endif /* ENABLE_FEATURE_MDEV_RENAME */
210 219
211 /* The rest (opt): command to run */ 220#if ENABLE_FEATURE_MDEV_EXEC
212 if (!val) 221 /* The rest (opt): command to run */
213 break; 222 if (!val)
214 if (ENABLE_FEATURE_MDEV_EXEC) { 223 break;
215 const char *s = "@$*"; 224 {
216 const char *s2 = strchr(s, *val); 225 const char *s = "@$*";
217 226 const char *s2 = strchr(s, *val);
218 if (!s2) 227
219 bb_error_msg_and_die("bad line %u", parser->lineno); 228 if (!s2)
220 229 bb_error_msg_and_die("bad line %u", parser->lineno);
221 /* Correlate the position in the "@$*" with the delete 230
222 * step so that we get the proper behavior: 231 /* Correlate the position in the "@$*" with the delete
223 * @cmd: run on create 232 * step so that we get the proper behavior:
224 * $cmd: run on delete 233 * @cmd: run on create
225 * *cmd: run on both 234 * $cmd: run on delete
226 */ 235 * *cmd: run on both
227 if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) { 236 */
228 command = xstrdup(val + 1); 237 if ((s2 - s + 1) /*1/2/3*/ & /*1/2*/ (1 + delete)) {
229 } 238 command = xstrdup(val + 1);
230 } 239 }
231 /* end of field parsing */ 240 }
232 break; /* we found matching line, stop */ 241#endif
233 } /* end of "while line is read from /etc/mdev.conf" */ 242 /* end of field parsing */
243 break; /* we found matching line, stop */
244 } /* end of "while line is read from /etc/mdev.conf" */
234 245
235 config_close(parser); 246 config_close(parser);
236 }
237 end_parse: 247 end_parse:
248#endif /* ENABLE_FEATURE_MDEV_CONF */
238 249
239 if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) { 250 if (!delete && sscanf(dev_maj_min, "%u:%u", &major, &minor) == 2) {
240 251
@@ -247,23 +258,26 @@ static void make_device(char *path, int delete)
247 if (major == root_major && minor == root_minor) 258 if (major == root_major && minor == root_minor)
248 symlink(device_name, "root"); 259 symlink(device_name, "root");
249 260
250 if (ENABLE_FEATURE_MDEV_CONF) { 261#if ENABLE_FEATURE_MDEV_CONF
251 chown(device_name, uid, gid); 262 chown(device_name, uid, gid);
252 263
253 if (ENABLE_FEATURE_MDEV_RENAME && alias) { 264#if ENABLE_FEATURE_MDEV_RENAME
254 alias = build_alias(alias, device_name); 265 if (alias) {
266 alias = build_alias(alias, device_name);
255 267
256 /* move the device, and optionally 268 /* move the device, and optionally
257 * make a symlink to moved device node */ 269 * make a symlink to moved device node */
258 if (rename(device_name, alias) == 0 && aliaslink == '>') 270 if (rename(device_name, alias) == 0 && aliaslink == '>')
259 symlink(alias, device_name); 271 symlink(alias, device_name);
260 272
261 free(alias); 273 free(alias);
262 }
263 } 274 }
275#endif
276#endif
264 } 277 }
265 278
266 if (ENABLE_FEATURE_MDEV_EXEC && command) { 279#if ENABLE_FEATURE_MDEV_EXEC
280 if (command) {
267 /* setenv will leak memory, use putenv/unsetenv/free */ 281 /* setenv will leak memory, use putenv/unsetenv/free */
268 char *s = xasprintf("MDEV=%s", device_name); 282 char *s = xasprintf("MDEV=%s", device_name);
269 putenv(s); 283 putenv(s);
@@ -274,16 +288,19 @@ static void make_device(char *path, int delete)
274 free(s); 288 free(s);
275 free(command); 289 free(command);
276 } 290 }
291#endif
277 292
278 if (delete) { 293 if (delete) {
279 unlink(device_name); 294 unlink(device_name);
280 /* At creation time, device might have been moved 295 /* At creation time, device might have been moved
281 * and a symlink might have been created. Undo that. */ 296 * and a symlink might have been created. Undo that. */
282 if (ENABLE_FEATURE_MDEV_RENAME && alias) { 297#if ENABLE_FEATURE_MDEV_RENAME
298 if (alias) {
283 alias = build_alias(alias, device_name); 299 alias = build_alias(alias, device_name);
284 unlink(alias); 300 unlink(alias);
285 free(alias); 301 free(alias);
286 } 302 }
303#endif
287 } 304 }
288} 305}
289 306