diff options
author | Tom Gundersen <teg@jklm.no> | 2011-05-26 20:57:57 +0200 |
---|---|---|
committer | Jon Masters <jcm@jonmasters.org> | 2011-05-30 23:01:31 -0400 |
commit | 799506a34a14df6cbea3e73cd32af26626fca5d3 (patch) | |
tree | 9c29c464af6177651bfee58bdd9a2d75d2960c99 | |
parent | 9454d710137be3799f343cc9d0f833f0802e2111 (diff) | |
download | module-init-tools-799506a34a14df6cbea3e73cd32af26626fca5d3.tar.gz |
modprobe: implement precedence of configuration directories
Configuration files are parsed in alphabetic order, regardles of what
directory they reside in. Furthermore, if several files by the same name
exist in different directories only the one in the directory with highest
precedence is loaded.
The order of precedence is /run, /etc, /usr/local/lib, /lib.
Cc: Jon Masters <jcm@jonmasters.org>
Cc: Kay Sievers <kay.sievers@vrfy.org>
Cc: Aaron Griffin <aaron@archlinux.org>
Cc: Thomas Bächler <thomas@archlinux.org>
Signed-off-by: Tom Gundersen <teg@jklm.no>
Signed-off-by: Jon Masters <jcm@jonmasters.org>
-rw-r--r-- | modprobe.c | 69 |
1 files changed, 44 insertions, 25 deletions
@@ -1050,6 +1050,13 @@ static int parse_config_scan(struct modprobe_conf *conf, va_list filelist; char *filename; DIR *dir; + struct file_entry { + struct list_head node; + char *name; + char *path; + }; + struct file_entry *fe, *fe_tmp; + LIST_HEAD(files_list); int ret = 0; va_start(filelist, removing); @@ -1057,17 +1064,12 @@ static int parse_config_scan(struct modprobe_conf *conf, while ((filename = va_arg(filelist, char*))) { dir = opendir(filename); if (dir) { - struct file_entry { - struct list_head node; - char name[]; - }; - LIST_HEAD(files_list); - struct file_entry *fe, *fe_tmp; struct dirent *i; - /* sort files from directory into list */ + /* sort files from directories into list, ignoring duplicates */ while ((i = readdir(dir)) != NULL) { size_t len; + int cmp = -1; if (i->d_name[0] == '.') continue; @@ -1081,30 +1083,29 @@ static int parse_config_scan(struct modprobe_conf *conf, warn("All config files need .conf: %s/%s, " "it will be ignored in a future release.\n", filename, i->d_name); - fe = malloc(sizeof(struct file_entry) + len + 1); + fe = malloc(sizeof(struct file_entry)); if (fe == NULL) continue; - strcpy(fe->name, i->d_name); + list_for_each_entry(fe_tmp, &files_list, node) - if (strcmp(fe_tmp->name, fe->name) >= 0) + if ((cmp = strcmp(fe_tmp->name, i->d_name)) >= 0) break; - list_add_tail(&fe->node, &fe_tmp->node); - } - closedir(dir); - /* parse list of files */ - list_for_each_entry_safe(fe, fe_tmp, &files_list, node) { - char *cfgfile; - - nofail_asprintf(&cfgfile, "%s/%s", filename, fe->name); - if (!parse_config_file(cfgfile, conf, - dump_only, removing)) - warn("Failed to open config file " - "%s: %s\n", fe->name, strerror(errno)); - free(cfgfile); - list_del(&fe->node); - free(fe); + if (cmp != 0) { + fe->name = malloc(len + 1); + fe->path = malloc(strlen(filename) + 1); + strcpy(fe->name, i->d_name); + strcpy(fe->path, filename); + + if (cmp < 0) + list_add_tail(&fe->node, &files_list); + else + list_add_tail(&fe->node, &fe_tmp->node); + } else + info("Ignoring config file %s/%s\n", filename, i->d_name); + } + closedir(dir); ret = 1; } else { @@ -1113,6 +1114,24 @@ static int parse_config_scan(struct modprobe_conf *conf, } } + /* parse list of files */ + list_for_each_entry_safe(fe, fe_tmp, &files_list, node) { + char *cfgfile; + + nofail_asprintf(&cfgfile, "%s/%s", fe->path, fe->name); + if (!parse_config_file(cfgfile, conf, + dump_only, removing)) + warn("Failed to open config file %s: %s\n", + cfgfile, strerror(errno)); + else + info("Parsing config file %s\n", cfgfile); + free(cfgfile); + list_del(&fe->node); + free(fe->name); + free(fe->path); + free(fe); + } + va_end(filelist); return ret; } |