~ubuntu-branches/ubuntu/hoary/postfix/hoary-security

« back to all changes in this revision

Viewing changes to src/bounce/bounce.c

  • Committer: Bazaar Package Importer
  • Author(s): LaMont Jones
  • Date: 2004-10-06 11:50:33 UTC
  • Revision ID: james.westby@ubuntu.com-20041006115033-ooo6yfg6kmoteu04
Tags: upstream-2.1.3
ImportĀ upstreamĀ versionĀ 2.1.3

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*++
 
2
/* NAME
 
3
/*      bounce 8
 
4
/* SUMMARY
 
5
/*      Postfix message bounce or defer daemon
 
6
/* SYNOPSIS
 
7
/*      \fBbounce\fR [generic Postfix daemon options]
 
8
/* DESCRIPTION
 
9
/*      The \fBbounce\fR daemon maintains per-message log files with
 
10
/*      non-delivery status information. Each log file is named after the
 
11
/*      queue file that it corresponds to, and is kept in a queue subdirectory
 
12
/*      named after the service name in the \fBmaster.cf\fR file (either
 
13
/*      \fBbounce\fR, \fBdefer\fR or \fBtrace\fR).
 
14
/*      This program expects to be run from the \fBmaster\fR(8) process
 
15
/*      manager.
 
16
/*
 
17
/*      The \fBbounce\fR daemon processes two types of service requests:
 
18
/* .IP \(bu
 
19
/*      Append a recipient (non-)delivery status record to a per-message
 
20
/*      log file.
 
21
/* .IP \(bu
 
22
/*      Enqueue a bounce message, with a copy of a per-message log file
 
23
/*      and of the corresponding message. When the bounce message is
 
24
/*      enqueued successfully, the per-message log file is deleted.
 
25
/* .PP
 
26
/*      The software does a best notification effort. A non-delivery
 
27
/*      notification is sent even when the log file or the original
 
28
/*      message cannot be read.
 
29
/*
 
30
/*      Optionally, a bounce (defer, trace) client can request that the
 
31
/*      per-message log file be deleted when the requested operation fails.
 
32
/*      This is used by clients that cannot retry transactions by
 
33
/*      themselves, and that depend on retry logic in their own client.
 
34
/* STANDARDS
 
35
/*      RFC 822 (ARPA Internet Text Messages)
 
36
/*      RFC 1894 (Delivery Status Notifications)
 
37
/*      RFC 2045 (Format of Internet Message Bodies)
 
38
/* DIAGNOSTICS
 
39
/*      Problems and transactions are logged to \fBsyslogd\fR(8).
 
40
/* CONFIGURATION PARAMETERS
 
41
/* .ad
 
42
/* .fi
 
43
/*      Changes to \fBmain.cf\fR are picked up automatically, as bounce(8)
 
44
/*      processes run for only a limited amount of time. Use the command
 
45
/*      "\fBpostfix reload\fR" to speed up a change.
 
46
/*
 
47
/*      The text below provides only a parameter summary. See
 
48
/*      postconf(5) for more details including examples.
 
49
/* .IP "\fB2bounce_notice_recipient (postmaster)\fR"
 
50
/*      The recipient of undeliverable mail that cannot be returned to
 
51
/*      the sender.
 
52
/* .IP "\fBbackwards_bounce_logfile_compatibility (yes)\fR"
 
53
/*      Produce additional bounce(8) logfile records that can be read by
 
54
/*      older Postfix versions.
 
55
/* .IP "\fBbounce_notice_recipient (postmaster)\fR"
 
56
/*      The recipient of postmaster notifications with the message headers
 
57
/*      of mail that Postfix did not deliver and of SMTP conversation
 
58
/*      transcripts of mail that Postfix did not receive.
 
59
/* .IP "\fBbounce_size_limit (50000)\fR"
 
60
/*      The maximal amount of original message text that is sent in a
 
61
/*      non-delivery notification.
 
62
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
 
63
/*      The default location of the Postfix main.cf and master.cf
 
64
/*      configuration files.
 
65
/* .IP "\fBdaemon_timeout (18000s)\fR"
 
66
/*      How much time a Postfix daemon process may take to handle a
 
67
/*      request before it is terminated by a built-in watchdog timer.
 
68
/* .IP "\fBdelay_notice_recipient (postmaster)\fR"
 
69
/*      The recipient of postmaster notifications with the message headers
 
70
/*      of mail that cannot be delivered within $delay_warning_time time
 
71
/*      units.
 
72
/* .IP "\fBdeliver_lock_attempts (20)\fR"
 
73
/*      The maximal number of attempts to acquire an exclusive lock on a
 
74
/*      mailbox file or bounce(8) logfile.
 
75
/* .IP "\fBdeliver_lock_delay (1s)\fR"
 
76
/*      The time between attempts to acquire an exclusive lock on a mailbox
 
77
/*      file or bounce(8) logfile.
 
78
/* .IP "\fBipc_timeout (3600s)\fR"
 
79
/*      The time limit for sending or receiving information over an internal
 
80
/*      communication channel.
 
81
/* .IP "\fBmail_name (Postfix)\fR"
 
82
/*      The mail system name that is displayed in Received: headers, in
 
83
/*      the SMTP greeting banner, and in bounced mail.
 
84
/* .IP "\fBmax_idle (100s)\fR"
 
85
/*      The maximum amount of time that an idle Postfix daemon process
 
86
/*      waits for the next service request before exiting.
 
87
/* .IP "\fBmax_use (100)\fR"
 
88
/*      The maximal number of connection requests before a Postfix daemon
 
89
/*      process terminates.
 
90
/* .IP "\fBnotify_classes (resource, software)\fR"
 
91
/*      The list of error classes that are reported to the postmaster.
 
92
/* .IP "\fBprocess_id (read-only)\fR"
 
93
/*      The process ID of a Postfix command or daemon process.
 
94
/* .IP "\fBprocess_name (read-only)\fR"
 
95
/*      The process name of a Postfix command or daemon process.
 
96
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
 
97
/*      The location of the Postfix top-level queue directory.
 
98
/* .IP "\fBsyslog_facility (mail)\fR"
 
99
/*      The syslog facility of Postfix logging.
 
100
/* .IP "\fBsyslog_name (postfix)\fR"
 
101
/*      The mail system name that is prepended to the process name in syslog
 
102
/*      records, so that "smtpd" becomes, for example, "postfix/smtpd".
 
103
/* FILES
 
104
/*      /var/spool/postfix/bounce/* non-delivery records
 
105
/*      /var/spool/postfix/defer/* non-delivery records
 
106
/*      /var/spool/postfix/trace/* delivery status records
 
107
/* SEE ALSO
 
108
/*      qmgr(8), queue manager
 
109
/*      postconf(5), configuration parameters
 
110
/*      master(8), process manager
 
111
/*      syslogd(8), system logging
 
112
/* LICENSE
 
113
/* .ad
 
114
/* .fi
 
115
/*      The Secure Mailer license must be distributed with this software.
 
116
/* AUTHOR(S)
 
117
/*      Wietse Venema
 
118
/*      IBM T.J. Watson Research
 
119
/*      P.O. Box 704
 
120
/*      Yorktown Heights, NY 10598, USA
 
121
/*--*/
 
