2
0
mirror of https://github.com/vdukhovni/postfix synced 2025-08-29 13:18:12 +00:00

postfix-2.9-20111120

This commit is contained in:
Wietse Venema 2011-11-20 00:00:00 -05:00 committed by Viktor Dukhovni
parent 2cfc3431dc
commit 38b0a080dc
13 changed files with 309 additions and 204 deletions

1
postfix/.indent.pro vendored
View File

@ -186,6 +186,7 @@
-TNAME_CODE
-TNAME_MASK
-TNBBIO
-TPC_MASTER_ENT
-TPC_SERVICE_DEF
-TPC_STRING_NV
-TPEER_NAME

View File

@ -17109,3 +17109,13 @@ Apologies for any names omitted.
Cleanup: "postconf" commands in postfix-install needed to
be updated before master.cf was installed. Reported by
Sahil Tandon. File: postfix-install.
20111120
Cleanup: support for parameter name spaces for master.cf
entries. With this, postconf should no longer log false
warnings for "-o user-defined-name=value" in master.cf. As
a benefit, it will warn for user-defined parameters with
"name=value" entries that are unused because they are hidden
by master.cf "-o name=value" entries with the same parameter
name. File: postconf/postconf.c.

View File

@ -14,6 +14,14 @@ specifies the release date of a stable release or snapshot release.
If you upgrade from Postfix 2.7 or earlier, read RELEASE_NOTES-2.8
before proceeding.
Major changes with snapshot 20111120
====================================
Eliminated the postconf limitation documented on 20111113 as "lack
of support for per-service parameter name spaces in master.cf,
meaning that "-o user-defined-name=value" always results in an
"unused parameter" warning".
Major changes with snapshot 20111118
====================================

View File

@ -22,12 +22,14 @@ POSTCONF(1) POSTCONF(1)
<b>postconf</b> [<b>-fMv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>service ...</i>]
<b>Managing bounce message templates:</b>
<b>postconf</b> [<b>-btv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>template</i><b>_</b><i>file</i>]
<b>Managing other configuration:</b>
<b>postconf</b> [<b>-aAlmv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>]
<b>postconf</b> [<b>-btv</b>] [<b>-c</b> <i>config</i><b>_</b><i>dir</i>] [<i>template</i><b>_</b><i>file</i>]
<b>DESCRIPTION</b>
By default, the <a href="postconf.1.html"><b>postconf</b>(1)</a> command displays the values of
<a href="postconf.5.html"><b>main.cf</b></a> configuration parameters, and warns about possible
@ -133,7 +135,7 @@ POSTCONF(1) POSTCONF(1)
human readability.
If <i>service ...</i> is specified, only the matching ser-
vices will be output. For example, a <i>service</i> <b>of</b>
vices will be output. For example, a <i>service</i> of
<b>inet</b> will match all services that listen on the
network.
@ -287,12 +289,6 @@ POSTCONF(1) POSTCONF(1)
<b>DIAGNOSTICS</b>
Problems are reported to the standard error stream.
<b>BUGS</b>
<a href="postconf.1.html"><b>postconf</b>(1)</a> may log "unused parameter" warnings for <b>mas-</b>
<b>ter.cf</b> entries with "-o user-defined-name=value".
Addressing this limitation requires support for per-ser-
vice parameter name spaces.
<b>ENVIRONMENT</b>
<b>MAIL_CONFIG</b>
Directory with Postfix configuration files.

View File

@ -25,11 +25,13 @@ Postfix configuration utility
\fBpostconf\fR [\fB-fMv\fR] [\fB-c \fIconfig_dir\fR]
[\fIservice ...\fR]
\fBManaging bounce message templates:\fR
\fBpostconf\fR [\fB-btv\fR] [\fB-c \fIconfig_dir\fR] [\fItemplate_file\fR]
\fBManaging other configuration:\fR
\fBpostconf\fR [\fB-aAlmv\fR] [\fB-c \fIconfig_dir\fR]
\fBpostconf\fR [\fB-btv\fR] [\fB-c \fIconfig_dir\fR] [\fItemplate_file\fR]
.SH DESCRIPTION
.ad
.fi
@ -124,7 +126,7 @@ file contents. Use \fB-Mf\fR to fold long lines for human
readability.
If \fIservice ...\fR is specified, only the matching services
will be output. For example, a \fIservice\fB of \fBinet\fR
will be output. For example, a \fIservice\fR of \fBinet\fR
will match all services that listen on the network.
Specify zero or more arguments, each with a \fIservice-type\fR
@ -244,13 +246,6 @@ This feature is available with Postfix 2.6 and later.
.ad
.fi
Problems are reported to the standard error stream.
.SH BUGS
.ad
.fi
\fBpostconf\fR(1) may log "unused parameter" warnings for
\fBmaster.cf\fR entries with "-o user-defined-name=value".
Addressing this limitation requires support for per-service
parameter name spaces.
.SH "ENVIRONMENT"
.na
.nf

