#include <xsasl.h>
+/* master library. */
+
+#include <master_proto.h>
+
/*
* What we're supposed to be doing.
*/
-#define SHOW_NONDEF (1<<0) /* show non-default settings */
-#define SHOW_DEFS (1<<1) /* show default setting */
-#define SHOW_NAME (1<<2) /* show parameter name */
+#define SHOW_NONDEF (1<<0) /* show main.cf non-default settings */
+#define SHOW_DEFS (1<<1) /* show main.cf default setting */
+#define SHOW_NAME (1<<2) /* show main.cf parameter name */
#define SHOW_MAPS (1<<3) /* show map types */
#define EDIT_MAIN (1<<4) /* edit main.cf */
#define SHOW_LOCKS (1<<5) /* show mailbox lock methods */
/*
* Lookup table for master.cf info.
*/
-ARGV **master_table;
+static ARGV **master_table;
/*
* Declarations generated by scanning actual C source files.
/*
* Manually extracted.
*/
-#include "auto_vars.h"
#include "install_vars.h"
/*
static const CONFIG_STR_TABLE str_table[] = {
#include "str_table.h"
-#include "auto_table.h" /* XXX */
#include "install_table.h"
0,
};
0,
};
+ /*
+ * Ad-hoc name-value string pair.
+ */
+typedef struct {
+ const char *name;
+ const char *value;
+} STRING_NV;
+
+ /*
+ * Support for parameters whose names are derived from master.cf message
+ * delivery transport names. These parameters have default values that are
+ * defined by other parameters.
+ */
+static STRING_NV *del_transp_table;
+static ssize_t del_transp_tablen;
+
+ /*
+ * Support for parameters whose names are specified in main.cf with
+ * smtpd_restriction_classes. These parameters have the empty string as
+ * their default value.
+ */
+static char **rest_class_table;
+static ssize_t rest_class_tablen;
+
/*
* Parameters with default values obtained via function calls.
*/
htable_free(table, myfree);
}
+/* set_config_dir - forcibly override var_config_dir */
+
+static void set_config_dir(void)
+{
+ char *config_dir;
+
+ if (var_config_dir)
+ myfree(var_config_dir);
+ var_config_dir = mystrdup((config_dir = safe_getenv(CONF_ENV_PATH)) != 0 ?
+ config_dir : DEF_CONFIG_DIR); /* XXX */
+ set_mail_conf_str(VAR_CONFIG_DIR, var_config_dir);
+}
+
/* read_parameters - read parameter info from file */
static void read_parameters(void)
{
- char *config_dir;
char *path;
/*
* better code decomposition.
*/
dict_unknown_allowed = 1;
- if (var_config_dir)
- myfree(var_config_dir);
- var_config_dir = mystrdup((config_dir = safe_getenv(CONF_ENV_PATH)) != 0 ?
- config_dir : DEF_CONFIG_DIR); /* XXX */
- set_mail_conf_str(VAR_CONFIG_DIR, var_config_dir);
+ set_config_dir();
path = concatenate(var_config_dir, "/", "main.cf", (char *) 0);
dict_load_file(CONFIG_DICT, path);
myfree(path);
*/
}
+ /*
+ * Basename of programs in $daemon_directory. XXX These belong in a header
+ * file, or they should be made configurable.
+ */
+#ifndef MAIL_PROGRAM_LOCAL
+#define MAIL_PROGRAM_LOCAL "local"
+#define MAIL_PROGRAM_ERROR "error"
+#define MAIL_PROGRAM_VIRTUAL "virtual"
+#define MAIL_PROGRAM_SMTP "smtp"
+#define MAIL_PROGRAM_LMTP "lmtp"
+#define MAIL_PROGRAM_PIPE "pipe"
+#define MAIL_PROGRAM_SPAWN "spawn"
+#endif
+
+/* add_restriction_class - add one smtpd_restriction_classes name */
+
+static void add_restriction_class(const char *name)
+{
+ rest_class_table = (char **)
+ myrealloc((char *) rest_class_table,
+ (rest_class_tablen + 1) * sizeof(*rest_class_table));
+ rest_class_table[rest_class_tablen] = mystrdup(name);
+ rest_class_tablen += 1;
+}
+
+/* add_dynamic_parameter - add one dynamic parameter name and default */
+
+static void add_dynamic_parameter(const char *service, const char *suffix,
+ const char *defparam)
+{
+ del_transp_table = (STRING_NV *)
+ myrealloc((char *) del_transp_table,
+ (del_transp_tablen + 1) * sizeof(*del_transp_table));
+ del_transp_table[del_transp_tablen].name =
+ concatenate(service, suffix, (char *) 0);
+ del_transp_table[del_transp_tablen].value = defparam;
+ del_transp_tablen += 1;
+}
+
+/* add_dynamic_parameters - add all dynamic parameters with defaults */
+
+static void add_dynamic_parameters(int mode)
+{
+ /* XXX Should this list be configurable? */
+ static const char *delivery_agents[] = {
+ MAIL_PROGRAM_LOCAL, MAIL_PROGRAM_ERROR,
+ MAIL_PROGRAM_VIRTUAL, MAIL_PROGRAM_SMTP,
+ MAIL_PROGRAM_LMTP, MAIL_PROGRAM_PIPE,
+ 0,
+ };
+ static const STRING_NV del_transp_params[] = {
+ /* suffix, default parameter name */
+ _XPORT_RCPT_LIMIT, VAR_XPORT_RCPT_LIMIT,
+ _STACK_RCPT_LIMIT, VAR_STACK_RCPT_LIMIT,
+ _XPORT_REFILL_LIMIT, VAR_XPORT_REFILL_LIMIT,
+ _XPORT_REFILL_DELAY, VAR_XPORT_REFILL_DELAY,
+ _DELIVERY_SLOT_COST, VAR_DELIVERY_SLOT_COST,
+ _DELIVERY_SLOT_LOAN, VAR_DELIVERY_SLOT_LOAN,
+ _DELIVERY_SLOT_DISCOUNT, VAR_DELIVERY_SLOT_DISCOUNT,
+ _MIN_DELIVERY_SLOTS, VAR_MIN_DELIVERY_SLOTS,
+ _INIT_DEST_CON, VAR_INIT_DEST_CON,
+ _DEST_CON_LIMIT, VAR_DEST_CON_LIMIT,
+ _DEST_RCPT_LIMIT, VAR_DEST_RCPT_LIMIT,
+ _CONC_POS_FDBACK, VAR_CONC_POS_FDBACK,
+ _CONC_NEG_FDBACK, VAR_CONC_NEG_FDBACK,
+ _CONC_COHORT_LIM, VAR_CONC_COHORT_LIM,
+ _DEST_RATE_DELAY, VAR_DEST_RATE_DELAY,
+ 0,
+ };
+ static const STRING_NV spawn_params[] = {
+ /* suffix, default parameter name */
+ _MAXTIME, VAR_COMMAND_MAXTIME,
+ 0,
+ };
+ const STRING_NV *sp;
+ const char *progname;
+ ARGV **argvp;
+ ARGV *argv;
+ const char **cpp;
+ const char *class_list;
+ char *cp;
+ char *saved_class_list;
+ char *class_name;
+
+ /*
+ * Initialize the tables with dynamic parameter names and defaults.
+ */
+ del_transp_table = (STRING_NV *) mymalloc(1);
+ del_transp_tablen = 0;
+
+ rest_class_table = (char **) mymalloc(1);
+ rest_class_tablen = 0;
+
+ /*
+ * Extract message delivery transport names from master.cf and generate
+ * dynamic parameter information.
+ */
+ for (argvp = master_table; (argv = *argvp) != 0; argvp++) {
+
+ /*
+ * Skip all endpoints except UNIX-domain sockets.
+ */
+ if (strcmp(argv->argv[1], MASTER_XPORT_NAME_UNIX) != 0)
+ continue;
+
+ /*
+ * Add dynamic parameters for message delivery transports.
+ */
+ progname = argv->argv[7];
+ for (cpp = delivery_agents; *cpp; cpp++)
+ if (strcmp(*cpp, progname) == 0)
+ break;
+ if (*cpp != 0) {
+ for (sp = del_transp_params; sp->name; sp++)
+ add_dynamic_parameter(argv->argv[0], sp->name, sp->value);
+ continue;
+ }
+
+ /*
+ * Add dynamic parameters for spawn(8)-based services.
+ */
+ if (strcmp(MAIL_PROGRAM_SPAWN, progname) == 0) {
+ for (sp = spawn_params; sp->name; sp++)
+ add_dynamic_parameter(argv->argv[0], sp->name, sp->value);
+ continue;
+ }
+ }
+
+ /*
+ * Add parameters specified with smtpd_restriction_classes.
+ */
+ if ((mode & SHOW_DEFS) == 0
+ && (class_list = mail_conf_lookup_eval(VAR_REST_CLASSES)) != 0) {
+ cp = saved_class_list = mystrdup(class_list);
+ while ((class_name = mystrtok(&cp, " \t\r\n")) != 0)
+ add_restriction_class(class_name);
+ myfree(saved_class_list);
+ }
+}
+
/* hash_parameters - hash all parameter names so we can find and sort them */
static void hash_parameters(void)
const CONFIG_NINT_TABLE *nst;
const CONFIG_NBOOL_TABLE *bst;
const CONFIG_LONG_TABLE *lst;
+ const STRING_NV *dst;
+ char **rct;
param_table = htable_create(100);
+ /*
+ * Don't allow dynamic parameter names to override built-in names.
+ */
for (ctt = time_table; ctt->name; ctt++)
htable_enter(param_table, ctt->name, (char *) ctt);
for (cbt = bool_table; cbt->name; cbt++)
htable_enter(param_table, bst->name, (char *) bst);
for (lst = long_table; lst->name; lst++)
htable_enter(param_table, lst->name, (char *) lst);
+ for (dst = del_transp_table; dst < del_transp_table + del_transp_tablen; dst++)
+ if (htable_locate(param_table, dst->name) == 0)
+ htable_enter(param_table, dst->name, (char *) dst);
+ for (rct = rest_class_table; rct < rest_class_table + rest_class_tablen; rct++)
+ if (htable_locate(param_table, *rct) == 0)
+ htable_enter(param_table, *rct, (char *) rct);
}
/* read_master - read and digest the master.cf file */
static void read_master(void)
{
- char *path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0);
+ char *path;
VSTRING *buf = vstring_alloc(100);
ARGV *argv;
VSTREAM *fp;
int entry_count = 0;
int line_count = 0;
+ /*
+ * Get the location of master.cf.
+ */
+ if (var_config_dir == 0)
+ set_config_dir();
+ path = concatenate(var_config_dir, "/", MASTER_CONF_FILE, (char *) 0);
+
/*
* We can't use the master_ent routines in their current form. They
* convert everything to internal form, and they skip disabled services.
/* print_bool - print boolean parameter */
-static void print_bool(int mode, CONFIG_BOOL_TABLE *cbt)
+static void print_bool(int mode, const char *name, CONFIG_BOOL_TABLE *cbt)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_strval(mode, cbt->name, cbt->defval ? "yes" : "no");
+ show_strval(mode, name, cbt->defval ? "yes" : "no");
} else {
- value = dict_lookup(CONFIG_DICT, cbt->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, cbt->name, cbt->defval ? "yes" : "no");
+ show_strval(mode, name, cbt->defval ? "yes" : "no");
} else {
- show_strval(mode, cbt->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, cbt->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_time - print relative time parameter */
-static void print_time(int mode, CONFIG_TIME_TABLE *ctt)
+static void print_time(int mode, const char *name, CONFIG_TIME_TABLE *ctt)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_strval(mode, ctt->name, ctt->defval);
+ show_strval(mode, name, ctt->defval);
} else {
- value = dict_lookup(CONFIG_DICT, ctt->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, ctt->name, ctt->defval);
+ show_strval(mode, name, ctt->defval);
} else {
- show_strval(mode, ctt->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, ctt->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_int - print integer parameter */
-static void print_int(int mode, CONFIG_INT_TABLE *cit)
+static void print_int(int mode, const char *name, CONFIG_INT_TABLE *cit)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_intval(mode, cit->name, cit->defval);
+ show_intval(mode, name, cit->defval);
} else {
- value = dict_lookup(CONFIG_DICT, cit->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_intval(mode, cit->name, cit->defval);
+ show_intval(mode, name, cit->defval);
} else {
- show_strval(mode, cit->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, cit->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_str - print string parameter */
-static void print_str(int mode, CONFIG_STR_TABLE *cst)
+static void print_str(int mode, const char *name, CONFIG_STR_TABLE *cst)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_strval(mode, cst->name, cst->defval);
+ show_strval(mode, name, cst->defval);
} else {
- value = dict_lookup(CONFIG_DICT, cst->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, cst->name, cst->defval);
+ show_strval(mode, name, cst->defval);
} else {
- show_strval(mode, cst->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, cst->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_str_fn - print string-function parameter */
-static void print_str_fn(int mode, CONFIG_STR_FN_TABLE *csft)
+static void print_str_fn(int mode, const char *name, CONFIG_STR_FN_TABLE *csft)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_strval(mode, csft->name, csft->defval());
+ show_strval(mode, name, csft->defval());
} else {
- value = dict_lookup(CONFIG_DICT, csft->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, csft->name, csft->defval());
+ show_strval(mode, name, csft->defval());
} else {
- show_strval(mode, csft->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, csft->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_str_fn_2 - print string-function parameter */
-static void print_str_fn_2(int mode, CONFIG_STR_FN_TABLE *csft)
+static void print_str_fn_2(int mode, const char *name, CONFIG_STR_FN_TABLE *csft)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_strval(mode, csft->name, csft->defval());
+ show_strval(mode, name, csft->defval());
} else {
- value = dict_lookup(CONFIG_DICT, csft->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, csft->name, csft->defval());
+ show_strval(mode, name, csft->defval());
} else {
- show_strval(mode, csft->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, csft->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_raw - print raw string parameter */
-static void print_raw(int mode, CONFIG_RAW_TABLE *rst)
+static void print_raw(int mode, const char *name, CONFIG_RAW_TABLE *rst)
{
const char *value;
mode &= ~SHOW_EVAL;
if (mode & SHOW_DEFS) {
- show_strval(mode, rst->name, rst->defval);
+ show_strval(mode, name, rst->defval);
} else {
- value = dict_lookup(CONFIG_DICT, rst->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, rst->name, rst->defval);
+ show_strval(mode, name, rst->defval);
} else {
- show_strval(mode, rst->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, rst->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_nint - print new integer parameter */
-static void print_nint(int mode, CONFIG_NINT_TABLE *rst)
+static void print_nint(int mode, const char *name, CONFIG_NINT_TABLE *rst)
{
const char *value;
if (mode & SHOW_EVAL)
- msg_warn("parameter %s expands at run-time", rst->name);
+ msg_warn("parameter %s expands at run-time", name);
mode &= ~SHOW_EVAL;
if (mode & SHOW_DEFS) {
- show_strval(mode, rst->name, rst->defval);
+ show_strval(mode, name, rst->defval);
} else {
- value = dict_lookup(CONFIG_DICT, rst->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, rst->name, rst->defval);
+ show_strval(mode, name, rst->defval);
} else {
- show_strval(mode, rst->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, rst->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_nbool - print new boolean parameter */
-static void print_nbool(int mode, CONFIG_NBOOL_TABLE *bst)
+static void print_nbool(int mode, const char *name, CONFIG_NBOOL_TABLE *bst)
{
const char *value;
if (mode & SHOW_EVAL)
- msg_warn("parameter %s expands at run-time", bst->name);
+ msg_warn("parameter %s expands at run-time", name);
mode &= ~SHOW_EVAL;
if (mode & SHOW_DEFS) {
- show_strval(mode, bst->name, bst->defval);
+ show_strval(mode, name, bst->defval);
} else {
- value = dict_lookup(CONFIG_DICT, bst->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_strval(mode, bst->name, bst->defval);
+ show_strval(mode, name, bst->defval);
} else {
- show_strval(mode, bst->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, bst->name, value);
+ show_strval(mode, name, value);
}
}
}
/* print_long - print long parameter */
-static void print_long(int mode, CONFIG_LONG_TABLE *clt)
+static void print_long(int mode, const char *name, CONFIG_LONG_TABLE *clt)
{
const char *value;
if (mode & SHOW_DEFS) {
- show_longval(mode, clt->name, clt->defval);
+ show_longval(mode, name, clt->defval);
} else {
- value = dict_lookup(CONFIG_DICT, clt->name);
+ value = dict_lookup(CONFIG_DICT, name);
if ((mode & SHOW_NONDEF) == 0) {
if (value == 0) {
- show_longval(mode, clt->name, clt->defval);
+ show_longval(mode, name, clt->defval);
} else {
- show_strval(mode, clt->name, value);
+ show_strval(mode, name, value);
}
} else {
if (value != 0)
- show_strval(mode, clt->name, value);
+ show_strval(mode, name, value);
+ }
+ }
+}
+
+static void print_parameter(int, const char *, char *);
+
+/* print_del_transp_param_default show delivery agent parameter default value */
+
+static void print_del_transp_param_default(int mode, const char *name,
+ const char *defparam)
+{
+ const char *myname = "print_del_transp_param_default";
+ char *ptr;
+
+ if ((ptr = htable_find(param_table, defparam)) == 0)
+ msg_panic("%s: dynamic parameter %s has unknown default value $%s",
+ myname, name, defparam);
+ if (mode & SHOW_EVAL)
+ print_parameter(mode, name, ptr);
+ else
+ print_line(mode, "%s = $%s\n", name, defparam);
+}
+
+/* print_del_transp_param - show dynamic delivery agent parameter */
+
+static void print_del_transp_param(int mode, const char *name,
+ const STRING_NV *dst)
+{
+ const char *value;
+
+ if (mode & SHOW_DEFS) {
+ print_del_transp_param_default(mode, name, dst->value);
+ } else {
+ value = dict_lookup(CONFIG_DICT, name);
+ if ((mode & SHOW_NONDEF) == 0) {
+ if (value == 0) {
+ print_del_transp_param_default(mode, name, dst->value);
+ } else {
+ show_strval(mode, name, value);
+ }
+ } else {
+ if (value != 0)
+ show_strval(mode, name, value);
+ }
+ }
+}
+
+/* print_rest_class_param - show dynamic parameter */
+
+static void print_rest_class_param(int mode, const char *name)
+{
+ const char *value;
+
+ if (mode & SHOW_DEFS) { /* can't happen */
+ show_strval(mode, name, "");
+ } else {
+ value = dict_lookup(CONFIG_DICT, name);
+ if ((mode & SHOW_NONDEF) == 0) {
+ if (value == 0) {
+ show_strval(mode, name, "");
+ } else {
+ show_strval(mode, name, value);
+ }
+ } else {
+ if (value != 0)
+ show_strval(mode, name, value);
}
}
}
/* print_parameter - show specific parameter */
-static void print_parameter(int mode, char *ptr)
+static void print_parameter(int mode, const char *name, char *ptr)
{
#define INSIDE(p,t) (ptr >= (char *) t && ptr < ((char *) t) + sizeof(t))
+#define INSIDE3(p,t,l) (ptr >= (char *) t && ptr < (char *) ((t) + (l)))
/*
* This is gross, but the best we can do on short notice.
*/
if (INSIDE(ptr, time_table))
- print_time(mode, (CONFIG_TIME_TABLE *) ptr);
+ print_time(mode, name, (CONFIG_TIME_TABLE *) ptr);
if (INSIDE(ptr, bool_table))
- print_bool(mode, (CONFIG_BOOL_TABLE *) ptr);
+ print_bool(mode, name, (CONFIG_BOOL_TABLE *) ptr);
if (INSIDE(ptr, int_table))
- print_int(mode, (CONFIG_INT_TABLE *) ptr);
+ print_int(mode, name, (CONFIG_INT_TABLE *) ptr);
if (INSIDE(ptr, str_table))
- print_str(mode, (CONFIG_STR_TABLE *) ptr);
+ print_str(mode, name, (CONFIG_STR_TABLE *) ptr);
if (INSIDE(ptr, str_fn_table))
- print_str_fn(mode, (CONFIG_STR_FN_TABLE *) ptr);
+ print_str_fn(mode, name, (CONFIG_STR_FN_TABLE *) ptr);
if (INSIDE(ptr, str_fn_table_2))
- print_str_fn_2(mode, (CONFIG_STR_FN_TABLE *) ptr);
+ print_str_fn_2(mode, name, (CONFIG_STR_FN_TABLE *) ptr);
if (INSIDE(ptr, raw_table))
- print_raw(mode, (CONFIG_RAW_TABLE *) ptr);
+ print_raw(mode, name, (CONFIG_RAW_TABLE *) ptr);
if (INSIDE(ptr, nint_table))
- print_nint(mode, (CONFIG_NINT_TABLE *) ptr);
+ print_nint(mode, name, (CONFIG_NINT_TABLE *) ptr);
if (INSIDE(ptr, nbool_table))
- print_nbool(mode, (CONFIG_NBOOL_TABLE *) ptr);
+ print_nbool(mode, name, (CONFIG_NBOOL_TABLE *) ptr);
if (INSIDE(ptr, long_table))
- print_long(mode, (CONFIG_LONG_TABLE *) ptr);
+ print_long(mode, name, (CONFIG_LONG_TABLE *) ptr);
+ if (INSIDE3(ptr, del_transp_table, del_transp_tablen))
+ print_del_transp_param(mode, name, (STRING_NV *) ptr);
+ if (INSIDE3(ptr, rest_class_table, rest_class_tablen))
+ print_rest_class_param(mode, name);
if (msg_verbose)
vstream_fflush(VSTREAM_OUT);
}
list = htable_list(param_table);
qsort((char *) list, param_table->used, sizeof(*list), comp_names);
for (ht = list; *ht; ht++)
- print_parameter(mode, ht[0]->value);
+ print_parameter(mode, ht[0]->key, ht[0]->value);
myfree((char *) list);
return;
}
if ((value = htable_find(param_table, *namep)) == 0) {
msg_warn("%s: unknown parameter", *namep);
} else {
- print_parameter(mode, value);
+ print_parameter(mode, *namep, value);
}
}
}
* If showing master.cf entries, show them and exit
*/
else if (cmd_mode & SHOW_MASTER) {
- mail_conf_read();
read_master();
show_master(cmd_mode);
}
read_parameters();
set_parameters();
}
+ read_master();
+ add_dynamic_parameters(cmd_mode);
/*
* Throw together all parameters and show the asked values.