122
 
 
123
/* System library. */
 
124
 
 
125
#include <sys_defs.h>
 
126
#include <string.h>
 
127
 
 
128
#ifdef STRCASECMP_IN_STRINGS_H
 
129
#include <strings.h>
 
130
#endif
 
131
 
 
132
/* Utility library. */
 
133
 
 
134
#include <msg.h>
 
135
#include <vstring.h>
 
136
#include <vstream.h>
 
137
#include <stringops.h>
 
138
 
 
139
/* Global library. */
 
140
 
 
141
#include <mail_proto.h>
 
142
#include <mail_queue.h>
 
143
#include <mail_params.h>
 
144
#include <mail_conf.h>
 
145
#include <bounce.h>
 
146
#include <mail_addr.h>
 
147
 
 
148
/* Single-threaded server skeleton. */
 
149
 
 
150
#include <mail_server.h>
 
151
 
 
152
/* Application-specific. */
 
153
 
 
154
#include "bounce_service.h"
 
155
 
 
156
 /*
 
157
  * Tunables.
 
158
  */
 
159
int     var_bounce_limit;
 
160
int     var_max_queue_time;
 
161
int     var_delay_warn_time;
 
162
char   *var_notify_classes;
 
163
char   *var_bounce_rcpt;
 
164
char   *var_2bounce_rcpt;
 
