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