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

« back to all changes in this revision

Viewing changes to src/sendmail/sendmail.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
/*      sendmail 1
 
4
/* SUMMARY
 
5
/*      Postfix to Sendmail compatibility interface
 
6
/* SYNOPSIS
 
7
/*      \fBsendmail\fR [\fIoption ...\fR] [\fIrecipient ...\fR]
 
8
/*
 
9
/*      \fBmailq\fR
 
10
/*      \fBsendmail -bp\fR
 
11
/*
 
12
/*      \fBnewaliases\fR
 
13
/*      \fBsendmail -I\fR
 
14
/* DESCRIPTION
 
15
/*      The Postfix \fBsendmail\fR command implements the Postfix to Sendmail
 
16
/*      compatibility interface.
 
17
/*      For the sake of compatibility with existing applications, some
 
18
/*      Sendmail command-line options are recognized but silently ignored.
 
19
/*
 
20
/*      By default, Postfix \fBsendmail\fR reads a message from standard input
 
21
/*      until EOF or until it reads a line with only a \fB.\fR character,
 
22
/*      and arranges for delivery.  Postfix \fBsendmail\fR relies on the
 
23
/*      \fBpostdrop\fR(1) command to create a queue file in the \fBmaildrop\fR
 
24
/*      directory.
 
25
/*
 
26
/*      Specific command aliases are provided for other common modes of
 
27
/*      operation:
 
28
/* .IP \fBmailq\fR
 
29
/*      List the mail queue. Each entry shows the queue file ID, message
 
30
/*      size, arrival time, sender, and the recipients that still need to
 
31
/*      be delivered.  If mail could not be delivered upon the last attempt,
 
32
/*      the reason for failure is shown. This mode of operation is implemented
 
33
/*      by executing the \fBpostqueue\fR(1) command.
 
34
/* .IP \fBnewaliases\fR
 
35
/*      Initialize the alias database.  If no input file is specified (with
 
36
/*      the \fB-oA\fR option, see below), the program processes the file(s)
 
37
/*      specified with the \fBalias_database\fR configuration parameter.
 
38
/*      If no alias database type is specified, the program uses the type
 
39
/*      specified with the \fBdefault_database_type\fR configuration parameter.
 
40
/*      This mode of operation is implemented by running the \fBpostalias\fR(1)
 
41
/*      command.
 
42
/* .sp
 
43
/*      Note: it may take a minute or so before an alias database update
 
44
/*      becomes visible. Use the \fBpostfix reload\fR command to eliminate
 
45
/*      this delay.
 
46
/* .PP
 
47
/*      These and other features can be selected by specifying the
 
48
/*      appropriate combination of command-line options. Some features are
 
49
/*      controlled by parameters in the \fBmain.cf\fR configuration file.
 
50
/*
 
51
/*      The following options are recognized:
 
52
/* .IP "\fB-Am\fR (ignored)"
 
53
/* .IP "\fB-Ac\fR (ignored)"
 
54
/*      Postfix sendmail uses the same configuration file regardless of
 
55
/*      whether or not a message is an initial submission.
 
56
/* .IP "\fB-B \fIbody_type\fR"
 
57
/*      The message body MIME type: \fB7BIT\fR or \fB8BITMIME\fR.
 
58
/* .IP \fB-bd\fR
 
59
/*      Go into daemon mode. This mode of operation is implemented by
 
60
/*      executing the \fBpostfix start\fR command.
 
61
/* .IP "\fB-bh\fR (ignored)"
 
62
/* .IP "\fB-bH\fR (ignored)"
 
63
/*      Postfix has no persistent host status database.
 
64
/* .IP \fB-bi\fR
 
65
/*      Initialize alias database. See the \fBnewaliases\fR
 
66
/*      command above.
 
67
/* .IP \fB-bm\fR
 
68
/*      Read mail from standard input and arrange for delivery.
 
69
/*      This is the default mode of operation.
 
70
/* .IP \fB-bp\fR
 
71
/*      List the mail queue. See the \fBmailq\fR command above.
 
72
/* .IP \fB-bs\fR
 
73
/*      Stand-alone SMTP server mode. Read SMTP commands from
 
74
/*      standard input, and write responses to standard output.
 
75
/*      In stand-alone SMTP server mode, mail relaying and other
 
76
/*      access controls are disabled by default. To enable them,
 
77
/*      run the process as the \fBmail_owner\fR user.
 
78
/* .sp
 
79
/*      This mode of operation is implemented by running the
 
80
/*      \fBsmtpd\fR(8) daemon.
 
81
/* .IP \fB-bv\fR
 
82
/*      Do not collect or deliver a message. Instead, send an email
 
83
/*      report after verifying each recipient address.  This is useful
 
84
/*      for testing address rewriting and routing configurations.
 
85
/* .sp
 
86
/*      This feature is available in Postfix version 2.1 and later.
 
87
/* .IP "\fB-C \fIconfig_file\fR (ignored)"
 
88
/*      The path name of the \fBsendmail.cf\fR file. Postfix configuration
 
89
/*      files are kept in the \fB/etc/postfix\fR directory.
 
90
/* .IP "\fB-F \fIfull_name\fR
 
91
/*      Set the sender full name. This is used only with messages that
 
92
/*      have no \fBFrom:\fR message header.
 
93
/* .IP "\fB-f \fIsender\fR"
 
94
/*      Set the envelope sender address. This is the address where
 
95
/*      delivery problems are sent to, unless the message contains an
 
96
/*      \fBErrors-To:\fR message header.
 
97
/* .IP "\fB-G\fR (ignored)"
 
98
/*      Gateway (relay) submission, as opposed to initial user submission.
 
99
/* .IP "\fB-h \fIhop_count\fR (ignored)"
 
100
/*      Hop count limit. Use the \fBhopcount_limit\fR configuration
 
101
/*      parameter instead.
 
102
/* .IP \fB-I\fR
 
103
/*      Initialize alias database. See the \fBnewaliases\fR
 
104
/*      command above.
 
105
/* .IP "\fB-i\fR"
 
106
/*      When reading a message from standard input, don\'t treat a line
 
107
/*      with only a \fB.\fR character as the end of input.
 
108
/* .IP "\fB-L \fIlabel\fR (ignored)"
 
109
/*      The logging label. Use the \fBsyslog_name\fR configuration
 
110
/*      parameter instead.
 
111
/* .IP "\fB-m\fR (ignored)"
 
112
/*      Backwards compatibility.
 
113
/* .IP "\fB-N \fIdsn\fR (ignored)"
 
114
/*      Delivery status notification control. Currently, Postfix does
 
115
/*      not implement \fBDSN\fR.
 
116
/* .IP "\fB-n\fR (ignored)"
 
117
/*      Backwards compatibility.
 
118
/* .IP "\fB-oA\fIalias_database\fR"
 
119
/*      Non-default alias database. Specify \fIpathname\fR or
 
120
/*      \fItype\fR:\fIpathname\fR. See \fBpostalias\fR(1) for
 
121
/*      details.
 
122
/* .IP "\fB-o7\fR (ignored)"
 
123
/* .IP "\fB-o8\fR (ignored)"
 
124
/*      To send 8-bit or binary content, use an appropriate MIME encapsulation
 
125
/*      and specify the appropriate \fB-B\fR command-line option.
 
126
/* .IP "\fB-oi\fR"
 
127
/*      When reading a message from standard input, don\'t treat a line
 
128
/*      with only a \fB.\fR character as the end of input.
 
129
/* .IP "\fB-om\fR (ignored)"
 
130
/*      The sender is never eliminated from alias etc. expansions.
 
131
/* .IP "\fB-o \fIx value\fR (ignored)"
 
132
/*      Set option \fIx\fR to \fIvalue\fR. Use the equivalent
 
133
/*      configuration parameter in \fBmain.cf\fR instead.
 
134
/* .IP "\fB-r \fIsender\fR"
 
135
/*      Set the envelope sender address. This is the address where
 
136
/*      delivery problems are sent to, unless the message contains an
 
137
/*      \fBErrors-To:\fR message header.
 
138
/* .IP "\fB-R \fIreturn_limit\fR (ignored)"
 
139
/*      Limit the size of bounced mail. Use the \fBbounce_size_limit\fR
 
140
/*      configuration parameter instead.
 
141
/* .IP \fB-q\fR
 
142
/*      Attempt to deliver all queued mail. This is implemented by
 
143
/*      executing the \fBpostqueue\fR(1) command.
 
144
/*
 
145
/*      Warning: flushing undeliverable mail frequently will result in
 
146
/*      poor delivery performance of all other mail.
 
147
/* .IP "\fB-q\fIinterval\fR (ignored)"
 
148
/*      The interval between queue runs. Use the \fBqueue_run_delay\fR
 
149
/*      configuration parameter instead.
 
150
/* .IP \fB-qR\fIsite\fR
 
151
/*      Schedule immediate delivery of all mail that is queued for the named
 
152
/*      \fIsite\fR. This option accepts only \fIsite\fR names that are
 
153
/*      eligible for the "fast flush" service, and is implemented by
 
154
/*      executing the \fBpostqueue\fR(1) command.
 
155
/*      See \fBflush\fR(8) for more information about the "fast flush"
 
156
/*      service.
 
157
/* .IP \fB-qS\fIsite\fR
 
158
/*      This command is not implemented. Use the slower \fBsendmail -q\fR
 
159
/*      command instead.
 
160
/* .IP \fB-t\fR
 
161
/*      Extract recipients from message headers. These are added to any
 
162
/*      recipients specified on the command line.
 
163
/*
 
164
/*      With Postfix versions prior to 2.1, this option requires that
 
165
/*      no recipient addresses are specified on the command line.
 
166
/* .IP "\fB-U\fR (ignored)"
 
167
/*      Initial user submission.
 
168
/* .IP \fB-V\fR
 
169
/*      Variable Envelope Return Path. Given an envelope sender address
 
170
/*      of the form \fIowner-listname\fR@\fIorigin\fR, each recipient
 
171
/*      \fIuser\fR@\fIdomain\fR receives mail with a personalized envelope
 
172
/*      sender address.
 
173
/* .sp
 
174
/*      By default, the personalized envelope sender address is
 
175
/*      \fIowner-listname\fB+\fIuser\fB=\fIdomain\fR@\fIorigin\fR. The default
 
176
/*      \fB+\fR and \fB=\fR characters are configurable with the
 
177
/*      \fBdefault_verp_delimiters\fR configuration parameter.
 
178
/* .sp
 
179
/*      This feature is available in Postfix version 1.1 and later.
 
180
/* .IP \fB-V\fIxy\fR
 
181
/*      As \fB-V\fR, but uses \fIx\fR and \fIy\fR as the VERP delimiter
 
182
/*      characters, instead of the characters specified with the
 
183
/*      \fBdefault_verp_delimiters\fR configuration parameter.
 
184
/* .IP \fB-v\fR
 
185
/*      Send an email report of the first delivery attempt (Postfix
 
186
/*      versions 2.1 and later). Mail delivery
 
187
/*      always happens in the background. When multiple \fB-v\fR
 
188
/*      options are given, enable verbose logging for debugging purposes.
 
189
/* .IP "\fB-X \fIlog_file\fR (ignored)"
 
190
/*      Log mailer traffic. Use the \fBdebug_peer_list\fR and
 
191
/*      \fBdebug_peer_level\fR configuration parameters instead.
 
192
/* SECURITY
 
193
/* .ad
 
194
/* .fi
 
195
/*      By design, this program is not set-user (or group) id. However,
 
196
/*      it must handle data from untrusted users or untrusted machines.
 
197
/*      Thus, the usual precautions need to be taken against malicious
 
198
/*      inputs.
 
199
/* DIAGNOSTICS
 
200
/*      Problems are logged to \fBsyslogd\fR(8) and to the standard error
 
201
/*      stream.
 
202
/* ENVIRONMENT
 
203
/* .ad
 
204
/* .fi
 
205
/* .IP \fBMAIL_CONFIG\fR
 
206
/*      Directory with Postfix configuration files.
 
207
/* .IP \fBMAIL_VERBOSE\fR
 
208
/*      Enable verbose logging for debugging purposes.
 
209
/* .IP \fBMAIL_DEBUG\fR
 
210
/*      Enable debugging with an external command, as specified with the
 
211
/*      \fBdebugger_command\fR configuration parameter.
 
212
/* CONFIGURATION PARAMETERS
 
213
/* .ad
 
214
/* .fi
 
215
/*      The following \fBmain.cf\fR parameters are especially relevant to
 
216
/*      this program.
 
217
/*      The text below provides only a parameter summary. See
 
218
/*      postconf(5) for more details including examples.
 
219
/* TROUBLE SHOOTING CONTROLS
 
220
/* .ad
 
221
/* .fi
 
222
/*      The DEBUG_README file gives examples of how to trouble shoot a
 
223
/*      Postfix system.
 
224
/* .IP "\fBdebugger_command (empty)\fR"
 
225
/*      The external command to execute when a Postfix daemon program is
 
226
/*      invoked with the -D option.
 
227
/* .IP "\fBdebug_peer_level (2)\fR"
 
228
/*      The increment in verbose logging level when a remote client or
 
229
/*      server matches a pattern in the debug_peer_list parameter.
 
230
/* .IP "\fBdebug_peer_list (empty)\fR"
 
231
/*      Optional list of remote client or server hostname or network
 
232
/*      address patterns that cause the verbose logging level to increase
 
233
/*      by the amount specified in $debug_peer_level.
 
234
/* RESOURCE AND RATE CONTROLS
 
235
/* .ad
 
236
/* .fi
 
237
/* .IP "\fBbounce_size_limit (50000)\fR"
 
238
/*      The maximal amount of original message text that is sent in a
 
239
/*      non-delivery notification.
 
240
/* .IP "\fBfork_attempts (5)\fR"
 
241
/*      The maximal number of attempts to fork() a child process.
 
242
/* .IP "\fBfork_delay (1s)\fR"
 
243
/*      The delay between attempts to fork() a child process.
 
244
/* .IP "\fBhopcount_limit (50)\fR"
 
245
/*      The maximal number of Received:  message headers that is allowed
 
246
/*      in the primary message headers.
 
247
/* .IP "\fBqueue_run_delay (1000s)\fR"
 
248
/*      The time between deferred queue scans by the queue manager.
 
249
/* FAST FLUSH CONTROLS
 
250
/* .ad
 
251
/* .fi
 
252
/*      The ETRN_README file describes configuration and operation
 
253
/*      details for the Postfix "fast flush" service.
 
254
/* .IP "\fBfast_flush_domains ($relay_domains)\fR"
 
255
/*      Optional list of destinations that are eligible for per-destination
 
256
/*      logfiles with mail that is queued to those destinations.
 
257
/* VERP CONTROLS
 
258
/* .ad
 
259
/* .fi
 
260
/*      The VERP_README file describes configuration and operation
 
261
/*      details of Postfix support for variable envelope return
 
262
/*      path addresses.
 
263
/* .IP "\fBdefault_verp_delimiters (+=)\fR"
 
264
/*      The two default VERP delimiter characters.
 
265
/* .IP "\fBverp_delimiter_filter (-=+)\fR"
 
266
/*      The characters Postfix accepts as VERP delimiter characters on the
 
267
/*      Postfix sendmail(1) command line and in SMTP commands.
 
268
/* MISCELLANEOUS CONTROLS
 
269
/* .ad
 
270
/* .fi
 
271
/* .IP "\fBalias_database (see 'postconf -d' output)\fR"
 
272
/*      The alias databases for local(8) delivery that are updated with
 
273
/*      "\fBnewaliases\fR" or with "\fBsendmail -bi\fR".
 
274
/* .IP "\fBcommand_directory (see 'postconf -d' output)\fR"
 
275
/*      The location of all postfix administrative commands.
 
276
/* .IP "\fBconfig_directory (see 'postconf -d' output)\fR"
 
277
/*      The default location of the Postfix main.cf and master.cf
 
278
/*      configuration files.
 
279
/* .IP "\fBdaemon_directory (see 'postconf -d' output)\fR"
 
280
/*      The directory with Postfix support programs and daemon programs.
 
281
/* .IP "\fBdefault_database_type (see 'postconf -d' output)\fR"
 
282
/*      The default database type for use in newaliases(1), postalias(1)
 
283
/*      and postmap(1) commands.
 
284
/* .IP "\fBdelay_warning_time (0h)\fR"
 
285
/*      The time after which the sender receives the message headers of
 
286
/*      mail that is still queued.
 
287
/* .IP "\fBmail_owner (postfix)\fR"
 
288
/*      The UNIX system account that owns the Postfix queue and most Postfix
 
289
/*      daemon processes.
 
290
/* .IP "\fBqueue_directory (see 'postconf -d' output)\fR"
 
291
/*      The location of the Postfix top-level queue directory.
 
292
/* .IP "\fBsyslog_facility (mail)\fR"
 
293
/*      The syslog facility of Postfix logging.
 
294
/* .IP "\fBsyslog_name (postfix)\fR"
 
295
/*      The mail system name that is prepended to the process name in syslog
 
296
/*      records, so that "smtpd" becomes, for example, "postfix/smtpd".
 
297
/* .IP "\fBtrigger_timeout (10s)\fR"
 
298
/*      The time limit for sending a trigger to a Postfix daemon (for
 
299
/*      example, the pickup(8) or qmgr(8) daemon).
 
300
/* FILES
 
301
/*      /var/spool/postfix, mail queue
 
302
/*      /etc/postfix, configuration files
 
303
/* SEE ALSO
 
304
/*      pickup(8), mail pickup daemon
 
305
/*      qmgr(8), queue manager
 
306
/*      smtpd(8), SMTP server
 
307
/*      flush(8), fast flush service
 
308
/*      postsuper(1), queue maintenance
 
309
/*      postalias(1), create/update/query alias database
 
310
/*      postdrop(1), mail posting utility
 
311
/*      postfix(1), mail system control
 
312
/*      postqueue(1), mail queue control
 
313
/*      syslogd(8), system logging
 
314
/* README_FILES
 
315
/*      Use "\fBpostconf readme_directory\fR" or
 
316
/*      "\fBpostconf html_directory\fR" to locate this information.
 
317
/*      DEBUG_README, Postfix debugging howto
 
318
/*      ETRN_README, Postfix ETRN howto
 
319
/*      VERP_README, Postfix VERP howto
 
320
/* LICENSE
 
321
/* .ad
 
322
/* .fi
 
323
/*      The Secure Mailer license must be distributed with this software.
 
324
/* AUTHOR(S)
 
325
/*      Wietse Venema
 
326
/*      IBM T.J. Watson Research
 
327
/*      P.O. Box 704
 
328
/*      Yorktown Heights, NY 10598, USA
 
329
/*--*/
 
