xref: /netbsd-src/external/ibm-public/postfix/dist/src/postconf/postconf.c (revision b7b7574d3bf8eeb51a1fa3977b59142ec6434a55)
1 /*	$NetBSD: postconf.c,v 1.1.1.7 2014/01/18 17:04:19 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	postconf 1
6 /* SUMMARY
7 /*	Postfix configuration utility
8 /* SYNOPSIS
9 /* .fi
10 /*	\fBManaging main.cf:\fR
11 /*
12 /*	\fBpostconf\fR [\fB-dfhnovx\fR] [\fB-c \fIconfig_dir\fR]
13 /*	[\fB-C \fIclass,...\fR] [\fIparameter ...\fR]
14 /*
15 /*	\fBpostconf\fR [\fB-ev\fR] [\fB-c \fIconfig_dir\fR]
16 /*	[\fIparameter=value ...\fR]
17 /*
18 /*	\fBpostconf\fR [\fB-#vX\fR] [\fB-c \fIconfig_dir\fR]
19 /*	[\fIparameter ...\fR]
20 /*
21 /*	\fBManaging master.cf:\fR
22 /*
23 /*	\fBpostconf\fR [\fB-fMovx\fR] [\fB-c \fIconfig_dir\fR]
24 /*	[\fIservice ...\fR]
25 /*
26 /*	\fBManaging bounce message templates:\fR
27 /*
28 /*	\fBpostconf\fR [\fB-btv\fR] [\fB-c \fIconfig_dir\fR] [\fItemplate_file\fR]
29 /*
30 /*	\fBManaging other configuration:\fR
31 /*
32 /*	\fBpostconf\fR [\fB-aAlmv\fR] [\fB-c \fIconfig_dir\fR]
33 /* DESCRIPTION
34 /*	By default, the \fBpostconf\fR(1) command displays the
35 /*	values of \fBmain.cf\fR configuration parameters, and warns
36 /*	about possible mis-typed parameter names (Postfix 2.9 and later).
37 /*	It can also change \fBmain.cf\fR configuration
38 /*	parameter values, or display other configuration information
39 /*	about the Postfix mail system.
40 /*
41 /*	Options:
42 /* .IP \fB-a\fR
43 /*	List the available SASL server plug-in types.  The SASL
44 /*	plug-in type is selected with the \fBsmtpd_sasl_type\fR
45 /*	configuration parameter by specifying one of the names
46 /*	listed below.
47 /* .RS
48 /* .IP \fBcyrus\fR
49 /*	This server plug-in is available when Postfix is built with
50 /*	Cyrus SASL support.
51 /* .IP \fBdovecot\fR
52 /*	This server plug-in uses the Dovecot authentication server,
53 /*	and is available when Postfix is built with any form of SASL
54 /*	support.
55 /* .RE
56 /* .IP
57 /*	This feature is available with Postfix 2.3 and later.
58 /* .IP \fB-A\fR
59 /*	List the available SASL client plug-in types.  The SASL
60 /*	plug-in type is selected with the \fBsmtp_sasl_type\fR or
61 /*	\fBlmtp_sasl_type\fR configuration parameters by specifying
62 /*	one of the names listed below.
63 /* .RS
64 /* .IP \fBcyrus\fR
65 /*	This client plug-in is available when Postfix is built with
66 /*	Cyrus SASL support.
67 /* .RE
68 /* .IP
69 /*	This feature is available with Postfix 2.3 and later.
70 /* .IP "\fB-b\fR [\fItemplate_file\fR]"
71 /*	Display the message text that appears at the beginning of
72 /*	delivery status notification (DSN) messages, replacing
73 /*	$\fBname\fR expressions with actual values as described in
74 /*	\fBbounce\fR(5).
75 /*
76 /*	To override the built-in templates, specify a template file
77 /*	name at the end of the \fBpostconf\fR(1) command line, or
78 /*	specify a file name in \fBmain.cf\fR with the
79 /*	\fBbounce_template_file\fR parameter.
80 /*
81 /*	To force selection of the built-in templates, specify an
82 /*	empty template file name on the \fBpostconf\fR(1) command
83 /*	line (in shell language: "").
84 /*
85 /*	This feature is available with Postfix 2.3 and later.
86 /* .IP "\fB-c \fIconfig_dir\fR"
87 /*	The \fBmain.cf\fR configuration file is in the named directory
88 /*	instead of the default configuration directory.
89 /* .IP "\fB-C \fIclass,...\fR"
90 /*	When displaying \fBmain.cf\fR parameters, select only
91 /*	parameters from the specified class(es):
92 /* .RS
93 /* .IP \fBbuiltin\fR
94 /*	Parameters with built-in names.
95 /* .IP \fBservice\fR
96 /*	Parameters with service-defined names (the first field of
97 /*	a \fBmaster.cf\fR entry plus a Postfix-defined suffix).
98 /* .IP \fBuser\fR
99 /*	Parameters with user-defined names.
100 /* .IP \fBall\fR
101 /*	All the above classes.
102 /* .RE
103 /* .IP
104 /*	The default is as if "\fB-C all\fR" is
105 /*	specified.
106 /* .IP \fB-d\fR
107 /*	Print \fBmain.cf\fR default parameter settings instead of
108 /*	actual settings.
109 /*	Specify \fB-df\fR to fold long lines for human readability
110 /*	(Postfix 2.9 and later).
111 /* .IP \fB-e\fR
112 /*	Edit the \fBmain.cf\fR configuration file, and update
113 /*	parameter settings with the "\fIname=value\fR" pairs
114 /*	on the \fBpostconf\fR(1) command line. The file is copied
115 /*	to a temporary file then renamed into place.
116 /*	Specify quotes to protect special characters and whitespace
117 /*	on the \fBpostconf\fR(1) command line.
118 /*
119 /*	The \fB-e\fR is no longer needed with Postfix version 2.8
120 /*	and later.
121 /* .IP \fB-f\fR
122 /*	Fold long lines when printing \fBmain.cf\fR or \fBmaster.cf\fR
123 /*	configuration file entries, for human readability.
124 /*
125 /*	This feature is available with Postfix 2.9 and later.
126 /* .IP \fB-h\fR
127 /*	Show \fBmain.cf\fR parameter values without the "\fIname\fR
128 /*	= " label that normally precedes the value.
129 /* .IP \fB-l\fR
130 /*	List the names of all supported mailbox locking methods.
131 /*	Postfix supports the following methods:
132 /* .RS
133 /* .IP \fBflock\fR
134 /*	A kernel-based advisory locking method for local files only.
135 /*	This locking method is available on systems with a BSD
136 /*	compatible library.
137 /* .IP \fBfcntl\fR
138 /*	A kernel-based advisory locking method for local and remote files.
139 /* .IP \fBdotlock\fR
140 /*	An application-level locking method. An application locks a file
141 /*	named \fIfilename\fR by creating a file named \fIfilename\fB.lock\fR.
142 /*	The application is expected to remove its own lock file, as well as
143 /*	stale lock files that were left behind after abnormal program
144 /*	termination.
145 /* .RE
146 /* .IP \fB-m\fR
147 /*	List the names of all supported lookup table types. In Postfix
148 /*	configuration files,
149 /*	lookup tables are specified as \fItype\fB:\fIname\fR, where
150 /*	\fItype\fR is one of the types listed below. The table \fIname\fR
151 /*	syntax depends on the lookup table type as described in the
152 /*	DATABASE_README document.
153 /* .RS
154 /* .IP \fBbtree\fR
155 /*	A sorted, balanced tree structure.
156 /*	This is available on systems with support for Berkeley DB
157 /*	databases.
158 /* .IP \fBcdb\fR
159 /*	A read-optimized structure with no support for incremental updates.
160 /*	This is available on systems with support for CDB databases.
161 /* .IP \fBcidr\fR
162 /*	A table that associates values with Classless Inter-Domain Routing
163 /*	(CIDR) patterns. This is described in \fBcidr_table\fR(5).
164 /* .IP \fBdbm\fR
165 /*	An indexed file type based on hashing.
166 /*	This is available on systems with support for DBM databases.
167 /* .IP \fBenviron\fR
168 /*	The UNIX process environment array. The lookup key is the variable
169 /*	name. Originally implemented for testing, someone may find this
170 /*	useful someday.
171 /* .IP \fBfail\fR
172 /*	A table that reliably fails all requests. The lookup table
173 /*	name is used for logging. This table exists to simplify
174 /*	Postfix error tests.
175 /* .IP \fBhash\fR
176 /*	An indexed file type based on hashing.
177 /*	This is available on systems with support for Berkeley DB
178 /*	databases.
179 /* .IP \fBinternal\fR
180 /*	A non-shared, in-memory hash table. Its content are lost
181 /*	when a process terminates.
182 /* .IP "\fBldap\fR (read-only)"
183 /*	Perform lookups using the LDAP protocol. This is described
184 /*	in \fBldap_table\fR(5).
185 /* .IP "\fBmemcache\fR"
186 /*	Perform lookups using the memcache protocol. This is described
187 /*	in \fBmemcache_table\fR(5).
188 /* .IP "\fBmysql\fR (read-only)"
189 /*	Perform lookups using the MYSQL protocol. This is described
190 /*	in \fBmysql_table\fR(5).
191 /* .IP "\fBpcre\fR (read-only)"
192 /*	A lookup table based on Perl Compatible Regular Expressions. The
193 /*	file format is described in \fBpcre_table\fR(5).
194 /* .IP "\fBpgsql\fR (read-only)"
195 /*	Perform lookups using the PostgreSQL protocol. This is described
196 /*	in \fBpgsql_table\fR(5).
197 /* .IP "\fBproxy\fR"
198 /*	A lookup table that is implemented via the Postfix
199 /*	\fBproxymap\fR(8) service. The table name syntax is
200 /*	\fItype\fB:\fIname\fR.
201 /* .IP "\fBregexp\fR (read-only)"
202 /*	A lookup table based on regular expressions. The file format is
203 /*	described in \fBregexp_table\fR(5).
204 /* .IP \fBsdbm\fR
205 /*	An indexed file type based on hashing.
206 /*	This is available on systems with support for SDBM databases.
207 /* .IP "\fBsocketmap\fR (read-only)"
208 /*	Query a Sendmail-style socketmap server. The name of the
209 /*	table specifies
210 /*	\fBinet\fR:\fIhost\fR:\fIport\fR:\fIsocketmap-name\fR for
211 /*	a TCP-based server, or
212 /*	\fBunix\fR:\fIpathname\fR:\fIsocketmap-name\fR for a
213 /*	UNIX-domain server. In both cases, \fIsocketmap-name\fR is
214 /*	the name of the socketmap.
215 /* .IP "\fBsqlite\fR (read-only)"
216 /*	Perform lookups from SQLite database files. This is described
217 /*	in \fBsqlite_table\fR(5).
218 /* .IP "\fBstatic\fR (read-only)"
219 /*	A table that always returns its name as lookup result. For example,
220 /*	\fBstatic:foobar\fR always returns the string \fBfoobar\fR as lookup
221 /*	result.
222 /* .IP "\fBtcp\fR (read-only)"
223 /*	Perform lookups using a simple request-reply protocol that is
224 /*	described in \fBtcp_table\fR(5).
225 /* .IP "\fBtexthash\fR (read-only)"
226 /*	Produces similar results as hash: files, except that you don't
227 /*	need to run the \fBpostmap\fR(1) command before you can use the file,
228 /*	and that it does not detect changes after the file is read.
229 /* .IP "\fBunix\fR (read-only)"
230 /*	A limited way to query the UNIX authentication database. The
231 /*	following tables are implemented:
232 /* .RS
233 /*. IP \fBunix:passwd.byname\fR
234 /*	The table is the UNIX password database. The key is a login name.
235 /*	The result is a password file entry in \fBpasswd\fR(5) format.
236 /* .IP \fBunix:group.byname\fR
237 /*	The table is the UNIX group database. The key is a group name.
238 /*	The result is a group file entry in \fBgroup\fR(5) format.
239 /* .RE
240 /* .RE
241 /* .IP
242 /*	Other table types may exist depending on how Postfix was built.
243 /* .IP \fB-M\fR
244 /*	Show \fBmaster.cf\fR file contents instead of \fBmain.cf\fR
245 /*	file contents.
246 /*	Specify \fB-Mf\fR to fold long lines for human readability.
247 /*
248 /*	If \fIservice ...\fR is specified, only the matching services
249 /*	will be output. For example, "\fBpostconf -Mf inet\fR"
250 /*	will output all services that listen on the network.
251 /*
252 /*	Specify zero or more arguments, each with a \fIservice-type\fR
253 /*	name (\fBinet\fR, \fBunix\fR, \fBfifo\fR, or \fBpass\fR)
254 /*	or with a \fIservice-name.service-type\fR pair, where
255 /*	\fIservice-name\fR is the first field of a master.cf entry.
256 /*
257 /*	This feature is available with Postfix 2.9 and later.
258 /* .IP \fB-n\fR
259 /*	Show only configuration parameters that have explicit
260 /*	\fIname=value\fR settings in \fBmain.cf\fR.
261 /*	Specify \fB-nf\fR to fold long lines for human readability
262 /*	(Postfix 2.9 and later).
263 /* .IP "\fB-o \fIname=value\fR"
264 /*	Override \fBmain.cf\fR parameter settings.
265 /*
266 /*	This feature is available with Postfix 2.10 and later.
267 /* .IP "\fB-t\fR [\fItemplate_file\fR]"
268 /*	Display the templates for text that appears at the beginning
269 /*	of delivery status notification (DSN) messages, without
270 /*	expanding $\fBname\fR expressions.
271 /*
272 /*	To override the built-in templates, specify a template file
273 /*	name at the end of the \fBpostconf\fR(1) command line, or
274 /*	specify a file name in \fBmain.cf\fR with the
275 /*	\fBbounce_template_file\fR parameter.
276 /*
277 /*	To force selection of the built-in templates, specify an
278 /*	empty template file name on the \fBpostconf\fR(1) command
279 /*	line (in shell language: "").
280 /*
281 /*	This feature is available with Postfix 2.3 and later.
282 /* .IP \fB-v\fR
283 /*	Enable verbose logging for debugging purposes. Multiple \fB-v\fR
284 /*	options make the software increasingly verbose.
285 /* .IP \fB-x\fR
286 /*	Expand \fI$name\fR in \fBmain.cf\fR or \fBmaster.cf\fR
287 /*	parameter values. The expansion is recursive.
288 /*
289 /*	This feature is available with Postfix 2.10 and later.
290 /* .IP \fB-X\fR
291 /*	Edit the \fBmain.cf\fR configuration file, and remove
292 /*	the parameters named on the \fBpostconf\fR(1) command line.
293 /*	The file is copied to a temporary file then renamed into
294 /*	place.
295 /*	Specify a list of parameter names, not "\fIname=value\fR"
296 /*	pairs.  There is no \fBpostconf\fR(1) command to perform
297 /*	the reverse operation.
298 /*
299 /*	This feature is available with Postfix 2.10 and later.
300 /* .IP \fB-#\fR
301 /*	Edit the \fBmain.cf\fR configuration file, and comment out
302 /*	the parameters named on the \fBpostconf\fR(1) command line,
303 /*	so that those parameters revert to their default values.
304 /*	The file is copied to a temporary file then renamed into
305 /*	place.
306 /*	Specify a list of parameter names, not "\fIname=value\fR"
307 /*	pairs.  There is no \fBpostconf\fR(1) command to perform
308 /*	the reverse operation.
309 /*
310 /*	This feature is available with Postfix 2.6 and later.
311 /* DIAGNOSTICS
312 /*	Problems are reported to the standard error stream.
313 /* ENVIRONMENT
314 /* .ad
315 /* .fi
316 /* .IP \fBMAIL_CONFIG\fR
317 /*	Directory with Postfix configuration files.
318 /* CONFIGURATION PARAMETERS
319 /* .ad
320 /* .fi
321 /*	The following \fBmain.cf\fR parameters are especially relevant to
322 /*	this program.
323 /*
324 /*	The text below provides only a parameter summary. See
325 /*	\fBpostconf\fR(5) for more details including examples.
326 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
327 /*	The default location of the Postfix main.cf and master.cf
328 /*	configuration files.
329 /* .IP "\fBbounce_template_file (empty)\fR"
330 /*	Pathname of a configuration file with bounce message templates.
331 /* FILES
332 /*	/etc/postfix/main.cf, Postfix configuration parameters
333 /*	/etc/postfix/master.cf, Postfix master daemon configuraton
334 /* SEE ALSO
335 /*	bounce(5), bounce template file format
336 /*	master(5), master.cf configuration file syntax
337 /*	postconf(5), main.cf configuration file syntax
338 /* README FILES
339 /* .ad
340 /* .fi
341 /*	Use "\fBpostconf readme_directory\fR" or
342 /*	"\fBpostconf html_directory\fR" to locate this information.
343 /* .na
344 /* .nf
345 /*	DATABASE_README, Postfix lookup table overview
346 /* LICENSE
347 /* .ad
348 /* .fi
349 /*	The Secure Mailer license must be distributed with this software.
350 /* AUTHOR(S)
351 /*	Wietse Venema
352 /*	IBM T.J. Watson Research
353 /*	P.O. Box 704
354 /*	Yorktown Heights, NY 10598, USA
355 /*--*/
356 
357 /* System library. */
358 
359 #include <sys_defs.h>
360 #include <sys/stat.h>
361 #include <stdlib.h>
362 
363 /* Utility library. */
364 
365 #include <msg.h>
366 #include <msg_vstream.h>
367 #include <dict.h>
368 #include <htable.h>
369 #include <vstring.h>
370 #include <vstream.h>
371 #include <stringops.h>
372 #include <name_mask.h>
373 #include <warn_stat.h>
374 #include <mymalloc.h>
375 
376 /* Global library. */
377 
378 #include <mail_params.h>
379 #include <mail_conf.h>
380 #include <mail_version.h>
381 #include <mail_run.h>
382 #include <mail_dict.h>
383 
384 /* Application-specific. */
385 
386 #include <postconf.h>
387 
388  /*
389   * Global storage. See postconf.h for description.
390   */
391 PC_PARAM_TABLE *param_table;
392 PC_MASTER_ENT *master_table;
393 int     cmd_mode = DEF_MODE;
394 
395  /*
396   * Application fingerprinting.
397   */
398 MAIL_VERSION_STAMP_DECLARE;
399 
400 /* main */
401 
402 int     main(int argc, char **argv)
403 {
404     int     ch;
405     int     fd;
406     struct stat st;
407     int     junk;
408     ARGV   *ext_argv = 0;
409     int     param_class = PC_PARAM_MASK_CLASS;
410     static const NAME_MASK param_class_table[] = {
411 	"builtin", PC_PARAM_FLAG_BUILTIN,
412 	"service", PC_PARAM_FLAG_SERVICE,
413 	"user", PC_PARAM_FLAG_USER,
414 	"all", PC_PARAM_MASK_CLASS,
415 	0,
416     };
417     ARGV   *override_params = 0;
418 
419     /*
420      * Fingerprint executables and core dumps.
421      */
422     MAIL_VERSION_STAMP_ALLOCATE;
423 
424     /*
425      * Be consistent with file permissions.
426      */
427     umask(022);
428 
429     /*
430      * To minimize confusion, make sure that the standard file descriptors
431      * are open before opening anything else. XXX Work around for 44BSD where
432      * fstat can return EBADF on an open file descriptor.
433      */
434     for (fd = 0; fd < 3; fd++)
435 	if (fstat(fd, &st) == -1
436 	    && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
437 	    msg_fatal("open /dev/null: %m");
438 
439     /*
440      * Set up logging.
441      */
442     msg_vstream_init(argv[0], VSTREAM_ERR);
443 
444     /*
445      * Parse JCL.
446      */
447     while ((ch = GETOPT(argc, argv, "aAbc:C:deEf#hlmMno:tvxX")) > 0) {
448 	switch (ch) {
449 	case 'a':
450 	    cmd_mode |= SHOW_SASL_SERV;
451 	    break;
452 	case 'A':
453 	    cmd_mode |= SHOW_SASL_CLNT;
454 	    break;
455 	case 'b':
456 	    if (ext_argv)
457 		msg_fatal("specify one of -b and -t");
458 	    ext_argv = argv_alloc(2);
459 	    argv_add(ext_argv, "bounce", "-SVnexpand_templates", (char *) 0);
460 	    break;
461 	case 'c':
462 	    if (setenv(CONF_ENV_PATH, optarg, 1) < 0)
463 		msg_fatal("out of memory");
464 	    break;
465 	case 'C':
466 	    param_class = name_mask_opt("-C option", param_class_table,
467 			      optarg, NAME_MASK_ANY_CASE | NAME_MASK_FATAL);
468 	    break;
469 	case 'd':
470 	    cmd_mode |= SHOW_DEFS;
471 	    break;
472 	case 'e':
473 	    cmd_mode |= EDIT_MAIN;
474 	    break;
475 	case 'f':
476 	    cmd_mode |= FOLD_LINE;
477 	    break;
478 	case '#':
479 	    cmd_mode |= COMMENT_OUT;
480 	    break;
481 	case 'h':
482 	    cmd_mode &= ~SHOW_NAME;
483 	    break;
484 	case 'l':
485 	    cmd_mode |= SHOW_LOCKS;
486 	    break;
487 	case 'm':
488 	    cmd_mode |= SHOW_MAPS;
489 	    break;
490 	case 'M':
491 	    cmd_mode |= SHOW_MASTER;
492 	    break;
493 	case 'n':
494 	    cmd_mode |= SHOW_NONDEF;
495 	    break;
496 	case 'o':
497 	    if (override_params == 0)
498 		override_params = argv_alloc(2);
499 	    argv_add(override_params, optarg, (char *) 0);
500 	    break;
501 	case 't':
502 	    if (ext_argv)
503 		msg_fatal("specify one of -b and -t");
504 	    ext_argv = argv_alloc(2);
505 	    argv_add(ext_argv, "bounce", "-SVndump_templates", (char *) 0);
506 	    break;
507 	case 'x':
508 	    cmd_mode |= SHOW_EVAL;
509 	    break;
510 	case 'X':
511 	    /* This is irreversible, therefore require two-finger action. */
512 	    cmd_mode |= EDIT_EXCL;
513 	    break;
514 	case 'v':
515 	    msg_verbose++;
516 	    break;
517 	default:
518 	    msg_fatal("usage: %s [-a (server SASL types)] [-A (client SASL types)] [-b (bounce templates)] [-c config_dir] [-C param_class] [-d (defaults)] [-e (edit)] [-f (fold lines)] [-# (comment-out)] [-h (no names)] [-l (lock types)] [-m (map types)] [-M (master.cf)] [-n (non-defaults)] [-v] [-X (exclude)] [name...]", argv[0]);
519 	}
520     }
521 
522     /*
523      * Sanity check.
524      */
525     junk = (cmd_mode & (SHOW_DEFS | SHOW_MAPS | SHOW_LOCKS | EDIT_MAIN | SHOW_SASL_SERV | SHOW_SASL_CLNT | COMMENT_OUT | SHOW_MASTER | EDIT_EXCL));
526     if (junk != 0 && ((junk != SHOW_DEFS
527 	     && junk != SHOW_MAPS && junk != SHOW_LOCKS && junk != EDIT_MAIN
528 		       && junk != SHOW_SASL_SERV && junk != SHOW_SASL_CLNT
529 		       && junk != COMMENT_OUT && junk != SHOW_MASTER
530 		       && junk != EDIT_EXCL)
531 		      || ext_argv != 0))
532 	msg_fatal("specify one of -a, -A, -b, -d, -e, -#, -l, -m, -M, and -X");
533     if ((cmd_mode & SHOW_EVAL) != 0 && junk != 0 && junk != SHOW_DEFS && junk != SHOW_MASTER)
534 	msg_fatal("do not specify -x with -a, -A, -b, -e, -#, -l, -m, or -X");
535     if ((cmd_mode & SHOW_NONDEF) != 0 && junk != 0)
536 	msg_fatal("do not specify -n with -a, -A, -b, -d, -e, -#, -l, -m, -M, or -X");
537     if (override_params != 0 && junk != 0 && junk != SHOW_MASTER)
538 	msg_fatal("do not specify -o with -a, -A, -b, -d, -e, -#, -l, -m, or -X");
539 
540     /*
541      * Display bounce template information and exit.
542      */
543     if (ext_argv) {
544 	if (argv[optind]) {
545 	    if (argv[optind + 1])
546 		msg_fatal("options -b and -t require at most one template file");
547 	    argv_add(ext_argv, "-o",
548 		     concatenate(VAR_BOUNCE_TMPL, "=",
549 				 argv[optind], (char *) 0),
550 		     (char *) 0);
551 	}
552 	/* Grr... */
553 	argv_add(ext_argv, "-o",
554 		 concatenate(VAR_QUEUE_DIR, "=", ".", (char *) 0),
555 		 (char *) 0);
556 	mail_conf_read();
557 	mail_run_replace(var_daemon_dir, ext_argv->argv);
558 	/* NOTREACHED */
559     }
560 
561     /*
562      * If showing map types, show them and exit
563      */
564     if (cmd_mode & SHOW_MAPS) {
565 	mail_dict_init();
566 	show_maps();
567     }
568 
569     /*
570      * If showing locking methods, show them and exit
571      */
572     else if (cmd_mode & SHOW_LOCKS) {
573 	show_locks();
574     }
575 
576     /*
577      * If showing master.cf entries, show them and exit
578      */
579     else if (cmd_mode & SHOW_MASTER) {
580 	read_master(FAIL_ON_OPEN_ERROR);
581 	read_parameters();
582 	if (override_params)
583 	    set_parameters(override_params->argv);
584 	register_builtin_parameters(basename(argv[0]), getpid());
585 	register_service_parameters();
586 	register_user_parameters();
587 	show_master(VSTREAM_OUT, cmd_mode, argv + optind);
588     }
589 
590     /*
591      * If showing SASL plug-in types, show them and exit
592      */
593     else if (cmd_mode & SHOW_SASL_SERV) {
594 	show_sasl(SHOW_SASL_SERV);
595     } else if (cmd_mode & SHOW_SASL_CLNT) {
596 	show_sasl(SHOW_SASL_CLNT);
597     }
598 
599     /*
600      * Edit main.cf.
601      */
602     else if (cmd_mode & (EDIT_MAIN | COMMENT_OUT | EDIT_EXCL)) {
603 	edit_parameters(cmd_mode, argc - optind, argv + optind);
604     } else if (cmd_mode == DEF_MODE
605 	       && argv[optind] && strchr(argv[optind], '=')) {
606 	edit_parameters(cmd_mode | EDIT_MAIN, argc - optind, argv + optind);
607     }
608 
609     /*
610      * If showing non-default values, read main.cf.
611      */
612     else {
613 	if ((cmd_mode & SHOW_DEFS) == 0) {
614 	    read_parameters();
615 	    if (override_params)
616 		set_parameters(override_params->argv);
617 	}
618 	register_builtin_parameters(basename(argv[0]), getpid());
619 
620 	/*
621 	 * Add service-dependent parameters (service names from master.cf)
622 	 * and user-defined parameters ($name macros in parameter values in
623 	 * main.cf and master.cf, but only if those names have a name=value
624 	 * in main.cf or master.cf).
625 	 */
626 	read_master(WARN_ON_OPEN_ERROR);
627 	register_service_parameters();
628 	if ((cmd_mode & SHOW_DEFS) == 0)
629 	    register_user_parameters();
630 
631 	/*
632 	 * Show the requested values.
633 	 */
634 	show_parameters(VSTREAM_OUT, cmd_mode, param_class, argv + optind);
635 
636 	/*
637 	 * Flag unused parameters. This makes no sense with "postconf -d",
638 	 * because that ignores all the user-specified parameters and
639 	 * user-specified macro expansions in main.cf.
640 	 */
641 	if ((cmd_mode & SHOW_DEFS) == 0) {
642 	    flag_unused_main_parameters();
643 	    flag_unused_master_parameters();
644 	}
645     }
646     vstream_fflush(VSTREAM_OUT);
647     exit(0);
648 }
649