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