330
 
 
331
/* System library. */
 
332
 
 
333
#include <sys_defs.h>
 
334
#include <sys/stat.h>
 
335
#include <unistd.h>
 
336
#include <string.h>
 
337
#include <stdio.h>                      /* remove() */
 
338
#include <stdlib.h>
 
339
#include <signal.h>
 
340
#include <fcntl.h>
 
341
#include <syslog.h>
 
342
#include <time.h>
 
343
#include <errno.h>
 
344
#include <ctype.h>
 
345
#include <stdarg.h>
 
346
#include <sysexits.h>
 
347
 
 
348
/* Utility library. */
 
349
 
 
350
#include <msg.h>
 
351
#include <mymalloc.h>
 
352
#include <vstream.h>
 
353
#include <msg_vstream.h>
 
354
#include <msg_syslog.h>
 
355
#include <vstring_vstream.h>
 
356
#include <username.h>
 
357
#include <fullname.h>
 
358
#include <argv.h>
 
359
#include <safe.h>
 
360
#include <iostuff.h>
 
361
#include <stringops.h>
 
362
#include <set_ugid.h>
 
363
#include <connect.h>
 
364
#include <split_at.h>
 
365
 
 
366
/* Global library. */
 
367
 
 
368
#include <mail_queue.h>
 
