1 /*	$NetBSD: cleanup.c,v 1.3 2010/06/17 18:18:15 tron Exp $	*/
2 
3 /*++
4 /* NAME
5 /*	cleanup 8
6 /* SUMMARY
7 /*	canonicalize and enqueue Postfix message
8 /* SYNOPSIS
9 /*	\fBcleanup\fR [generic Postfix daemon options]
10 /* DESCRIPTION
11 /*	The \fBcleanup\fR(8) daemon processes inbound mail, inserts it
12 /*	into the \fBincoming\fR mail queue, and informs the queue
13 /*	manager of its arrival.
14 /*
15 /*	The \fBcleanup\fR(8) daemon always performs the following transformations:
16 /* .IP \(bu
17 /*	Insert missing message headers: (\fBResent-\fR) \fBFrom:\fR,
18 /*	\fBTo:\fR, \fBMessage-Id:\fR, and \fBDate:\fR.
19 /* .IP \(bu
20 /*	Transform envelope and header addresses to the standard
21 /*	\fIuser@fully-qualified-domain\fR form that is expected by other
22 /*	Postfix programs.
23 /*	This task is delegated to the \fBtrivial-rewrite\fR(8) daemon.
24 /* .IP \(bu
25 /*	Eliminate duplicate envelope recipient addresses.
26 /* .PP
27 /*	The following address transformations are optional:
28 /* .IP \(bu
29 /*	Optionally, rewrite all envelope and header addresses according
30 /*	to the mappings specified in the \fBcanonical\fR(5) lookup tables.
31 /* .IP \(bu
32 /*	Optionally, masquerade envelope sender addresses and message
33 /*	header addresses (i.e. strip host or domain information below
34 /*	all domains listed in the \fBmasquerade_domains\fR parameter,
35 /*	except for user names listed in \fBmasquerade_exceptions\fR).
36 /*	By default, address masquerading does not affect envelope recipients.
37 /* .IP \(bu
38 /*	Optionally, expand envelope recipients according to information
39 /*	found in the \fBvirtual\fR(5) lookup tables.
40 /* .PP
41 /*	The \fBcleanup\fR(8) daemon performs sanity checks on the content of
42 /*	each message. When it finds a problem, by default it returns a
43 /*	diagnostic status to the client, and leaves it up to the client
44 /*	to deal with the problem. Alternatively, the client can request
45 /*	the \fBcleanup\fR(8) daemon to bounce the message back to the sender
46 /*	in case of trouble.
47 /* STANDARDS
48 /*	RFC 822 (ARPA Internet Text Messages)
49 /*	RFC 2045 (MIME: Format of Internet Message Bodies)
50 /*	RFC 2046 (MIME: Media Types)
51 /*	RFC 2822 (Internet Message Format)
52 /*	RFC 3463 (Enhanced Status Codes)
53 /*	RFC 3464 (Delivery status notifications)
54 /*	RFC 5322 (Internet Message Format)
55 /* DIAGNOSTICS
56 /*	Problems and transactions are logged to \fBsyslogd\fR(8).
57 /* BUGS
58 /*	Table-driven rewriting rules make it hard to express \fBif then
59 /*	else\fR and other logical relationships.
60 /* CONFIGURATION PARAMETERS
61 /* .ad
62 /* .fi
63 /*	Changes to \fBmain.cf\fR are picked up automatically, as
64 /*	\fBcleanup\fR(8)
65 /*	processes run for only a limited amount of time. Use the command
66 /*	"\fBpostfix reload\fR" to speed up a change.
67 /*
68 /*	The text below provides only a parameter summary. See
69 /*	\fBpostconf\fR(5) for more details including examples.
70 /* COMPATIBILITY CONTROLS
71 /* .ad
72 /* .fi
73 /* .IP "\fBundisclosed_recipients_header (To: undisclosed-recipients:;)\fR"
74 /*	Message header that the Postfix \fBcleanup\fR(8) server inserts when a
75 /*	message contains no To: or Cc: message header.
76 /* .PP
77 /*	Available in Postfix version 2.1 only:
78 /* .IP "\fBenable_errors_to (no)\fR"
79 /*	Report mail delivery errors to the address specified with the
80 /*	non-standard Errors-To: message header, instead of the envelope
81 /*	sender address (this feature is removed with Postfix version 2.2, is
82 /*	turned off by default with Postfix version 2.1, and is always turned on
83 /*	with older Postfix versions).
84 /* .PP
85 /*	Available in Postfix version 2.6 and later:
86 /* .IP "\fBalways_add_missing_headers (no)\fR"
87 /*	Always add (Resent-) From:, To:, Date: or Message-ID: headers
88 /*	when not present.
89 /* BUILT-IN CONTENT FILTERING CONTROLS
90 /* .ad
91 /* .fi
92 /*	Postfix built-in content filtering is meant to stop a flood of
93 /*	worms or viruses. It is not a general content filter.
94 /* .IP "\fBbody_checks (empty)\fR"
95 /*	Optional lookup tables for content inspection as specified in
96 /*	the \fBbody_checks\fR(5) manual page.
97 /* .IP "\fBheader_checks (empty)\fR"
98 /*	Optional lookup tables for content inspection of primary non-MIME
99 /*	message headers, as specified in the \fBheader_checks\fR(5) manual page.
100 /* .PP
101 /*	Available in Postfix version 2.0 and later:
102 /* .IP "\fBbody_checks_size_limit (51200)\fR"
103 /*	How much text in a message body segment (or attachment, if you
104 /*	prefer to use that term) is subjected to body_checks inspection.
105 /* .IP "\fBmime_header_checks ($header_checks)\fR"
106 /*	Optional lookup tables for content inspection of MIME related
107 /*	message headers, as described in the \fBheader_checks\fR(5) manual page.
108 /* .IP "\fBnested_header_checks ($header_checks)\fR"
109 /*	Optional lookup tables for content inspection of non-MIME message
110 /*	headers in attached messages, as described in the \fBheader_checks\fR(5)
111 /*	manual page.
112 /* .PP
113 /*	Available in Postfix version 2.3 and later:
114 /* .IP "\fBmessage_reject_characters (empty)\fR"
115 /*	The set of characters that Postfix will reject in message
116 /*	content.
117 /* .IP "\fBmessage_strip_characters (empty)\fR"
118 /*	The set of characters that Postfix will remove from message
119 /*	content.
120 /* BEFORE QUEUE MILTER CONTROLS
121 /* .ad
122 /* .fi
123 /*	As of version 2.3, Postfix supports the Sendmail version 8
124 /*	Milter (mail filter) protocol. When mail is not received via
125 /*	the smtpd(8) server, the cleanup(8) server will simulate
126 /*	SMTP events to the extent that this is possible. For details
127 /*	see the MILTER_README document.
128 /* .IP "\fBnon_smtpd_milters (empty)\fR"
129 /*	A list of Milter (mail filter) applications for new mail that
130 /*	does not arrive via the Postfix \fBsmtpd\fR(8) server.
131 /* .IP "\fBmilter_protocol (6)\fR"
132 /*	The mail filter protocol version and optional protocol extensions
133 /*	for communication with a Milter application; prior to Postfix 2.6
134 /*	the default protocol is 2.
135 /* .IP "\fBmilter_default_action (tempfail)\fR"
136 /*	The default action when a Milter (mail filter) application is
137 /*	unavailable or mis-configured.
138 /* .IP "\fBmilter_macro_daemon_name ($myhostname)\fR"
139 /*	The {daemon_name} macro value for Milter (mail filter) applications.
140 /* .IP "\fBmilter_macro_v ($mail_name $mail_version)\fR"
141 /*	The {v} macro value for Milter (mail filter) applications.
142 /* .IP "\fBmilter_connect_timeout (30s)\fR"
143 /*	The time limit for connecting to a Milter (mail filter)
144 /*	application, and for negotiating protocol options.
145 /* .IP "\fBmilter_command_timeout (30s)\fR"
146 /*	The time limit for sending an SMTP command to a Milter (mail
147 /*	filter) application, and for receiving the response.
148 /* .IP "\fBmilter_content_timeout (300s)\fR"
149 /*	The time limit for sending message content to a Milter (mail
150 /*	filter) application, and for receiving the response.
151 /* .IP "\fBmilter_connect_macros (see 'postconf -d' output)\fR"
152 /*	The macros that are sent to Milter (mail filter) applications
153 /*	after completion of an SMTP connection.
154 /* .IP "\fBmilter_helo_macros (see 'postconf -d' output)\fR"
155 /*	The macros that are sent to Milter (mail filter) applications
156 /*	after the SMTP HELO or EHLO command.
157 /* .IP "\fBmilter_mail_macros (see 'postconf -d' output)\fR"
158 /*	The macros that are sent to Milter (mail filter) applications
159 /*	after the SMTP MAIL FROM command.
160 /* .IP "\fBmilter_rcpt_macros (see 'postconf -d' output)\fR"
161 /*	The macros that are sent to Milter (mail filter) applications
162 /*	after the SMTP RCPT TO command.
163 /* .IP "\fBmilter_data_macros (see 'postconf -d' output)\fR"
164 /*	The macros that are sent to version 4 or higher Milter (mail
165 /*	filter) applications after the SMTP DATA command.
166 /* .IP "\fBmilter_unknown_command_macros (see 'postconf -d' output)\fR"
167 /*	The macros that are sent to version 3 or higher Milter (mail
168 /*	filter) applications after an unknown SMTP command.
169 /* .IP "\fBmilter_end_of_data_macros (see 'postconf -d' output)\fR"
170 /*	The macros that are sent to Milter (mail filter) applications
171 /*	after the message end-of-data.
172 /* .PP
173 /*	Available in Postfix version 2.5 and later:
174 /* .IP "\fBmilter_end_of_header_macros (see 'postconf -d' output)\fR"
175 /*	The macros that are sent to Milter (mail filter) applications
176 /*	after the end of the message header.
177 /* .PP
178 /*	Available in Postfix version 2.7 and later:
179 /* .IP "\fBmilter_header_checks (empty)\fR"
180 /*	Optional lookup tables for content inspection of message headers
181 /*	that are produced by Milter applications.
182 /* MIME PROCESSING CONTROLS
183 /* .ad
184 /* .fi
185 /*	Available in Postfix version 2.0 and later:
186 /* .IP "\fBdisable_mime_input_processing (no)\fR"
187 /*	Turn off MIME processing while receiving mail.
188 /* .IP "\fBmime_boundary_length_limit (2048)\fR"
189 /*	The maximal length of MIME multipart boundary strings.
190 /* .IP "\fBmime_nesting_limit (100)\fR"
191 /*	The maximal recursion level that the MIME processor will handle.
192 /* .IP "\fBstrict_8bitmime (no)\fR"
193 /*	Enable both strict_7bit_headers and strict_8bitmime_body.
194 /* .IP "\fBstrict_7bit_headers (no)\fR"
195 /*	Reject mail with 8-bit text in message headers.
196 /* .IP "\fBstrict_8bitmime_body (no)\fR"
197 /*	Reject 8-bit message body text without 8-bit MIME content encoding
198 /*	information.
199 /* .IP "\fBstrict_mime_encoding_domain (no)\fR"
200 /*	Reject mail with invalid Content-Transfer-Encoding: information
201 /*	for the message/* or multipart/* MIME content types.
202 /* .PP
203 /*	Available in Postfix version 2.5 and later:
204 /* .IP "\fBdetect_8bit_encoding_header (yes)\fR"
205 /*	Automatically detect 8BITMIME body content by looking at
206 /*	Content-Transfer-Encoding: message headers; historically, this
207 /*	behavior was hard-coded to be "always on".
208 /* AUTOMATIC BCC RECIPIENT CONTROLS
209 /* .ad
210 /* .fi
211 /*	Postfix can automatically add BCC (blind carbon copy)
212 /*	when mail enters the mail system:
213 /* .IP "\fBalways_bcc (empty)\fR"
214 /*	Optional address that receives a "blind carbon copy" of each message
215 /*	that is received by the Postfix mail system.
216 /* .PP
217 /*	Available in Postfix version 2.1 and later:
218 /* .IP "\fBsender_bcc_maps (empty)\fR"
219 /*	Optional BCC (blind carbon-copy) address lookup tables, indexed
220 /*	by sender address.
221 /* .IP "\fBrecipient_bcc_maps (empty)\fR"
222 /*	Optional BCC (blind carbon-copy) address lookup tables, indexed by
223 /*	recipient address.
224 /* ADDRESS TRANSFORMATION CONTROLS
225 /* .ad
226 /* .fi
227 /*	Address rewriting is delegated to the \fBtrivial-rewrite\fR(8) daemon.
228 /*	The \fBcleanup\fR(8) server implements table driven address mapping.
229 /* .IP "\fBempty_address_recipient (MAILER-DAEMON)\fR"
230 /*	The recipient of mail addressed to the null address.
231 /* .IP "\fBcanonical_maps (empty)\fR"
232 /*	Optional address mapping lookup tables for message headers and
233 /*	envelopes.
234 /* .IP "\fBrecipient_canonical_maps (empty)\fR"
235 /*	Optional address mapping lookup tables for envelope and header
236 /*	recipient addresses.
237 /* .IP "\fBsender_canonical_maps (empty)\fR"
238 /*	Optional address mapping lookup tables for envelope and header
239 /*	sender addresses.
240 /* .IP "\fBmasquerade_classes (envelope_sender, header_sender, header_recipient)\fR"
241 /*	What addresses are subject to address masquerading.
242 /* .IP "\fBmasquerade_domains (empty)\fR"
243 /*	Optional list of domains whose subdomain structure will be stripped
244 /*	off in email addresses.
245 /* .IP "\fBmasquerade_exceptions (empty)\fR"
246 /*	Optional list of user names that are not subjected to address
247 /*	masquerading, even when their address matches $masquerade_domains.
248 /* .IP "\fBpropagate_unmatched_extensions (canonical, virtual)\fR"
249 /*	What address lookup tables copy an address extension from the lookup
250 /*	key to the lookup result.
251 /* .PP
252 /*	Available before Postfix version 2.0:
253 /* .IP "\fBvirtual_maps (empty)\fR"
254 /*	Optional lookup tables with a) names of domains for which all
255 /*	addresses are aliased to addresses in other local or remote domains,
256 /*	and b) addresses that are aliased to addresses in other local or
257 /*	remote domains.
258 /* .PP
259 /*	Available in Postfix version 2.0 and later:
260 /* .IP "\fBvirtual_alias_maps ($virtual_maps)\fR"
261 /*	Optional lookup tables that alias specific mail addresses or domains
262 /*	to other local or remote address.
263 /* .PP
264 /*	Available in Postfix version 2.2 and later:
265 /* .IP "\fBcanonical_classes (envelope_sender, envelope_recipient, header_sender, header_recipient)\fR"
266 /*	What addresses are subject to canonical_maps address mapping.
267 /* .IP "\fBrecipient_canonical_classes (envelope_recipient, header_recipient)\fR"
268 /*	What addresses are subject to recipient_canonical_maps address
269 /*	mapping.
270 /* .IP "\fBsender_canonical_classes (envelope_sender, header_sender)\fR"
271 /*	What addresses are subject to sender_canonical_maps address
272 /*	mapping.
273 /* .IP "\fBremote_header_rewrite_domain (empty)\fR"
274 /*	Don't rewrite message headers from remote clients at all when
275 /*	this parameter is empty; otherwise, rewrite message headers and
276 /*	append the specified domain name to incomplete addresses.
277 /* RESOURCE AND RATE CONTROLS
278 /* .ad
279 /* .fi
280 /* .IP "\fBduplicate_filter_limit (1000)\fR"
281 /*	The maximal number of addresses remembered by the address
282 /*	duplicate filter for \fBaliases\fR(5) or \fBvirtual\fR(5) alias expansion, or
283 /*	for \fBshowq\fR(8) queue displays.
284 /* .IP "\fBheader_size_limit (102400)\fR"
285 /*	The maximal amount of memory in bytes for storing a message header.
286 /* .IP "\fBhopcount_limit (50)\fR"
287 /*	The maximal number of Received:  message headers that is allowed
288 /*	in the primary message headers.
289 /* .IP "\fBin_flow_delay (1s)\fR"
290 /*	Time to pause before accepting a new message, when the message
291 /*	arrival rate exceeds the message delivery rate.
292 /* .IP "\fBmessage_size_limit (10240000)\fR"
293 /*	The maximal size in bytes of a message, including envelope information.
294 /* .PP
295 /*	Available in Postfix version 2.0 and later:
296 /* .IP "\fBheader_address_token_limit (10240)\fR"
297 /*	The maximal number of address tokens are allowed in an address
298 /*	message header.
299 /* .IP "\fBmime_boundary_length_limit (2048)\fR"
300 /*	The maximal length of MIME multipart boundary strings.
301 /* .IP "\fBmime_nesting_limit (100)\fR"
302 /*	The maximal recursion level that the MIME processor will handle.
303 /* .IP "\fBqueue_file_attribute_count_limit (100)\fR"
304 /*	The maximal number of (name=value) attributes that may be stored
305 /*	in a Postfix queue file.
306 /* .PP
307 /*	Available in Postfix version 2.1 and later:
308 /* .IP "\fBvirtual_alias_expansion_limit (1000)\fR"
309 /*	The maximal number of addresses that virtual alias expansion produces
310 /*	from each original recipient.
311 /* .IP "\fBvirtual_alias_recursion_limit (1000)\fR"
312 /*	The maximal nesting depth of virtual alias expansion.
313 /* MISCELLANEOUS CONTROLS
314 /* .ad
315 /* .fi
316 /* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
317 /*	The default location of the Postfix main.cf and master.cf
318 /*	configuration files.
319 /* .IP "\fBdaemon_timeout (18000s)\fR"
320 /*	How much time a Postfix daemon process may take to handle a
321 /*	request before it is terminated by a built-in watchdog timer.
322 /* .IP "\fBdelay_logging_resolution_limit (2)\fR"
323 /*	The maximal number of digits after the decimal point when logging
324 /*	sub-second delay values.
325 /* .IP "\fBdelay_warning_time (0h)\fR"
326 /*	The time after which the sender receives the message headers of
327 /*	mail that is still queued.
328 /* .IP "\fBipc_timeout (3600s)\fR"
329 /*	The time limit for sending or receiving information over an internal
330 /*	communication channel.
331 /* .IP "\fBmax_idle (100s)\fR"
332 /*	The maximum amount of time that an idle Postfix daemon process waits
333 /*	for an incoming connection before terminating voluntarily.
334 /* .IP "\fBmax_use (100)\fR"
335 /*	The maximal number of incoming connections that a Postfix daemon
336 /*	process will service before terminating voluntarily.
337 /* .IP "\fBmyhostname (see 'postconf -d' output)\fR"
338 /*	The internet hostname of this mail system.
339 /* .IP "\fBmyorigin ($myhostname)\fR"
340 /*	The domain name that locally-posted mail appears to come
341 /*	from, and that locally posted mail is delivered to.
342 /* .IP "\fBprocess_id (read-only)\fR"
343 /*	The process ID of a Postfix command or daemon process.
344 /* .IP "\fBprocess_name (read-only)\fR"
345 /*	The process name of a Postfix command or daemon process.
346 /* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
347 /*	The location of the Postfix top-level queue directory.
348 /* .IP "\fBsoft_bounce (no)\fR"
349 /*	Safety net to keep mail queued that would otherwise be returned to
350 /*	the sender.
351 /* .IP "\fBsyslog_facility (mail)\fR"
352 /*	The syslog facility of Postfix logging.
353 /* .IP "\fBsyslog_name (see 'postconf -d' output)\fR"
354 /*	The mail system name that is prepended to the process name in syslog
355 /*	records, so that "smtpd" becomes, for example, "postfix/smtpd".
356 /* .PP
357 /*	Available in Postfix version 2.1 and later:
358 /* .IP "\fBenable_original_recipient (yes)\fR"
359 /*	Enable support for the X-Original-To message header.
360 /* FILES
361 /*	/etc/postfix/canonical*, canonical mapping table
362 /*	/etc/postfix/virtual*, virtual mapping table
363 /* SEE ALSO
364 /*	trivial-rewrite(8), address rewriting
365 /*	qmgr(8), queue manager
366 /*	header_checks(5), message header content inspection
367 /*	body_checks(5), body parts content inspection
368 /*	canonical(5), canonical address lookup table format
369 /*	virtual(5), virtual alias lookup table format
370 /*	postconf(5), configuration parameters
371 /*	master(5), generic daemon options
372 /*	master(8), process manager
373 /*	syslogd(8), system logging
374 /* README FILES
375 /* .ad
376 /* .fi
377 /*	Use "\fBpostconf readme_directory\fR" or
378 /*	"\fBpostconf html_directory\fR" to locate this information.
379 /* .na
380 /* .nf
381 /*	ADDRESS_REWRITING_README Postfix address manipulation
382 /*	CONTENT_INSPECTION_README content inspection
383 /* LICENSE
384 /* .ad
385 /* .fi
386 /*	The Secure Mailer license must be distributed with this software.
387 /* AUTHOR(S)
388 /*	Wietse Venema
389 /*	IBM T.J. Watson Research
390 /*	P.O. Box 704
391 /*	Yorktown Heights, NY 10598, USA
392 /*--*/
393 
394 /* System library. */
395 
396 #include <sys_defs.h>
397 #include <signal.h>
398 #include <unistd.h>
399 #include <stdlib.h>
400 
401 /* Utility library. */
402 
403 #include <msg.h>
404 #include <vstring.h>
405 #include <dict.h>
406 
407 /* Global library. */
408 
409 #include <mail_conf.h>
410 #include <cleanup_user.h>
411 #include <mail_proto.h>
412 #include <mail_params.h>
413 #include <record.h>
414 #include <rec_type.h>
415 #include <mail_version.h>
416 
417 /* Single-threaded server skeleton. */
418 
419 #include <mail_server.h>
420 
421 /* Application-specific. */
422 
423 #include "cleanup.h"
424 
425 /* cleanup_service - process one request to inject a message into the queue */
426 
427 static void cleanup_service(VSTREAM *src, char *unused_service, char **argv)
428 {
429     VSTRING *buf = vstring_alloc(100);
430     CLEANUP_STATE *state;
431     int     flags;
432     int     type = 0;
433     int     status;
434 
435     /*
436      * Sanity check. This service takes no command-line arguments.
437      */
438     if (argv[0])
439 	msg_fatal("unexpected command-line argument: %s", argv[0]);
440 
441     /*
442      * Open a queue file and initialize state.
443      */
444     state = cleanup_open(src);
445 
446     /*
447      * Send the queue id to the client. Read client processing options. If we
448      * can't read the client processing options we can pretty much forget
449      * about the whole operation.
450      */
451     attr_print(src, ATTR_FLAG_NONE,
452 	       ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, state->queue_id,
453 	       ATTR_TYPE_END);
454     if (attr_scan(src, ATTR_FLAG_STRICT,
455 		  ATTR_TYPE_INT, MAIL_ATTR_FLAGS, &flags,
456 		  ATTR_TYPE_END) != 1) {
457 	state->errs |= CLEANUP_STAT_BAD;
458 	flags = 0;
459     }
460     cleanup_control(state, flags);
461 
462     /*
463      * XXX Rely on the front-end programs to enforce record size limits.
464      *
465      * First, copy the envelope records to the queue file. Then, copy the
466      * message content (headers and body). Finally, attach any information
467      * extracted from message headers.
468      */
469     while (CLEANUP_OUT_OK(state)) {
470 	if ((type = rec_get_raw(src, buf, 0, REC_FLAG_NONE)) < 0) {
471 	    state->errs |= CLEANUP_STAT_BAD;
472 	    break;
473 	}
474 	if (REC_GET_HIDDEN_TYPE(type)) {
475 	    msg_warn("%s: record type %d not allowed - discarding this message",
476 		     state->queue_id, type);
477 	    state->errs |= CLEANUP_STAT_BAD;
478 	    break;
479 	}
480 	CLEANUP_RECORD(state, type, vstring_str(buf), VSTRING_LEN(buf));
481 	if (type == REC_TYPE_END)
482 	    break;
483     }
484 
485     /*
486      * Keep reading in case of problems, until the sender is ready to receive
487      * our status report.
488      */
489     if (CLEANUP_OUT_OK(state) == 0 && type > 0) {
490 	while (type != REC_TYPE_END
491 	       && (type = rec_get(src, buf, 0)) > 0)
492 	     /* void */ ;
493     }
494 
495     /*
496      * Log something to make timeout errors easier to debug.
497      */
498     if (vstream_ftimeout(src))
499 	msg_warn("%s: read timeout on %s",
500 		 state->queue_id, VSTREAM_PATH(src));
501 
502     /*
503      * Finish this message, and report the result status to the client.
504      */
505     status = cleanup_flush(state);		/* in case state is modified */
506     attr_print(src, ATTR_FLAG_NONE,
507 	       ATTR_TYPE_INT, MAIL_ATTR_STATUS, status,
508 	       ATTR_TYPE_STR, MAIL_ATTR_WHY,
509 	       (state->flags & CLEANUP_FLAG_SMTP_REPLY)
510 	       && state->smtp_reply ? state->smtp_reply :
511 	       state->reason ? state->reason : "",
512 	       ATTR_TYPE_END);
513     cleanup_free(state);
514 
515     /*
516      * Cleanup.
517      */
518     vstring_free(buf);
519 }
520 
521 /* pre_accept - see if tables have changed */
522 
523 static void pre_accept(char *unused_name, char **unused_argv)
524 {
525     const char *table;
526 
527     if ((table = dict_changed_name()) != 0) {
528 	msg_info("table %s has changed -- restarting", table);
529 	exit(0);
530     }
531 }
532 
533 MAIL_VERSION_STAMP_DECLARE;
534 
535 /* main - the main program */
536 
537 int     main(int argc, char **argv)
538 {
539 
540     /*
541      * Fingerprint executables and core dumps.
542      */
543     MAIL_VERSION_STAMP_ALLOCATE;
544 
545     /*
546      * Clean up an incomplete queue file in case of a fatal run-time error,
547      * or after receiving SIGTERM from the master at shutdown time.
548      */
549     signal(SIGTERM, cleanup_sig);
550     msg_cleanup(cleanup_all);
551 
552     /*
553      * Pass control to the single-threaded service skeleton.
554      */
555     single_server_main(argc, argv, cleanup_service,
556 		       MAIL_SERVER_BOOL_TABLE, cleanup_bool_table,
557 		       MAIL_SERVER_INT_TABLE, cleanup_int_table,
558 		       MAIL_SERVER_BOOL_TABLE, cleanup_bool_table,
559 		       MAIL_SERVER_STR_TABLE, cleanup_str_table,
560 		       MAIL_SERVER_TIME_TABLE, cleanup_time_table,
561 		       MAIL_SERVER_PRE_INIT, cleanup_pre_jail,
562 		       MAIL_SERVER_POST_INIT, cleanup_post_jail,
563 		       MAIL_SERVER_PRE_ACCEPT, pre_accept,
564 		       MAIL_SERVER_IN_FLOW_DELAY,
565 		       MAIL_SERVER_UNLIMITED,
566 		       0);
567 }
568