165
char   *var_delay_rcpt;
 
166
 
 
167
 /*
 
168
  * We're single threaded, so we can avoid some memory allocation overhead.
 
169
  */
 
170
static VSTRING *queue_id;
 
171
static VSTRING *queue_name;
 
172
static VSTRING *orig_rcpt;
 
173
static VSTRING *recipient;
 
174
static VSTRING *encoding;
 
175
static VSTRING *sender;
 
176
static VSTRING *verp_delims;
 
177
static VSTRING *dsn_status;
 
178
static VSTRING *dsn_action;
 
179
static VSTRING *why;
 
180
 
 
181
#define STR vstring_str
 
182
 
 
183
/* bounce_append_proto - bounce_append server protocol */
 
184
 
 
185
static int bounce_append_proto(char *service_name, VSTREAM *client)
 
186
{
 
187
    char   *myname = "bounce_append_proto";
 
188
    int     flags;
 
189
    long    offset;
 
190
 
 
191
    /*
 
192
     * Read the and validate the client request.
 
193
     */
 
194
    if (mail_command_server(client,
 
195
                            ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
 
196
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
 
197
                            ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt,
 
198
                            ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient,
 
199
                            ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &offset,
 
200
                            ATTR_TYPE_STR, MAIL_ATTR_STATUS, dsn_status,
 
201
                            ATTR_TYPE_STR, MAIL_ATTR_ACTION, dsn_action,
 
202
                            ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
 
203
                            ATTR_TYPE_END) != 8) {
 
204
        msg_warn("malformed request");
 
205
        return (-1);
 
206
    }
 
207
    if (mail_queue_id_ok(STR(queue_id)) == 0) {
 
208
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
 
209
        return (-1);
 
210
    }
 
211
    if (msg_verbose)
 
212
        msg_info("%s: flags=0x%x service=%s id=%s org_to=%s to=%s off=%ld stat=%s act=%s why=%s",
 
213
                 myname, flags, service_name, STR(queue_id), STR(orig_rcpt),
 
214
                 STR(recipient), offset, STR(dsn_status),
 
215
                 STR(dsn_action), STR(why));
 
216
 
 
217
    /*
 
218
     * On request by the client, set up a trap to delete the log file in case
 
219
     * of errors.
 
220
     */
 
221
    if (flags & BOUNCE_FLAG_CLEAN)
 
222
        bounce_cleanup_register(service_name, STR(queue_id));
 
223
 
 
224
    /*
 
225
     * Execute the request.
 
226
     */
 
227
    return (bounce_append_service(flags, service_name, STR(queue_id),
 
228
                                  STR(orig_rcpt), STR(recipient), offset,
 
229
                                  STR(dsn_status), STR(dsn_action),
 
230
                                  STR(why)));
 
231
}
 
232
 
 
233
/* bounce_notify_proto - bounce_notify server protocol */
 
234
 
 
235
static int bounce_notify_proto(char *service_name, VSTREAM *client,
 
236
               int (*service) (int, char *, char *, char *, char *, char *))
 
237
{
 
238
    char   *myname = "bounce_notify_proto";
 
239
    int     flags;
 
240
 
 
241
    /*
 
242
     * Read and validate the client request.
 
243
     */
 
244
    if (mail_command_server(client,
 
245
                            ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
 
246
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
 
247
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
 
248
                            ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
 
249
                            ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
 
250
                            ATTR_TYPE_END) != 5) {
 
251
        msg_warn("malformed request");
 
252
        return (-1);
 
253
    }
 
254
    if (mail_queue_name_ok(STR(queue_name)) == 0) {
 
255
        msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
 
256
        return (-1);
 
257
    }
 
258
    if (mail_queue_id_ok(STR(queue_id)) == 0) {
 
259
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
 
260
        return (-1);
 
261
    }
 
262
    if (msg_verbose)
 
263
        msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sender=%s",
 
264
                 myname, flags, service_name, STR(queue_name), STR(queue_id),
 
265
                 STR(encoding), STR(sender));
 