369
#include <mail_proto.h>
 
370
#include <mail_params.h>
 
371
#include <record.h>
 
372
#include <rec_type.h>
 
373
#include <rec_streamlf.h>
 
374
#include <mail_conf.h>
 
375
#include <cleanup_user.h>
 
376
#include <mail_task.h>
 
377
#include <mail_run.h>
 
378
#include <debug_process.h>
 
379
#include <tok822.h>
 
380
#include <mail_flush.h>
 
381
#include <mail_stream.h>
 
382
#include <verp_sender.h>
 
383
#include <deliver_request.h>
 
384
#include <mime_state.h>
 
385
#include <header_opts.h>
 
386
 
 
387
/* Application-specific. */
 
388
 
 
389
 /*
 
390
  * Modes of operation.
 
391
  */
 
392
#define SM_MODE_ENQUEUE         1       /* delivery mode */
 
393
#define SM_MODE_NEWALIAS        2       /* initialize alias database */
 
394
#define SM_MODE_MAILQ           3       /* list mail queue */
 
395
#define SM_MODE_DAEMON          4       /* daemon mode */
 
396
#define SM_MODE_USER            5       /* user (stand-alone) mode */
 
397
#define SM_MODE_FLUSHQ          6       /* user (stand-alone) mode */
 
398
#define SM_MODE_IGNORE          7       /* ignore this mode */
 
