more cleanup for DSN drafts
[unix-history] / usr / src / usr.sbin / sendmail / src / deliver.c
CommitLineData
d185cb11 1/*
dc45ba8c 2 * Copyright (c) 1983 Eric P. Allman
31de980b
KB
3 * Copyright (c) 1988, 1993
4 * The Regents of the University of California. All rights reserved.
bee79b64 5 *
417f7a11 6 * %sccs.include.redist.c%
bee79b64 7 */
d185cb11
DF
8
9#ifndef lint
66d16835 10static char sccsid[] = "@(#)deliver.c 8.137 (Berkeley) %G%";
bee79b64 11#endif /* not lint */
d185cb11 12
97543758 13#include "sendmail.h"
7b6e7aee
KB
14#include <netdb.h>
15#include <errno.h>
efe7f723 16#if NAMED_BIND
f28c9fe2 17#include <resolv.h>
8e5c6745
EA
18
19extern int h_errno;
35af2f06 20#endif
b3cbe40f 21
965c2488
EA
22extern char SmtpError[];
23
b3cbe40f 24/*
6acfa498 25** SENDALL -- actually send all the messages.
b3cbe40f 26**
b3cbe40f 27** Parameters:
6acfa498
EA
28** e -- the envelope to send.
29** mode -- the delivery mode to use. If SM_DEFAULT, use
30** the current e->e_sendmode.
b3cbe40f
EA
31**
32** Returns:
6acfa498 33** none.
b3cbe40f
EA
34**
35** Side Effects:
6acfa498
EA
36** Scans the send lists and sends everything it finds.
37** Delivers any appropriate error messages.
38** If we are running in a non-interactive mode, takes the
39** appropriate action.
b3cbe40f
EA
40*/
41
ea07b2d2 42void
6acfa498
EA
43sendall(e, mode)
44 ENVELOPE *e;
45 char mode;
b3cbe40f 46{
6acfa498
EA
47 register ADDRESS *q;
48 char *owner;
49 int otherowners;
11024b4c 50 bool oldverbose = Verbose;
1ce944f0 51 bool somedeliveries = FALSE;
11024b4c 52 int pid;
ea07b2d2 53 extern void sendenvelope();
1d303d98
EA
54 int pid;
55#ifdef LOCKF
56 struct flock lfd;
57#endif
b3cbe40f 58
d4f6a25e
EA
59 /*
60 ** If we have had global, fatal errors, don't bother sending
61 ** the message at all if we are in SMTP mode. Local errors
62 ** (e.g., a single address failing) will still cause the other
63 ** addresses to be sent.
64 */
65
198d9e9c
EA
66 if (bitset(EF_FATALERRS, e->e_flags) &&
67 (OpMode == MD_SMTP || OpMode == MD_DAEMON))
004a2b9c 68 {
004a2b9c
EA
69 e->e_flags |= EF_CLRQUEUE;
70 return;
71 }
72
6acfa498 73 /* determine actual delivery mode */
fc826a82 74 CurrentLA = getla();
6acfa498
EA
75 if (mode == SM_DEFAULT)
76 {
6acfa498
EA
77 mode = e->e_sendmode;
78 if (mode != SM_VERIFY &&
79 shouldqueue(e->e_msgpriority, e->e_ctime))
80 mode = SM_QUEUE;
f28c9fe2 81 }
3135d20c 82
6acfa498 83 if (tTd(13, 1))
3135d20c 84 {
1ce944f0
EA
85 extern void printenvflags();
86
b5618bbc
EA
87 printf("\n===== SENDALL: mode %c, id %s, e_from ",
88 mode, e->e_id);
6acfa498 89 printaddr(&e->e_from, FALSE);
1ce944f0
EA
90 printf("\te_flags = ");
91 printenvflags(e);
6acfa498
EA
92 printf("sendqueue:\n");
93 printaddr(e->e_sendqueue, TRUE);
3135d20c
EA
94 }
95
a530c75f 96 /*
6acfa498
EA
97 ** Do any preprocessing necessary for the mode we are running.
98 ** Check to make sure the hop count is reasonable.
99 ** Delete sends to the sender in mailing lists.
a530c75f
EA
100 */
101
6acfa498 102 CurEnv = e;
a530c75f 103
6acfa498 104 if (e->e_hopcount > MaxHopCount)
779597d8 105 {
6acfa498 106 errno = 0;
1ce944f0 107 queueup(e, TRUE, mode == SM_QUEUE);
ec33213e 108 e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
b8b715bc 109 syserr("554 too many hops %d (%d max): from %s via %s, to %s",
6acfa498 110 e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
389c0d5e
EA
111 RealHostName == NULL ? "localhost" : RealHostName,
112 e->e_sendqueue->q_paddr);
6acfa498 113 return;
779597d8 114 }
b3cbe40f 115
2eb74b19
EA
116 /*
117 ** Do sender deletion.
118 **
119 ** If the sender has the QQUEUEUP flag set, skip this.
120 ** This can happen if the name server is hosed when you
121 ** are trying to send mail. The result is that the sender
122 ** is instantiated in the queue as a recipient.
123 */
124
80ec5253
EA
125 if (!bitset(EF_METOO, e->e_flags) &&
126 !bitset(QQUEUEUP, e->e_from.q_flags))
b3cbe40f 127 {
6acfa498 128 if (tTd(13, 5))
779597d8 129 {
6acfa498
EA
130 printf("sendall: QDONTSEND ");
131 printaddr(&e->e_from, FALSE);
779597d8 132 }
6acfa498 133 e->e_from.q_flags |= QDONTSEND;
f8c2f9fd 134 (void) recipient(&e->e_from, &e->e_sendqueue, 0, e);
b3cbe40f 135 }
e6b0a75b 136
1d303d98
EA
137# ifdef QUEUE
138 if ((mode == SM_QUEUE || mode == SM_FORK ||
139 (mode != SM_VERIFY && SuperSafe)) &&
140 !bitset(EF_INQUEUE, e->e_flags))
141 {
142 /* be sure everything is instantiated in the queue */
143 queueup(e, TRUE, mode == SM_QUEUE);
144 }
145#endif /* QUEUE */
146
147 switch (mode)
148 {
149 case SM_VERIFY:
150 Verbose = TRUE;
151 break;
152
153 case SM_QUEUE:
154 queueonly:
155 e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
156 return;
157
158 case SM_FORK:
159 if (e->e_xfp != NULL)
160 (void) fflush(e->e_xfp);
161
162# ifdef LOCKF
163 /*
164 ** Since lockf has the interesting semantic that the
165 ** lock is lost when we fork, we have to risk losing
166 ** the lock here by closing before the fork, and then
167 ** trying to get it back in the child.
168 */
169
170 if (e->e_lockfp != NULL)
171 {
172 (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp");
173 e->e_lockfp = NULL;
174 }
175# endif /* LOCKF */
176
177 pid = fork();
178 if (pid < 0)
179 {
180 goto queueonly;
181 }
182 else if (pid > 0)
183 {
184 /* be sure we leave the temp files to our child */
185 e->e_id = e->e_df = NULL;
186# ifndef LOCKF
187 if (e->e_lockfp != NULL)
188 {
189 (void) xfclose(e->e_lockfp, "sendenvelope", "lockfp");
190 e->e_lockfp = NULL;
191 }
192# endif
193
194 /* close any random open files in the envelope */
195 if (e->e_dfp != NULL)
196 {
197 (void) xfclose(e->e_dfp, "sendenvelope", "dfp");
198 e->e_dfp = NULL;
199 }
200 if (e->e_xfp != NULL)
201 {
202 (void) xfclose(e->e_xfp, "sendenvelope", "xfp");
203 e->e_xfp = NULL;
204 }
205 return;
206 }
207
208 /* double fork to avoid zombies */
209 if (fork() > 0)
210 exit(EX_OK);
211
212 /* be sure we are immune from the terminal */
213 disconnect(FALSE, e);
214
215# ifdef LOCKF
216 /*
217 ** Now try to get our lock back.
218 */
219
220 lfd.l_type = F_WRLCK;
221 lfd.l_whence = lfd.l_start = lfd.l_len = 0;
222 e->e_lockfp = fopen(queuename(e, 'q'), "r+");
223 if (e->e_lockfp == NULL ||
224 fcntl(fileno(e->e_lockfp), F_SETLK, &lfd) < 0)
225 {
226 /* oops.... lost it */
227 if (tTd(13, 1))
228 printf("sendenvelope: %s lost lock: lockfp=%x, %s\n",
229 e->e_id, e->e_lockfp, errstring(errno));
230
231# ifdef LOG
232 if (LogLevel > 29)
233 syslog(LOG_NOTICE, "%s: lost lock: %m",
234 e->e_id);
235# endif /* LOG */
236 exit(EX_OK);
237 }
238# endif /* LOCKF */
239
240 /*
241 ** Close any cached connections.
242 **
243 ** We don't send the QUIT protocol because the parent
244 ** still knows about the connection.
245 **
246 ** This should only happen when delivering an error
247 ** message.
248 */
249
250 mci_flush(FALSE, NULL);
251
252 break;
253 }
254
255 /*
256 ** If we haven't fully expanded aliases, do it now
257 */
258
259 if (bitset(EF_VRFYONLY, e->e_flags))
260 {
261 e->e_flags &= ~EF_VRFYONLY;
262 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
263 {
264 extern ADDRESS *recipient();
265
266 if (bitset(QVERIFIED, q->q_flags))
267 recipient(q, &e->e_sendqueue, e);
268 }
269 }
270
1ab402f2 271 /*
6acfa498
EA
272 ** Handle alias owners.
273 **
274 ** We scan up the q_alias chain looking for owners.
275 ** We discard owners that are the same as the return path.
b3cbe40f
EA
276 */
277
6acfa498 278 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
b3cbe40f 279 {
6acfa498 280 register struct address *a;
779597d8 281
6acfa498 282 for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias)
779597d8 283 continue;
6acfa498
EA
284 if (a != NULL)
285 q->q_owner = a->q_owner;
286
287 if (q->q_owner != NULL &&
288 !bitset(QDONTSEND, q->q_flags) &&
289 strcmp(q->q_owner, e->e_from.q_paddr) == 0)
290 q->q_owner = NULL;
291 }
292
293 owner = "";
294 otherowners = 1;
295 while (owner != NULL && otherowners > 0)
296 {
297 owner = NULL;
298 otherowners = 0;
1bf7c76b 299
6acfa498 300 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
78bbbc48 301 {
6acfa498
EA
302 if (bitset(QDONTSEND, q->q_flags))
303 continue;
779597d8 304
6acfa498
EA
305 if (q->q_owner != NULL)
306 {
307 if (owner == NULL)
308 owner = q->q_owner;
309 else if (owner != q->q_owner)
310 {
311 if (strcmp(owner, q->q_owner) == 0)
312 {
313 /* make future comparisons cheap */
314 q->q_owner = owner;
315 }
316 else
317 {
318 otherowners++;
319 }
320 owner = q->q_owner;
321 }
322 }
323 else
324 {
325 otherowners++;
326 }
1ce944f0
EA
327
328 /*
329 ** If this mailer is expensive, and if we don't
330 ** want to make connections now, just mark these
331 ** addresses and return. This is useful if we
332 ** want to batch connections to reduce load. This
333 ** will cause the messages to be queued up, and a
334 ** daemon will come along to send the messages later.
335 */
336
337 if (bitset(QBADADDR|QQUEUEUP, q->q_flags))
338 continue;
339 if (NoConnect && !Verbose &&
340 bitnset(M_EXPENSIVE, q->q_mailer->m_flags))
341 {
342 q->q_flags |= QQUEUEUP;
343 e->e_to = q->q_paddr;
344 message("queued");
345 if (LogLevel > 8)
346 logdelivery(q->q_mailer, NULL,
347 "queued", NULL,
348 (time_t) 0, e);
349 e->e_to = NULL;
350 }
351 else
352 {
353 somedeliveries = TRUE;
354 }
779597d8
EA
355 }
356
6acfa498 357 if (owner != NULL && otherowners > 0)
b3cbe40f 358 {
04f6f6a9 359 register ENVELOPE *ee;
6acfa498
EA
360 extern HDR *copyheader();
361 extern ADDRESS *copyqueue();
779597d8 362
6acfa498
EA
363 /*
364 ** Split this envelope into two.
365 */
74c5fe7c 366
6acfa498
EA
367 ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE));
368 *ee = *e;
369 ee->e_id = NULL;
370 (void) queuename(ee, '\0');
0df76d69 371
6acfa498
EA
372 if (tTd(13, 1))
373 printf("sendall: split %s into %s\n",
374 e->e_id, ee->e_id);
779597d8 375
6acfa498
EA
376 ee->e_header = copyheader(e->e_header);
377 ee->e_sendqueue = copyqueue(e->e_sendqueue);
378 ee->e_errorqueue = copyqueue(e->e_errorqueue);
5b4215a7
EA
379 ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT);
380 ee->e_flags |= EF_NORECEIPT;
6acfa498
EA
381 setsender(owner, ee, NULL, TRUE);
382 if (tTd(13, 5))
383 {
384 printf("sendall(split): QDONTSEND ");
385 printaddr(&ee->e_from, FALSE);
386 }
387 ee->e_from.q_flags |= QDONTSEND;
388 ee->e_dfp = NULL;
389 ee->e_xfp = NULL;
6acfa498 390 ee->e_errormode = EM_MAIL;
6acfa498
EA
391
392 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
393 if (q->q_owner == owner)
0cf862de 394 {
6acfa498 395 q->q_flags |= QDONTSEND;
0cf862de
EA
396 q->q_flags &= ~QQUEUEUP;
397 }
6acfa498
EA
398 for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
399 if (q->q_owner != owner)
0cf862de 400 {
6acfa498 401 q->q_flags |= QDONTSEND;
0cf862de
EA
402 q->q_flags &= ~QQUEUEUP;
403 }
e6b0a75b 404
18a81ac0 405 if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags))
e6b0a75b 406 {
18a81ac0
EA
407 char df1buf[20], df2buf[20];
408
6acfa498 409 ee->e_dfp = NULL;
18a81ac0
EA
410 strcpy(df1buf, queuename(e, 'd'));
411 strcpy(df2buf, queuename(ee, 'd'));
412 if (link(df1buf, df2buf) < 0)
6acfa498
EA
413 {
414 syserr("sendall: link(%s, %s)",
18a81ac0 415 df1buf, df2buf);
6acfa498 416 }
e6b0a75b 417 }
6acfa498
EA
418#ifdef LOG
419 if (LogLevel > 4)
9cc11aa8
EA
420 syslog(LOG_INFO, "%s: clone %s, owner=%s",
421 ee->e_id, e->e_id, owner);
6acfa498 422#endif
04f6f6a9
EA
423 CurEnv = ee;
424 sendenvelope(ee, mode, announcequeueup);
425 dropenvelope(ee);
779597d8 426 }
b3cbe40f
EA
427 }
428
04f6f6a9
EA
429 /*
430 ** Split off envelopes have been sent -- now send original
431 */
432
6acfa498 433 if (owner != NULL)
e6b0a75b 434 {
6acfa498
EA
435 setsender(owner, e, NULL, TRUE);
436 if (tTd(13, 5))
437 {
438 printf("sendall(owner): QDONTSEND ");
439 printaddr(&e->e_from, FALSE);
440 }
441 e->e_from.q_flags |= QDONTSEND;
442 e->e_errormode = EM_MAIL;
5b4215a7 443 e->e_flags |= EF_NORECEIPT;
e6b0a75b 444 }
1ef61b9f 445
1ce944f0
EA
446 /* if nothing to be delivered, just queue up everything */
447 if (!somedeliveries && mode != SM_QUEUE && mode != SM_VERIFY)
448 mode = SM_QUEUE;
449
11024b4c
EA
450 bool oldverbose = Verbose;
451
452 if (splitenv != NULL)
453 {
454 if (tTd(13, 1))
455 {
456 printf("\nsendall: Split queue; remaining queue:\n");
457 printaddr(e->e_sendqueue, TRUE);
458 }
459
460 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
461 {
462 CurEnv = ee;
463 if (mode != SM_VERIFY)
464 openxscript(ee);
465 sendenvelope(ee, mode);
466 dropenvelope(ee);
467 }
468
469 CurEnv = e;
470 }
471 sendenvelope(e, mode);
472 Verbose = oldverbose;
6acfa498
EA
473}
474
ea07b2d2 475void
11024b4c 476sendenvelope(e, mode)
6acfa498
EA
477 register ENVELOPE *e;
478 char mode;
479{
6acfa498 480 register ADDRESS *q;
11024b4c
EA
481 bool didany;
482
483 /*
484 ** If we have had global, fatal errors, don't bother sending
485 ** the message at all if we are in SMTP mode. Local errors
486 ** (e.g., a single address failing) will still cause the other
487 ** addresses to be sent.
488 */
489
490 if (bitset(EF_FATALERRS, e->e_flags) &&
491 (OpMode == MD_SMTP || OpMode == MD_DAEMON))
492 {
493 e->e_flags |= EF_CLRQUEUE;
494 return;
495 }
f2e44ded 496
ed45aae1 497 /*
6acfa498 498 ** Run through the list and send everything.
0fc3fb21
EA
499 **
500 ** Set EF_GLOBALERRS so that error messages during delivery
501 ** result in returned mail.
ed45aae1
EA
502 */
503
6acfa498 504 e->e_nsent = 0;
0fc3fb21 505 e->e_flags |= EF_GLOBALERRS;
f009d24b 506 didany = FALSE;
69c74bb8 507
69c74bb8 508 /* now run through the queue */
6acfa498 509 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
f2e44ded 510 {
f9fbda25
EA
511#ifdef XDEBUG
512 char wbuf[MAXNAME + 20];
513
514 (void) sprintf(wbuf, "sendall(%s)", q->q_paddr);
515 checkfd012(wbuf);
516#endif
6acfa498 517 if (mode == SM_VERIFY)
1627a785 518 {
6acfa498
EA
519 e->e_to = q->q_paddr;
520 if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
d1c234d8 521 {
58057ca3
EA
522 if (q->q_host != NULL && q->q_host[0] != '\0')
523 message("deliverable: mailer %s, host %s, user %s",
524 q->q_mailer->m_name,
525 q->q_host,
526 q->q_user);
527 else
528 message("deliverable: mailer %s, user %s",
529 q->q_mailer->m_name,
530 q->q_user);
d1c234d8 531 }
6acfa498
EA
532 }
533 else if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
534 {
535# ifdef QUEUE
536 /*
537 ** Checkpoint the send list every few addresses
538 */
539
540 if (e->e_nsent >= CheckpointInterval)
541 {
542 queueup(e, TRUE, FALSE);
543 e->e_nsent = 0;
544 }
545# endif /* QUEUE */
546 (void) deliver(e, q);
f009d24b 547 didany = TRUE;
1627a785 548 }
f2e44ded 549 }
f009d24b
EA
550 if (didany)
551 {
552 e->e_dtime = curtime();
553 e->e_ntries++;
554 }
f2e44ded 555
f9fbda25
EA
556#ifdef XDEBUG
557 checkfd012("end of sendenvelope");
558#endif
559
6acfa498
EA
560 if (mode == SM_FORK)
561 finis();
779597d8
EA
562}
563\f/*
6acfa498
EA
564** DOFORK -- do a fork, retrying a couple of times on failure.
565**
566** This MUST be a macro, since after a vfork we are running
567** two processes on the same stack!!!
b9e44c3d
EA
568**
569** Parameters:
6acfa498 570** none.
b9e44c3d
EA
571**
572** Returns:
6acfa498 573** From a macro??? You've got to be kidding!
b9e44c3d
EA
574**
575** Side Effects:
6acfa498
EA
576** Modifies the ==> LOCAL <== variable 'pid', leaving:
577** pid of child in parent, zero in child.
578** -1 on unrecoverable error.
579**
580** Notes:
581** I'm awfully sorry this looks so awful. That's
582** vfork for you.....
b9e44c3d
EA
583*/
584
6acfa498 585# define NFORKTRIES 5
140717b5
EA
586
587# ifndef FORK
588# define FORK fork
589# endif
67e64653
EA
590
591# define DOFORK(fORKfN) \
592{\
593 register int i;\
594\
11e32817 595 for (i = NFORKTRIES; --i >= 0; )\
67e64653
EA
596 {\
597 pid = fORKfN();\
598 if (pid >= 0)\
599 break;\
11e32817 600 if (i > 0)\
901911f8 601 sleep((unsigned) NFORKTRIES - i);\
67e64653
EA
602 }\
603}
604\f/*
2cf55cb7
EA
605** DOFORK -- simple fork interface to DOFORK.
606**
607** Parameters:
608** none.
609**
610** Returns:
611** pid of child in parent.
612** zero in child.
613** -1 on error.
614**
615** Side Effects:
616** returns twice, once in parent and once in child.
617*/
618
619dofork()
620{
ea07b2d2 621 register int pid = -1;
2cf55cb7
EA
622
623 DOFORK(fork);
624 return (pid);
625}
626\f/*
6acfa498 627** DELIVER -- Deliver a message to a list of addresses.
e6b0a75b 628**
6acfa498
EA
629** This routine delivers to everyone on the same host as the
630** user on the head of the list. It is clever about mailers
631** that don't handle multiple users. It is NOT guaranteed
632** that it will deliver to all these addresses however -- so
633** deliver should be called once for each address on the
634** list.
e6b0a75b
EA
635**
636** Parameters:
6acfa498
EA
637** e -- the envelope to deliver.
638** firstto -- head of the address list to deliver to.
e6b0a75b
EA
639**
640** Returns:
6acfa498
EA
641** zero -- successfully delivered.
642** else -- some failure, see ExitStat for more info.
e6b0a75b
EA
643**
644** Side Effects:
6acfa498 645** The standard input is passed off to someone.
e6b0a75b
EA
646*/
647
ea07b2d2 648int
6acfa498 649deliver(e, firstto)
30eab7ca 650 register ENVELOPE *e;
6acfa498 651 ADDRESS *firstto;
e6b0a75b 652{
6acfa498
EA
653 char *host; /* host being sent to */
654 char *user; /* user being sent to */
655 char **pvp;
656 register char **mvp;
657 register char *p;
658 register MAILER *m; /* mailer for this recipient */
659 ADDRESS *ctladdr;
660 register MCI *mci;
661 register ADDRESS *to = firstto;
662 bool clever = FALSE; /* running user smtp to this mailer */
ea07b2d2 663 ADDRESS *tochain = NULL; /* users chain in this mailer call */
6acfa498
EA
664 int rcode; /* response code */
665 char *firstsig; /* signature of firstto */
ea07b2d2 666 int pid = -1;
6acfa498 667 char *curhost;
3500a891 668 time_t xstart;
6acfa498
EA
669 int mpvect[2];
670 int rpvect[2];
671 char *pv[MAXPV+1];
672 char tobuf[TOBUFSIZE]; /* text line of to people */
8446c922
EA
673 char buf[MAXNAME + 1];
674 char rpathbuf[MAXNAME + 1]; /* translated return path */
6acfa498 675 extern int checkcompat();
e6b0a75b 676
6acfa498
EA
677 errno = 0;
678 if (!ForceMail && bitset(QDONTSEND|QPSEUDO, to->q_flags))
679 return (0);
2ae0e0ed 680
efe7f723 681#if NAMED_BIND
6acfa498 682 /* unless interactive, try twice, over a minute */
198d9e9c
EA
683 if (OpMode == MD_DAEMON || OpMode == MD_SMTP)
684 {
6acfa498
EA
685 _res.retrans = 30;
686 _res.retry = 2;
687 }
688#endif
1ab402f2 689
6acfa498
EA
690 m = to->q_mailer;
691 host = to->q_host;
692 CurEnv = e; /* just in case */
0992263e 693 e->e_statmsg = NULL;
fe3849ea 694 SmtpError[0] = '\0';
4c309714 695 xstart = curtime();
6acfa498
EA
696
697 if (tTd(10, 1))
116d2937
EA
698 printf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
699 e->e_id, m->m_name, host, to->q_user);
35f14050
EA
700 if (tTd(10, 100))
701 printopenfds(FALSE);
6acfa498 702
6acfa498
EA
703 /*
704 ** Do initial argv setup.
705 ** Insert the mailer name. Notice that $x expansion is
706 ** NOT done on the mailer name. Then, if the mailer has
707 ** a picky -f flag, we insert it as appropriate. This
708 ** code does not check for 'pv' overflow; this places a
709 ** manifest lower limit of 4 for MAXPV.
710 ** The from address rewrite is expected to make
711 ** the address relative to the other end.
712 */
713
714 /* rewrite from address, using rewriting rules */
9e43a19e 715 rcode = EX_OK;
295b05c5
EA
716 if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags))
717 p = e->e_sender;
718 else
719 p = e->e_from.q_paddr;
720 (void) strcpy(rpathbuf, remotename(p, m,
9e43a19e
EA
721 RF_SENDERADDR|RF_CANONICAL,
722 &rcode, e));
6acfa498
EA
723 define('g', rpathbuf, e); /* translated return path */
724 define('h', host, e); /* to host */
725 Errors = 0;
726 pvp = pv;
727 *pvp++ = m->m_argv[0];
728
729 /* insert -f or -r flag as appropriate */
730 if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
731 {
732 if (bitnset(M_FOPT, m->m_flags))
733 *pvp++ = "-f";
734 else
735 *pvp++ = "-r";
736 *pvp++ = newstr(rpathbuf);
737 }
738
739 /*
740 ** Append the other fixed parts of the argv. These run
741 ** up to the first entry containing "$u". There can only
742 ** be one of these, and there are only a few more slots
743 ** in the pv after it.
744 */
745
746 for (mvp = m->m_argv; (p = *++mvp) != NULL; )
747 {
748 /* can't use strchr here because of sign extension problems */
749 while (*p != '\0')
750 {
751 if ((*p++ & 0377) == MACROEXPAND)
752 {
753 if (*p == 'u')
754 break;
755 }
756 }
757
758 if (*p != '\0')
759 break;
760
761 /* this entry is safe -- go ahead and process it */
832e8a27 762 expand(*mvp, buf, sizeof buf, e);
6acfa498
EA
763 *pvp++ = newstr(buf);
764 if (pvp >= &pv[MAXPV - 3])
765 {
766 syserr("554 Too many parameters to %s before $u", pv[0]);
767 return (-1);
768 }
769 }
770
771 /*
772 ** If we have no substitution for the user name in the argument
773 ** list, we know that we must supply the names otherwise -- and
774 ** SMTP is the answer!!
775 */
776
777 if (*mvp == NULL)
778 {
779 /* running SMTP */
780# ifdef SMTP
781 clever = TRUE;
782 *pvp = NULL;
783# else /* SMTP */
784 /* oops! we don't implement SMTP */
fe3849ea 785 syserr("554 SMTP style mailer not implemented");
7338e3d4 786 return (EX_SOFTWARE);
6acfa498 787# endif /* SMTP */
e6b0a75b 788 }
1ab402f2 789
6acfa498
EA
790 /*
791 ** At this point *mvp points to the argument with $u. We
792 ** run through our address list and append all the addresses
793 ** we can. If we run out of space, do not fret! We can
794 ** always send another copy later.
795 */
796
797 tobuf[0] = '\0';
798 e->e_to = tobuf;
799 ctladdr = NULL;
800 firstsig = hostsignature(firstto->q_mailer, firstto->q_host, e);
801 for (; to != NULL; to = to->q_next)
e6b0a75b 802 {
6acfa498
EA
803 /* avoid sending multiple recipients to dumb mailers */
804 if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
805 break;
30eab7ca 806
6acfa498
EA
807 /* if already sent or not for this host, don't send */
808 if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) ||
809 to->q_mailer != firstto->q_mailer ||
810 strcmp(hostsignature(to->q_mailer, to->q_host, e), firstsig) != 0)
811 continue;
812
813 /* avoid overflowing tobuf */
814 if (sizeof tobuf < (strlen(to->q_paddr) + strlen(tobuf) + 2))
815 break;
816
817 if (tTd(10, 1))
30eab7ca 818 {
6acfa498
EA
819 printf("\nsend to ");
820 printaddr(to, FALSE);
821 }
30eab7ca 822
6acfa498 823 /* compute effective uid/gid when sending */
2bade550 824 if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
c8de5c6d 825 ctladdr = getctladdr(to);
6acfa498 826
bdd1eb9a
EA
827 if (tTd(10, 2))
828 {
829 printf("ctladdr=");
830 printaddr(ctladdr, FALSE);
831 }
832
6acfa498
EA
833 user = to->q_user;
834 e->e_to = to->q_paddr;
835 if (tTd(10, 5))
836 {
837 printf("deliver: QDONTSEND ");
838 printaddr(to, FALSE);
30eab7ca 839 }
6acfa498 840 to->q_flags |= QDONTSEND;
30eab7ca 841
6acfa498
EA
842 /*
843 ** Check to see that these people are allowed to
844 ** talk to each other.
845 */
846
847 if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
848 {
c7a0eaaf 849 e->e_flags |= EF_NO_BODY_RETN;
6acfa498 850 usrerr("552 Message is too large; %ld bytes max", m->m_maxsize);
3500a891 851 giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, xstart, e);
6acfa498
EA
852 continue;
853 }
fdcfa6b8
EA
854#if NAMED_BIND
855 h_errno = 0;
856#endif
6acfa498
EA
857 rcode = checkcompat(to, e);
858 if (rcode != EX_OK)
859 {
a542cc51 860 markfailure(e, to, NULL, rcode);
3500a891 861 giveresponse(rcode, m, NULL, ctladdr, xstart, e);
6acfa498
EA
862 continue;
863 }
864
865 /*
866 ** Strip quote bits from names if the mailer is dumb
867 ** about them.
868 */
869
870 if (bitnset(M_STRIPQ, m->m_flags))
871 {
872 stripquotes(user);
873 stripquotes(host);
874 }
875
876 /* hack attack -- delivermail compatibility */
877 if (m == ProgMailer && *user == '|')
878 user++;
879
880 /*
881 ** If an error message has already been given, don't
882 ** bother to send to this address.
883 **
884 ** >>>>>>>>>> This clause assumes that the local mailer
885 ** >> NOTE >> cannot do any further aliasing; that
886 ** >>>>>>>>>> function is subsumed by sendmail.
887 */
888
889 if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
890 continue;
891
892 /* save statistics.... */
893 markstats(e, to);
894
895 /*
896 ** See if this user name is "special".
897 ** If the user name has a slash in it, assume that this
898 ** is a file -- send it off without further ado. Note
899 ** that this type of addresses is not processed along
900 ** with the others, so we fudge on the To person.
901 */
902
903 if (m == FileMailer)
904 {
1bf9f503 905 rcode = mailfile(user, ctladdr, e);
3500a891 906 giveresponse(rcode, m, NULL, ctladdr, xstart, e);
f8c2f9fd 907 e->e_nsent++;
6acfa498 908 if (rcode == EX_OK)
f8c2f9fd 909 {
6acfa498 910 to->q_flags |= QSENT;
f8c2f9fd
EA
911 if (bitnset(M_LOCALMAILER, m->m_flags) &&
912 (e->e_receiptto != NULL ||
913 bitset(QPINGONSUCCESS, to->q_flags)))
914 {
915 to->q_flags |= QREPORT;
916 fprintf(e->e_xfp, "%s... Successfully delivered\n",
917 to->q_paddr);
918 }
919 }
68d9129a 920 to->q_statdate = curtime();
6acfa498
EA
921 continue;
922 }
923
924 /*
925 ** Address is verified -- add this user to mailer
926 ** argv, and add it to the print list of recipients.
927 */
928
929 /* link together the chain of recipients */
930 to->q_tchain = tochain;
931 tochain = to;
932
933 /* create list of users for error messages */
934 (void) strcat(tobuf, ",");
935 (void) strcat(tobuf, to->q_paddr);
936 define('u', user, e); /* to user */
ce4c39a9
EA
937 p = to->q_home;
938 if (p == NULL && ctladdr != NULL)
939 p = ctladdr->q_home;
940 define('z', p, e); /* user's home */
6acfa498
EA
941
942 /*
943 ** Expand out this user into argument list.
944 */
945
946 if (!clever)
947 {
832e8a27 948 expand(*mvp, buf, sizeof buf, e);
6acfa498
EA
949 *pvp++ = newstr(buf);
950 if (pvp >= &pv[MAXPV - 2])
951 {
952 /* allow some space for trailing parms */
953 break;
954 }
955 }
e6b0a75b 956 }
1ab402f2 957
6acfa498
EA
958 /* see if any addresses still exist */
959 if (tobuf[0] == '\0')
960 {
961 define('g', (char *) NULL, e);
962 return (0);
963 }
964
965 /* print out messages as full list */
966 e->e_to = tobuf + 1;
967
968 /*
969 ** Fill out any parameters after the $u parameter.
970 */
971
972 while (!clever && *++mvp != NULL)
973 {
832e8a27 974 expand(*mvp, buf, sizeof buf, e);
6acfa498
EA
975 *pvp++ = newstr(buf);
976 if (pvp >= &pv[MAXPV])
977 syserr("554 deliver: pv overflow after $u for %s", pv[0]);
978 }
979 *pvp++ = NULL;
980
981 /*
982 ** Call the mailer.
983 ** The argument vector gets built, pipes
984 ** are created as necessary, and we fork & exec as
985 ** appropriate.
986 ** If we are running SMTP, we just need to clean up.
987 */
e6b0a75b 988
c8de5c6d 989 /*XXX this seems a bit wierd */
a773ed15
EA
990 if (ctladdr == NULL && m != ProgMailer &&
991 bitset(QGOODUID, e->e_from.q_flags))
c8de5c6d
EA
992 ctladdr = &e->e_from;
993
efe7f723 994#if NAMED_BIND
6acfa498
EA
995 if (ConfigLevel < 2)
996 _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
997#endif
779597d8 998
9678c96d 999 if (tTd(11, 1))
b3cbe40f 1000 {
857afefe 1001 printf("openmailer:");
6acfa498 1002 printav(pv);
b3cbe40f 1003 }
d829793b 1004 errno = 0;
fdcfa6b8
EA
1005#if NAMED_BIND
1006 h_errno = 0;
1007#endif
779597d8 1008
a542cc51 1009 CurHostName = NULL;
57c97d4a 1010
1ab402f2
EA
1011 /*
1012 ** Deal with the special case of mail handled through an IPC
1013 ** connection.
1014 ** In this case we don't actually fork. We must be
1015 ** running SMTP for this to work. We will return a
1016 ** zero pid to indicate that we are running IPC.
5463e94d 1017 ** We also handle a debug version that just talks to stdin/out.
1ab402f2
EA
1018 */
1019
6acfa498 1020 curhost = NULL;
649a3283 1021 SmtpPhase = NULL;
fe3849ea 1022 mci = NULL;
6acfa498 1023
061a3d08
EA
1024#ifdef XDEBUG
1025 {
1026 char wbuf[MAXLINE];
1027
1028 /* make absolutely certain 0, 1, and 2 are in use */
1029 sprintf(wbuf, "%s... openmailer(%s)", e->e_to, m->m_name);
1030 checkfd012(wbuf);
1031 }
1032#endif
1033
e3c84ea8
EA
1034 /* check for 8-bit available */
1035 if (bitset(EF_HAS8BIT, e->e_flags) &&
1036 bitnset(M_7BITS, m->m_flags) &&
1037 !bitset(MM_MIME8BIT, MimeMode))
1038 {
1039 usrerr("554 Cannot send 8-bit data to 7-bit destination");
1040 rcode = EX_DATAERR;
1041 goto give_up;
1042 }
1043
5463e94d
EA
1044 /* check for Local Person Communication -- not for mortals!!! */
1045 if (strcmp(m->m_mailer, "[LPC]") == 0)
1046 {
f2e44ded 1047 mci = (MCI *) xalloc(sizeof *mci);
3eb4fac4 1048 bzero((char *) mci, sizeof *mci);
2ae0e0ed
EA
1049 mci->mci_in = stdin;
1050 mci->mci_out = stdout;
f2e44ded 1051 mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
e62e1144 1052 mci->mci_mailer = m;
5463e94d 1053 }
f2e44ded
EA
1054 else if (strcmp(m->m_mailer, "[IPC]") == 0 ||
1055 strcmp(m->m_mailer, "[TCP]") == 0)
1ab402f2 1056 {
140717b5 1057#ifdef DAEMON
7e70d3c8 1058 register int i;
ea07b2d2 1059 register u_short port = 0;
1ab402f2 1060
7bdee402
EA
1061 if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
1062 {
1063 syserr("null host name for %s mailer", m->m_mailer);
1064 rcode = EX_CONFIG;
1065 goto give_up;
1066 }
1067
6acfa498
EA
1068 CurHostName = pv[1];
1069 curhost = hostsignature(m, pv[1], e);
f2e44ded 1070
f2b8376e
EA
1071 if (curhost == NULL || curhost[0] == '\0')
1072 {
7bdee402 1073 syserr("null host signature for %s", pv[1]);
37750f57 1074 rcode = EX_CONFIG;
6acfa498 1075 goto give_up;
f2b8376e
EA
1076 }
1077
1ab402f2 1078 if (!clever)
f2b8376e 1079 {
b6edea3d 1080 syserr("554 non-clever IPC");
fe3849ea 1081 rcode = EX_CONFIG;
6acfa498 1082 goto give_up;
f2b8376e 1083 }
6acfa498
EA
1084 if (pv[2] != NULL)
1085 port = atoi(pv[2]);
6acfa498 1086tryhost:
7e70d3c8 1087 while (*curhost != '\0')
e2abd3be 1088 {
7e70d3c8 1089 register char *p;
8446c922 1090 static char hostbuf[MAXNAME + 1];
7e70d3c8
EA
1091
1092 /* pull the next host from the signature */
1093 p = strchr(curhost, ':');
1094 if (p == NULL)
1095 p = &curhost[strlen(curhost)];
fe3849ea
EA
1096 if (p == curhost)
1097 {
1098 syserr("deliver: null host name in signature");
7c40218a 1099 curhost++;
fe3849ea
EA
1100 continue;
1101 }
7e70d3c8
EA
1102 strncpy(hostbuf, curhost, p - curhost);
1103 hostbuf[p - curhost] = '\0';
1104 if (*p != '\0')
1105 p++;
1106 curhost = p;
1107
8657d05f 1108 /* see if we already know that this host is fried */
7e70d3c8
EA
1109 CurHostName = hostbuf;
1110 mci = mci_get(hostbuf, m);
f2e44ded 1111 if (mci->mci_state != MCIS_CLOSED)
237bda52
EA
1112 {
1113 if (tTd(11, 1))
1114 {
1115 printf("openmailer: ");
deff97fd 1116 mci_dump(mci, FALSE);
237bda52 1117 }
322eceee 1118 CurHostName = mci->mci_host;
5f14cfca
EA
1119 message("Using cached connection to %s via %s...",
1120 hostbuf, m->m_name);
6acfa498 1121 break;
237bda52 1122 }
e62e1144 1123 mci->mci_mailer = m;
f2e44ded
EA
1124 if (mci->mci_exitstat != EX_OK)
1125 continue;
1126
1127 /* try the connection */
7e70d3c8 1128 setproctitle("%s %s: %s", e->e_id, hostbuf, "user open");
5f14cfca 1129 message("Connecting to %s via %s...",
7e70d3c8
EA
1130 hostbuf, m->m_name);
1131 i = makeconnection(hostbuf, port, mci,
f2e44ded
EA
1132 bitnset(M_SECURE_PORT, m->m_flags));
1133 mci->mci_exitstat = i;
1134 mci->mci_errno = errno;
efe7f723 1135#if NAMED_BIND
8e5c6745
EA
1136 mci->mci_herrno = h_errno;
1137#endif
f2e44ded 1138 if (i == EX_OK)
e2abd3be 1139 {
f2e44ded
EA
1140 mci->mci_state = MCIS_OPENING;
1141 mci_cache(mci);
8e5c6745
EA
1142 if (TrafficLogFile != NULL)
1143 fprintf(TrafficLogFile, "%05d == CONNECT %s\n",
1144 getpid(), hostbuf);
f2e44ded 1145 break;
e2abd3be 1146 }
f2e44ded
EA
1147 else if (tTd(11, 1))
1148 printf("openmailer: makeconnection => stat=%d, errno=%d\n",
1149 i, errno);
1150
2ae0e0ed
EA
1151 /* enter status of this host */
1152 setstat(i);
fe3849ea
EA
1153
1154 /* should print some message here for -v mode */
1155 }
1156 if (mci == NULL)
1157 {
1158 syserr("deliver: no host name");
1159 rcode = EX_OSERR;
1160 goto give_up;
1ea752a1 1161 }
3eb4fac4 1162 mci->mci_pid = 0;
f2e44ded 1163#else /* no DAEMON */
b6edea3d 1164 syserr("554 openmailer: no IPC");
237bda52
EA
1165 if (tTd(11, 1))
1166 printf("openmailer: NULL\n");
fe3849ea
EA
1167 rcode = EX_UNAVAILABLE;
1168 goto give_up;
f2e44ded 1169#endif /* DAEMON */
1ab402f2 1170 }
f2e44ded 1171 else
b3cbe40f 1172 {
c1dc4fb9
EA
1173 /* flush any expired connections */
1174 (void) mci_scan(NULL);
1175
1176 /* announce the connection to verbose listeners */
5f14cfca
EA
1177 if (host == NULL || host[0] == '\0')
1178 message("Connecting to %s...", m->m_name);
1179 else
1180 message("Connecting to %s via %s...", host, m->m_name);
8e5c6745 1181 if (TrafficLogFile != NULL)
4a101ce5 1182 {
8e5c6745 1183 char **av;
f22c6db0 1184
8e5c6745
EA
1185 fprintf(TrafficLogFile, "%05d === EXEC", getpid());
1186 for (av = pv; *av != NULL; av++)
1187 fprintf(TrafficLogFile, " %s", *av);
1188 fprintf(TrafficLogFile, "\n");
4a101ce5
EA
1189 }
1190
f2e44ded
EA
1191 /* create a pipe to shove the mail through */
1192 if (pipe(mpvect) < 0)
1193 {
f22c6db0
EA
1194 syserr("%s... openmailer(%s): pipe (to mailer)",
1195 e->e_to, m->m_name);
237bda52
EA
1196 if (tTd(11, 1))
1197 printf("openmailer: NULL\n");
6acfa498
EA
1198 rcode = EX_OSERR;
1199 goto give_up;
f2e44ded 1200 }
e6b0a75b 1201
f2e44ded
EA
1202 /* if this mailer speaks smtp, create a return pipe */
1203 if (clever && pipe(rpvect) < 0)
1204 {
f22c6db0
EA
1205 syserr("%s... openmailer(%s): pipe (from mailer)",
1206 e->e_to, m->m_name);
f2e44ded
EA
1207 (void) close(mpvect[0]);
1208 (void) close(mpvect[1]);
237bda52
EA
1209 if (tTd(11, 1))
1210 printf("openmailer: NULL\n");
6acfa498
EA
1211 rcode = EX_OSERR;
1212 goto give_up;
f2e44ded 1213 }
e6b0a75b 1214
f2e44ded
EA
1215 /*
1216 ** Actually fork the mailer process.
1217 ** DOFORK is clever about retrying.
1218 **
1219 ** Dispose of SIGCHLD signal catchers that may be laying
1220 ** around so that endmail will get it.
1221 */
1ab402f2 1222
f2e44ded
EA
1223 if (e->e_xfp != NULL)
1224 (void) fflush(e->e_xfp); /* for debugging */
1225 (void) fflush(stdout);
1cc8903f 1226# ifdef SIGCHLD
39270cfd 1227 (void) setsignal(SIGCHLD, SIG_DFL);
f3d8f6d6 1228# endif /* SIGCHLD */
f2e44ded
EA
1229 DOFORK(FORK);
1230 /* pid is set by DOFORK */
1231 if (pid < 0)
e6b0a75b 1232 {
f2e44ded 1233 /* failure */
f22c6db0
EA
1234 syserr("%s... openmailer(%s): cannot fork",
1235 e->e_to, m->m_name);
f2e44ded
EA
1236 (void) close(mpvect[0]);
1237 (void) close(mpvect[1]);
1238 if (clever)
1239 {
1240 (void) close(rpvect[0]);
1241 (void) close(rpvect[1]);
1242 }
237bda52
EA
1243 if (tTd(11, 1))
1244 printf("openmailer: NULL\n");
6acfa498
EA
1245 rcode = EX_OSERR;
1246 goto give_up;
e6b0a75b 1247 }
f2e44ded
EA
1248 else if (pid == 0)
1249 {
1250 int i;
f62b79ae 1251 int saveerrno;
8381386b
EA
1252 char **ep;
1253 char *env[MAXUSERENVIRON];
1254 extern char **environ;
f2e44ded 1255 extern int DtableSize;
f2ba91d2 1256
2c2b6557 1257 if (e->e_lockfp != NULL)
633a3177 1258 (void) close(fileno(e->e_lockfp));
2c2b6557 1259
f2e44ded 1260 /* child -- set up input & exec mailer */
39270cfd
EA
1261 (void) setsignal(SIGINT, SIG_IGN);
1262 (void) setsignal(SIGHUP, SIG_IGN);
1263 (void) setsignal(SIGTERM, SIG_DFL);
49086753 1264
8d6e073f 1265 /* reset user and group */
1ff27f9b
EA
1266 if (bitnset(M_SPECIFIC_UID, m->m_flags))
1267 {
1268 (void) setgid(m->m_gid);
1269 (void) setuid(m->m_uid);
1270 }
f5195abb
EA
1271 else if (ctladdr != NULL && ctladdr->q_uid != 0)
1272 {
1273 (void) initgroups(ctladdr->q_ruser?
1274 ctladdr->q_ruser: ctladdr->q_user,
1275 ctladdr->q_gid);
1276 (void) setgid(ctladdr->q_gid);
1277 (void) setuid(ctladdr->q_uid);
1278 }
1ff27f9b 1279 else
8d6e073f 1280 {
f5195abb
EA
1281 (void) initgroups(DefUser, DefGid);
1282 if (m->m_gid == 0)
94d9df0e 1283 (void) setgid(DefGid);
f5195abb
EA
1284 else
1285 (void) setgid(m->m_gid);
1286 if (m->m_uid == 0)
8d6e073f 1287 (void) setuid(DefUid);
8d6e073f 1288 else
f5195abb 1289 (void) setuid(m->m_uid);
8d6e073f
EA
1290 }
1291
1292 if (tTd(11, 2))
1293 printf("openmailer: running as r/euid=%d/%d\n",
1294 getuid(), geteuid());
1295
6f5db107
EA
1296 /* move into some "safe" directory */
1297 if (m->m_execdir != NULL)
1298 {
1299 char *p, *q;
8446c922 1300 char buf[MAXLINE + 1];
6f5db107
EA
1301
1302 for (p = m->m_execdir; p != NULL; p = q)
1303 {
1304 q = strchr(p, ':');
1305 if (q != NULL)
1306 *q = '\0';
832e8a27 1307 expand(p, buf, sizeof buf, e);
6f5db107
EA
1308 if (q != NULL)
1309 *q++ = ':';
1310 if (tTd(11, 20))
1311 printf("openmailer: trydir %s\n",
1312 buf);
1313 if (buf[0] != '\0' && chdir(buf) >= 0)
1314 break;
1315 }
1316 }
1317
f2e44ded
EA
1318 /* arrange to filter std & diag output of command */
1319 if (clever)
1320 {
1321 (void) close(rpvect[0]);
4a101ce5
EA
1322 if (dup2(rpvect[1], STDOUT_FILENO) < 0)
1323 {
f22c6db0
EA
1324 syserr("%s... openmailer(%s): cannot dup pipe %d for stdout",
1325 e->e_to, m->m_name, rpvect[1]);
4a101ce5
EA
1326 _exit(EX_OSERR);
1327 }
f2e44ded
EA
1328 (void) close(rpvect[1]);
1329 }
52f56f58
EA
1330 else if (OpMode == MD_SMTP || OpMode == MD_DAEMON ||
1331 HoldErrs || DisConnected)
f2e44ded
EA
1332 {
1333 /* put mailer output in transcript */
4a101ce5
EA
1334 if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0)
1335 {
f22c6db0
EA
1336 syserr("%s... openmailer(%s): cannot dup xscript %d for stdout",
1337 e->e_to, m->m_name,
4a101ce5
EA
1338 fileno(e->e_xfp));
1339 _exit(EX_OSERR);
1340 }
1341 }
1342 if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
1343 {
f22c6db0
EA
1344 syserr("%s... openmailer(%s): cannot dup stdout for stderr",
1345 e->e_to, m->m_name);
4a101ce5 1346 _exit(EX_OSERR);
f2e44ded 1347 }
49086753 1348
f2e44ded
EA
1349 /* arrange to get standard input */
1350 (void) close(mpvect[1]);
d74803dd 1351 if (dup2(mpvect[0], STDIN_FILENO) < 0)
208e82d2 1352 {
f22c6db0
EA
1353 syserr("%s... openmailer(%s): cannot dup pipe %d for stdin",
1354 e->e_to, m->m_name, mpvect[0]);
f2e44ded 1355 _exit(EX_OSERR);
208e82d2 1356 }
f2e44ded 1357 (void) close(mpvect[0]);
7338e3d4 1358
f2e44ded
EA
1359 /* arrange for all the files to be closed */
1360 for (i = 3; i < DtableSize; i++)
1361 {
1362 register int j;
8d6e073f 1363
f2e44ded 1364 if ((j = fcntl(i, F_GETFD, 0)) != -1)
8d6e073f 1365 (void) fcntl(i, F_SETFD, j | 1);
f2e44ded 1366 }
1ab402f2 1367
33cbaada
EA
1368 /*
1369 ** Set up the mailer environment
7c593b58 1370 ** _FORCE_MAIL_LOCAL_ is DG-UX equiv of -d flag.
33cbaada
EA
1371 ** TZ is timezone information.
1372 ** SYSTYPE is Apollo software sys type (required).
1373 ** ISP is Apollo hardware system type (required).
1374 */
1375
8381386b
EA
1376 i = 0;
1377 env[i++] = "AGENT=sendmail";
7c593b58 1378 env[i++] = "_FORCE_MAIL_LOCAL_=yes";
8381386b
EA
1379 for (ep = environ; *ep != NULL; ep++)
1380 {
33cbaada
EA
1381 if (strncmp(*ep, "TZ=", 3) == 0 ||
1382 strncmp(*ep, "ISP=", 4) == 0 ||
1383 strncmp(*ep, "SYSTYPE=", 8) == 0)
8381386b
EA
1384 env[i++] = *ep;
1385 }
7c593b58 1386 env[i] = NULL;
8381386b 1387
53d9380f
EA
1388 /* run disconnected from terminal */
1389 (void) setsid();
1390
f2e44ded 1391 /* try to execute the mailer */
6acfa498 1392 execve(m->m_mailer, pv, env);
f62b79ae 1393 saveerrno = errno;
f2e44ded 1394 syserr("Cannot exec %s", m->m_mailer);
2bade550
EA
1395 if (bitnset(M_LOCALMAILER, m->m_flags) ||
1396 transienterror(saveerrno))
55b12947 1397 _exit(EX_OSERR);
f2e44ded
EA
1398 _exit(EX_UNAVAILABLE);
1399 }
1400
1401 /*
1402 ** Set up return value.
1403 */
1404
1405 mci = (MCI *) xalloc(sizeof *mci);
3eb4fac4 1406 bzero((char *) mci, sizeof *mci);
f2e44ded
EA
1407 mci->mci_mailer = m;
1408 mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
3eb4fac4 1409 mci->mci_pid = pid;
f2e44ded
EA
1410 (void) close(mpvect[0]);
1411 mci->mci_out = fdopen(mpvect[1], "w");
e9d81da2
EA
1412 if (mci->mci_out == NULL)
1413 {
1414 syserr("deliver: cannot create mailer output channel, fd=%d",
1415 mpvect[1]);
1416 (void) close(mpvect[1]);
1417 if (clever)
1418 {
1419 (void) close(rpvect[0]);
1420 (void) close(rpvect[1]);
1421 }
1422 rcode = EX_OSERR;
1423 goto give_up;
1424 }
f2e44ded
EA
1425 if (clever)
1426 {
1427 (void) close(rpvect[1]);
1428 mci->mci_in = fdopen(rpvect[0], "r");
e9d81da2
EA
1429 if (mci->mci_in == NULL)
1430 {
1431 syserr("deliver: cannot create mailer input channel, fd=%d",
1432 mpvect[1]);
1433 (void) close(rpvect[0]);
1434 fclose(mci->mci_out);
1435 mci->mci_out = NULL;
1436 rcode = EX_OSERR;
1437 goto give_up;
1438 }
f2e44ded
EA
1439 }
1440 else
1441 {
1442 mci->mci_flags |= MCIF_TEMP;
1443 mci->mci_in = NULL;
4287d84d 1444 }
b3cbe40f
EA
1445 }
1446
6acfa498
EA
1447 /*
1448 ** If we are in SMTP opening state, send initial protocol.
1449 */
1450
1451 if (clever && mci->mci_state != MCIS_CLOSED)
1452 {
1453 smtpinit(m, mci, e);
1454 }
f900f13b
EA
1455
1456 if (bitset(EF_HAS8BIT, e->e_flags) && bitnset(M_7BITS, m->m_flags))
1457 mci->mci_flags |= MCIF_CVT8TO7;
1458 else
1459 mci->mci_flags &= ~MCIF_CVT8TO7;
1460
6acfa498
EA
1461 if (tTd(11, 1))
1462 {
1463 printf("openmailer: ");
deff97fd 1464 mci_dump(mci, FALSE);
6acfa498
EA
1465 }
1466
1467 if (mci->mci_state != MCIS_OPEN)
1468 {
1469 /* couldn't open the mailer */
1470 rcode = mci->mci_exitstat;
1471 errno = mci->mci_errno;
efe7f723 1472#if NAMED_BIND
8e5c6745
EA
1473 h_errno = mci->mci_herrno;
1474#endif
6acfa498
EA
1475 if (rcode == EX_OK)
1476 {
1477 /* shouldn't happen */
1478 syserr("554 deliver: rcode=%d, mci_state=%d, sig=%s",
1479 rcode, mci->mci_state, firstsig);
1480 rcode = EX_SOFTWARE;
1481 }
c7a0eaaf 1482 else if (curhost != NULL && *curhost != '\0')
e80c91fc
EA
1483 {
1484 /* try next MX site */
1485 goto tryhost;
1486 }
6acfa498
EA
1487 }
1488 else if (!clever)
1489 {
1490 /*
1491 ** Format and send message.
1492 */
1493
23fafb99 1494 putfromline(mci, e);
51d448e5
EA
1495 (*e->e_puthdr)(mci, e->e_header, e);
1496 (*e->e_putbody)(mci, e, NULL);
6acfa498
EA
1497
1498 /* get the exit status */
1499 rcode = endmailer(mci, e, pv);
1500 }
1501 else
1502#ifdef SMTP
1503 {
1504 /*
1505 ** Send the MAIL FROM: protocol
1506 */
1507
1508 rcode = smtpmailfrom(m, mci, e);
1509 if (rcode == EX_OK)
1510 {
1511 register char *t = tobuf;
1512 register int i;
1513
1514 /* send the recipient list */
1515 tobuf[0] = '\0';
1516 for (to = tochain; to != NULL; to = to->q_tchain)
1517 {
1518 e->e_to = to->q_paddr;
1519 if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
1520 {
a542cc51 1521 markfailure(e, to, mci, i);
3500a891 1522 giveresponse(i, m, mci, ctladdr, xstart, e);
6acfa498
EA
1523 }
1524 else
1525 {
1526 *t++ = ',';
1527 for (p = to->q_paddr; *p; *t++ = *p++)
1528 continue;
51d3cbf1 1529 *t = '\0';
6acfa498
EA
1530 }
1531 }
1532
1533 /* now send the data */
1534 if (tobuf[0] == '\0')
1535 {
1536 rcode = EX_OK;
1537 e->e_to = NULL;
1538 if (bitset(MCIF_CACHED, mci->mci_flags))
1539 smtprset(m, mci, e);
1540 }
1541 else
1542 {
1543 e->e_to = tobuf + 1;
1544 rcode = smtpdata(m, mci, e);
1545 }
1546
1547 /* now close the connection */
1548 if (!bitset(MCIF_CACHED, mci->mci_flags))
1549 smtpquit(m, mci, e);
1550 }
95203269 1551 if (rcode != EX_OK && curhost != NULL && *curhost != '\0')
6acfa498
EA
1552 {
1553 /* try next MX site */
1554 goto tryhost;
1555 }
1556 }
1557#else /* not SMTP */
1558 {
1559 syserr("554 deliver: need SMTP compiled to use clever mailer");
1560 rcode = EX_CONFIG;
1561 goto give_up;
1562 }
1563#endif /* SMTP */
efe7f723 1564#if NAMED_BIND
6acfa498
EA
1565 if (ConfigLevel < 2)
1566 _res.options |= RES_DEFNAMES | RES_DNSRCH; /* XXX */
1567#endif
1568
1569 /* arrange a return receipt if requested */
fe3849ea
EA
1570 if (rcode == EX_OK && e->e_receiptto != NULL &&
1571 bitnset(M_LOCALMAILER, m->m_flags))
6acfa498
EA
1572 {
1573 e->e_flags |= EF_SENDRECEIPT;
1574 /* do we want to send back more info? */
1575 }
1576
1577 /*
1578 ** Do final status disposal.
1579 ** We check for something in tobuf for the SMTP case.
1580 ** If we got a temporary failure, arrange to queue the
1581 ** addressees.
1582 */
1583
1584 give_up:
1585 if (tobuf[0] != '\0')
3500a891 1586 giveresponse(rcode, m, mci, ctladdr, xstart, e);
6acfa498
EA
1587 for (to = tochain; to != NULL; to = to->q_tchain)
1588 {
1589 if (rcode != EX_OK)
a542cc51 1590 markfailure(e, to, mci, rcode);
c8e44a17 1591 else if (!bitset(QBADADDR|QQUEUEUP, to->q_flags))
6acfa498
EA
1592 {
1593 to->q_flags |= QSENT;
f8c2f9fd 1594 to->q_statdate = curtime();
6acfa498 1595 e->e_nsent++;
68d9129a
EA
1596 if (bitnset(M_LOCALMAILER, m->m_flags) &&
1597 (e->e_receiptto != NULL ||
1598 bitset(QPINGONSUCCESS, to->q_flags)))
fe3849ea 1599 {
68d9129a 1600 to->q_flags |= QREPORT;
fe3849ea
EA
1601 fprintf(e->e_xfp, "%s... Successfully delivered\n",
1602 to->q_paddr);
1603 }
c8e44a17 1604 else if (bitset(QPINGONSUCCESS, to->q_flags) &&
66d16835 1605 bitset(QPRIMARY, to->q_flags) &&
c8e44a17
EA
1606 !bitset(MCIF_DSN, mci->mci_flags))
1607 {
1608 to->q_flags |= QRELAYED;
1609 fprintf(e->e_xfp, "%s... relayed; expect no further notifications\n",
1610 to->q_paddr);
1611 }
6acfa498
EA
1612 }
1613 }
1614
1615 /*
1616 ** Restore state and return.
1617 */
1618
061a3d08
EA
1619#ifdef XDEBUG
1620 {
1621 char wbuf[MAXLINE];
1622
1623 /* make absolutely certain 0, 1, and 2 are in use */
164f3011
EA
1624 sprintf(wbuf, "%s... end of deliver(%s)",
1625 e->e_to == NULL ? "NO-TO-LIST" : e->e_to,
1626 m->m_name);
061a3d08
EA
1627 checkfd012(wbuf);
1628 }
1629#endif
1630
6acfa498
EA
1631 errno = 0;
1632 define('g', (char *) NULL, e);
1633 return (rcode);
1634}
1635\f/*
1636** MARKFAILURE -- mark a failure on a specific address.
1637**
1638** Parameters:
1639** e -- the envelope we are sending.
1640** q -- the address to mark.
a542cc51 1641** mci -- mailer connection information.
6acfa498
EA
1642** rcode -- the code signifying the particular failure.
1643**
1644** Returns:
1645** none.
1646**
1647** Side Effects:
1648** marks the address (and possibly the envelope) with the
1649** failure so that an error will be returned or
1650** the message will be queued, as appropriate.
1651*/
1652
a542cc51 1653markfailure(e, q, mci, rcode)
6acfa498
EA
1654 register ENVELOPE *e;
1655 register ADDRESS *q;
a542cc51 1656 register MCI *mci;
6acfa498
EA
1657 int rcode;
1658{
a542cc51 1659 char *stat = NULL;
6acfa498 1660
26c2fd9b
EA
1661 switch (rcode)
1662 {
1663 case EX_OK:
1664 break;
1665
1666 case EX_TEMPFAIL:
1667 case EX_IOERR:
1668 case EX_OSERR:
6acfa498 1669 q->q_flags |= QQUEUEUP;
26c2fd9b
EA
1670 break;
1671
1672 default:
8e5c6745 1673 q->q_flags |= QBADADDR;
26c2fd9b
EA
1674 break;
1675 }
a542cc51
EA
1676
1677 if (q->q_status == NULL && mci != NULL)
1678 q->q_status = mci->mci_status;
1679 switch (rcode)
1680 {
1681 case EX_USAGE:
09d45ea9 1682 stat = "5.5.4";
a542cc51
EA
1683 break;
1684
1685 case EX_DATAERR:
09d45ea9 1686 stat = "5.5.2";
a542cc51
EA
1687 break;
1688
a542cc51
EA
1689 case EX_NOUSER:
1690 case EX_NOHOST:
09d45ea9
EA
1691 stat = "5.1.1";
1692 break;
1693
1694 case EX_NOINPUT:
a542cc51
EA
1695 case EX_CANTCREAT:
1696 case EX_NOPERM:
09d45ea9 1697 stat = "5.3.0";
a542cc51
EA
1698 break;
1699
1700 case EX_UNAVAILABLE:
1701 case EX_SOFTWARE:
1702 case EX_OSFILE:
1703 case EX_PROTOCOL:
1704 case EX_CONFIG:
09d45ea9 1705 stat = "5.5.0";
a542cc51
EA
1706 break;
1707
1708 case EX_OSERR:
1709 case EX_IOERR:
09d45ea9 1710 stat = "4.5.0";
a542cc51
EA
1711 break;
1712
1713 case EX_TEMPFAIL:
09d45ea9 1714 stat = "4.2.0";
a542cc51
EA
1715 break;
1716 }
1717 if (stat != NULL && q->q_status == NULL)
1718 q->q_status = stat;
1719
68d9129a 1720 q->q_statdate = curtime();
429602a4
EA
1721 if (CurHostName != NULL && CurHostName[0] != '\0')
1722 q->q_statmta = newstr(CurHostName);
a542cc51
EA
1723 if (rcode != EX_OK && q->q_rstatus == NULL)
1724 {
1725 char buf[30];
1726
1727 (void) sprintf(buf, "%d", rcode);
1728 q->q_rstatus = newstr(buf);
1729 }
6acfa498
EA
1730}
1731\f/*
1732** ENDMAILER -- Wait for mailer to terminate.
1733**
1734** We should never get fatal errors (e.g., segmentation
1735** violation), so we report those specially. For other
1736** errors, we choose a status message (into statmsg),
1737** and if it represents an error, we print it.
1738**
1739** Parameters:
1740** pid -- pid of mailer.
1741** e -- the current envelope.
1742** pv -- the parameter vector that invoked the mailer
1743** (for error messages).
1744**
1745** Returns:
1746** exit code of mailer.
1747**
1748** Side Effects:
1749** none.
1750*/
1751
1752endmailer(mci, e, pv)
1753 register MCI *mci;
1754 register ENVELOPE *e;
1755 char **pv;
1756{
1757 int st;
1758
1759 /* close any connections */
1760 if (mci->mci_in != NULL)
14809fd5 1761 (void) xfclose(mci->mci_in, mci->mci_mailer->m_name, "mci_in");
6acfa498 1762 if (mci->mci_out != NULL)
14809fd5 1763 (void) xfclose(mci->mci_out, mci->mci_mailer->m_name, "mci_out");
6acfa498
EA
1764 mci->mci_in = mci->mci_out = NULL;
1765 mci->mci_state = MCIS_CLOSED;
49086753 1766
6acfa498
EA
1767 /* in the IPC case there is nothing to wait for */
1768 if (mci->mci_pid == 0)
1769 return (EX_OK);
1770
1771 /* wait for the mailer process to die and collect status */
1772 st = waitfor(mci->mci_pid);
1773 if (st == -1)
b3cbe40f 1774 {
6acfa498
EA
1775 syserr("endmailer %s: wait", pv[0]);
1776 return (EX_SOFTWARE);
2ae0e0ed 1777 }
6acfa498 1778
e3791bb6 1779 if (WIFEXITED(st))
237bda52 1780 {
e3791bb6
EA
1781 /* normal death -- return status */
1782 return (WEXITSTATUS(st));
1783 }
6acfa498 1784
e3791bb6 1785 /* it died a horrid death */
0baa9aea
EA
1786 syserr("451 mailer %s died with signal %o",
1787 mci->mci_mailer->m_name, st);
6acfa498 1788
e3791bb6 1789 /* log the arguments */
c1e6eba2 1790 if (pv != NULL && e->e_xfp != NULL)
e3791bb6
EA
1791 {
1792 register char **av;
6acfa498 1793
e3791bb6
EA
1794 fprintf(e->e_xfp, "Arguments:");
1795 for (av = pv; *av != NULL; av++)
1796 fprintf(e->e_xfp, " %s", *av);
1797 fprintf(e->e_xfp, "\n");
237bda52 1798 }
e6b0a75b 1799
e3791bb6
EA
1800 ExitStat = EX_TEMPFAIL;
1801 return (EX_TEMPFAIL);
b3cbe40f
EA
1802}
1803\f/*
1804** GIVERESPONSE -- Interpret an error response from a mailer
1805**
1806** Parameters:
1807** stat -- the status code from the mailer (high byte
1808** only; core dumps must have been taken care of
1809** already).
c0ae0b24
EA
1810** m -- the mailer info for this mailer.
1811** mci -- the mailer connection info -- can be NULL if the
1812** response is given before the connection is made.
5c18c358
EA
1813** ctladdr -- the controlling address for the recipient
1814** address(es).
3500a891
EA
1815** xstart -- the transaction start time, for computing
1816** transaction delays.
c0ae0b24 1817** e -- the current envelope.
b3cbe40f
EA
1818**
1819** Returns:
29871fef 1820** none.
b3cbe40f
EA
1821**
1822** Side Effects:
d916f0ca 1823** Errors may be incremented.
b3cbe40f 1824** ExitStat may be set.
b3cbe40f
EA
1825*/
1826
3500a891 1827giveresponse(stat, m, mci, ctladdr, xstart, e)
b3cbe40f 1828 int stat;
7338e3d4 1829 register MAILER *m;
c0ae0b24 1830 register MCI *mci;
5c18c358 1831 ADDRESS *ctladdr;
3500a891 1832 time_t xstart;
baa0c390 1833 ENVELOPE *e;
b3cbe40f 1834{
c51d6c4c 1835 register const char *statmsg;
b3cbe40f
EA
1836 extern char *SysExMsg[];
1837 register int i;
a0c75a49 1838 extern int N_SysEx;
baa0c390 1839 char buf[MAXLINE];
b3cbe40f 1840
74c5fe7c
EA
1841 /*
1842 ** Compute status message from code.
1843 */
1844
b3cbe40f 1845 i = stat - EX__BASE;
7338e3d4 1846 if (stat == 0)
4a101ce5 1847 {
7338e3d4 1848 statmsg = "250 Sent";
988a20e2 1849 if (e->e_statmsg != NULL)
4a101ce5 1850 {
988a20e2 1851 (void) sprintf(buf, "%s (%s)", statmsg, e->e_statmsg);
4a101ce5
EA
1852 statmsg = buf;
1853 }
1854 }
7338e3d4
EA
1855 else if (i < 0 || i > N_SysEx)
1856 {
1857 (void) sprintf(buf, "554 unknown mailer error %d", stat);
1858 stat = EX_UNAVAILABLE;
1859 statmsg = buf;
1860 }
baa0c390
EA
1861 else if (stat == EX_TEMPFAIL)
1862 {
2388926b 1863 (void) strcpy(buf, SysExMsg[i] + 1);
efe7f723 1864#if NAMED_BIND
88d7486c 1865 if (h_errno == TRY_AGAIN)
92f2b65e 1866 statmsg = errstring(h_errno+E_DNSBASE);
46f6ec52 1867 else
a0c75a49 1868#endif
46f6ec52 1869 {
88d7486c 1870 if (errno != 0)
88d7486c 1871 statmsg = errstring(errno);
88d7486c
MAN
1872 else
1873 {
46f6ec52 1874#ifdef SMTP
88d7486c 1875 statmsg = SmtpError;
f3d8f6d6 1876#else /* SMTP */
88d7486c 1877 statmsg = NULL;
f3d8f6d6 1878#endif /* SMTP */
88d7486c 1879 }
46f6ec52
EA
1880 }
1881 if (statmsg != NULL && statmsg[0] != '\0')
1882 {
e41c463e 1883 (void) strcat(buf, ": ");
46f6ec52 1884 (void) strcat(buf, statmsg);
baa0c390 1885 }
baa0c390
EA
1886 statmsg = buf;
1887 }
efe7f723 1888#if NAMED_BIND
8e5c6745
EA
1889 else if (stat == EX_NOHOST && h_errno != 0)
1890 {
92f2b65e 1891 statmsg = errstring(h_errno + E_DNSBASE);
1fd465b3 1892 (void) sprintf(buf, "%s (%s)", SysExMsg[i] + 1, statmsg);
8e5c6745
EA
1893 statmsg = buf;
1894 }
1895#endif
b3cbe40f 1896 else
46f6ec52 1897 {
b3cbe40f 1898 statmsg = SysExMsg[i];
2388926b
EA
1899 if (*statmsg++ == ':')
1900 {
1901 (void) sprintf(buf, "%s: %s", statmsg, errstring(errno));
1902 statmsg = buf;
1903 }
46f6ec52 1904 }
7338e3d4
EA
1905
1906 /*
1907 ** Print the message as appropriate
1908 */
1909
baa0c390 1910 if (stat == EX_OK || stat == EX_TEMPFAIL)
fe3849ea
EA
1911 {
1912 extern char MsgBuf[];
1913
b10e0325 1914 message("%s", &statmsg[4]);
fe3849ea
EA
1915 if (stat == EX_TEMPFAIL && e->e_xfp != NULL)
1916 fprintf(e->e_xfp, "%s\n", &MsgBuf[4]);
1917 }
b3cbe40f
EA
1918 else
1919 {
1fd465b3
EA
1920 char mbuf[8];
1921
d916f0ca 1922 Errors++;
1fd465b3
EA
1923 sprintf(mbuf, "%.3s %%s", statmsg);
1924 usrerr(mbuf, &statmsg[4]);
b3cbe40f
EA
1925 }
1926
1927 /*
1928 ** Final cleanup.
1929 ** Log a record of the transaction. Compute the new
1930 ** ExitStat -- if we already had an error, stick with
1931 ** that.
1932 */
1933
68f7099c 1934 if (LogLevel > ((stat == EX_TEMPFAIL) ? 8 : (stat == EX_OK) ? 7 : 6))
3500a891 1935 logdelivery(m, mci, &statmsg[4], ctladdr, xstart, e);
96476cab 1936
ed3d2b02
EA
1937 if (tTd(11, 2))
1938 printf("giveresponse: stat=%d, e->e_message=%s\n",
7ad0fe38 1939 stat, e->e_message == NULL ? "<NULL>" : e->e_message);
ed3d2b02 1940
ed45aae1
EA
1941 if (stat != EX_TEMPFAIL)
1942 setstat(stat);
f2a96b27 1943 if (stat != EX_OK && (stat != EX_TEMPFAIL || e->e_message == NULL))
baa0c390
EA
1944 {
1945 if (e->e_message != NULL)
1946 free(e->e_message);
1947 e->e_message = newstr(&statmsg[4]);
1948 }
e4602f52 1949 errno = 0;
efe7f723 1950#if NAMED_BIND
88d7486c 1951 h_errno = 0;
a0c75a49 1952#endif
b3cbe40f
EA
1953}
1954\f/*
fe033a8f
EA
1955** LOGDELIVERY -- log the delivery in the system log
1956**
eaad1064
EA
1957** Care is taken to avoid logging lines that are too long, because
1958** some versions of syslog have an unfortunate proclivity for core
1959** dumping. This is a hack, to be sure, that is at best empirical.
1960**
fe033a8f 1961** Parameters:
c0ae0b24
EA
1962** m -- the mailer info. Can be NULL for initial queue.
1963** mci -- the mailer connection info -- can be NULL if the
1964** log is occuring when no connection is active.
1965** stat -- the message to print for the status.
5c18c358 1966** ctladdr -- the controlling address for the to list.
3500a891
EA
1967** xstart -- the transaction start time, used for
1968** computing transaction delay.
c0ae0b24 1969** e -- the current envelope.
fe033a8f
EA
1970**
1971** Returns:
1972** none
1973**
1974** Side Effects:
1975** none
1976*/
1977
3500a891 1978logdelivery(m, mci, stat, ctladdr, xstart, e)
c0ae0b24
EA
1979 MAILER *m;
1980 register MCI *mci;
fe033a8f 1981 char *stat;
5c18c358 1982 ADDRESS *ctladdr;
3500a891 1983 time_t xstart;
f2e44ded 1984 register ENVELOPE *e;
fe033a8f 1985{
fc93dffb 1986# ifdef LOG
5c18c358 1987 register char *bp;
eaad1064
EA
1988 register char *p;
1989 int l;
ef71c549 1990 char buf[512];
fe033a8f 1991
2bbc90ee 1992# if (SYSLOG_BUFSIZE) >= 256
5c18c358
EA
1993 bp = buf;
1994 if (ctladdr != NULL)
1995 {
1996 strcpy(bp, ", ctladdr=");
ab88ddec 1997 strcat(bp, shortenstring(ctladdr->q_paddr, 83));
5c18c358
EA
1998 bp += strlen(bp);
1999 if (bitset(QGOODUID, ctladdr->q_flags))
2000 {
2001 (void) sprintf(bp, " (%d/%d)",
2002 ctladdr->q_uid, ctladdr->q_gid);
2003 bp += strlen(bp);
2004 }
2005 }
2006
3500a891 2007 sprintf(bp, ", delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
5c18c358 2008 bp += strlen(bp);
c0ae0b24 2009
3500a891
EA
2010 if (xstart != (time_t) 0)
2011 {
2012 sprintf(bp, ", xdelay=%s", pintvl(curtime() - xstart, TRUE));
2013 bp += strlen(bp);
2014 }
2015
4e82a943 2016 if (m != NULL)
9b95d94a 2017 {
5c18c358
EA
2018 (void) strcpy(bp, ", mailer=");
2019 (void) strcat(bp, m->m_name);
2020 bp += strlen(bp);
9b95d94a 2021 }
4e82a943
EA
2022
2023 if (mci != NULL && mci->mci_host != NULL)
9b95d94a 2024 {
9b95d94a 2025# ifdef DAEMON
3341995c 2026 extern SOCKADDR CurHostAddr;
4e82a943
EA
2027# endif
2028
5c18c358
EA
2029 (void) strcpy(bp, ", relay=");
2030 (void) strcat(bp, mci->mci_host);
9b95d94a 2031
4e82a943 2032# ifdef DAEMON
d285c43b 2033 (void) strcat(bp, " [");
5c18c358 2034 (void) strcat(bp, anynet_ntoa(&CurHostAddr));
d285c43b 2035 (void) strcat(bp, "]");
9b95d94a 2036# endif
9b95d94a 2037 }
8fbbb079 2038 else if (strcmp(stat, "queued") != 0)
4e82a943
EA
2039 {
2040 char *p = macvalue('h', e);
fc93dffb 2041
4e82a943
EA
2042 if (p != NULL && p[0] != '\0')
2043 {
5c18c358
EA
2044 (void) strcpy(bp, ", relay=");
2045 (void) strcat(bp, p);
4e82a943
EA
2046 }
2047 }
95203269 2048 bp += strlen(bp);
eaad1064 2049
2bbc90ee
EA
2050#define STATLEN (((SYSLOG_BUFSIZE) - 100) / 4)
2051#if (STATLEN) < 63
2052# undef STATLEN
2053# define STATLEN 63
2054#endif
2055#if (STATLEN) > 203
2056# undef STATLEN
2057# define STATLEN 203
2058#endif
2059
2060 if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
eaad1064
EA
2061 {
2062 /* desperation move -- truncate data */
2bbc90ee 2063 bp = buf + sizeof buf - ((STATLEN) + 17);
eaad1064
EA
2064 strcpy(bp, "...");
2065 bp += 3;
2066 }
2067
2068 (void) strcpy(bp, ", stat=");
2069 bp += strlen(bp);
2bbc90ee
EA
2070
2071 (void) strcpy(bp, shortenstring(stat, (STATLEN)));
ef71c549 2072
eaad1064
EA
2073 l = SYSLOG_BUFSIZE - 100 - strlen(buf);
2074 p = e->e_to;
2075 while (strlen(p) >= l)
2076 {
2077 register char *q = strchr(p + l, ',');
2078
58e480ef 2079 if (q == NULL)
eaad1064
EA
2080 break;
2081 syslog(LOG_INFO, "%s: to=%.*s [more]%s",
2082 e->e_id, ++q - p, p, buf);
2083 p = q;
2084 }
2085 syslog(LOG_INFO, "%s: to=%s%s", e->e_id, p, buf);
2bbc90ee
EA
2086
2087# else /* we have a very short log buffer size */
2088
ec33213e 2089 l = SYSLOG_BUFSIZE - 85;
2bbc90ee
EA
2090 p = e->e_to;
2091 while (strlen(p) >= l)
2092 {
2093 register char *q = strchr(p + l, ',');
2094
2095 if (q == NULL)
2096 break;
2097 syslog(LOG_INFO, "%s: to=%.*s [more]",
2098 e->e_id, ++q - p, p);
2099 p = q;
2100 }
2101 syslog(LOG_INFO, "%s: to=%s", e->e_id, p);
2102
2103 if (ctladdr != NULL)
2104 {
2105 bp = buf;
2106 strcpy(buf, "ctladdr=");
2107 bp += strlen(buf);
2108 strcpy(bp, shortenstring(ctladdr->q_paddr, 83));
2109 bp += strlen(buf);
2110 if (bitset(QGOODUID, ctladdr->q_flags))
2111 {
2112 (void) sprintf(bp, " (%d/%d)",
2113 ctladdr->q_uid, ctladdr->q_gid);
2114 bp += strlen(bp);
2115 }
2116 syslog(LOG_INFO, "%s: %s", e->e_id, buf);
2117 }
3e05a82f
EA
2118 bp = buf;
2119 sprintf(bp, "delay=%s", pintvl(curtime() - e->e_ctime, TRUE));
2120 bp += strlen(bp);
3500a891
EA
2121 if (xstart != (time_t) 0)
2122 {
2123 sprintf(bp, ", xdelay=%s", pintvl(curtime() - xstart, TRUE));
2124 bp += strlen(bp);
2125 }
2bbc90ee
EA
2126
2127 if (m != NULL)
3e05a82f
EA
2128 {
2129 sprintf(bp, ", mailer=%s", m->m_name);
2130 bp += strlen(bp);
2131 }
e5b0f01f 2132 syslog(LOG_INFO, "%s: %s", e->e_id, buf);
2bbc90ee 2133
e5b0f01f 2134 buf[0] = '\0';
2bbc90ee
EA
2135 if (mci != NULL && mci->mci_host != NULL)
2136 {
2137# ifdef DAEMON
2138 extern SOCKADDR CurHostAddr;
2139# endif
2140
2c5b66fc 2141 sprintf(buf, "relay=%s", mci->mci_host);
2bbc90ee
EA
2142
2143# ifdef DAEMON
e5b0f01f
EA
2144 (void) strcat(buf, " [");
2145 (void) strcat(buf, anynet_ntoa(&CurHostAddr));
2146 (void) strcat(buf, "]");
2bbc90ee 2147# endif
2bbc90ee 2148 }
8fbbb079 2149 else if (strcmp(stat, "queued") != 0)
2bbc90ee
EA
2150 {
2151 char *p = macvalue('h', e);
2152
2153 if (p != NULL && p[0] != '\0')
2c5b66fc 2154 sprintf(buf, "relay=%s", p);
2bbc90ee 2155 }
e5b0f01f
EA
2156 if (buf[0] != '\0')
2157 syslog(LOG_INFO, "%s: %s", e->e_id, buf);
2bbc90ee 2158
2bbc90ee
EA
2159 syslog(LOG_INFO, "%s: stat=%s", e->e_id, shortenstring(stat, 63));
2160# endif /* short log buffer */
f3d8f6d6 2161# endif /* LOG */
fe033a8f
EA
2162}
2163\f/*
dd1fe05b 2164** PUTFROMLINE -- output a UNIX-style from line (or whatever)
b3cbe40f 2165**
3c567393
EA
2166** then passes the rest of the message through. If we have
2167** managed to extract a date already, use that; otherwise,
2168** use the current date/time.
b3cbe40f 2169**
a73ae8ac
EA
2170** One of the ugliest hacks seen by human eyes is contained herein:
2171** UUCP wants those stupid "remote from <host>" lines. Why oh why
2172** does a well-meaning programmer such as myself have to deal with
2173** this kind of antique garbage????
dd1fe05b 2174**
b3cbe40f 2175** Parameters:
23fafb99
EA
2176** mci -- the connection information.
2177** e -- the envelope.
b3cbe40f
EA
2178**
2179** Returns:
dd1fe05b 2180** none
b3cbe40f
EA
2181**
2182** Side Effects:
dd1fe05b 2183** outputs some text to fp.
b3cbe40f
EA
2184*/
2185
23fafb99
EA
2186putfromline(mci, e)
2187 register MCI *mci;
f2e44ded 2188 ENVELOPE *e;
b3cbe40f 2189{
2bee003d 2190 char *template = "\201l\n";
dd1fe05b 2191 char buf[MAXLINE];
3c567393 2192 extern char SentDate[];
b3cbe40f 2193
23fafb99 2194 if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
dd1fe05b 2195 return;
74c5fe7c 2196
884a20cb 2197# ifdef UGLYUUCP
23fafb99 2198 if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
79bd7c07 2199 {
9aecbdbe
EA
2200 char *bang;
2201 char xbuf[MAXLINE];
79bd7c07 2202
832e8a27 2203 expand("\201g", buf, sizeof buf, e);
f3d8f6d6 2204 bang = strchr(buf, '!');
dd1fe05b 2205 if (bang == NULL)
1673be04
EA
2206 {
2207 errno = 0;
2208 syserr("554 No ! in UUCP From address! (%s given)", buf);
2209 }
dd1fe05b 2210 else
7338e3d4 2211 {
9aecbdbe 2212 *bang++ = '\0';
2bee003d 2213 (void) sprintf(xbuf, "From %s \201d remote from %s\n", bang, buf);
9aecbdbe 2214 template = xbuf;
7338e3d4 2215 }
79bd7c07 2216 }
f3d8f6d6 2217# endif /* UGLYUUCP */
832e8a27 2218 expand(template, buf, sizeof buf, e);
a9d5941e 2219 putxline(buf, mci, FALSE);
79bd7c07
EA
2220}
2221\f/*
6acfa498 2222** PUTBODY -- put the body of a message.
cbdb7357
EA
2223**
2224** Parameters:
23fafb99 2225** mci -- the connection information.
6acfa498 2226** e -- the envelope to put out.
2f6a8a78
EA
2227** separator -- if non-NULL, a message separator that must
2228** not be permitted in the resulting message.
cbdb7357
EA
2229**
2230** Returns:
2231** none.
2232**
2233** Side Effects:
6acfa498 2234** The message is written onto fp.
cbdb7357
EA
2235*/
2236
0d721ffb
EA
2237/* values for output state variable */
2238#define OS_HEAD 0 /* at beginning of line */
2239#define OS_CR 1 /* read a carriage return */
2240#define OS_INLINE 2 /* putting rest of line */
2241
51d448e5 2242putbody(mci, e, separator)
23fafb99 2243 register MCI *mci;
6acfa498 2244 register ENVELOPE *e;
2f6a8a78 2245 char *separator;
cbdb7357 2246{
6acfa498 2247 char buf[MAXLINE];
cbdb7357 2248
3c7fe765 2249 /*
6acfa498 2250 ** Output the body of the message
3c7fe765
EA
2251 */
2252
18a81ac0 2253 if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
cd37f61d 2254 {
18a81ac0
EA
2255 char *df = queuename(e, 'd');
2256
2257 e->e_dfp = fopen(df, "r");
cd37f61d
EA
2258 if (e->e_dfp == NULL)
2259 syserr("putbody: Cannot open %s for %s from %s",
18a81ac0 2260 df, e->e_to, e->e_from.q_paddr);
cd37f61d 2261 }
6acfa498 2262 if (e->e_dfp == NULL)
7338e3d4 2263 {
cd37f61d 2264 if (bitset(MCIF_INHEADER, mci->mci_flags))
78bbbc48 2265 {
cd37f61d
EA
2266 putline("", mci);
2267 mci->mci_flags &= ~MCIF_INHEADER;
c23930c0 2268 }
cd37f61d
EA
2269 putline("<<< No Message Collected >>>", mci);
2270 goto endofmessage;
84daea29 2271 }
cd37f61d 2272 if (e->e_dfino == (ino_t) 0)
f009d24b
EA
2273 {
2274 struct stat stbuf;
2275
2276 if (fstat(fileno(e->e_dfp), &stbuf) < 0)
2277 e->e_dfino = -1;
2278 else
bb4fde22
EA
2279 {
2280 e->e_dfdev = stbuf.st_dev;
f009d24b 2281 e->e_dfino = stbuf.st_ino;
bb4fde22 2282 }
f009d24b 2283 }
0d721ffb 2284 rewind(e->e_dfp);
c23930c0 2285
0d721ffb
EA
2286 if (bitset(MCIF_CVT8TO7, mci->mci_flags))
2287 {
022362dd
EA
2288 char *boundaries[MAXMIMENESTING + 1];
2289
bb4fde22
EA
2290 /*
2291 ** Do 8 to 7 bit MIME conversion.
2292 */
2293
2294 /* make sure it looks like a MIME message */
0d721ffb
EA
2295 if (hvalue("MIME-Version", e->e_header) == NULL)
2296 putline("MIME-Version: 1.0", mci);
bb4fde22 2297
bb4fde22 2298 if (hvalue("Content-Type", e->e_header) == NULL)
a50ac3e2 2299 {
a50ac3e2 2300 sprintf(buf, "Content-Type: text/plain; charset=%s",
3caf3b1f 2301 defcharset(e));
a50ac3e2
EA
2302 putline(buf, mci);
2303 }
bb4fde22
EA
2304
2305 /* now do the hard work */
022362dd
EA
2306 boundaries[0] = NULL;
2307 mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
0d721ffb
EA
2308 }
2309 else
2310 {
2311 int ostate;
2312 register char *bp;
2313 register char *pbp;
2314 register int c;
2315 int padc;
2316 char *buflim;
ea07b2d2 2317 int pos = 0;
0d721ffb
EA
2318 char peekbuf[10];
2319
2320 /* we can pass it through unmodified */
2321 if (bitset(MCIF_INHEADER, mci->mci_flags))
c23930c0 2322 {
0d721ffb
EA
2323 putline("", mci);
2324 mci->mci_flags &= ~MCIF_INHEADER;
c23930c0 2325 }
0d721ffb
EA
2326
2327 /* determine end of buffer; allow for short mailer lines */
2328 buflim = &buf[sizeof buf - 1];
098e8e2c
EA
2329 if (mci->mci_mailer->m_linelimit > 0 &&
2330 mci->mci_mailer->m_linelimit < sizeof buf - 1)
0d721ffb
EA
2331 buflim = &buf[mci->mci_mailer->m_linelimit - 1];
2332
2333 /* copy temp file to output with mapping */
2334 ostate = OS_HEAD;
2335 bp = buf;
2336 pbp = peekbuf;
2337 while (!ferror(mci->mci_out))
84daea29 2338 {
0d721ffb
EA
2339 register char *xp;
2340
2341 if (pbp > peekbuf)
2342 c = *--pbp;
2343 else if ((c = fgetc(e->e_dfp)) == EOF)
2344 break;
2345 if (bitset(MCIF_7BIT, mci->mci_flags))
2346 c &= 0x7f;
2347 switch (ostate)
2f6a8a78 2348 {
0d721ffb
EA
2349 case OS_HEAD:
2350 if (c != '\r' && c != '\n' && bp < buflim)
2351 {
2352 *bp++ = c;
2353 break;
2354 }
2355
2356 /* check beginning of line for special cases */
2357 *bp = '\0';
2358 pos = 0;
2359 padc = EOF;
c23930c0
EA
2360 if (buf[0] == 'F' &&
2361 bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&
2362 strncmp(buf, "From ", 5) == 0)
0d721ffb
EA
2363 {
2364 padc = '>';
2365 }
c23930c0
EA
2366 if (buf[0] == '-' && buf[1] == '-' &&
2367 separator != NULL)
2368 {
2369 /* possible separator */
2370 int sl = strlen(separator);
2f6a8a78 2371
c23930c0 2372 if (strncmp(&buf[2], separator, sl) == 0)
0d721ffb 2373 padc = ' ';
c23930c0 2374 }
0d721ffb
EA
2375 if (buf[0] == '.' &&
2376 bitnset(M_XDOT, mci->mci_mailer->m_flags))
2377 {
2378 padc = '.';
2379 }
2380
2381 /* now copy out saved line */
2382 if (TrafficLogFile != NULL)
2383 {
2384 fprintf(TrafficLogFile, "%05d >>> ", getpid());
2385 if (padc != EOF)
2386 fputc(padc, TrafficLogFile);
2387 for (xp = buf; xp < bp; xp++)
2388 fputc(*xp, TrafficLogFile);
2389 if (c == '\n')
2390 fputs(mci->mci_mailer->m_eol,
2391 TrafficLogFile);
2392 }
2393 if (padc != EOF)
2394 {
2395 fputc(padc, mci->mci_out);
2396 pos++;
2397 }
2398 for (xp = buf; xp < bp; xp++)
2399 fputc(*xp, mci->mci_out);
2400 if (c == '\n')
2401 {
2402 fputs(mci->mci_mailer->m_eol,
2403 mci->mci_out);
2404 pos = 0;
2405 }
2406 else
2407 {
2408 pos += bp - buf;
a4041586
EA
2409 if (c != '\r')
2410 *pbp++ = c;
0d721ffb
EA
2411 }
2412 bp = buf;
2413
2414 /* determine next state */
2415 if (c == '\n')
2416 ostate = OS_HEAD;
2417 else if (c == '\r')
2418 ostate = OS_CR;
2419 else
2420 ostate = OS_INLINE;
2421 continue;
2422
2423 case OS_CR:
2424 if (c == '\n')
2425 {
2426 /* got CRLF */
2427 fputs(mci->mci_mailer->m_eol, mci->mci_out);
2428 if (TrafficLogFile != NULL)
2429 {
2430 fputs(mci->mci_mailer->m_eol,
2431 TrafficLogFile);
2432 }
2433 ostate = OS_HEAD;
2434 continue;
2435 }
2436
2437 /* had a naked carriage return */
2438 *pbp++ = c;
2439 c = '\r';
68e6bb99 2440 goto putch;
0d721ffb
EA
2441
2442 case OS_INLINE:
2443 if (c == '\r')
2444 {
2445 ostate = OS_CR;
2446 continue;
2447 }
68e6bb99 2448putch:
098e8e2c
EA
2449 if (mci->mci_mailer->m_linelimit > 0 &&
2450 pos > mci->mci_mailer->m_linelimit &&
0d721ffb
EA
2451 c != '\n')
2452 {
2453 putc('!', mci->mci_out);
2454 fputs(mci->mci_mailer->m_eol, mci->mci_out);
2455 if (TrafficLogFile != NULL)
2456 {
2457 fprintf(TrafficLogFile, "!%s",
2458 mci->mci_mailer->m_eol);
2459 }
2460 ostate = OS_HEAD;
2461 *pbp++ = c;
2462 continue;
2463 }
2464 if (TrafficLogFile != NULL)
2465 fputc(c, TrafficLogFile);
2466 putc(c, mci->mci_out);
2467 pos++;
a4041586 2468 ostate = c == '\n' ? OS_HEAD : OS_INLINE;
0d721ffb 2469 break;
2f6a8a78 2470 }
84daea29 2471 }
0d721ffb 2472 }
84daea29 2473
0d721ffb
EA
2474 if (ferror(e->e_dfp))
2475 {
18a81ac0 2476 syserr("putbody: df%s: read error", e->e_id);
0d721ffb 2477 ExitStat = EX_IOERR;
baa2b877 2478 }
75f95954 2479
0d721ffb 2480endofmessage:
1537ac22 2481 /* some mailers want extra blank line at end of message */
23fafb99
EA
2482 if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
2483 buf[0] != '\0' && buf[0] != '\n')
2484 putline("", mci);
1537ac22 2485
23fafb99
EA
2486 (void) fflush(mci->mci_out);
2487 if (ferror(mci->mci_out) && errno != EPIPE)
84daea29 2488 {
6acfa498
EA
2489 syserr("putbody: write error");
2490 ExitStat = EX_IOERR;
84daea29 2491 }
6acfa498 2492 errno = 0;
bc854e30 2493}
6acfa498
EA
2494\f/*
2495** MAILFILE -- Send a message to a file.
2496**
2497** If the file has the setuid/setgid bits set, but NO execute
2498** bits, sendmail will try to become the owner of that file
2499** rather than the real user. Obviously, this only works if
2500** sendmail runs as root.
2501**
2502** This could be done as a subordinate mailer, except that it
2503** is used implicitly to save messages in ~/dead.letter. We
2504** view this as being sufficiently important as to include it
2505** here. For example, if the system is dying, we shouldn't have
2506** to create another process plus some pipes to save the message.
2507**
2508** Parameters:
2509** filename -- the name of the file to send to.
2510** ctladdr -- the controlling address header -- includes
2511** the userid/groupid to be when sending.
2512**
2513** Returns:
2514** The exit code associated with the operation.
2515**
2516** Side Effects:
2517** none.
2518*/
bc854e30 2519
6acfa498
EA
2520mailfile(filename, ctladdr, e)
2521 char *filename;
2522 ADDRESS *ctladdr;
bc854e30 2523 register ENVELOPE *e;
bc854e30 2524{
6acfa498 2525 register FILE *f;
ea07b2d2 2526 register int pid = -1;
6acfa498 2527 int mode;
84daea29 2528
831d7357
EA
2529 if (tTd(11, 1))
2530 {
2531 printf("mailfile %s\n ctladdr=", filename);
2532 printaddr(ctladdr, FALSE);
2533 }
2534
8e5c6745
EA
2535 if (e->e_xfp != NULL)
2536 fflush(e->e_xfp);
2537
6acfa498
EA
2538 /*
2539 ** Fork so we can change permissions here.
2540 ** Note that we MUST use fork, not vfork, because of
2541 ** the complications of calling subroutines, etc.
2542 */
2543
2544 DOFORK(fork);
2545
2546 if (pid < 0)
2547 return (EX_OSERR);
2548 else if (pid == 0)
75f95954 2549 {
6acfa498
EA
2550 /* child -- actually write to file */
2551 struct stat stb;
2c2b6557 2552 struct stat fsb;
23fafb99 2553 MCI mcibuf;
99fd9645 2554 int oflags = O_WRONLY|O_APPEND;
8726396d 2555 int oflags = O_WRONLY|O_APPEND;
75f95954 2556
2c2b6557
EA
2557 if (e->e_lockfp != NULL)
2558 {
2559 fclose(e->e_lockfp);
2560 e->e_lockfp = NULL;
2561 }
2562
39270cfd
EA
2563 (void) setsignal(SIGINT, SIG_DFL);
2564 (void) setsignal(SIGHUP, SIG_DFL);
2565 (void) setsignal(SIGTERM, SIG_DFL);
6acfa498 2566 (void) umask(OldUmask);
75f95954 2567
99fd9645
EA
2568#ifdef HASLSTAT
2569 if ((SafeFileEnv != NULL ? lstat(filename, &stb)
2570 : stat(filename, &stb)) < 0)
2571#else
6acfa498 2572 if (stat(filename, &stb) < 0)
8726396d 2573 {
99fd9645
EA
2574#endif
2575 {
6f7f4e2c 2576 stb.st_mode = FileMode;
99fd9645
EA
2577 oflags |= O_CREAT|O_EXCL;
2578 }
2579 else if (bitset(0111, stb.st_mode) || stb.st_nlink != 1 ||
2580 (SafeFileEnv != NULL && !S_ISREG(stb.st_mode)))
2c2b6557 2581 exit(EX_CANTCREAT);
6acfa498 2582 mode = stb.st_mode;
07800f98 2583
6acfa498
EA
2584 /* limit the errors to those actually caused in the child */
2585 errno = 0;
2586 ExitStat = EX_OK;
07800f98 2587
0419e00c 2588 if (ctladdr != NULL)
07800f98 2589 {
6acfa498
EA
2590 /* ignore setuid and setgid bits */
2591 mode &= ~(S_ISGID|S_ISUID);
07800f98 2592 }
07800f98 2593
6acfa498 2594 /* we have to open the dfile BEFORE setuid */
18a81ac0 2595 if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
813d8709 2596 {
18a81ac0
EA
2597 char *df = queuename(e, 'd');
2598
2599 e->e_dfp = fopen(df, "r");
6acfa498 2600 if (e->e_dfp == NULL)
78bbbc48 2601 {
6acfa498 2602 syserr("mailfile: Cannot open %s for %s from %s",
18a81ac0 2603 df, e->e_to, e->e_from.q_paddr);
78bbbc48 2604 }
6acfa498 2605 }
78bbbc48 2606
e0c8c651 2607 if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
99fd9645
EA
2608 {
2609 int i;
2610
2611 if (chroot(SafeFileEnv) < 0)
2612 {
2613 syserr("mailfile: Cannot chroot(%s)",
2614 SafeFileEnv);
2615 exit(EX_CANTCREAT);
2616 }
2617 i = strlen(SafeFileEnv);
2618 if (strncmp(SafeFileEnv, filename, i) == 0)
2619 filename += i;
2620 }
2621 if (chdir("/") < 0)
2622 syserr("mailfile: cannot chdir(/)");
2623
6acfa498
EA
2624 if (!bitset(S_ISGID, mode) || setgid(stb.st_gid) < 0)
2625 {
0c35b842 2626 if (ctladdr != NULL && ctladdr->q_uid != 0)
6acfa498
EA
2627 (void) initgroups(ctladdr->q_ruser ?
2628 ctladdr->q_ruser : ctladdr->q_user,
2629 ctladdr->q_gid);
0c35b842
EA
2630 else if (FileMailer != NULL && FileMailer->m_gid != 0)
2631 (void) initgroups(DefUser, FileMailer->m_gid);
2632 else
2633 (void) initgroups(DefUser, DefGid);
813d8709 2634 }
6acfa498 2635 if (!bitset(S_ISUID, mode) || setuid(stb.st_uid) < 0)
4ae3ff58 2636 {
0c35b842 2637 if (ctladdr != NULL && ctladdr->q_uid != 0)
6acfa498 2638 (void) setuid(ctladdr->q_uid);
0c35b842
EA
2639 else if (FileMailer != NULL && FileMailer->m_uid != 0)
2640 (void) setuid(FileMailer->m_uid);
2641 else
2642 (void) setuid(DefUid);
4ae3ff58 2643 }
6acfa498
EA
2644 FileName = filename;
2645 LineNumber = 0;
99fd9645 2646 f = dfopen(filename, oflags, FileMode);
6acfa498 2647 if (f == NULL)
cbdb7357 2648 {
6814f197 2649 message("554 cannot open: %s", errstring(errno));
6acfa498 2650 exit(EX_CANTCREAT);
cbdb7357 2651 }
2c2b6557 2652 if (fstat(fileno(f), &fsb) < 0 ||
99fd9645
EA
2653 (!bitset(O_CREAT, oflags) &&
2654 (stb.st_nlink != fsb.st_nlink ||
2655 stb.st_dev != fsb.st_dev ||
2656 stb.st_ino != fsb.st_ino ||
2657 stb.st_uid != fsb.st_uid)))
2c2b6557
EA
2658 {
2659 message("554 cannot write: file changed after open");
2660 exit(EX_CANTCREAT);
2661 }
8dcff118 2662
23fafb99
EA
2663 bzero(&mcibuf, sizeof mcibuf);
2664 mcibuf.mci_mailer = FileMailer;
2665 mcibuf.mci_out = f;
2666 if (bitnset(M_7BITS, FileMailer->m_flags))
2667 mcibuf.mci_flags |= MCIF_7BIT;
2668
2669 putfromline(&mcibuf, e);
51d448e5
EA
2670 (*e->e_puthdr)(&mcibuf, e->e_header, e);
2671 (*e->e_putbody)(&mcibuf, e, NULL);
23fafb99 2672 putline("\n", &mcibuf);
6acfa498
EA
2673 if (ferror(f))
2674 {
6814f197 2675 message("451 I/O error: %s", errstring(errno));
6acfa498 2676 setstat(EX_IOERR);
8dcff118 2677 }
6acfa498
EA
2678 (void) xfclose(f, "mailfile", filename);
2679 (void) fflush(stdout);
3c7fe765 2680
6acfa498
EA
2681 /* reset ISUID & ISGID bits for paranoid systems */
2682 (void) chmod(filename, (int) stb.st_mode);
2683 exit(ExitStat);
2684 /*NOTREACHED*/
bc854e30 2685 }
6acfa498 2686 else
3c7fe765 2687 {
6acfa498
EA
2688 /* parent -- wait for exit status */
2689 int st;
bc854e30 2690
6acfa498 2691 st = waitfor(pid);
e3791bb6
EA
2692 if (WIFEXITED(st))
2693 return (WEXITSTATUS(st));
6acfa498 2694 else
6814f197
EA
2695 {
2696 syserr("child died on signal %d", st);
e3791bb6 2697 return (EX_UNAVAILABLE);
6814f197 2698 }
6acfa498 2699 /*NOTREACHED*/
3c7fe765
EA
2700 }
2701}
7e70d3c8
EA
2702\f/*
2703** HOSTSIGNATURE -- return the "signature" for a host.
2704**
2705** The signature describes how we are going to send this -- it
2706** can be just the hostname (for non-Internet hosts) or can be
2707** an ordered list of MX hosts.
2708**
2709** Parameters:
2710** m -- the mailer describing this host.
2711** host -- the host name.
2712** e -- the current envelope.
2713**
2714** Returns:
2715** The signature for this host.
2716**
2717** Side Effects:
2718** Can tweak the symbol table.
2719*/
2720
2721char *
2722hostsignature(m, host, e)
2723 register MAILER *m;
2724 char *host;
2725 ENVELOPE *e;
2726{
2727 register char *p;
2728 register STAB *s;
2729 int i;
2730 int len;
efe7f723 2731#if NAMED_BIND
7e70d3c8
EA
2732 int nmx;
2733 auto int rcode;
db113c28
EA
2734 char *hp;
2735 char *endp;
ea07b2d2 2736 int oldoptions = _res.options;
7e70d3c8 2737 char *mxhosts[MAXMXHOSTS + 1];
7e70d3c8
EA
2738#endif
2739
2740 /*
2741 ** Check to see if this uses IPC -- if not, it can't have MX records.
2742 */
2743
2744 p = m->m_mailer;
2745 if (strcmp(p, "[IPC]") != 0 && strcmp(p, "[TCP]") != 0)
2746 {
2747 /* just an ordinary mailer */
2748 return host;
2749 }
2750
7e70d3c8
EA
2751 /*
2752 ** Look it up in the symbol table.
2753 */
2754
2755 s = stab(host, ST_HOSTSIG, ST_ENTER);
2756 if (s->s_hostsig != NULL)
2757 return s->s_hostsig;
2758
2759 /*
2760 ** Not already there -- create a signature.
2761 */
2762
efe7f723 2763#if NAMED_BIND
c8f4bc0b 2764 if (ConfigLevel < 2)
c8f4bc0b 2765 _res.options &= ~(RES_DEFNAMES | RES_DNSRCH); /* XXX */
c8f4bc0b 2766
db113c28 2767 for (hp = host; hp != NULL; hp = endp)
7e70d3c8 2768 {
db113c28
EA
2769 endp = strchr(hp, ':');
2770 if (endp != NULL)
2771 *endp = '\0';
7e70d3c8 2772
c3577cd6 2773 nmx = getmxrr(hp, mxhosts, TRUE, &rcode);
7e70d3c8 2774
db113c28
EA
2775 if (nmx <= 0)
2776 {
2777 register MCI *mci;
7e70d3c8 2778
db113c28
EA
2779 /* update the connection info for this host */
2780 mci = mci_get(hp, m);
2781 mci->mci_exitstat = rcode;
2782 mci->mci_errno = errno;
8e5c6745 2783 mci->mci_herrno = h_errno;
db113c28
EA
2784
2785 /* and return the original host name as the signature */
2786 nmx = 1;
2787 mxhosts[0] = hp;
2788 }
2789
2790 len = 0;
2791 for (i = 0; i < nmx; i++)
2792 {
2793 len += strlen(mxhosts[i]) + 1;
2794 }
2795 if (s->s_hostsig != NULL)
2796 len += strlen(s->s_hostsig) + 1;
2797 p = xalloc(len);
2798 if (s->s_hostsig != NULL)
2799 {
2800 (void) strcpy(p, s->s_hostsig);
2801 free(s->s_hostsig);
2802 s->s_hostsig = p;
2803 p += strlen(p);
7e70d3c8 2804 *p++ = ':';
db113c28
EA
2805 }
2806 else
2807 s->s_hostsig = p;
2808 for (i = 0; i < nmx; i++)
2809 {
2810 if (i != 0)
2811 *p++ = ':';
2812 strcpy(p, mxhosts[i]);
2813 p += strlen(p);
2814 }
2815 if (endp != NULL)
2816 *endp++ = ':';
7e70d3c8
EA
2817 }
2818 makelower(s->s_hostsig);
c8f4bc0b
EA
2819 if (ConfigLevel < 2)
2820 _res.options = oldoptions;
7e70d3c8
EA
2821#else
2822 /* not using BIND -- the signature is just the host name */
2823 s->s_hostsig = host;
2824#endif
2825 if (tTd(17, 1))
2826 printf("hostsignature(%s) = %s\n", host, s->s_hostsig);
2827 return s->s_hostsig;
2828}
68d9129a
EA
2829\f/*
2830** SETSTATUS -- set the address status for return messages
2831**
2832** Parameters:
2833** a -- the address to set.
2834** msg -- the text of the message, which must be in standard
2835** SMTP form (3 digits, a space, and a message).
2836**
2837** Returns:
2838** none.
2839*/
2840
2841setstatus(a, msg)
2842 register ADDRESS *a;
2843 char *msg;
2844{
2845 char buf[MAXLINE];
2846
d51d925d
EA
2847 if (a->q_rstatus != NULL)
2848 free(a->q_rstatus);
68d9129a
EA
2849 if (strlen(msg) > 4)
2850 {
2851 register char *p, *q;
2852 int parenlev = 0;
2853
2854 strncpy(buf, msg, 4);
2855 p = &buf[4];
2856 *p++ = '(';
ad36a408 2857 for (q = &msg[4]; *q != '\0'; q++)
68d9129a
EA
2858 {
2859 switch (*q)
2860 {
2861 case '(':
2862 parenlev++;
2863 break;
2864
2865 case ')':
2866 if (parenlev > 0)
2867 parenlev--;
2868 else
2869 *p++ = '\\';
2870 break;
2871 }
2872 *p++ = *q;
2873 }
2874 while (parenlev-- >= 0)
2875 *p++ = ')';
2876 *p++ = '\0';
2877 msg = buf;
2878 }
d51d925d 2879 a->q_rstatus = newstr(msg);
68d9129a 2880}