266
 
 
267
    /*
 
268
     * On request by the client, set up a trap to delete the log file in case
 
269
     * of errors.
 
270
     */
 
271
    if (flags & BOUNCE_FLAG_CLEAN)
 
272
        bounce_cleanup_register(service_name, STR(queue_id));
 
273
 
 
274
    /*
 
275
     * Execute the request.
 
276
     */
 
277
    return (service(flags, service_name, STR(queue_name),
 
278
                    STR(queue_id), STR(encoding),
 
279
                    STR(sender)));
 
280
}
 
281
 
 
282
/* bounce_verp_proto - bounce_notify server protocol, VERP style */
 
283
 
 
284
static int bounce_verp_proto(char *service_name, VSTREAM *client)
 
285
{
 
286
    char   *myname = "bounce_verp_proto";
 
287
    int     flags;
 
288
 
 
289
    /*
 
290
     * Read and validate the client request.
 
291
     */
 
292
    if (mail_command_server(client,
 
293
                            ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
 
294
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
 
295
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
 
296
                            ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
 
297
                            ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
 
298
                            ATTR_TYPE_STR, MAIL_ATTR_VERPDL, verp_delims,
 
299
                            ATTR_TYPE_END) != 6) {
 
300
        msg_warn("malformed request");
 
301
        return (-1);
 
302
    }
 
303
    if (mail_queue_name_ok(STR(queue_name)) == 0) {
 
304
        msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
 
305
        return (-1);
 
306
    }
 
307
    if (mail_queue_id_ok(STR(queue_id)) == 0) {
 
308
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
 
309
        return (-1);
 
310
    }
 
311
    if (strlen(STR(verp_delims)) != 2) {
 
312
        msg_warn("malformed verp delimiter string: %s",
 
313
                 printable(STR(verp_delims), '?'));
 
314
        return (-1);
 
315
    }
 
316
    if (msg_verbose)
 
317
        msg_info("%s: flags=0x%x service=%s queue=%s id=%s encoding=%s sender=%s delim=%s",
 
318
                 myname, flags, service_name, STR(queue_name), STR(queue_id),
 
319
                 STR(encoding), STR(sender), STR(verp_delims));
 
320
 
 
321
    /*
 
322
     * On request by the client, set up a trap to delete the log file in case
 
323
     * of errors.
 
324
     */
 
325
    if (flags & BOUNCE_FLAG_CLEAN)
 
326
        bounce_cleanup_register(service_name, STR(queue_id));
 
327
 
 
328
    /*
 
329
     * Execute the request. Fall back to traditional notification if a bounce
 
330
     * was returned as undeliverable, because we don't want to VERPify those.
 
331
     */
 
332
    if (!*STR(sender) || !strcasecmp(STR(sender), mail_addr_double_bounce())) {
 
333
        msg_warn("request to send VERP-style notification of bounced mail");
 
334
        return (bounce_notify_service(flags, service_name, STR(queue_name),
 
335
                                      STR(queue_id), STR(encoding),
 
336
                                      STR(sender)));
 
337
    } else
 
338
        return (bounce_notify_verp(flags, service_name, STR(queue_name),
 
339
                                   STR(queue_id), STR(encoding),
 
340
                                   STR(sender), STR(verp_delims)));
 
341
}
 
342
 
 
343
/* bounce_one_proto - bounce_one server protocol */
 
344
 
 
345
static int bounce_one_proto(char *service_name, VSTREAM *client)
 