399
 
 
400
 /*
 
401
  * Flag parade. Flags 8-15 are reserved for delivery request trace flags.
 
402
  */
 
403
#define SM_FLAG_AEOF    (1<<0)          /* archaic EOF */
 
404
#define SM_FLAG_XRCPT   (1<<1)          /* extract recipients from headers */
 
405
 
 
406
#define SM_FLAG_DEFAULT (SM_FLAG_AEOF)
 
407
 
 
408
 /*
 
409
  * VERP support.
 
410
  */
 
411
char   *verp_delims;
 
412
 
 
413
 /*
 
414
  * Callback context for extracting recipients.
 
415
  */
 
416
typedef struct SM_STATE {
 
417
    VSTREAM *dst;                       /* output stream */
 
418
    ARGV   *recipients;                 /* recipients from regular headers */
 
419
    ARGV   *resent_recip;               /* recipients from resent headers */
 
420
    int     resent;                     /* resent flag */
 
421
    const char *saved_sender;           /* for error messages */
 
422
    uid_t   uid;                        /* for error messages */
 
423
    VSTRING *temp;                      /* scratch buffer */
 
424
} SM_STATE;
 
425
 
 
426
 /*
 
427
  * Silly little macros (SLMs).
 
428
  */
 
429
#define STR     vstring_str
 
430
 
 
431
/* output_text - output partial or complete text line */
 
432
 
 
433
static void output_text(void *context, int rec_type, const char *buf, int len,
 
434
                                off_t unused_offset)
 
435
{
 
436
    SM_STATE *state = (SM_STATE *) context;
 
437
 
 
438
    if (rec_put(state->dst, rec_type, buf, len) < 0)
 
439
        msg_fatal_status(EX_TEMPFAIL,
 
440
                         "%s(%ld): error writing queue file: %m",
 
441
                         state->saved_sender, (long) state->uid);
 
442
}
 
443
 
 
444
/* output_header - output one message header */
 
445
 
 
446
static void output_header(void *context, int header_class,
 
447
                                  HEADER_OPTS *header_info,
 
448
                                  VSTRING *buf, off_t offset)
 
449
{
 
450
    SM_STATE *state = (SM_STATE *) context;
 
451
    TOK822 *tree;
 
452
    TOK822 **addr_list;
 
453
    TOK822 **tpp;
 
454
    ARGV   *rcpt;
 
455
    char   *start;
 
456
    char   *line;
 
457
    char   *next_line;
 
458
 
 
459
    /*
 
460
     * Parse the header line, and save copies of recipient addresses in the
 
461
     * appropriate place.
 
462
     */
 
463
    if (header_class == MIME_HDR_PRIMARY
 
464
        && header_info
 
465
        && (header_info->flags & HDR_OPT_RECIP)
 
466
        && (header_info->flags & HDR_OPT_EXTRACT)
 
467
        && (state->resent == 0 || (header_info->flags & HDR_OPT_RR))) {
 
468
        if (header_info->flags & HDR_OPT_RR) {
 
469
            rcpt = state->resent_recip;
 
470
            if (state->resent == 0)
 
471
                state->resent = 1;
 
472
        } else
 
473
            rcpt = state->recipients;
 
474
        tree = tok822_parse(vstring_str(buf) + strlen(header_info->name) + 1);
 
475
        addr_list = tok822_grep(tree, TOK822_ADDR);
 
476
        for (tpp = addr_list; *tpp; tpp++) {
 
477
            tok822_internalize(state->temp, tpp[0]->head, TOK822_STR_DEFL);
 
478
            argv_add(rcpt, vstring_str(state->temp), (char *) 0);
 
479
        }
 
480
        myfree((char *) addr_list);
 
481
        tok822_free_tree(tree);
 
482
    }
 
483
 
 
484
    /*
 
485
     * Pipe the unmodified message header through the header line folding
 
486
     * routine.
 
487
     */
 
488
    for (line = start = STR(buf); line; line = next_line) {
 
489
        next_line = split_at(line, '\n');
 
490
        output_text(context, REC_TYPE_NORM, line, next_line ?
 
491
                    next_line - line - 1 : strlen(line), offset);
 
492
    }
 
493
}
 
494
 
 
495
/* enqueue - post one message */
 
496
 
 
497
static void enqueue(const int flags, const char *encoding, const char *sender,
 
498
                            const char *full_name, char **recipients)
 