View File

@ -20,7 +20,7 @@
* Patches change both the patchlevel and the release date. Snapshots have no
* patchlevel; they change the release date only.
*/
#define MAIL_RELEASE_DATE "20111119"
#define MAIL_RELEASE_DATE "20111120"
#define MAIL_VERSION_NUMBER "2.9"
#ifdef SNAPSHOT

View File

@ -36,7 +36,8 @@ Makefile: Makefile.in
test: $(TESTPROG)
tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11
tests: test1 test2 test3 test4 test5 test6 test7 test8 test9 test10 test11 \
test12 test13 test14 test15
root_tests:
@ -100,9 +101,7 @@ test4: $(PROG) test4.ref
rm -f main.cf master.cf test4.tmp
# Define one user-defined parameter with name=value in master.cf,
# validate it with known_parameter=$name in master.cf. Currently,
# user-defined parameter definitions in master.cf are not recognized
# as definitions, and result in an "unused parameter" warning.
# validate it with known_parameter=$name in master.cf.
test5: $(PROG) test5.ref
rm -f main.cf master.cf
@ -169,6 +168,58 @@ test11: $(PROG) test11.ref
diff test11.ref test11.tmp
rm -f main.cf master.cf test11.tmp
# Duplicate service entry.
test12: $(PROG) test12.ref
rm -f main.cf master.cf
touch main.cf master.cf
echo bar=yes >> main.cf
echo foo inet - n n - 0 spawn >> master.cf
echo ' -o always_bcc=$$bar -o' >> master.cf
echo foo inet - n n - 0 spawn >> master.cf
echo ' -o always_bcc=$$bar -o' >> master.cf
./$(PROG) -c . -M >test12.tmp 2>&1
diff test12.ref test12.tmp
rm -f main.cf master.cf test12.tmp
# Define parameter with restriction_classes in master.cf, validate in main.cf.
test13: $(PROG) test13.ref
rm -f main.cf master.cf
touch main.cf master.cf
echo bar=yes >> main.cf
echo baz=xx >> main.cf
echo foo inet - n n - 0 spawn >> master.cf
echo ' -o smtpd_restriction_classes=bar' >> master.cf
./$(PROG) -nc . >test13.tmp 2>&1
diff test13.ref test13.tmp
rm -f main.cf master.cf test13.tmp
# Define parameter with restriction_classes in main.cf, validate in master.cf.
test14: $(PROG) test14.ref
rm -f main.cf master.cf
touch main.cf master.cf
echo smtpd_restriction_classes=bar >> main.cf
echo foo inet - n n - 0 spawn >> master.cf
echo ' -o bar=yes -o baz=xx' >> master.cf
./$(PROG) -nc . >test14.tmp 2>&1
diff test14.ref test14.tmp
rm -f main.cf master.cf test14.tmp
# Define two parameters, one is hidden by master.cf.
test15: $(PROG) test15.ref
rm -f main.cf master.cf
touch main.cf master.cf
echo bar=xx >> main.cf
echo baz=yy >> main.cf
echo foo inet - n n - 0 spawn >> master.cf
echo ' -o bar=yes -o always_bcc=$$bar$$baz' >> master.cf
./$(PROG) -nc . >test15.tmp 2>&1
diff test15.ref test15.tmp
rm -f main.cf master.cf test15.tmp
printfck: $(OBJS) $(PROG)
rm -rf printfck
mkdir printfck

View File

