+/* Init the storage for the pre-parsed config lines */
+void
+readconf_save_config(const uschar *s)
+{
+ save_config_line(string_sprintf("# Exim Configuration (%s)",
+ running_in_test_harness ? US"X" : s));
+}
+
+static void
+save_config_position(const uschar *file, int line)
+{
+ save_config_line(string_sprintf("# %d \"%s\"", line, file));
+}
+
+/* Append a pre-parsed logical line to the config lines store,
+this operates on a global (static) list that holds all the pre-parsed
+config lines */
+static void
+save_config_line(const uschar* line)
+{
+static config_line_item *current;
+config_line_item *next;
+
+next = (config_line_item*) store_get(sizeof(config_line_item));
+next->line = string_copy(line);
+next->next = NULL;
+
+if (!config_lines) config_lines = next;
+else current->next = next;
+
+current = next;
+}
+
+/* List the parsed config lines, care about nice formatting and
+hide the <hide> values unless we're the admin user */
+void
+print_config(BOOL admin)
+{
+config_line_item *i;
+const int TS = 2;
+int indent = 0;
+
+for (i = config_lines; i; i = i->next)
+ {
+ const uschar *current;
+ uschar *p;
+
+ /* skip over to the first non-space */
+ for (current = i->line; *current && isspace(*current); ++current)
+ ;
+
+ if (*current == '\0')
+ continue;
+
+ /* TODO: Collapse or insert spaces around the first '=' */
+
+ /* # lines */
+ if (current[0] == '#')
+ {
+ puts(current);
+ continue;
+ }
+
+ /* begin lines are left aligned */
+ if (strncmp(current, "begin", 5) == 0 && isspace(current[5]))
+ {
+ puts(current);
+ indent = TS;
+ continue;
+ }
+
+ /* router/acl/transport block names */
+ if (current[strlen(current)-1] == ':' && !strchr(current, '='))
+ {
+ printf("%*s%s\n", TS, "", current);
+ indent = 2 * TS;
+ continue;
+ }
+
+ /* as admin we don't care, as we do for "public" lines */
+ if (admin || (!isupper(*current) && (strcmp(current, "hide") != 0)))
+ {
+ printf("%*s%s\n", indent, "", current);
+ continue;
+ }
+
+ /* hidden lines */
+ if (p = strchr(current, '='))
+ {
+ *p = '\0';
+ printf("%*s%s = %s\n", indent, "", current, hidden);
+ continue;
+ }
+ }
+}
+