Parses files from /etc/depmod.alternatives which specify pairs of (module directory, config file). Signed-off-by: Keegan McAllister <keegan@xxxxxxxxxxx> --- depmod.c | 96 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 96 insertions(+), 0 deletions(-) diff --git a/depmod.c b/depmod.c index d9652b3..14da871 100644 --- a/depmod.c +++ b/depmod.c @@ -1368,6 +1368,99 @@ struct config_alternative char *config_file; }; +static void parse_alternative(const char *filename, + struct config_alternative **alts) +{ + char *line; + unsigned int linenum = 0; + FILE *cfile; + struct config_alternative *alt; + char *module_dir = NULL, *config_file = NULL; + + cfile = fopen(filename, "r"); + if (!cfile) { + if (errno != ENOENT) + fatal("could not open '%s', reason: %s\n", filename, + strerror(errno)); + else if (verbose) + warn("config file does not actually exist " + "(broken symlink?): %s\n", filename); + return; + } + + while ((line = getline_wrapped(cfile, &linenum)) != NULL) { + char *ptr = line; + char *cmd, *tmp; + + cmd = strsep_skipspace(&ptr, "\t "); + + if (cmd == NULL || cmd[0] == '#' || cmd[0] == '\0') { + free(line); + continue; + } + + if (streq(cmd, "moduledir")) { + tmp = strsep_skipspace(&ptr, "\t "); + if (!tmp || module_dir) + goto bad_file; + module_dir = NOFAIL(strdup(tmp)); + } else if (streq(cmd, "config")) { + tmp = strsep_skipspace(&ptr, "\t "); + if (!tmp || config_file) + goto bad_file; + config_file = NOFAIL(strdup(tmp)); + } else { + goto bad_file; + } + + free(line); + } + + fclose(cfile); + + if (!module_dir) + goto bad_file; + + alt = NOFAIL(malloc(sizeof(*alt))); + alt->module_dir = module_dir; + alt->config_file = config_file; + + alt->next = *alts; + *alts = alt; + return; + +bad_file: + warn("%s line %u: malformed alternatives file\n", filename, linenum); + /* These may be NULL, but free(NULL) is fine. */ + free(module_dir); + free(config_file); + free(line); +} + +static void parse_alternatives_dir(const char *dirname, + struct config_alternative **alts) +{ + LIST_HEAD(files_list); + if (read_config_dir(dirname, &files_list)) { + struct file_entry *fe, *fe_tmp; + + /* parse list of files */ + list_for_each_entry_safe(fe, fe_tmp, &files_list, node) { + char *cfgfile; + + nofail_asprintf(&cfgfile, "%s/%s", dirname, fe->name); + parse_alternative(cfgfile, alts); + free(cfgfile); + list_del(&fe->node); + free(fe); + } + } else { + if (verbose) + warn("Failed to open alternatives directory " + "%s: %s\n", dirname, strerror(errno)); + } +} + static void do_alternative(struct config_alternative *alt, const char *basedir, const char *version, int argc, char *argv[]) @@ -1572,6 +1665,9 @@ int main(int argc, char *argv[]) alts->module_dir = NOFAIL(strdup(MODULE_DIR)); alts->config_file = config ? NOFAIL(strdup(config)) : NULL; + /* Read more alternatives from a directory, if present. */ + parse_alternatives_dir("/etc/depmod.alternatives", &alts); + /* Process each alternative */ for (alt = alts; alt; alt = alt->next) do_alternative(alt, basedir, version, argc, argv); -- 1.7.2.3 -- To unsubscribe from this list: send the line "unsubscribe linux-modules" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html