@ -21,11 +21,13 @@
/* \fBpostconf\fR [\fB-fMv\fR] [\fB-c \fIconfig_dir\fR]
/* [\fIservice ...\fR]
/*
/* \fBManaging bounce message templates:\fR
/*
/* \fBpostconf\fR [\fB-btv\fR] [\fB-c \fIconfig_dir\fR] [\fItemplate_file\fR]
/*
/* \fBManaging other configuration:\fR
/*
/* \fBpostconf\fR [\fB-aAlmv\fR] [\fB-c \fIconfig_dir\fR]
/*
/* \fBpostconf\fR [\fB-btv\fR] [\fB-c \fIconfig_dir\fR] [\fItemplate_file\fR]
/* DESCRIPTION
/* By default, the \fBpostconf\fR(1) command displays the
/* values of \fBmain.cf\fR configuration parameters, and warns
@ -118,7 +120,7 @@
/* readability.
/*
/* If \fIservice ...\fR is specified, only the matching services
/* will be output. For example, a \fIservice\fB of \fBinet\fR
/* will be output. For example, a \fIservice\fR of \fBinet\fR
/* will match all services that listen on the network.
/*
/* Specify zero or more arguments, each with a \fIservice-type\fR
@ -236,11 +238,6 @@
/* This feature is available with Postfix 2.6 and later.
/* DIAGNOSTICS
/* Problems are reported to the standard error stream.
/* BUGS
/* \fBpostconf\fR(1) may log "unused parameter" warnings for
/* \fBmaster.cf\fR entries with "-o user-defined-name=value".
/* Addressing this limitation requires support for per-service
/* parameter name spaces.
/* ENVIRONMENT
/* .ad
/* .fi
@ -358,7 +355,7 @@
#define FOLD_LINE (1<<11) /* fold long *.cf entries */
/*
* Lookup table for in-core parameter info.
* Lookup table for global parameter info.
*
* XXX Change the value pointers from table indices into pointers to parameter
* objects with print methods.
@ -366,13 +363,21 @@
HTABLE *param_table;
/*
* Lookup table for master.cf info.
*
* XXX Replace by data structures with per-entry hashes for "-o name=value", so
* that we can properly handle name=value definitions in per-service name
* spaces.
* Global restriction_classes hash.
*/
static ARGV **master_table;
HTABLE *rest_class_table;
/*
* Lookup table for master.cf info. The table is null-terminated.
*/
typedef struct {
char *name_space; /* service.type, parameter name space */
ARGV *argv; /* terminator, or master.cf fields */
DICT *all_params; /* all name=value entries */
HTABLE *valid_names; /* "blessed" parameters */
} PC_MASTER_ENT;
static PC_MASTER_ENT *master_table;
/*
* Support for built-in parameters: declarations generated by scanning
@ -458,24 +463,25 @@ static ssize_t serv_param_tablen;
*
* There are three categories of known parameters: built-in, service-defined
* (see previous comment), and valid user-defined. In addition there are
* multiple name spaces: the global main.cf name space, and the per-service
* name space of each master.cf entry.
* multiple name spaces: the global main.cf name space, and the local name
* space of each master.cf entry.
*
* There are two categories of valid user-defined parameters:
*
* - Parameters whose name appears in the value of smtpd_restriction_classes in
* main.cf, and whose name has a "name=value" entry in main.cf (todo:
* support for creating names with "-o smtpd_restriction_classes=name"
* within a master.cf per-service name space).
* - Parameters whose user-defined-name appears in the value of
* smtpd_restriction_classes in main.cf or master.cf, and that have a
* "user-defined-name=value" entry in main.cf or master.cf.
*
* - Parameters whose $name (macro expansion) appears in the value of a
* "name=value" entry in main.cf or master.cf of a "known" parameter, and
* whose name has a "name=value" entry in main.cf (todo: master.cf).
* - Parameters whose $user-defined-name appears in the value of a "name=value"
* entry in main.cf or master.cf, and whose user-defined-name has a
* "name=value" entry in main.cf or master.cf.
*
* All other user-defined parameters are invalid. We currently log a warning
* for "name=value" entries in main.cf or master.cf whose $name does not
* appear in the value of a main.cf or master.cf "name=value" entry of a
* "known" parameter.
* Other user-defined parameters are flagged as "unused".
*/
/*
* Global-scope valid user-defined parameter names. The local-scope valid
* user-defined names are kept in the table with master.cf entries.
*/
static char **user_param_table;
static ssize_t user_param_tablen;
@ -820,10 +826,12 @@ static void read_master(void)
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.
* We need to be able to show default fields as "-", and we need to know
* about all service names so that we can generate service-dependent
* We can't use the master daemon's master_ent routines in their current
* form. They convert everything to internal form, and they skip disabled
* services.
*
* The postconf command needs to show default fields as "-", and needs to
* know about all service names so that it can generate service-dependent
* parameter names (transport-dependent etc.).
*/
#define MASTER_BLANKS " \t\r\n" /* XXX */
@ -832,7 +840,7 @@ static void read_master(void)
/*
* Initialize the in-memory master table.
*/
master_table = (ARGV **) mymalloc(sizeof(*master_table));
master_table = (PC_MASTER_ENT *) mymalloc(sizeof(*master_table));
/*
* Skip blank lines and comment lines.
@ -840,14 +848,23 @@ static void read_master(void)
if ((fp = vstream_fopen(path, O_RDONLY, 0)) == 0)
msg_fatal("open %s: %m", path);
while (readlline(buf, fp, &line_count) != 0) {
master_table = (ARGV **) myrealloc((char *) master_table,
master_table = (PC_MASTER_ENT *) myrealloc((char *) master_table,
(entry_count + 2) * sizeof(*master_table));
argv = argv_split(STR(buf), MASTER_BLANKS);
if (argv->argc < MASTER_FIELD_COUNT)
msg_fatal("file %s: line %d: bad field count", path, line_count);
master_table[entry_count++] = argv;
master_table[entry_count].name_space =
concatenate(argv->argv[0], ".", argv->argv[1], (char *) 0);
master_table[entry_count].argv = argv;
master_table[entry_count].valid_names = 0;
master_table[entry_count].all_params = 0;
entry_count += 1;
}
master_table[entry_count] = 0;
/*
* Null-terminate the master table and clean up.
*/
master_table[entry_count].argv = 0;
vstream_fclose(fp);
myfree(path);
vstring_free(buf);
@ -938,7 +955,7 @@ static void add_service_parameters(void)
const PC_STRING_NV *sp;
const char *progname;
const char *service;
ARGV **argvp;
PC_MASTER_ENT *masterp;
ARGV *argv;
const PC_SERVICE_DEF *sd;
@ -952,7 +969,7 @@ static void add_service_parameters(void)
* Extract service names from master.cf and generate service parameter
* information.
*/
for (argvp = master_table; (argv = *argvp) != 0; argvp++) {
for (masterp = master_table; (argv = masterp->argv) != 0; masterp++) {
/*
* Add service parameters for message delivery transports or spawn
@ -978,118 +995,152 @@ static void add_service_parameters(void)
htable_enter(param_table, sp->name, (char *) sp);
}
/* add_user_parameter - add one user-defined parameter name */
static void add_user_parameter(const char *name)
{
/* XXX Merge this with check_parameter_value() */
user_param_table = (char **)
myrealloc((char *) user_param_table,
(user_param_tablen + 1) * sizeof(*user_param_table));
user_param_table[user_param_tablen] = mystrdup(name);
user_param_tablen += 1;
}
/* scan_user_parameter_value - extract macro names from parameter value */
/* scan_user_parameter_value - examine macro names in parameter value */
#define NO_SCAN_RESULT ((VSTRING *) 0)
#define NO_SCAN_FILTER ((char *) 0)
#define NO_SCAN_MODE (0)
#define NO_SCAN_CONTEXT ((char *) 0)
#define scan_user_parameter_value(value) do { \
#define scan_user_parameter_value(value, context) do { \
(void) mac_expand(NO_SCAN_RESULT, (value), MAC_EXP_FLAG_SCAN, \
NO_SCAN_FILTER, check_user_parameter, NO_SCAN_CONTEXT); \
NO_SCAN_FILTER, check_user_parameter, (context)); \
} while (0)
/* check_user_parameter - try to promote user-defined parameter */
/* check_user_parameter - promote user-defined name if it has name=value */
static const char *check_user_parameter(const char *mac_name,
int unused_mode,
char *unused_context)
char *context)
{
const char *mac_value;
PC_MASTER_ENT *local_scope = (PC_MASTER_ENT *) context;
/*
* Promote only user-defined parameters with an explicit "name=value"
* definition in main.cf (todo: master.cf). Do not promote parameters
* whose name appears only as a macro expansion; this is how Postfix
* implements backwards compatibility after a feature name change.
* definition. If the name=value exists in the local scope, update the
* local "valid" parameter name table, otherwise update the global one.
*
* Skip parameters that are already in the param_table hash.
* Do not promote user-defined parameters whose name appears only as macro
* expansion; this is how Postfix implements backwards compatibility
* after a feature name change.
*
* Skip global names that are already in the param_table hash.
*/
if (htable_locate(param_table, mac_name) == 0) {
mac_value = mail_conf_lookup(mac_name);
if (mac_value != 0) {
add_user_parameter(mac_name);
/* Promote parameter names recursively. */
scan_user_parameter_value(mac_value);
if (local_scope && dict_get(local_scope->all_params, mac_name)) {
if (htable_locate(local_scope->valid_names, mac_name) == 0)
htable_enter(local_scope->valid_names, mac_name, "");
} else if (htable_locate(param_table, mac_name) == 0) {
if (mail_conf_lookup(mac_name) != 0) {
user_param_table = (char **)
myrealloc((char *) user_param_table,
(user_param_tablen + 1) * sizeof(*user_param_table));
user_param_table[user_param_tablen] = mystrdup(mac_name);
user_param_tablen += 1;
}
}
return (0);
}
/* pc_lookup_eval - generalized mail_conf_lookup_eval */
static const char *pc_lookup_eval(const char *dict_name, const char *name)
{
const char *value;
#define RECURSIVE 1
if ((value = dict_lookup(dict_name, name)) != 0)
value = dict_eval(dict_name, value, RECURSIVE);
return (value);
}
/* scan_user_parameter_namespace - scan parameters in name space */
static void scan_user_parameter_namespace(const char *dict_name,
PC_MASTER_ENT *local_scope)
{
const char *myname = "scan_user_parameter_namespace";
const char *class_list;
char *saved_class_list;
char *cp;
DICT *dict;
char *param_name;
int how;
const char *cparam_name;
const char *cparam_value;
/*
* Add parameters whose names are defined with smtpd_restriction_classes,
* but only if they have a "name=value" entry. If we are in the global
* scope, update the global restriction class name table, so that we can
* query the table from within a local master.cf name space.
*/
if ((class_list = pc_lookup_eval(dict_name, VAR_REST_CLASSES)) != 0) {
cp = saved_class_list = mystrdup(class_list);
while ((param_name = mystrtok(&cp, ", \t\r\n")) != 0) {
if (local_scope == 0
&& htable_locate(rest_class_table, param_name) == 0)
htable_enter(rest_class_table, param_name, "");
check_user_parameter(param_name, NO_SCAN_MODE,
(char *) local_scope);
}
myfree(saved_class_list);
}
/*
* For all "name=value" instances: a) if the scope is local and the name
* appears in the global restriction class table, flag the name as
* "valid" in the local scope; b) scan the value for macro expansions of
* unknown parameter names, and flag those parameter names as "valid" if
* they have a "name=value" entry.
*/
if ((dict = dict_handle(dict_name)) == 0)
msg_panic("%s: parameter dictionary %s not found",
myname, dict_name);
if (dict->sequence == 0)
msg_panic("%s: parameter dictionary %s has no iterator",
myname, dict_name);
for (how = DICT_SEQ_FUN_FIRST;
dict->sequence(dict, how, &cparam_name, &cparam_value) == 0;
how = DICT_SEQ_FUN_NEXT) {
if (local_scope != 0
&& htable_locate(local_scope->valid_names, cparam_name) == 0
&& htable_locate(rest_class_table, cparam_name) != 0)
htable_enter(local_scope->valid_names, cparam_name, "");
scan_user_parameter_value(cparam_value, (char *) local_scope);
}
}
/* add_user_parameters - add parameters with user-defined names */
static void add_user_parameters(void)
{
const char *class_list;
char *saved_class_list;
char *cp;
const char *cparam_value;
HTABLE_INFO **ht_info;
HTABLE_INFO **ht;
ARGV **argvp;
PC_MASTER_ENT *masterp;
ARGV *argv;
char *arg;
int field;
char *saved_arg;
char *param_name;
char *param_value;
DICT *dict;
char **up;
/*
* Initialize the table with user-defined parameter names and values.
* Initialize the global table with user-defined parameter names, and the
* table with global restriction class names.
*/
user_param_table = (char **) mymalloc(1);
user_param_tablen = 0;
rest_class_table = htable_create(1);
/*
* Add parameters whose names are defined with smtpd_restriction_classes,
* but only if they have a "name=value" entry in main.cf.
*
* XXX It is possible that a user-defined parameter is defined in master.cf
* with "-o smtpd_restriction_classes=name -o name=value". This requires
* name space support for master.cf entries. Without this, we always log
* "unused parameter" warnings for "-o user-defined-name=value" entries.
* Scan the explicit name=value entries in the global name space.
*/
if ((class_list = mail_conf_lookup_eval(VAR_REST_CLASSES)) != 0) {
cp = saved_class_list = mystrdup(class_list);
while ((param_name = mystrtok(&cp, ", \t\r\n")) != 0)
check_user_parameter(param_name, NO_SCAN_MODE, NO_SCAN_CONTEXT);
myfree(saved_class_list);
}
scan_user_parameter_namespace(CONFIG_DICT, (PC_MASTER_ENT *) 0);
/*
* Parse the "name=value" instances in main.cf of built-in and service
* parameters only, look for macro expansions of unknown parameter names,
* and flag those parameter names as "known" if they have a "name=value"
* entry in main.cf. Recursively apply the procedure to the values of
* newly-flagged parameters.
* Scan the "-o parameter=value" instances in each master.cf name space.
*/
for (ht_info = ht = htable_list(param_table); *ht; ht++)
if ((cparam_value = mail_conf_lookup(ht[0]->key)) != 0)
scan_user_parameter_value(cparam_value);
myfree((char *) ht_info);
/*
* Parse all "-o parameter=value" instances in master.cf, look for macro
* expansions of unknown parameter names, and flag those parameter names
* as "known" if they have a "name=value" entry in main.cf (XXX todo: in
* master.cf; without master.cf name space support we always log "unused
* parameter" warnings for "-o user-defined-name=value" entries).
*/
for (argvp = master_table; (argv = *argvp) != 0; argvp++) {
for (masterp = master_table; (argv = masterp->argv) != 0; masterp++) {
for (field = MASTER_FIELD_COUNT; argv->argv[field] != 0; field++) {
arg = argv->argv[field];
if (arg[0] != '-')
@ -1097,11 +1148,16 @@ static void add_user_parameters(void)
if (strcmp(arg, "-o") == 0 && (arg = argv->argv[field + 1]) != 0) {
saved_arg = mystrdup(arg);
if (split_nameval(saved_arg, &param_name, &param_value) == 0)
scan_user_parameter_value(param_value);
dict_update(masterp->name_space, param_name, param_value);
myfree(saved_arg);
field += 1;
}
}
if ((dict = dict_handle(masterp->name_space)) != 0) {
masterp->all_params = dict;
masterp->valid_names = htable_create(1);
scan_user_parameter_namespace(masterp->name_space, masterp);
}
}
/*
@ -1756,35 +1812,25 @@ static void print_master_line(int mode, ARGV *argv)
static void show_master(int mode, char **filters)
{
ARGV **argvp;
PC_MASTER_ENT *masterp;
ARGV *argv;
VSTRING *service_name = 0;
ARGV *service_filter = 0;
/*
* Initialize the service filter.
*/
if (filters[0]) {
service_name = vstring_alloc(10);
if (filters[0])
service_filter = match_service_init_argv(filters);
}
/*
* Iterate over the master table.
*/
for (argvp = master_table; (argv = *argvp) != 0; argvp++) {
if (service_filter) {
vstring_sprintf(service_name, "%s.%s",
argv->argv[0], argv->argv[1]);
if (match_service_match(service_filter, STR(service_name)) == 0)
continue;
}
for (masterp = master_table; (argv = masterp->argv) != 0; masterp++)
if (service_filter == 0
|| match_service_match(service_filter, masterp->name_space) != 0)
print_master_line(mode, argv);
}
if (service_filter) {
if (service_filter != 0)
argv_free(service_filter);
vstring_free(service_name);
}
}
/* show_sasl - show SASL plug-in types */
@ -1801,79 +1847,67 @@ static void show_sasl(int what)
argv_free(sasl_argv);
}
/* flag_unused_parameters - warn about unused parameters */
static void flag_unused_parameters(DICT *dict, const char *conf_name,
PC_MASTER_ENT *local_scope)
{
const char *myname = "flag_unused_parameters";
const char *param_name;
const char *param_value;
int how;
/*
* Iterate over all entries, and flag parameter names that aren't used
* anywhere. Show the warning message at the end of the output.
*/
if (dict->sequence == 0)
msg_panic("%s: parameter dictionary %s has no iterator",
myname, conf_name);
for (how = DICT_SEQ_FUN_FIRST;
dict->sequence(dict, how, &param_name, &param_value) == 0;
how = DICT_SEQ_FUN_NEXT) {
if (htable_locate(param_table, param_name) == 0
&& (local_scope == 0
|| htable_locate(local_scope->valid_names, param_name) == 0)) {
vstream_fflush(VSTREAM_OUT);
msg_warn("%s/%s: unused parameter: %s=%s",
var_config_dir, conf_name, param_name, param_value);
}
}
}
/* flag_unused_main_parameters - warn about unused parameters */
static void flag_unused_main_parameters(void)
{
const char *myname = "flag_unused_main_parameters";
DICT *dict;
const char *param_name;
const char *param_value;
int how;
/*
* Iterate over all main.cf entries, and flag parameter names that aren't
* used anywhere. Show the warning message at the end of the output.
* used anywhere.
*/
if ((dict = dict_handle(CONFIG_DICT)) == 0)
msg_panic("%s: parameter dictionary %s not found",
myname, CONFIG_DICT);
if (dict->sequence == 0)
msg_panic("%s: parameter dictionary %s has no iterator",
myname, CONFIG_DICT);
for (how = DICT_SEQ_FUN_FIRST;
dict->sequence(dict, how, &param_name, &param_value) == 0;
how = DICT_SEQ_FUN_NEXT) {
if (htable_locate(param_table, param_name) == 0) {
vstream_fflush(VSTREAM_OUT);
msg_warn("%s/" MAIN_CONF_FILE ": unused parameter: %s=%s",
var_config_dir, param_name, param_value);
}
}
flag_unused_parameters(dict, MAIN_CONF_FILE, (PC_MASTER_ENT *) 0);
}
/* flag_unused_master_parameters - warn about unused parameters */
static void flag_unused_master_parameters(void)
{
ARGV **argvp;
ARGV *argv;
int field;
char *arg;
char *saved_arg;
char *param_name;
char *param_value;
PC_MASTER_ENT *masterp;
DICT *dict;
/*
* Iterate over all master.cf entries, and flag parameter names that
* aren't used anywhere. Show the warning message at the end of the
* output.
*
* XXX It is possible that a user-defined parameter is defined in master.cf
* with "-o smtpd_restriction_classes=name", or with "-o name1=value1"
* and then used in a "-o name2=$name1" macro expansion in that same
* master.cf entry. To handle this we need to give each master.cf entry
* its own name space. Until then, we always log "unused parameter"
* warnings for "-o user-defined-name=value" entries.
* aren't used anywhere.
*/
for (argvp = master_table; (argv = *argvp) != 0; argvp++) {
for (field = MASTER_FIELD_COUNT; argv->argv[field] != 0; field++) {
arg = argv->argv[field];
if (arg[0] != '-')
break;
if (strcmp(arg, "-o") == 0 && (arg = argv->argv[field + 1]) != 0) {
saved_arg = mystrdup(arg);
if (split_nameval(saved_arg, &param_name, &param_value) == 0
&& htable_locate(param_table, param_name) == 0) {
vstream_fflush(VSTREAM_OUT);
msg_warn("%s/" MASTER_CONF_FILE ": unused parameter: %s=%s",
var_config_dir, param_name, param_value);
}
myfree(saved_arg);
field += 1;
}
}
}
for (masterp = master_table; masterp->argv != 0; masterp++)
if ((dict = masterp->all_params) != 0)
flag_unused_parameters(dict, MASTER_CONF_FILE, masterp);
}
MAIL_VERSION_STAMP_DECLARE;

View File

@ -0,0 +1,2 @@
foo inet - n n - 0 spawn -o always_bcc=$bar -o
foo inet - n n - 0 spawn -o always_bcc=$bar -o

View File

@ -0,0 +1,3 @@
bar = yes
config_directory = .
./postconf: warning: ./main.cf: unused parameter: baz=xx

View File

@ -0,0 +1,3 @@
config_directory = .
smtpd_restriction_classes = bar
./postconf: warning: ./master.cf: unused parameter: baz=xx

View File

@ -0,0 +1,3 @@
baz = yy
config_directory = .
./postconf: warning: ./main.cf: unused parameter: bar=xx

View File

@ -1,2 +1 @@
config_directory = .
./postconf: warning: ./master.cf: unused parameter: bar=yes