[PATCH 09/14] depmod: read config alternatives from a directory

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]



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


[Index of Archives]     [Linux USB Devel]     [Video for Linux]     [Linux Audio Users]     [Photo]     [Yosemite News]    [Yosemite Photos]     [Linux Kernel]     [Linux SCSI]     [XFree86]     [Big List of Linux Books]

  Powered by Linux