[dovecot-cvs] dovecot/src/lib-settings settings.c,1.4,1.5 settings.h,1.2,1.3

cras at procontrol.fi cras at procontrol.fi
Thu Jul 10 07:04:09 EEST 2003


Update of /home/cvs/dovecot/src/lib-settings
In directory danu:/tmp/cvs-serv32098/src/lib-settings

Modified Files:
	settings.c settings.h 
Log Message:
New configuration file code. Some syntax changes, but tries to be somewhat
backwards compatible. SIGHUP now reverts back to old configuration if it
detected errors in new one.



Index: settings.c
===================================================================
RCS file: /home/cvs/dovecot/src/lib-settings/settings.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -d -r1.4 -r1.5
--- settings.c	10 Mar 2003 00:36:08 -0000	1.4
+++ settings.c	10 Jul 2003 03:04:07 -0000	1.5
@@ -59,19 +59,32 @@
 
 #define IS_WHITE(c) ((c) == ' ' || (c) == '\t')
 
-void settings_read(const char *path, settings_callback_t *callback,
-		   void *context)
+int settings_read(const char *path, const char *section,
+		  settings_callback_t *callback,
+		  settings_section_callback_t *sect_callback, void *context)
 {
 	struct istream *input;
-	const char *errormsg;
-	char *line, *key;
-	int fd, linenum;
+	const char *errormsg, *next_section;
+	char *line, *key, *name;
+	int fd, linenum, skip, sections, root_section;
 
 	fd = open(path, O_RDONLY);
-	if (fd < 0)
-		i_fatal("Can't open configuration file %s: %m", path);
+	if (fd < 0) {
+		i_error("Can't open configuration file %s: %m", path);
+		return FALSE;
+	}
 
-	linenum = 0;
+	t_push();
+
+	if (section == NULL) {
+		skip = 0;
+                next_section = NULL;
+	} else {
+		skip = 1;
+		next_section = t_strcut(section, '/');
+	}
+
+	linenum = 0; sections = 0; root_section = 0; errormsg = NULL;
 	input = i_stream_create_file(fd, default_pool, 2048, TRUE);
 	while ((line = i_stream_read_next_line(input)) != NULL) {
 		linenum++;
@@ -86,7 +99,9 @@
 		if (*line == '#' || *line == '\0')
 			continue;
 
-		/* all lines must be in format "key = value" */
+		/* a) "key = value"
+		   b) section_type section_name {
+		   c) } */
 		key = line;
 		while (!IS_WHITE(*line) && *line != '\0')
 			line++;
@@ -95,21 +110,82 @@
 			while (IS_WHITE(*line)) line++;
 		}
 
-		if (*line != '=') {
-			errormsg = "Missing value";
-		} else {
-			/* skip whitespace after '=' */
+		if (strcmp(key, "}") == 0 && *line == '\0') {
+			if (sections == 0)
+				errormsg = "Unexpected '}'";
+			else {
+				if (skip > 0)
+					skip--;
+				else {
+					sect_callback(NULL, NULL, context,
+						      &errormsg);
+					if (root_section == sections &&
+					    errormsg == NULL) {
+						/* we found the section,
+						   now quit */
+						break;
+					}
+				}
+				sections--;
+			}
+		} else if (*line == '=') {
 			*line++ = '\0';
 			while (IS_WHITE(*line)) line++;
 
-			errormsg = callback(key, line, context);
+			errormsg = skip ? NULL :
+				callback(key, line, context);
+		} else {
+			line[-1] = '\0';
+
+			name = line;
+			while (!IS_WHITE(*line) && *line != '\0')
+				line++;
+
+			if (*line != '\0') {
+				*line++ = '\0';
+				while (IS_WHITE(*line))
+					line++;
+			}
+
+			if (*line != '{' || strcspn(line+1, " \t") != 0)
+				errormsg = "Missing value";
+			else {
+				sections++;
+				if (next_section != NULL &&
+				    strcmp(next_section, name) == 0) {
+					section += strlen(next_section);
+					if (*section == '\0') {
+						skip = 0;
+						next_section = NULL;
+						root_section = sections;
+					} else {
+						i_assert(*section == '/');
+						section++;
+						next_section =
+							t_strcut(section, '/');
+					}
+				}
+
+				if (skip > 0)
+					skip++;
+				else {
+					skip = sect_callback == NULL ? 1 :
+						!sect_callback(key, name,
+							       context,
+							       &errormsg);
+				}
+			}
 		}
 
 		if (errormsg != NULL) {
-			i_fatal("Error in configuration file %s line %d: %s",
+			i_error("Error in configuration file %s line %d: %s",
 				path, linenum, errormsg);
+			break;
 		}
-	};
+	}
 
 	i_stream_unref(input);
+	t_pop();
+
+	return errormsg == NULL;
 }

Index: settings.h
===================================================================
RCS file: /home/cvs/dovecot/src/lib-settings/settings.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -d -r1.2 -r1.3
--- settings.h	31 Jan 2003 06:57:40 -0000	1.2
+++ settings.h	10 Jul 2003 03:04:07 -0000	1.3
@@ -13,14 +13,20 @@
 	size_t offset;
 };
 
+/* Return error message. When closing section, key = NULL, value = NULL. */
 typedef const char *settings_callback_t(const char *key, const char *value,
 					void *context);
 
+/* Return TRUE if we want to go inside the section */
+typedef int settings_section_callback_t(const char *type, const char *name,
+					void *context, const char **errormsg);
+
 const char *
 parse_setting_from_defs(pool_t pool, struct setting_def *defs, void *base,
 			const char *key, const char *value);
 
-void settings_read(const char *path, settings_callback_t *callback,
-		   void *context);
+int settings_read(const char *path, const char *section,
+		  settings_callback_t *callback,
+		  settings_section_callback_t *sect_callback, void *context);
 
 #endif



More information about the dovecot-cvs mailing list