499
{
 
500
    VSTRING *buf;
 
501
    VSTREAM *dst;
 
502
    char   *saved_sender;
 
503
    char  **cpp;
 
504
    int     type;
 
505
    char   *start;
 
506
    int     skip_from_;
 
507
    TOK822 *tree;
 
508
    TOK822 *tp;
 
509
    enum {
 
510
        STRIP_CR_DUNNO, STRIP_CR_DO, STRIP_CR_DONT
 
511
    }       strip_cr;
 
512
    MAIL_STREAM *handle;
 
513
    char   *postdrop_command;
 
514
    uid_t   uid = getuid();
 
515
    int     status;
 
516
    int     naddr;
 
517
    int     prev_type;
 
518
    MIME_STATE *mime_state = 0;
 
519
    SM_STATE state;
 
520
    int     mime_errs;
 
521
 
 
522
    /*
 
523
     * Initialize.
 
524
     */
 
525
    buf = vstring_alloc(100);
 
526
 
 
527
    /*
 
528
     * Stop run-away process accidents by limiting the queue file size. This
 
529
     * is not a defense against DOS attack.
 
530
     */
 
531
    if (var_message_limit > 0 && get_file_limit() > var_message_limit)
 
532
        set_file_limit((off_t) var_message_limit);
 
533
 
 
534
    /*
 
535
     * The sender name is provided by the user. In principle, the mail pickup
 
536
     * service could deduce the sender name from queue file ownership, but:
 
537
     * pickup would not be able to run chrooted, and it may not be desirable
 
538
     * to use login names at all.
 
539
     */
 
540
    if (sender != 0) {
 
541
        VSTRING_RESET(buf);
 
542
        VSTRING_TERMINATE(buf);
 
543
        tree = tok822_parse(sender);
 
544
        for (naddr = 0, tp = tree; tp != 0; tp = tp->next)
 
545
            if (tp->type == TOK822_ADDR && naddr++ == 0)
 
546
                tok822_internalize(buf, tp->head, TOK822_STR_DEFL);
 
547
        tok822_free_tree(tree);
 
548
        saved_sender = mystrdup(STR(buf));
 
549
        if (naddr > 1)
 
550
            msg_warn("-f option specified malformed sender: %s", sender);
 
551
    } else {
 
552
        if ((sender = username()) == 0)
 
553
            msg_fatal_status(EX_OSERR, "no login name found for user ID %lu",
 
554
                             (unsigned long) uid);
 
555
        saved_sender = mystrdup(sender);
 
556
    }
 
557
 
 
558
    /*
 
559
     * Let the postdrop command open the queue file for us, and sanity check
 
560
     * the content. XXX Make postdrop a manifest constant.
 
561
     */
 
562
    errno = 0;
 
563
    postdrop_command = concatenate(var_command_dir, "/postdrop -r",
 
564
                              msg_verbose ? " -v" : (char *) 0, (char *) 0);
 
565
    if ((handle = mail_stream_command(postdrop_command)) == 0)
 
566
        msg_fatal_status(EX_UNAVAILABLE, "%s(%ld): unable to execute %s: %m",
 
567
                         saved_sender, (long) uid, postdrop_command);
 
568
    myfree(postdrop_command);
 
569
    dst = handle->stream;
 
570
 
 
571
    /*
 
572
     * First, write envelope information to the output stream.
 
573
     * 
 
574
     * For sendmail compatibility, parse each command-line recipient as if it
 
575
     * were an RFC 822 message header; some MUAs specify comma-separated
 
576
     * recipient lists; and some MUAs even specify "word word <address>".
 
577
     * 
 
578
     * Sort-uniq-ing the recipient list is done after address canonicalization,
 
579
     * before recipients are written to queue file. That's cleaner than
 
580
     * having the queue manager nuke duplicate recipient status records.
 
581
     * 
 
582
     * XXX Should limit the size of envelope records.
 
583
     */
 
584
    if (full_name || (full_name = fullname()) != 0)
 
585
        rec_fputs(dst, REC_TYPE_FULL, full_name);
 
586
    rec_fputs(dst, REC_TYPE_FROM, saved_sender);
 
587
    if (verp_delims && *saved_sender == 0)
 
588
        msg_fatal_status(EX_USAGE,
 
589
                         "-V option requires non-null sender address");
 
590
    if (encoding)
 
591
        rec_fprintf(dst, REC_TYPE_ATTR, "%s=%s", MAIL_ATTR_ENCODING, encoding);
 
592
    if (DEL_REQ_TRACE_FLAGS(flags))
 
593
        rec_fprintf(dst, REC_TYPE_ATTR, "%s=%d", MAIL_ATTR_TRACE_FLAGS,
 
594
                    DEL_REQ_TRACE_FLAGS(flags));
 
595
    if (verp_delims)
 
596
        rec_fputs(dst, REC_TYPE_VERP, verp_delims);
 
597
    if (recipients) {
 
598
        for (cpp = recipients; *cpp != 0; cpp++) {
 
599
            tree = tok822_parse(*cpp);
 
600
            for (tp = tree; tp != 0; tp = tp->next) {
 
601
                if (tp->type == TOK822_ADDR) {
 
602
                    tok822_internalize(buf, tp->head, TOK822_STR_DEFL);
 
603
                    if (REC_PUT_BUF(dst, REC_TYPE_RCPT, buf) < 0)
 
604
                        msg_fatal_status(EX_TEMPFAIL,
 
605
                                    "%s(%ld): error writing queue file: %m",
 
606
                                         saved_sender, (long) uid);
 
607
                }
 
608
            }
 
609
            tok822_free_tree(tree);
 
610
        }
 
611
    }
 
612
 
 
613
    /*
 
614
     * Append the message contents to the queue file. Write chunks of at most
 
615
     * 1kbyte. Internally, we use different record types for data ending in
 
616
     * LF and for data that doesn't, so we can actually be binary transparent
 
617
     * for local mail. Unfortunately, SMTP has no record continuation
 
618
     * convention, so there is no guarantee that arbitrary data will be
 
619
     * delivered intact via SMTP. Strip leading From_ lines. For the benefit
 
620
     * of UUCP environments, also get rid of leading >>>From_ lines.
 
621
     */
 
622
    rec_fputs(dst, REC_TYPE_MESG, "");
 
623
    if (DEL_REQ_TRACE_ONLY(flags) != 0) {
 
624
        rec_fprintf(dst, REC_TYPE_NORM, "Subject: probe");
 
625
        if (recipients) {
 
626
            rec_fprintf(dst, REC_TYPE_NORM, "To:");
 
627
            for (cpp = recipients; *cpp != 0; cpp++) {
 
628
                rec_fprintf(dst, REC_TYPE_NORM, "       %s%s",
 
629
                            *cpp, cpp[1] ? "," : "");
 
630
            }
 
631
        }
 
632
    } else {
 
633
 
 
634
        /*
 
635
         * Initialize the MIME processor and set up the callback context.
 
636
         */
 
637
        if (flags & SM_FLAG_XRCPT) {
 
638
            state.dst = dst;
 
639
            state.recipients = argv_alloc(2);
 
640
            state.resent_recip = argv_alloc(2);
 
641
            state.resent = 0;
 
642
            state.saved_sender = saved_sender;
 
643
            state.uid = uid;
 
644
            state.temp = vstring_alloc(10);
 
645
            mime_state = mime_state_alloc(MIME_OPT_DISABLE_MIME
 
646
                                          | MIME_OPT_REPORT_TRUNC_HEADER,
 
647
                                          output_header,
 
648
                                          (MIME_STATE_ANY_END) 0,
 
649
                                          output_text,
 
650
                                          (MIME_STATE_ANY_END) 0,
 
651
                                          (MIME_STATE_ERR_PRINT) 0,
 
652
                                          (void *) &state);
 
653
        }
 
654
 
 
655
        /*
 
656
         * Process header/body lines.
 
657
         */
 
658
        skip_from_ = 1;
 
659
        strip_cr = STRIP_CR_DUNNO;
 
660
        for (prev_type = 0; (type = rec_streamlf_get(VSTREAM_IN, buf, var_line_limit))
 
661
             != REC_TYPE_EOF; prev_type = type) {
 
662
            if (strip_cr == STRIP_CR_DUNNO && type == REC_TYPE_NORM) {
 
663
                if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
 
664
                    strip_cr = STRIP_CR_DO;
 
665
                else
 
666
                    strip_cr = STRIP_CR_DONT;
 
667
            }
 
668
            if (skip_from_) {
 
669
                if (type == REC_TYPE_NORM) {
 
670
                    start = vstring_str(buf);
 
671
                    if (strncmp(start + strspn(start, ">"), "From ", 5) == 0)
 
672
                        continue;
 
673
                }
 
674
                skip_from_ = 0;
 
675
            }
 
676
            if (strip_cr == STRIP_CR_DO && type == REC_TYPE_NORM)
 
677
                if (VSTRING_LEN(buf) > 0 && vstring_end(buf)[-1] == '\r')
 
678
                    vstring_truncate(buf, VSTRING_LEN(buf) - 1);
 
679
            if ((flags & SM_FLAG_AEOF) && prev_type != REC_TYPE_CONT
 
680
                && VSTRING_LEN(buf) == 1 && *STR(buf) == '.')
 
681
                break;
 
682
            if (mime_state) {
 
683
                mime_errs = mime_state_update(mime_state, type, STR(buf),
 
684
                                              VSTRING_LEN(buf));
 
685
                if (mime_errs)
 
686
                    msg_fatal_status(EX_DATAERR,
 
687
                                "%s(%ld): unable to extract recipients: %s",
 
688
                                     saved_sender, (long) uid,
 
689
                                     mime_state_error(mime_errs));
 
690
            } else {
 
691
                if (REC_PUT_BUF(dst, type, buf) < 0)
 
692
                    msg_fatal_status(EX_TEMPFAIL,
 
693
                                     "%s(%ld): error writing queue file: %m",
 
694
                                     saved_sender, (long) uid);
 
695
            }
 
696
        }
 
697
    }
 
698
 
 
699
    /*
 
700
     * Finish MIME processing. We need a final mime_state_update() call in
 
701
     * order to flush text that is still buffered. That can happen when the
 
702
     * last line did not end in newline.
 
703
     */
 
704
    if (mime_state) {
 
705
        mime_errs = mime_state_update(mime_state, REC_TYPE_EOF, "", 0);
 
706
        if (mime_errs)
 
707
            msg_fatal_status(EX_DATAERR,
 
708
                             "%s(%ld): unable to extract recipients: %s",
 
709
                             saved_sender, (long) uid,
 
710
                             mime_state_error(mime_errs));
 
711
        mime_state = mime_state_free(mime_state);
 
712
    }
 
713
 
 
714
    /*
 
715
     * Append recipient addresses that were extracted from message headers.
 
716
     */
 
717
    rec_fputs(dst, REC_TYPE_XTRA, "");
 
718
    if (flags & SM_FLAG_XRCPT) {
 
719
        for (cpp = state.resent ? state.resent_recip->argv :
 
720
             state.recipients->argv; *cpp; cpp++) {
 
721
            if (rec_put(dst, REC_TYPE_RCPT, *cpp, strlen(*cpp)) < 0)
 
722
                msg_fatal_status(EX_TEMPFAIL,
 
723
                                 "%s(%ld): error writing queue file: %m",
 
724
                                 saved_sender, (long) uid);
 
725
        }
 
726
        argv_free(state.recipients);
 
727
        argv_free(state.resent_recip);
 
728
        vstring_free(state.temp);
 
729
    }
 
730
 
 
731
    /*
 
732
     * Identify the end of the queue file.
 
733
     */
 
734
    rec_fputs(dst, REC_TYPE_END, "");
 
735
 
 
736
    /*
 
737
     * Make sure that the message makes it to the file system. Once we have
 
738
     * terminated with successful exit status we cannot lose the message due
 
739
     * to "frivolous reasons". If all goes well, prevent the run-time error
 
740
     * handler from removing the file.
 
741
     */
 
742
    if (vstream_ferror(VSTREAM_IN))
 
743
        msg_fatal_status(EX_DATAERR, "%s(%ld): error reading input: %m",
 
744
                         saved_sender, (long) uid);
 
745
    if ((status = mail_stream_finish(handle, (VSTRING *) 0)) != 0)
 
746
        msg_fatal_status((status & CLEANUP_STAT_BAD) ? EX_SOFTWARE :
 
747
                         (status & CLEANUP_STAT_WRITE) ? EX_TEMPFAIL :
 
748
                         EX_UNAVAILABLE, "%s(%ld): %s", saved_sender,
 
749
                         (long) uid, cleanup_strerror(status));
 
750
 
 
751
    /*
 
752
     * Don't leave them in the dark.
 
753
     */
 
754
    if (DEL_REQ_TRACE_FLAGS(flags)) {
 
755
        vstream_printf("Mail Delivery Status Report will be mailed to <%s>.\n",
 
756
                       saved_sender);
 
757
        vstream_fflush(VSTREAM_OUT);
 
758
    }
 
759
 
 
760
    /*
 
761
     * Cleanup. Not really necessary as we're about to exit, but good for
 
762
     * debugging purposes.
 
763
     */
 
764
    vstring_free(buf);
 
765
    myfree(saved_sender);
 
766
}
 