346
{
 
347
    char   *myname = "bounce_one_proto";
 
348
    int     flags;
 
349
    long    offset;
 
350
 
 
351
    /*
 
352
     * Read and validate the client request.
 
353
     */
 
354
    if (mail_command_server(client,
 
355
                            ATTR_TYPE_NUM, MAIL_ATTR_FLAGS, &flags,
 
356
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUE, queue_name,
 
357
                            ATTR_TYPE_STR, MAIL_ATTR_QUEUEID, queue_id,
 
358
                            ATTR_TYPE_STR, MAIL_ATTR_ENCODING, encoding,
 
359
                            ATTR_TYPE_STR, MAIL_ATTR_SENDER, sender,
 
360
                            ATTR_TYPE_STR, MAIL_ATTR_ORCPT, orig_rcpt,
 
361
                            ATTR_TYPE_STR, MAIL_ATTR_RECIP, recipient,
 
362
                            ATTR_TYPE_LONG, MAIL_ATTR_OFFSET, &offset,
 
363
                            ATTR_TYPE_STR, MAIL_ATTR_STATUS, dsn_status,
 
364
                            ATTR_TYPE_STR, MAIL_ATTR_ACTION, dsn_action,
 
365
                            ATTR_TYPE_STR, MAIL_ATTR_WHY, why,
 
366
                            ATTR_TYPE_END) != 11) {
 
367
        msg_warn("malformed request");
 
368
        return (-1);
 
369
    }
 
370
    if (strcmp(service_name, MAIL_SERVICE_BOUNCE) != 0) {
 
371
        msg_warn("wrong service name \"%s\" for one-recipient bouncing",
 
372
                 service_name);
 
373
        return (-1);
 
374
    }
 
375
    if (mail_queue_name_ok(STR(queue_name)) == 0) {
 
376
        msg_warn("malformed queue name: %s", printable(STR(queue_name), '?'));
 
377
        return (-1);
 
378
    }
 
379
    if (mail_queue_id_ok(STR(queue_id)) == 0) {
 
380
        msg_warn("malformed queue id: %s", printable(STR(queue_id), '?'));
 
381
        return (-1);
 
382
    }
 
383
    if (msg_verbose)
 
384
        msg_info("%s: flags=0x%x queue=%s id=%s encoding=%s sender=%s orig_to=%s to=%s off=%ld stat=%s act=%s why=%s",
 
385
               myname, flags, STR(queue_name), STR(queue_id), STR(encoding),
 
386
                 STR(sender), STR(orig_rcpt), STR(recipient), offset,
 
387
                 STR(dsn_status), STR(dsn_action), STR(why));
 
388
 
 
389
    /*
 
390
     * Execute the request.
 
391
     */
 
392
    return (bounce_one_service(flags, STR(queue_name), STR(queue_id),
 
393
                               STR(encoding), STR(sender), STR(orig_rcpt),
 
394
                               STR(recipient), offset, STR(dsn_status),
 
395
                               STR(dsn_action), STR(why)));
 
396
}
 
397
 
 
398
/* bounce_service - parse bounce command type and delegate */
 
399
 
 
400
static void bounce_service(VSTREAM *client, char *service_name, char **argv)
 
401
{
 
402
    int     command;
 
403
    int     status;
 
404
 
 
405
    /*
 
406
     * Sanity check. This service takes no command-line arguments. The
 
407
     * service name should be usable as a subdirectory name.
 
408
     */
 
409
    if (argv[0])
 
410
        msg_fatal("unexpected command-line argument: %s", argv[0]);
 
411
    if (mail_queue_name_ok(service_name) == 0)
 
412
        msg_fatal("malformed service name: %s", service_name);
 
413
 
 
414
    /*
 
415
     * Read and validate the first parameter of the client request. Let the
 
416
     * request-specific protocol routines take care of the remainder.
 
417
     */
 
418
    if (attr_scan(client, ATTR_FLAG_STRICT | ATTR_FLAG_MORE,
 
419
                  ATTR_TYPE_NUM, MAIL_ATTR_NREQ, &command, 0) != 1) {
 
420
        msg_warn("malformed request");
 
421
        status = -1;
 
422
    } else if (command == BOUNCE_CMD_VERP) {
 
423
        status = bounce_verp_proto(service_name, client);
 
424
    } else if (command == BOUNCE_CMD_FLUSH) {
 
425
        status = bounce_notify_proto(service_name, client,
 
426
                                     bounce_notify_service);
 
427
    } else if (command == BOUNCE_CMD_WARN) {
 
428
        status = bounce_notify_proto(service_name, client,
 
429
                                     bounce_warn_service);
 
430
    } else if (command == BOUNCE_CMD_TRACE) {
 
431
        status = bounce_notify_proto(service_name, client,
 
432
                                     bounce_trace_service);
 
433
    } else if (command == BOUNCE_CMD_APPEND) {
 
434
        status = bounce_append_proto(service_name, client);
 
435
    } else if (command == BOUNCE_CMD_ONE) {
 
436
        status = bounce_one_proto(service_name, client);
 
437
    } else {
 
438
        msg_warn("unknown command: %d", command);
 
439
        status = -1;
 
440
    }
 
441
 
 
442
    /*
 
443
     * When the request has completed, send the completion status to the
 
444
     * client.
 
445
     */
 
446
    attr_print(client, ATTR_FLAG_NONE,
 
447
               ATTR_TYPE_NUM, MAIL_ATTR_STATUS, status,
 
448
               ATTR_TYPE_END);
 
449
    vstream_fflush(client);
 
450
 
 
451
    /*
 
452
     * When a cleanup trap was set, delete the log file in case of error.
 
453
     * This includes errors while sending the completion status to the
 
454
     * client.
 
455
     */
 
456
    if (bounce_cleanup_path) {
 
457
        if (status || vstream_ferror(client))
 
458
            bounce_cleanup_log();
 
459
        bounce_cleanup_unregister();
 
460
    }
 
461
}
 
