Re: [Patch 3/8] NFS Mount Configuration File (Vers 2)

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

 




On 08/05/2009 03:29 PM, J. Bruce Fields wrote:
> On Wed, Aug 05, 2009 at 03:14:11PM -0400, Steve Dickson wrote:
>> After thinking about this.. I've convinced myself that the internal
>> parsing routines should make the Section names case-insensitive 
>> but the rest of the data (i.e the tag, value) should be returned as is
>> and let the callers deal with the case... 
>>
>> The reason being everything hangs off Section names. So making those
>> easier to find I think is a good thing and hopefully it will make
>> managing config files a bit less error prone.... 
> 
> That's probably not what I would do, but I could live with that, as long
> as we're preserving the case of paths and user/group names.
Cool...

> 
> By the way, it looks like the git code to handle their extended section
> names (the [key "string"] thing) is in git's
> config.c:get_extended_base_var(), if that's a useful example.
I did take a look that this... but thier parse appears to
be much different than what we use.... 

For better or worse (I'll make an official release) there
is what I've come up with...
commit fede9b293a8faf6c4214f6dabdb1d8664929901d
Author: Steve Dickson <steved@xxxxxxxxxx>
Date:   Wed Aug 5 16:02:33 2009 -0400

    Added an conditional argument to the Section names
    with the format being:
       [ Section <"argument"> ]
    This will help group similar functioning Section
    together. The argument is conditional but must be
    surrounded by the '"' characters.
    
    The new conf_get_section() interface can used
    to locate a Section by its Section name and/or
    argument.
    
    Signed-off-by: Steve Dickson <steved@xxxxxxxxxx>

diff --git a/support/include/conffile.h b/support/include/conffile.h
index 3309788..b263581 100644
--- a/support/include/conffile.h
+++ b/support/include/conffile.h
@@ -56,12 +56,12 @@ extern struct conf_list *conf_get_list(char *, char *);
 extern struct conf_list *conf_get_tag_list(char *);
 extern int      conf_get_num(char *, char *, int);
 extern char    *conf_get_str(char *, char *);
+extern char    *conf_get_section(char *, char *, char *);
 extern void     conf_init(void);
 extern int      conf_match_num(char *, char *, int);
 extern void     conf_reinit(void);
 extern int      conf_remove(int, char *, char *);
 extern int      conf_remove_section(int, char *);
-extern int      conf_set(int, char *, char *, char *, int, int);
 extern void     conf_report(void);
 
 #endif				/* _CONFFILE_H_ */
diff --git a/support/nfs/conffile.c b/support/nfs/conffile.c
index a8b8037..97dc88a 100644
--- a/support/nfs/conffile.c
+++ b/support/nfs/conffile.c
@@ -50,12 +50,15 @@
 #include "xlog.h"
 
 static void conf_load_defaults (int);
+static int conf_set(int , char *, char *, char *, 
+	char *, int , int );
 
 struct conf_trans {
 	TAILQ_ENTRY (conf_trans) link;
 	int trans;
 	enum conf_op { CONF_SET, CONF_REMOVE, CONF_REMOVE_SECTION } op;
 	char *section;
+	char *arg;
 	char *tag;
 	char *value;
 	int override;
@@ -93,6 +96,7 @@ static const u_int8_t asc2bin[] =
 struct conf_binding {
   LIST_ENTRY (conf_binding) link;
   char *section;
+  char *arg;
   char *tag;
   char *value;
   int is_default;
@@ -143,6 +147,7 @@ conf_remove_now(char *section, char *tag)
 			LIST_REMOVE(cb, link);
 			xlog(LOG_INFO,"[%s]:%s->%s removed", section, tag, cb->value);
 			free(cb->section);
+			free(cb->arg);
 			free(cb->tag);
 			free(cb->value);
 			free(cb);
@@ -166,6 +171,7 @@ conf_remove_section_now(char *section)
 			LIST_REMOVE(cb, link);
 			xlog(LOG_INFO, "[%s]:%s->%s removed", section, cb->tag, cb->value);
 			free(cb->section);
+			free(cb->arg);
 			free(cb->tag);
 			free(cb->value);
 			free(cb);
@@ -179,27 +185,28 @@ conf_remove_section_now(char *section)
  * into SECTION of our configuration database.
  */
 static int
-conf_set_now(char *section, char *tag, char *value, int override,
-	      int is_default)
+conf_set_now(char *section, char *arg, char *tag, 
+	char *value, int override, int is_default)
 {
 	struct conf_binding *node = 0;
 
 	if (override)
 		conf_remove_now(section, tag);
-	else if (conf_get_str(section, tag)) {
+	else if (conf_get_section(section, arg, tag)) {
 		if (!is_default) {
 			xlog(LOG_INFO, "conf_set: duplicate tag [%s]:%s, ignoring...\n", 
 				section, tag);
 		}
 		return 1;
 	}
-
 	node = calloc(1, sizeof *node);
 	if (!node) {
 		xlog_warn("conf_set: calloc (1, %lu) failed", (unsigned long)sizeof *node);
 		return 1;
 	}
 	node->section = strdup(section);
+	if (arg)
+		node->arg = strdup(arg);
 	node->tag = strdup(tag);
 	node->value = strdup(value);
 	node->is_default = is_default;
@@ -215,10 +222,11 @@ conf_set_now(char *section, char *tag, char *value, int override,
 static void
 conf_parse_line(int trans, char *line, size_t sz)
 {
-	char *val;
+	char *val, *ptr;
 	size_t i;
 	int j;
 	static char *section = 0;
+	static char *arg = 0;
 	static int ln = 0;
 
 	/* Lines starting with '#' or ';' are comments.  */
@@ -240,7 +248,6 @@ conf_parse_line(int trans, char *line, size_t sz)
 		/* Strip off any blanks after '[' */
 		while (isblank(*line)) 
 			line++;
-
 		for (i = 0; i < sz; i++) {
 			if (line[i] == ']') {
 				break;
@@ -260,7 +267,6 @@ conf_parse_line(int trans, char *line, size_t sz)
 			val++, j++;
 		if (*val)
 			i = j;
-
 		section = malloc(i);
 		if (!section) {
 			xlog_warn("conf_parse_line: %d: malloc (%lu) failed", ln,
@@ -268,6 +274,26 @@ conf_parse_line(int trans, char *line, size_t sz)
 			return;
 		}
 		strncpy(section, line, i);
+
+		if (arg) 
+			free(arg);
+		arg = 0;
+
+		ptr = strchr(val, '"');
+		if (ptr == NULL)
+			return;
+		line = ++ptr;
+		while (*ptr && *ptr != '"')
+			ptr++;
+		if (*ptr == '\0') {
+			xlog_warn("conf_parse_line: line %d:"
+ 				"non-matched '\"', ignoring until next section", ln);
+		}  else {
+			*ptr = '\0';
+			arg = strdup(line);
+			if (!arg) 
+				xlog_warn("conf_parse_line: %d: malloc arg failed", ln);
+		}
 		return;
 	}
 
@@ -286,7 +312,7 @@ conf_parse_line(int trans, char *line, size_t sz)
 			for (j = sz - (val - line) - 1; j > 0 && isspace(val[j]); j--)
 				val[j] = '\0';
 			/* XXX Perhaps should we not ignore errors?  */
-			conf_set(trans, section, line, val, 0, 0);
+			conf_set(trans, section, arg, line, val, 0, 0);
 			return;
 		}
 	}
@@ -460,6 +486,26 @@ conf_get_str(char *section, char *tag)
 	}
 	return 0;
 }
+/*
+ * Find a section that may or may not have an argument
+ */
+char *
+conf_get_section(char *section, char *arg, char *tag)
+{
+	struct conf_binding *cb;
+
+	cb = LIST_FIRST (&conf_bindings[conf_hash (section)]);
+	for (; cb; cb = LIST_NEXT (cb, link)) {
+		if (strcasecmp(section, cb->section) != 0)
+			continue;
+		if (arg && strcasecmp(arg, cb->arg) != 0)
+			continue;
+		if (strcasecmp(tag, cb->tag) != 0)
+			continue;
+		return cb->value;
+	}
+	return 0;
+}
 
 /*
  * Build a list of string values out of the comma separated value denoted by
@@ -652,9 +698,9 @@ conf_trans_node(int transaction, enum conf_op op)
 }
 
 /* Queue a set operation.  */
-int
-conf_set(int transaction, char *section, char *tag, 
-	char *value, int override, int is_default)
+static int
+conf_set(int transaction, char *section, char *arg,
+	char *tag, char *value, int override, int is_default)
 {
 	struct conf_trans *node;
 
@@ -669,6 +715,15 @@ conf_set(int transaction, char *section, char *tag,
 	/* Make Section names case-insensitive */
 	upper2lower(node->section);
 
+	if (arg) {
+		node->arg = strdup(arg);
+		if (!node->arg) {
+			xlog_warn("conf_set: strdup(\"%s\") failed", arg);
+			goto fail;
+		}
+	} else
+		node->arg = NULL;
+
 	node->tag = strdup(tag);
 	if (!node->tag) {
 		xlog_warn("conf_set: strdup(\"%s\") failed", tag);
@@ -756,8 +811,9 @@ conf_end(int transaction, int commit)
 			if (commit) {
 				switch (node->op) {
 				case CONF_SET:
-					conf_set_now(node->section, node->tag, node->value,
-					node->override, node->is_default);
+					conf_set_now(node->section, node->arg, 
+						node->tag, node->value, node->override, 
+						node->is_default);
 					break;
 				case CONF_REMOVE:
 					conf_remove_now(node->section, node->tag);
@@ -813,8 +869,9 @@ void
 conf_report (void)
 {
 	struct conf_binding *cb, *last = 0;
-	unsigned int i, len;
+	unsigned int i, len, diff_arg = 0;
 	char *current_section = (char *)0;
+	char *current_arg = (char *)0;
 	struct dumper *dumper, *dnode;
 
 	dumper = dnode = (struct dumper *)calloc(1, sizeof *dumper);
@@ -826,15 +883,29 @@ conf_report (void)
 	for (i = 0; i < sizeof conf_bindings / sizeof conf_bindings[0]; i++)
 		for (cb = LIST_FIRST(&conf_bindings[i]); cb; cb = LIST_NEXT(cb, link)) {
 			if (!cb->is_default) {
+				/* Make sure the Section arugment is the same */
+				if (current_arg && current_section && cb->arg) {
+					if (strcmp(cb->section, current_section) == 0 &&
+						strcmp(cb->arg, current_arg) != 0)
+					diff_arg = 1;
+				}
 				/* Dump this entry.  */
-				if (!current_section || strcmp(cb->section, current_section)) {
-					if (current_section) {
+				if (!current_section || strcmp(cb->section, current_section) 
+							|| diff_arg) {
+					if (current_section || diff_arg) {
 						len = strlen (current_section) + 3;
+						if (current_arg)
+							len += strlen(current_arg) + 3;
 						dnode->s = malloc(len);
 						if (!dnode->s)
 							goto mem_fail;
 
-						snprintf(dnode->s, len, "[%s]", current_section);
+						if (current_arg)
+							snprintf(dnode->s, len, "[%s \"%s\"]", 
+								current_section, current_arg);
+						else
+							snprintf(dnode->s, len, "[%s]", current_section);
+
 						dnode->next = 
 							(struct dumper *)calloc(1, sizeof (struct dumper));
 						dnode = dnode->next;
@@ -849,6 +920,8 @@ conf_report (void)
 						goto mem_fail;
 					}
 					current_section = cb->section;
+					current_arg = cb->arg;
+					diff_arg = 0;
 				}
 				dnode->s = cb->tag;
 				dnode->v = cb->value;
@@ -862,10 +935,15 @@ conf_report (void)
 
 	if (last) {
 		len = strlen(last->section) + 3;
+		if (last->arg)
+			len += strlen(last->arg) + 3;
 		dnode->s = malloc(len);
 		if (!dnode->s)
 			goto mem_fail;
-		snprintf(dnode->s, len, "[%s]", last->section);
+		if (last->arg)
+			snprintf(dnode->s, len, "[%s \"%s\"]", last->section, last->arg);
+		else
+			snprintf(dnode->s, len, "[%s]", last->section);
 	}
 	conf_report_dump(dumper);
 	return;


--
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