aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--modutils/modprobe.c169
1 files changed, 106 insertions, 63 deletions
diff --git a/modutils/modprobe.c b/modutils/modprobe.c
index 1a4f5d4d4..0c59e8ab3 100644
--- a/modutils/modprobe.c
+++ b/modutils/modprobe.c
@@ -48,6 +48,10 @@ struct mod_list_t { /* two-way list of modules to process */
48 struct mod_list_t * m_next; 48 struct mod_list_t * m_next;
49}; 49};
50 50
51struct include_conf_t {
52 struct dep_t *first;
53 struct dep_t *current;
54};
51 55
52static struct dep_t *depend; 56static struct dep_t *depend;
53 57
@@ -242,21 +246,60 @@ static int is_conf_command(char *buffer, const char *command)
242 * This function reads aliases and default module options from a configuration file 246 * This function reads aliases and default module options from a configuration file
243 * (/etc/modprobe.conf syntax). It supports includes (only files, no directories). 247 * (/etc/modprobe.conf syntax). It supports includes (only files, no directories).
244 */ 248 */
245static void include_conf(struct dep_t **first, struct dep_t **current, char *buffer, int buflen, int fd) 249
250static int FAST_FUNC include_conf_file_act(const char *filename,
251 struct stat *statbuf UNUSED_PARAM,
252 void *userdata,
253 int depth UNUSED_PARAM);
254
255static int FAST_FUNC include_conf_dir_act(const char *filename UNUSED_PARAM,
256 struct stat *statbuf UNUSED_PARAM,
257 void *userdata UNUSED_PARAM,
258 int depth)
259{
260 if (depth > 1)
261 return SKIP;
262
263 return TRUE;
264}
265
266static int inline include_conf_recursive(struct include_conf_t *conf, const char *filename)
267{
268 return recursive_action(filename, ACTION_RECURSE,
269 include_conf_file_act,
270 include_conf_dir_act,
271 conf, 1);
272}
273
274static int FAST_FUNC include_conf_file_act(const char *filename,
275 struct stat *statbuf UNUSED_PARAM,
276 void *userdata,
277 int depth UNUSED_PARAM)
246{ 278{
279 struct include_conf_t *conf = (struct include_conf_t *) userdata;
280 struct dep_t **first = &conf->first;
281 struct dep_t **current = &conf->current;
247 int continuation_line = 0; 282 int continuation_line = 0;
283 int fd;
284
285 if (bb_basename(filename)[0] == '.')
286 return TRUE;
287
288 fd = open(filename, O_RDONLY);
289 if (fd < 0)
290 return FALSE;
248 291
249 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)! 292 // alias parsing is not 100% correct (no correct handling of continuation lines within an alias)!
250 293
251 while (reads(fd, buffer, buflen)) { 294 while (reads(fd, line_buffer, sizeof(line_buffer))) {
252 int l; 295 int l;
253 296
254 *strchrnul(buffer, '#') = '\0'; 297 *strchrnul(line_buffer, '#') = '\0';
255 298
256 l = strlen(buffer); 299 l = strlen(line_buffer);
257 300
258 while (l && isspace(buffer[l-1])) { 301 while (l && isspace(line_buffer[l-1])) {
259 buffer[l-1] = '\0'; 302 line_buffer[l-1] = '\0';
260 l--; 303 l--;
261 } 304 }
262 305
@@ -268,10 +311,10 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
268 if (continuation_line) 311 if (continuation_line)
269 continue; 312 continue;
270 313
271 if (is_conf_command(buffer, "alias")) { 314 if (is_conf_command(line_buffer, "alias")) {
272 char *alias, *mod; 315 char *alias, *mod;
273 316
274 if (parse_tag_value(buffer + 6, &alias, &mod)) { 317 if (parse_tag_value(line_buffer + 6, &alias, &mod)) {
275 /* handle alias as a module dependent on the aliased module */ 318 /* handle alias as a module dependent on the aliased module */
276 if (!*current) { 319 if (!*current) {
277 (*first) = (*current) = xzalloc(sizeof(struct dep_t)); 320 (*first) = (*current) = xzalloc(sizeof(struct dep_t));
@@ -292,11 +335,11 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
292 } 335 }
293 /*(*current)->m_next = NULL; - done by xzalloc */ 336 /*(*current)->m_next = NULL; - done by xzalloc */
294 } 337 }
295 } else if (is_conf_command(buffer, "options")) { 338 } else if (is_conf_command(line_buffer, "options")) {
296 char *mod, *opt; 339 char *mod, *opt;
297 340
298 /* split the line in the module/alias name, and options */ 341 /* split the line in the module/alias name, and options */
299 if (parse_tag_value(buffer + 8, &mod, &opt)) { 342 if (parse_tag_value(line_buffer + 8, &mod, &opt)) {
300 struct dep_t *dt; 343 struct dep_t *dt;
301 344
302 /* find the corresponding module */ 345 /* find the corresponding module */
@@ -315,22 +358,17 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
315 } 358 }
316 } 359 }
317 } 360 }
318 } else if (is_conf_command(buffer, "include")) { 361 } else if (is_conf_command(line_buffer, "include")) {
319 int fdi; 362 char *includefile;
320 char *filename; 363
321 364 includefile = skip_whitespace(line_buffer + 8);
322 filename = skip_whitespace(buffer + 8); 365 include_conf_recursive(conf, includefile);
323 fdi = open(filename, O_RDONLY);
324 if (fdi >= 0) {
325 include_conf(first, current, buffer, buflen, fdi);
326 close(fdi);
327 }
328 } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST && 366 } else if (ENABLE_FEATURE_MODPROBE_BLACKLIST &&
329 (is_conf_command(buffer, "blacklist"))) { 367 (is_conf_command(line_buffer, "blacklist"))) {
330 char *mod; 368 char *mod;
331 struct dep_t *dt; 369 struct dep_t *dt;
332 370
333 mod = skip_whitespace(buffer + 10); 371 mod = skip_whitespace(line_buffer + 10);
334 for (dt = *first; dt; dt = dt->m_next) { 372 for (dt = *first; dt; dt = dt->m_next) {
335 if (strcmp(dt->m_name, mod) == 0) 373 if (strcmp(dt->m_name, mod) == 0)
336 break; 374 break;
@@ -339,6 +377,23 @@ static void include_conf(struct dep_t **first, struct dep_t **current, char *buf
339 dt->m_isblacklisted = 1; 377 dt->m_isblacklisted = 1;
340 } 378 }
341 } /* while (reads(...)) */ 379 } /* while (reads(...)) */
380
381 close(fd);
382 return TRUE;
383}
384
385static int include_conf_file(struct include_conf_t *conf,
386 const char *filename)
387{
388 return include_conf_file_act(filename, NULL, conf, 0);
389}
390
391static int include_conf_file2(struct include_conf_t *conf,
392 const char *filename, const char *oldname)
393{
394 if (include_conf_file(conf, filename) == TRUE)
395 return TRUE;
396 return include_conf_file(conf, oldname);
342} 397}
343 398
344/* 399/*
@@ -350,8 +405,7 @@ static struct dep_t *build_dep(void)
350{ 405{
351 int fd; 406 int fd;
352 struct utsname un; 407 struct utsname un;
353 struct dep_t *first = NULL; 408 struct include_conf_t conf = { NULL, NULL };
354 struct dep_t *current = NULL;
355 char *filename; 409 char *filename;
356 int continuation_line = 0; 410 int continuation_line = 0;
357 int k_version; 411 int k_version;
@@ -421,14 +475,14 @@ static struct dep_t *build_dep(void)
421 mod = xstrndup(mods, dot - mods); 475 mod = xstrndup(mods, dot - mods);
422 476
423 /* enqueue new module */ 477 /* enqueue new module */
424 if (!current) { 478 if (!conf.current) {
425 first = current = xzalloc(sizeof(struct dep_t)); 479 conf.first = conf.current = xzalloc(sizeof(struct dep_t));
426 } else { 480 } else {
427 current->m_next = xzalloc(sizeof(struct dep_t)); 481 conf.current->m_next = xzalloc(sizeof(struct dep_t));
428 current = current->m_next; 482 conf.current = conf.current->m_next;
429 } 483 }
430 current->m_name = mod; 484 conf.current->m_name = mod;
431 current->m_path = xstrdup(modpath); 485 conf.current->m_path = xstrdup(modpath);
432 /*current->m_options = NULL; - xzalloc did it*/ 486 /*current->m_options = NULL; - xzalloc did it*/
433 /*current->m_isalias = 0;*/ 487 /*current->m_isalias = 0;*/
434 /*current->m_depcnt = 0;*/ 488 /*current->m_depcnt = 0;*/
@@ -482,8 +536,8 @@ static struct dep_t *build_dep(void)
482 dep = xstrndup(deps, next - deps - ext + 1); 536 dep = xstrndup(deps, next - deps - ext + 1);
483 537
484 /* Add the new dependable module name */ 538 /* Add the new dependable module name */
485 current->m_deparr = xrealloc_vector(current->m_deparr, 2, current->m_depcnt); 539 conf.current->m_deparr = xrealloc_vector(conf.current->m_deparr, 2, conf.current->m_depcnt);
486 current->m_deparr[current->m_depcnt++] = dep; 540 conf.current->m_deparr[conf.current->m_depcnt++] = dep;
487 541
488 p = next + 2; 542 p = next + 2;
489 } while (next < end); 543 } while (next < end);
@@ -500,52 +554,41 @@ static struct dep_t *build_dep(void)
500 * >=2.6: we only care about modprobe.conf 554 * >=2.6: we only care about modprobe.conf
501 * <=2.4: we care about modules.conf and conf.modules 555 * <=2.4: we care about modules.conf and conf.modules
502 */ 556 */
503 if (ENABLE_FEATURE_2_6_MODULES 557 {
504 && (fd = open("/etc/modprobe.conf", O_RDONLY)) < 0) 558 int r = FALSE;
505 if (ENABLE_FEATURE_2_4_MODULES 559
506 && (fd = open("/etc/modules.conf", O_RDONLY)) < 0) 560 if (ENABLE_FEATURE_2_6_MODULES) {
507 if (ENABLE_FEATURE_2_4_MODULES) 561 if (include_conf_file(&conf, "/etc/modprobe.conf"))
508 fd = open("/etc/conf.modules", O_RDONLY); 562 r = TRUE;
509 563 if (include_conf_recursive(&conf, "/etc/modprobe.d"))
510 if (fd >= 0) { 564 r = TRUE;
511 include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd); 565 }
512 close(fd); 566 if (ENABLE_FEATURE_2_4_MODULES && !r)
567 include_conf_file2(&conf,
568 "/etc/modules.conf",
569 "/etc/conf.modules");
513 } 570 }
514 571
515 /* Only 2.6 has a modules.alias file */ 572 /* Only 2.6 has a modules.alias file */
516 if (ENABLE_FEATURE_2_6_MODULES) { 573 if (ENABLE_FEATURE_2_6_MODULES) {
517 /* Parse kernel-declared module aliases */ 574 /* Parse kernel-declared module aliases */
518 filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.alias", un.release); 575 filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.alias", un.release);
519 fd = open(filename, O_RDONLY); 576 include_conf_file2(&conf,
520 if (fd < 0) { 577 filename,
521 /* Ok, that didn't work. Fall back to looking in /lib/modules */ 578 CONFIG_DEFAULT_MODULES_DIR"/modules.alias");
522 fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.alias", O_RDONLY);
523 }
524 if (ENABLE_FEATURE_CLEAN_UP) 579 if (ENABLE_FEATURE_CLEAN_UP)
525 free(filename); 580 free(filename);
526 581
527 if (fd >= 0) {
528 include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
529 close(fd);
530 }
531
532 /* Parse kernel-declared symbol aliases */ 582 /* Parse kernel-declared symbol aliases */
533 filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.symbols", un.release); 583 filename = xasprintf(CONFIG_DEFAULT_MODULES_DIR"/%s/modules.symbols", un.release);
534 fd = open(filename, O_RDONLY); 584 include_conf_file2(&conf,
535 if (fd < 0) { 585 filename,
536 /* Ok, that didn't work. Fall back to looking in /lib/modules */ 586 CONFIG_DEFAULT_MODULES_DIR"/modules.symbols");
537 fd = open(CONFIG_DEFAULT_MODULES_DIR"/modules.symbols", O_RDONLY);
538 }
539 if (ENABLE_FEATURE_CLEAN_UP) 587 if (ENABLE_FEATURE_CLEAN_UP)
540 free(filename); 588 free(filename);
541
542 if (fd >= 0) {
543 include_conf(&first, &current, line_buffer, sizeof(line_buffer), fd);
544 close(fd);
545 }
546 } 589 }
547 590
548 return first; 591 return conf.first;
549} 592}
550 593
551/* return 1 = loaded, 0 = not loaded, -1 = can't tell */ 594/* return 1 = loaded, 0 = not loaded, -1 = can't tell */