462
 
 
463
/* post_jail_init - initialize after entering chroot jail */
 
464
 
 
465
static void post_jail_init(char *unused_name, char **unused_argv)
 
466
{
 
467
 
 
468
    /*
 
469
     * Initialize. We're single threaded so we can reuse some memory upon
 
470
     * successive requests.
 
471
     */
 
472
    queue_id = vstring_alloc(10);
 
473
    queue_name = vstring_alloc(10);
 
474
    orig_rcpt = vstring_alloc(10);
 
475
    recipient = vstring_alloc(10);
 
476
    encoding = vstring_alloc(10);
 
477
    sender = vstring_alloc(10);
 
478
    verp_delims = vstring_alloc(10);
 
479
    dsn_status = vstring_alloc(10);
 
480
    dsn_action = vstring_alloc(10);
 
481
    why = vstring_alloc(10);
 
482
}
 
483
 
 
484
/* main - the main program */
 
485
 
 
486
int     main(int argc, char **argv)
 
487
{
 
488
    static CONFIG_INT_TABLE int_table[] = {
 
489
        VAR_BOUNCE_LIMIT, DEF_BOUNCE_LIMIT, &var_bounce_limit, 1, 0,
 
490
        0,
 
491
    };
 
492
    static CONFIG_TIME_TABLE time_table[] = {
 
493
        VAR_MAX_QUEUE_TIME, DEF_MAX_QUEUE_TIME, &var_max_queue_time, 0, 8640000,
 
494
        VAR_DELAY_WARN_TIME, DEF_DELAY_WARN_TIME, &var_delay_warn_time, 0, 0,
 
495
        0,
 
496
    };
 
497
    static CONFIG_STR_TABLE str_table[] = {
 
498
        VAR_NOTIFY_CLASSES, DEF_NOTIFY_CLASSES, &var_notify_classes, 0, 0,
 
499
        VAR_BOUNCE_RCPT, DEF_BOUNCE_RCPT, &var_bounce_rcpt, 1, 0,
 
500
        VAR_2BOUNCE_RCPT, DEF_2BOUNCE_RCPT, &var_2bounce_rcpt, 1, 0,
 
501
        VAR_DELAY_RCPT, DEF_DELAY_RCPT, &var_delay_rcpt, 1, 0,
 
502
        0,
 
503
    };
 
504
 
 
505
    /*
 
506
     * Pass control to the single-threaded service skeleton.
 
507
     */
 
508
    single_server_main(argc, argv, bounce_service,
 
509
                       MAIL_SERVER_INT_TABLE, int_table,
 
510
                       MAIL_SERVER_STR_TABLE, str_table,
 
511
                       MAIL_SERVER_TIME_TABLE, time_table,
 
512
                       MAIL_SERVER_POST_INIT, post_jail_init,
 
513
                       MAIL_SERVER_UNLIMITED,
 
514
                       0);
 
515
}