767
 
 
768
/* main - the main program */
 
769
 
 
770
int     main(int argc, char **argv)
 
771
{
 
772
    static char *full_name = 0;         /* sendmail -F */
 
773
    struct stat st;
 
774
    char   *slash;
 
775
    char   *sender = 0;                 /* sendmail -f */
 
776
    int     c;
 
777
    int     fd;
 
778
    int     mode;
 
779
    ARGV   *ext_argv;
 
780
    int     debug_me = 0;
 
781
    int     err;
 
782
    int     n;
 
783
    int     flags = SM_FLAG_DEFAULT;
 
784
    char   *site_to_flush = 0;
 
785
    char   *encoding = 0;
 
786
    char   *qtime = 0;
 
787
 
 
788
    /*
 
789
     * Be consistent with file permissions.
 
790
     */
 
791
    umask(022);
 
792
 
 
793
    /*
 
794
     * To minimize confusion, make sure that the standard file descriptors
 
795
     * are open before opening anything else. XXX Work around for 44BSD where
 
796
     * fstat can return EBADF on an open file descriptor.
 
797
     */
 
798
    for (fd = 0; fd < 3; fd++)
 
799
        if (fstat(fd, &st) == -1
 
800
            && (close(fd), open("/dev/null", O_RDWR, 0)) != fd)
 
801
            msg_fatal_status(EX_OSERR, "open /dev/null: %m");
 
802
 
 
803
    /*
 
804
     * The CDE desktop calendar manager leaks a parent file descriptor into
 
805
     * the child process. For the sake of sendmail compatibility we have to
 
806
     * close the file descriptor otherwise mail notification will hang.
 
807
     */
 
808
    for ( /* void */ ; fd < 100; fd++)
 
809
        (void) close(fd);
 
810
 
 
811
    /*
 
812
     * Process environment options as early as we can. We might be called
 
813
     * from a set-uid (set-gid) program, so be careful with importing
 
814
     * environment variables.
 
815
     */
 
816
    if (safe_getenv(CONF_ENV_VERB))
 
817
        msg_verbose = 1;
 
818
    if (safe_getenv(CONF_ENV_DEBUG))
 
819
        debug_me = 1;
 
820
 
 
821
    /*
 
822
     * Initialize. Set up logging, read the global configuration file and
 
823
     * extract configuration information. Set up signal handlers so that we
 
824
     * can clean up incomplete output.
 
825
     */
 
826
    if ((slash = strrchr(argv[0], '/')) != 0 && slash[1])
 
827
        argv[0] = slash + 1;
 
828
    msg_vstream_init(argv[0], VSTREAM_ERR);
 
829
    msg_syslog_init(mail_task("sendmail"), LOG_PID, LOG_FACILITY);
 
830
    set_mail_conf_str(VAR_PROCNAME, var_procname = mystrdup(argv[0]));
 
831
 
 
832
    /*
 
833
     * Some sites mistakenly install Postfix sendmail as set-uid root. Drop
 
834
     * set-uid privileges only when root, otherwise some systems will not
 
835
     * reset the saved set-userid, which would be a security vulnerability.
 
836
     */
 
837
    if (geteuid() == 0 && getuid() != 0) {
 
838
        msg_warn("the Postfix sendmail command has set-uid root file permissions");
 
839
        msg_warn("or the command is run from a set-uid root process");
 
840
        msg_warn("the Postfix sendmail command must be installed without set-uid root file permissions");
 
841
        set_ugid(getuid(), getgid());
 
842
    }
 
843
 
 
844
    /*
 
845
     * Further initialization...
 
846
     */
 
847
    mail_conf_read();
 
848
 
 
849
    if (chdir(var_queue_dir))
 
850
        msg_fatal_status(EX_UNAVAILABLE, "chdir %s: %m", var_queue_dir);
 
851
 
 
852
    signal(SIGPIPE, SIG_IGN);
 
853
 
 
854
    /*
 
855
     * Optionally start the debugger on ourself. This must be done after
 
856
     * reading the global configuration file, because that file specifies
 
857
     * what debugger command to execute.
 
858
     */
 
859
    if (debug_me)
 
860
        debug_process();
 
861
 
 
862
    /*
 
863
     * The default mode of operation is determined by the process name. It
 
864
     * can, however, be changed via command-line options (for example,
 
865
     * "newaliases -bp" will show the mail queue).
 
866
     */
 
867
    if (strcmp(argv[0], "mailq") == 0) {
 
868
        mode = SM_MODE_MAILQ;
 
869
    } else if (strcmp(argv[0], "newaliases") == 0) {
 
870
        mode = SM_MODE_NEWALIAS;
 
871
    } else if (strcmp(argv[0], "smtpd") == 0) {
 
872
        mode = SM_MODE_DAEMON;
 
873
    } else {
 
874
        mode = SM_MODE_ENQUEUE;
 
875
    }
 
876
 
 
877
    /*
 
878
     * Parse JCL. Sendmail has been around for a long time, and has acquired
 
879
     * a large number of options in the course of time. Some options such as
 
880
     * -q are not parsable with GETOPT() and get special treatment.
 
881
     */
 
882
#define OPTIND  (optind > 0 ? optind : 1)
 
883
 
 
884
    while (argv[OPTIND] != 0) {
 
885
        if (strcmp(argv[OPTIND], "-q") == 0) {
 
886
            if (mode == SM_MODE_DAEMON)
 
887
                msg_warn("ignoring -q option in daemon mode");
 
888
            else
 
889
                mode = SM_MODE_FLUSHQ;
 
890
            optind++;
 
891
            continue;
 
892
        }
 
893
        if (strcmp(argv[OPTIND], "-V") == 0) {
 
894
            verp_delims = var_verp_delims;
 
895
            optind++;
 
896
            continue;
 
897
        }
 
898
        if ((c = GETOPT(argc, argv, "A:B:C:F:GIL:N:R:UV:X:b:ce:f:h:imno:p:r:q:tvx")) <= 0)
 
899
            break;
 
900
        switch (c) {
 
901
        default:
 
902
            if (msg_verbose)
 
903
                msg_info("-%c option ignored", c);
 
904
            break;
 
905
        case 'n':
 
906
            msg_fatal_status(EX_USAGE, "-%c option not supported", c);
 
907
        case 'B':
 
908
            if (strcmp(optarg, "8BITMIME") == 0)/* RFC 1652 */
 
909
                encoding = MAIL_ATTR_ENC_8BIT;
 
910
            else if (strcmp(optarg, "7BIT") == 0)       /* RFC 1652 */
 
911
                encoding = MAIL_ATTR_ENC_7BIT;
 
912
            else
 
913
                msg_fatal_status(EX_USAGE, "-B option needs 8BITMIME or 7BIT");
 
914
            break;
 
915
        case 'F':                               /* full name */
 
916
            full_name = optarg;
 
917
            break;
 
918
        case 'I':                               /* newaliases */
 
919
            mode = SM_MODE_NEWALIAS;
 
920
            break;
 
921
        case 'V':                               /* VERP */
 
922
            if (verp_delims_verify(optarg) != 0)
 
923
                msg_fatal_status(EX_USAGE, "-V requires two characters from %s",
 
924
                                 var_verp_filter);
 
925
            verp_delims = optarg;
 
926
            break;
 
927
        case 'b':
 
928
            switch (*optarg) {
 
929
            default:
 
930
                msg_fatal_status(EX_USAGE, "unsupported: -%c%c", c, *optarg);
 
931
            case 'd':                           /* daemon mode */
 
932
                if (mode == SM_MODE_FLUSHQ)
 
933
                    msg_warn("ignoring -q option in daemon mode");
 
934
                mode = SM_MODE_DAEMON;
 
935
                break;
 
936
            case 'h':                           /* print host status */
 
937
            case 'H':                           /* flush host status */
 
938
                mode = SM_MODE_IGNORE;
 
939
                break;
 
940
            case 'i':                           /* newaliases */
 
941
                mode = SM_MODE_NEWALIAS;
 
942
                break;
 
943
            case 'm':                           /* deliver mail */
 
944
                mode = SM_MODE_ENQUEUE;
 
945
                break;
 
946
            case 'p':                           /* mailq */
 
947
                mode = SM_MODE_MAILQ;
 
948
                break;
 
949
            case 's':                           /* stand-alone mode */
 
950
                mode = SM_MODE_USER;
 
951
                break;
 
952
            case 'v':                           /* expand recipients */
 
953
                flags |= DEL_REQ_FLAG_EXPAND;
 
954
                break;
 
955
            }
 
956
            break;
 
957
        case 'f':
 
958
            sender = optarg;
 
959
            break;
 
960
        case 'i':
 
961
            flags &= ~SM_FLAG_AEOF;
 
962
            break;
 
963
        case 'o':
 
964
            switch (*optarg) {
 
965
            default:
 
966
                if (msg_verbose)
 
967
                    msg_info("-%c%c option ignored", c, *optarg);
 
968
                break;
 
969
            case 'A':
 
970
                if (optarg[1] == 0)
 
971
                    msg_fatal_status(EX_USAGE, "-oA requires pathname");
 
972
                myfree(var_alias_db_map);
 
973
                var_alias_db_map = mystrdup(optarg + 1);
 
974
                set_mail_conf_str(VAR_ALIAS_DB_MAP, var_alias_db_map);
 
975
                break;
 
976
            case '7':
 
977
            case '8':
 
978
                break;
 
979
            case 'i':
 
980
                flags &= ~SM_FLAG_AEOF;
 
981
                break;
 
982
            case 'm':
 
983
                break;
 
984
            }
 
985
            break;
 
986
        case 'r':                               /* obsoleted by -f */
 
987
            sender = optarg;
 
988
            break;
 
989
        case 'q':
 
990
            if (ISDIGIT(optarg[0])) {
 
991
                qtime = optarg;
 
992
            } else if (optarg[0] == 'R') {
 
993
                site_to_flush = optarg + 1;
 
994
                if (*site_to_flush == 0)
 
995
                    msg_fatal_status(EX_USAGE, "specify: -qRsitename");
 
996
            } else {
 
997
                msg_fatal_status(EX_USAGE, "-q%c is not implemented",
 
998
                                 optarg[0]);
 
999
            }
 
1000
            break;
 
1001
        case 't':
 
1002
            flags |= SM_FLAG_XRCPT;
 
1003
            break;
 
1004
        case 'v':
 
1005
            msg_verbose++;
 
1006
            break;
 
1007
        case '?':
 
1008
            msg_fatal_status(EX_USAGE, "usage: %s [options]", argv[0]);
 
1009
        }
 
1010
    }
 
1011
 
 
1012
    /*
 
1013
     * Look for conflicting options and arguments.
 
1014
     */
 
1015
    if ((flags & SM_FLAG_XRCPT) && mode != SM_MODE_ENQUEUE)
 
1016
        msg_fatal_status(EX_USAGE, "-t can be used only in delivery mode");
 
1017
 
 
1018
    if (site_to_flush && mode != SM_MODE_ENQUEUE)
 
1019
        msg_fatal_status(EX_USAGE, "-qR can be used only in delivery mode");
 
1020
 
 
1021
    /*
 
1022
     * The -v option plays double duty. One requests verbose delivery, more
 
1023
     * than one requests verbose logging.
 
1024
     */
 
1025
    if (msg_verbose == 1 && mode == SM_MODE_ENQUEUE) {
 
1026
        msg_verbose = 0;
 
1027
        flags |= DEL_REQ_FLAG_RECORD;
 
1028
    }
 
1029
 
 
1030
    /*
 
1031
     * Start processing. Everything is delegated to external commands.
 
1032
     */
 
1033
    if (qtime && mode != SM_MODE_DAEMON)
 
1034
        exit(0);
 
1035
    switch (mode) {
 
1036
    default:
 
1037
        msg_panic("unknown operation mode: %d", mode);
 
1038
        /* NOTREACHED */
 
1039
    case SM_MODE_ENQUEUE:
 
1040
        if (site_to_flush == 0) {
 
1041
            enqueue(flags, encoding, sender, full_name, argv + OPTIND);
 
1042
            exit(0);
 
1043
        }
 
1044
        if (argv[OPTIND])
 
1045
            msg_fatal_status(EX_USAGE, "flush site requires no recipient");
 
1046
        ext_argv = argv_alloc(2);
 
1047
        argv_add(ext_argv, "postqueue", "-s", site_to_flush, (char *) 0);
 
1048
        for (n = 0; n < msg_verbose; n++)
 
1049
            argv_add(ext_argv, "-v", (char *) 0);
 
1050
        argv_terminate(ext_argv);
 
1051
        mail_run_replace(var_command_dir, ext_argv->argv);
 
1052
        /* NOTREACHED */
 
1053
        break;
 
1054
    case SM_MODE_MAILQ:
 
1055
        if (argv[OPTIND])
 
1056
            msg_fatal_status(EX_USAGE,
 
1057
                             "display queue mode requires no recipient");
 
1058
        ext_argv = argv_alloc(2);
 
1059
        argv_add(ext_argv, "postqueue", "-p", (char *) 0);
 
1060
        for (n = 0; n < msg_verbose; n++)
 
1061
            argv_add(ext_argv, "-v", (char *) 0);
 
1062
        argv_terminate(ext_argv);
 
1063
        mail_run_replace(var_command_dir, ext_argv->argv);
 
1064
        /* NOTREACHED */
 
1065
    case SM_MODE_FLUSHQ:
 
1066
        if (argv[OPTIND])
 
1067
            msg_fatal_status(EX_USAGE,
 
1068
                             "flush queue mode requires no recipient");
 
1069
        ext_argv = argv_alloc(2);
 
1070
        argv_add(ext_argv, "postqueue", "-f", (char *) 0);
 
1071
        for (n = 0; n < msg_verbose; n++)
 
1072
            argv_add(ext_argv, "-v", (char *) 0);
 
1073
        argv_terminate(ext_argv);
 
1074
        mail_run_replace(var_command_dir, ext_argv->argv);
 
1075
        /* NOTREACHED */
 
1076
    case SM_MODE_DAEMON:
 
1077
        if (argv[OPTIND])
 
1078
            msg_fatal_status(EX_USAGE, "daemon mode requires no recipient");
 
1079
        ext_argv = argv_alloc(2);
 
1080
        argv_add(ext_argv, "postfix", (char *) 0);
 
1081
        for (n = 0; n < msg_verbose; n++)
 
1082
            argv_add(ext_argv, "-v", (char *) 0);
 
1083
        argv_add(ext_argv, "start", (char *) 0);
 
1084
        argv_terminate(ext_argv);
 
1085
        err = (mail_run_background(var_command_dir, ext_argv->argv) < 0);
 
1086
        argv_free(ext_argv);
 
1087
        exit(err);
 
1088
        break;
 
1089
    case SM_MODE_NEWALIAS:
 
1090
        if (argv[OPTIND])
 
1091
            msg_fatal_status(EX_USAGE,
 
1092
                         "alias initialization mode requires no recipient");
 
1093
        if (*var_alias_db_map == 0)
 
1094
            return (0);
 
1095
        ext_argv = argv_alloc(2);
 
1096
        argv_add(ext_argv, "postalias", (char *) 0);
 
1097
        for (n = 0; n < msg_verbose; n++)
 
1098
            argv_add(ext_argv, "-v", (char *) 0);
 
1099
        argv_split_append(ext_argv, var_alias_db_map, ", \t\r\n");
 
1100
        argv_terminate(ext_argv);
 
1101
        mail_run_replace(var_command_dir, ext_argv->argv);
 
1102
        /* NOTREACHED */
 
1103
    case SM_MODE_USER:
 
1104
        if (argv[OPTIND])
 
1105
            msg_fatal_status(EX_USAGE,
 
1106
                             "stand-alone mode requires no recipient");
 
1107
        ext_argv = argv_alloc(2);
 
1108
        argv_add(ext_argv, "smtpd", "-S", (char *) 0);
 
1109
        for (n = 0; n < msg_verbose; n++)
 
1110
            argv_add(ext_argv, "-v", (char *) 0);
 
1111
        argv_terminate(ext_argv);
 
1112
        mail_run_replace(var_daemon_dir, ext_argv->argv);
 
1113
        /* NOTREACHED */
 
1114
    case SM_MODE_IGNORE:
 
1115
        exit(0);
 
1116
        /* NOTREACHED */
 
1117
    }
 
1118
}