[PATCH] Reimplement include functionality in nfs.conf

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

 



Re-implement include file functionality as documented.

Existing implementation had various issues, one of which was it allowed
a subordinate file to inadvertently change which section the subsequent
tags back in the master config file got assigned to.

Signed-off-by: Justin Mitchell <jumitche@xxxxxxxxxx>



---
 support/nfs/conffile.c | 78 ++++++++++++++++++++++++++++++++++++--------------
 1 file changed, 56 insertions(+), 22 deletions(-)

diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
index 449ac1c..05e0a6f 100644
--- a/support/nfs/conffile.c
+++ b/support/nfs/conffile.c
@@ -56,9 +56,11 @@
 #pragma GCC visibility push(hidden)
 
 static void conf_load_defaults(void);
-static int conf_load(int trans, const char *path);
+static char * conf_load(const char *path);
 static int conf_set(int , char *, char *, char *, 
 	char *, int , int );
+static void conf_parse(int trans, char *buf, 
+	char **section, char **subsection);
 
 struct conf_trans {
 	TAILQ_ENTRY (conf_trans) link;
@@ -202,7 +204,6 @@ conf_set_now(char *section, char *arg, char *tag,
 	node->tag = strdup(tag);
 	node->value = strdup(value);
 	node->is_default = is_default;
-
 	LIST_INSERT_HEAD(&conf_bindings[conf_hash (section)], node, link);
 	return 0;
 }
@@ -365,22 +366,47 @@ conf_parse_line(int trans, char *line, int lineno, char **section, char **subsec
 		return;
 	}
 
-	/* XXX Perhaps should we not ignore errors?  */
-	conf_set(trans, *section, *subsection, line, val, 0, 0);
+	if (strcasecmp(line, "include")==0) {
+		/* load and parse subordinate config files */
+		char * subconf = conf_load(val);
+		if (subconf == NULL) {
+			xlog_warn("config file error: line %d: "
+			"error loading included config", lineno);
+			return;
+		}
+
+		/* copy the section data so the included file can inherit it
+		 * without accidentally changing it for us */
+		char * inc_section = NULL;
+		char * inc_subsection = NULL;
+		if (*section != NULL) {
+			inc_section = strdup(*section);
+			if (*subsection != NULL)
+				inc_subsection = strdup(*subsection);
+		}
+
+		conf_parse(trans, subconf, &inc_section, &inc_subsection);
+
+		if (inc_section) free(inc_section);
+		if (inc_subsection) free(inc_subsection);
+		free(subconf);
+	} else {
+		/* XXX Perhaps should we not ignore errors?  */
+		conf_set(trans, *section, *subsection, line, val, 0, 0);
+	}
 }
 
 /* Parse the mapped configuration file.  */
 static void
-conf_parse(int trans, char *buf, size_t sz)
+conf_parse(int trans, char *buf, char **section, char **subsection)
 {
 	char *cp = buf;
-	char *bufend = buf + sz;
+	char *bufend = NULL;
 	char *line;
-	char *section = NULL;
-	char *subsection = NULL;
 	int lineno = 0;
 
 	line = cp;
+	bufend = buf + strlen(buf);
 	while (cp < bufend) {
 		if (*cp == '\n') {
 			/* Check for escaped newlines.  */
@@ -389,7 +415,7 @@ conf_parse(int trans, char *buf, size_t sz)
 			else {
 				*cp = '\0';
 				lineno++;
-				conf_parse_line(trans, line, lineno, &section, &subsection);
+				conf_parse_line(trans, line, lineno, section, subsection);
 				line = cp + 1;
 			}
 		}
@@ -397,8 +423,6 @@ conf_parse(int trans, char *buf, size_t sz)
 	}
 	if (cp != line)
 		xlog_warn("conf_parse: last line non-terminated, ignored.");
-	if (section) free(section);
-	if (subsection) free(subsection);
 }
 
 static void
@@ -408,21 +432,21 @@ conf_load_defaults(void)
 	return;
 }
 
-static int
-conf_load(int trans, const char *path)
+static char *
+conf_load(const char *path)
 {
 	struct stat sb;
 	if ((stat (path, &sb) == 0) || (errno != ENOENT)) {
-		char *new_conf_addr;
+		char *new_conf_addr = NULL;
 		size_t sz = sb.st_size;
 		int fd = open (path, O_RDONLY, 0);
 
 		if (fd == -1) {
 			xlog_warn("conf_reinit: open (\"%s\", O_RDONLY) failed", path);
-			return -1;
+			return NULL;
 		}
 
-		new_conf_addr = malloc(sz);
+		new_conf_addr = malloc(sz+1);
 		if (!new_conf_addr) {
 			xlog_warn("conf_reinit: malloc (%lu) failed", (unsigned long)sz);
 			goto fail;
@@ -437,14 +461,13 @@ conf_load(int trans, const char *path)
 		close(fd);
 
 		/* XXX Should we not care about errors and rollback?  */
-		conf_parse(trans, new_conf_addr, sz);
-		free(new_conf_addr);
-		return 0;
+		new_conf_addr[sz] = '\0';
+		return new_conf_addr;
 	fail:
 		close(fd);
-		free(new_conf_addr);
+		if (new_conf_addr) free(new_conf_addr);
 	}
-	return -1;
+	return NULL;
 }
 
 /* remove and free up any existing config state */
@@ -473,14 +496,25 @@ static void
 conf_reinit(const char *conf_file)
 {
 	int trans;
+	char * conf_data;
 
 	trans = conf_begin();
-	if (conf_load(trans, conf_file) < 0)
+	conf_data = conf_load(conf_file);
+
+	if (conf_data == NULL)
 		return;
 
 	/* Load default configuration values.  */
 	conf_load_defaults();
 
+	/* Parse config contents into the transaction queue */
+	char *section = NULL;
+	char *subsection = NULL;
+	conf_parse(trans, conf_data, &section, &subsection);
+	if (section) free(section);
+	if (subsection) free(subsection);
+	free(conf_data);
+
 	/* Free potential existing configuration.  */
 	conf_free_bindings();
 
-- 
1.8.3.1



--
To unsubscribe from this list: send the line "unsubscribe linux-nfs" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html



[Index of Archives]     [Linux Filesystem Development]     [Linux USB Development]     [Linux Media Development]     [Video for Linux]     [Linux NILFS]     [Linux Audio Users]     [Yosemite Info]     [Linux SCSI]

  Powered by Linux