]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/sendmail/src/deliver.c
This commit was generated by cvs2svn to compensate for changes in r52746,
[FreeBSD/FreeBSD.git] / contrib / sendmail / src / deliver.c
1 /*
2  * Copyright (c) 1998 Sendmail, Inc.  All rights reserved.
3  * Copyright (c) 1983, 1995-1997 Eric P. Allman.  All rights reserved.
4  * Copyright (c) 1988, 1993
5  *      The Regents of the University of California.  All rights reserved.
6  *
7  * By using this file, you agree to the terms and conditions set
8  * forth in the LICENSE file which can be found at the top level of
9  * the sendmail distribution.
10  *
11  */
12
13 #ifndef lint
14 static char sccsid[] = "@(#)deliver.c   8.367 (Berkeley) 1/18/1999";
15 #endif /* not lint */
16
17 #include "sendmail.h"
18 #include <errno.h>
19 #include <grp.h>
20 #if NAMED_BIND
21 #include <resolv.h>
22 #endif
23
24 #if HASSETUSERCONTEXT
25 # include <login_cap.h>
26 #endif
27
28 #if SMTP
29 extern char     SmtpError[];
30 #endif
31
32 /*
33 **  SENDALL -- actually send all the messages.
34 **
35 **      Parameters:
36 **              e -- the envelope to send.
37 **              mode -- the delivery mode to use.  If SM_DEFAULT, use
38 **                      the current e->e_sendmode.
39 **
40 **      Returns:
41 **              none.
42 **
43 **      Side Effects:
44 **              Scans the send lists and sends everything it finds.
45 **              Delivers any appropriate error messages.
46 **              If we are running in a non-interactive mode, takes the
47 **                      appropriate action.
48 */
49
50 void
51 sendall(e, mode)
52         ENVELOPE *e;
53         int mode;
54 {
55         register ADDRESS *q;
56         char *owner;
57         int otherowners;
58         register ENVELOPE *ee;
59         ENVELOPE *splitenv = NULL;
60         int oldverbose = Verbose;
61         bool somedeliveries = FALSE, expensive = FALSE;
62         pid_t pid;
63         void sendenvelope __P((ENVELOPE *, int));
64
65         /*
66         **  If this message is to be discarded, don't bother sending
67         **  the message at all.
68         */
69
70         if (bitset(EF_DISCARD, e->e_flags))
71         {
72                 if (tTd(13, 1))
73                         printf("sendall: discarding id %s\n", e->e_id);
74                 e->e_flags |= EF_CLRQUEUE;
75                 if (LogLevel > 4)
76                         sm_syslog(LOG_INFO, e->e_id, "discarded");
77                 markstats(e, NULL, TRUE);
78                 return;
79         }
80
81         /*
82         **  If we have had global, fatal errors, don't bother sending
83         **  the message at all if we are in SMTP mode.  Local errors
84         **  (e.g., a single address failing) will still cause the other
85         **  addresses to be sent.
86         */
87
88         if (bitset(EF_FATALERRS, e->e_flags) &&
89             (OpMode == MD_SMTP || OpMode == MD_DAEMON))
90         {
91                 e->e_flags |= EF_CLRQUEUE;
92                 return;
93         }
94
95         /* determine actual delivery mode */
96         if (mode == SM_DEFAULT)
97         {
98                 mode = e->e_sendmode;
99                 if (mode != SM_VERIFY && mode != SM_DEFER &&
100                     shouldqueue(e->e_msgpriority, e->e_ctime))
101                         mode = SM_QUEUE;
102         }
103
104         if (tTd(13, 1))
105         {
106                 extern void printenvflags __P((ENVELOPE *));
107
108                 printf("\n===== SENDALL: mode %c, id %s, e_from ",
109                         mode, e->e_id);
110                 printaddr(&e->e_from, FALSE);
111                 printf("\te_flags = ");
112                 printenvflags(e);
113                 printf("sendqueue:\n");
114                 printaddr(e->e_sendqueue, TRUE);
115         }
116
117         /*
118         **  Do any preprocessing necessary for the mode we are running.
119         **      Check to make sure the hop count is reasonable.
120         **      Delete sends to the sender in mailing lists.
121         */
122
123         CurEnv = e;
124         if (tTd(62, 1))
125                 checkfds(NULL);
126
127         if (e->e_hopcount > MaxHopCount)
128         {
129                 errno = 0;
130 #if QUEUE
131                 queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
132 #endif
133                 e->e_flags |= EF_FATALERRS|EF_PM_NOTIFY|EF_CLRQUEUE;
134                 syserr("554 Too many hops %d (%d max): from %s via %s, to %s",
135                         e->e_hopcount, MaxHopCount, e->e_from.q_paddr,
136                         RealHostName == NULL ? "localhost" : RealHostName,
137                         e->e_sendqueue->q_paddr);
138                 e->e_sendqueue->q_status = "5.4.6";
139                 return;
140         }
141
142         /*
143         **  Do sender deletion.
144         **
145         **      If the sender has the QQUEUEUP flag set, skip this.
146         **      This can happen if the name server is hosed when you
147         **      are trying to send mail.  The result is that the sender
148         **      is instantiated in the queue as a recipient.
149         */
150
151         if (!bitset(EF_METOO, e->e_flags) &&
152             !bitset(QQUEUEUP, e->e_from.q_flags))
153         {
154                 if (tTd(13, 5))
155                 {
156                         printf("sendall: QDONTSEND ");
157                         printaddr(&e->e_from, FALSE);
158                 }
159                 e->e_from.q_flags |= QDONTSEND;
160                 (void) recipient(&e->e_from, &e->e_sendqueue, 0, e);
161         }
162
163         /*
164         **  Handle alias owners.
165         **
166         **      We scan up the q_alias chain looking for owners.
167         **      We discard owners that are the same as the return path.
168         */
169
170         for (q = e->e_sendqueue; q != NULL; q = q->q_next)
171         {
172                 register struct address *a;
173
174                 for (a = q; a != NULL && a->q_owner == NULL; a = a->q_alias)
175                         continue;
176                 if (a != NULL)
177                         q->q_owner = a->q_owner;
178
179                 if (q->q_owner != NULL &&
180                     !bitset(QDONTSEND, q->q_flags) &&
181                     strcmp(q->q_owner, e->e_from.q_paddr) == 0)
182                         q->q_owner = NULL;
183         }
184
185         if (tTd(13, 25))
186         {
187                 printf("\nAfter first owner pass, sendq =\n");
188                 printaddr(e->e_sendqueue, TRUE);
189         }
190
191         owner = "";
192         otherowners = 1;
193         while (owner != NULL && otherowners > 0)
194         {
195                 if (tTd(13, 28))
196                         printf("owner = \"%s\", otherowners = %d\n",
197                                 owner, otherowners);
198                 owner = NULL;
199                 otherowners = bitset(EF_SENDRECEIPT, e->e_flags) ? 1 : 0;
200
201                 for (q = e->e_sendqueue; q != NULL; q = q->q_next)
202                 {
203                         if (tTd(13, 30))
204                         {
205                                 printf("Checking ");
206                                 printaddr(q, FALSE);
207                         }
208                         if (bitset(QDONTSEND, q->q_flags))
209                         {
210                                 if (tTd(13, 30))
211                                         printf("    ... QDONTSEND\n");
212                                 continue;
213                         }
214                         if (tTd(13, 29) && !tTd(13, 30))
215                         {
216                                 printf("Checking ");
217                                 printaddr(q, FALSE);
218                         }
219
220                         if (q->q_owner != NULL)
221                         {
222                                 if (owner == NULL)
223                                 {
224                                         if (tTd(13, 40))
225                                                 printf("    ... First owner = \"%s\"\n",
226                                                         q->q_owner);
227                                         owner = q->q_owner;
228                                 }
229                                 else if (owner != q->q_owner)
230                                 {
231                                         if (strcmp(owner, q->q_owner) == 0)
232                                         {
233                                                 if (tTd(13, 40))
234                                                         printf("    ... Same owner = \"%s\"\n",
235                                                                 owner);
236
237                                                 /* make future comparisons cheap */
238                                                 q->q_owner = owner;
239                                         }
240                                         else
241                                         {
242                                                 if (tTd(13, 40))
243                                                         printf("    ... Another owner \"%s\"\n",
244                                                                 q->q_owner);
245                                                 otherowners++;
246                                         }
247                                         owner = q->q_owner;
248                                 }
249                                 else if (tTd(13, 40))
250                                         printf("    ... Same owner = \"%s\"\n",
251                                                 owner);
252                         }
253                         else
254                         {
255                                 if (tTd(13, 40))
256                                         printf("    ... Null owner\n");
257                                 otherowners++;
258                         }
259
260                         /*
261                         **  If this mailer is expensive, and if we don't
262                         **  want to make connections now, just mark these
263                         **  addresses and return.  This is useful if we
264                         **  want to batch connections to reduce load.  This
265                         **  will cause the messages to be queued up, and a
266                         **  daemon will come along to send the messages later.
267                         */
268
269                         if (bitset(QBADADDR|QQUEUEUP, q->q_flags))
270                         {
271                                 if (tTd(13, 30))
272                                         printf("    ... QBADADDR|QQUEUEUP\n");
273                                 continue;
274                         }
275                         if (NoConnect && !Verbose &&
276                             bitnset(M_EXPENSIVE, q->q_mailer->m_flags))
277                         {
278                                 if (tTd(13, 30))
279                                         printf("    ... expensive\n");
280                                 q->q_flags |= QQUEUEUP;
281                                 expensive = TRUE;
282                         }
283                         else
284                         {
285                                 if (tTd(13, 30))
286                                         printf("    ... deliverable\n");
287                                 somedeliveries = TRUE;
288                         }
289                 }
290
291                 if (owner != NULL && otherowners > 0)
292                 {
293                         extern HDR *copyheader __P((HDR *));
294                         extern ADDRESS *copyqueue __P((ADDRESS *));
295                         extern void dup_queue_file __P((ENVELOPE *, ENVELOPE *, int));
296
297                         /*
298                         **  Split this envelope into two.
299                         */
300
301                         ee = (ENVELOPE *) xalloc(sizeof(ENVELOPE));
302                         *ee = *e;
303                         ee->e_id = NULL;
304                         (void) queuename(ee, '\0');
305
306                         if (tTd(13, 1))
307                                 printf("sendall: split %s into %s, owner = \"%s\", otherowners = %d\n",
308                                         e->e_id, ee->e_id, owner, otherowners);
309
310                         ee->e_header = copyheader(e->e_header);
311                         ee->e_sendqueue = copyqueue(e->e_sendqueue);
312                         ee->e_errorqueue = copyqueue(e->e_errorqueue);
313                         ee->e_flags = e->e_flags & ~(EF_INQUEUE|EF_CLRQUEUE|EF_FATALERRS|EF_SENDRECEIPT|EF_RET_PARAM);
314                         ee->e_flags |= EF_NORECEIPT;
315                         setsender(owner, ee, NULL, '\0', TRUE);
316                         if (tTd(13, 5))
317                         {
318                                 printf("sendall(split): QDONTSEND ");
319                                 printaddr(&ee->e_from, FALSE);
320                         }
321                         ee->e_from.q_flags |= QDONTSEND;
322                         ee->e_dfp = NULL;
323                         ee->e_xfp = NULL;
324                         ee->e_errormode = EM_MAIL;
325                         ee->e_sibling = splitenv;
326                         splitenv = ee;
327
328                         for (q = e->e_sendqueue; q != NULL; q = q->q_next)
329                         {
330                                 if (q->q_owner == owner)
331                                 {
332                                         q->q_flags |= QDONTSEND;
333                                         q->q_flags &= ~(QQUEUEUP|QBADADDR);
334                                         if (tTd(13, 6))
335                                                 printf("\t... stripping %s from original envelope\n",
336                                                         q->q_paddr);
337                                 }
338                         }
339                         for (q = ee->e_sendqueue; q != NULL; q = q->q_next)
340                         {
341                                 if (q->q_owner != owner)
342                                 {
343                                         q->q_flags |= QDONTSEND;
344                                         q->q_flags &= ~(QQUEUEUP|QBADADDR);
345                                         if (tTd(13, 6))
346                                                 printf("\t... dropping %s from cloned envelope\n",
347                                                         q->q_paddr);
348                                 }
349                                 else
350                                 {
351                                         /* clear DSN parameters */
352                                         q->q_flags &= ~(QHASNOTIFY|Q_PINGFLAGS);
353                                         q->q_flags |= DefaultNotify & ~QPINGONSUCCESS;
354                                         if (tTd(13, 6))
355                                                 printf("\t... moving %s to cloned envelope\n",
356                                                         q->q_paddr);
357                                 }
358                         }
359
360                         if (mode != SM_VERIFY && bitset(EF_HAS_DF, e->e_flags))
361                                 dup_queue_file(e, ee, 'd');
362                         openxscript(ee);
363                         if (mode != SM_VERIFY && LogLevel > 4)
364                                 sm_syslog(LOG_INFO, ee->e_id,
365                                         "clone %s, owner=%s",
366                                         e->e_id, owner);
367                 }
368         }
369
370         if (owner != NULL)
371         {
372                 setsender(owner, e, NULL, '\0', TRUE);
373                 if (tTd(13, 5))
374                 {
375                         printf("sendall(owner): QDONTSEND ");
376                         printaddr(&e->e_from, FALSE);
377                 }
378                 e->e_from.q_flags |= QDONTSEND;
379                 e->e_errormode = EM_MAIL;
380                 e->e_flags |= EF_NORECEIPT;
381                 e->e_flags &= ~EF_FATALERRS;
382         }
383
384         /* if nothing to be delivered, just queue up everything */
385         if (!somedeliveries && mode != SM_QUEUE && mode != SM_DEFER &&
386             mode != SM_VERIFY)
387         {
388                 if (tTd(13, 29))
389                         printf("No deliveries: auto-queuing\n");
390                 mode = SM_QUEUE;
391
392                 /* treat this as a delivery in terms of counting tries */
393                 e->e_dtime = curtime();
394                 if (!expensive)
395                         e->e_ntries++;
396                 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
397                 {
398                         ee->e_dtime = curtime();
399                         if (!expensive)
400                                 ee->e_ntries++;
401                 }
402         }
403
404 # if QUEUE
405         if ((mode == SM_QUEUE || mode == SM_DEFER || mode == SM_FORK ||
406              (mode != SM_VERIFY && SuperSafe)) &&
407             (!bitset(EF_INQUEUE, e->e_flags) || splitenv != NULL))
408         {
409                 /* be sure everything is instantiated in the queue */
410                 queueup(e, mode == SM_QUEUE || mode == SM_DEFER);
411                 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
412                         queueup(ee, mode == SM_QUEUE || mode == SM_DEFER);
413         }
414 #endif /* QUEUE */
415
416         if (tTd(62, 10))
417                 checkfds("after envelope splitting");
418
419         /*
420         **  If we belong in background, fork now.
421         */
422
423         if (tTd(13, 20))
424         {
425                 printf("sendall: final mode = %c\n", mode);
426                 if (tTd(13, 21))
427                 {
428                         printf("\n================ Final Send Queue(s) =====================\n");
429                         printf("\n  *** Envelope %s, e_from=%s ***\n",
430                                 e->e_id, e->e_from.q_paddr);
431                         printaddr(e->e_sendqueue, TRUE);
432                         for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
433                         {
434                                 printf("\n  *** Envelope %s, e_from=%s ***\n",
435                                         ee->e_id, ee->e_from.q_paddr);
436                                 printaddr(ee->e_sendqueue, TRUE);
437                         }
438                         printf("==========================================================\n\n");
439                 }
440         }
441         switch (mode)
442         {
443           case SM_VERIFY:
444                 Verbose = 2;
445                 break;
446
447           case SM_QUEUE:
448           case SM_DEFER:
449 # if HASFLOCK
450   queueonly:
451 # endif
452                 if (e->e_nrcpts > 0)
453                         e->e_flags |= EF_INQUEUE;
454                 dropenvelope(e, splitenv != NULL);
455                 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
456                 {
457                         if (ee->e_nrcpts > 0)
458                                 ee->e_flags |= EF_INQUEUE;
459                         dropenvelope(ee, FALSE);
460                 }
461                 return;
462
463           case SM_FORK:
464                 if (e->e_xfp != NULL)
465                         (void) fflush(e->e_xfp);
466
467 # if !HASFLOCK
468                 /*
469                 **  Since fcntl locking has the interesting semantic that
470                 **  the lock is owned by a process, not by an open file
471                 **  descriptor, we have to flush this to the queue, and
472                 **  then restart from scratch in the child.
473                 */
474
475                 {
476                         /* save id for future use */
477                         char *qid = e->e_id;
478
479                         /* now drop the envelope in the parent */
480                         e->e_flags |= EF_INQUEUE;
481                         dropenvelope(e, splitenv != NULL);
482
483                         /* arrange to reacquire lock after fork */
484                         e->e_id = qid;
485                 }
486
487                 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
488                 {
489                         /* save id for future use */
490                         char *qid = ee->e_id;
491
492                         /* drop envelope in parent */
493                         ee->e_flags |= EF_INQUEUE;
494                         dropenvelope(ee, FALSE);
495
496                         /* and save qid for reacquisition */
497                         ee->e_id = qid;
498                 }
499
500 # endif /* !HASFLOCK */
501
502                 pid = fork();
503                 if (pid < 0)
504                 {
505 # if HASFLOCK
506                         goto queueonly;
507 # else
508                         e->e_id = NULL;
509                         for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
510                                 ee->e_id = NULL;
511                         return;
512 # endif /* HASFLOCK */
513                 }
514                 else if (pid > 0)
515                 {
516 # if HASFLOCK
517                         /* be sure we leave the temp files to our child */
518                         /* close any random open files in the envelope */
519                         closexscript(e);
520                         if (e->e_dfp != NULL)
521                                 (void) xfclose(e->e_dfp, "sendenvelope dfp", e->e_id);
522                         e->e_dfp = NULL;
523                         e->e_flags &= ~EF_HAS_DF;
524
525                         /* can't call unlockqueue to avoid unlink of xfp */
526                         if (e->e_lockfp != NULL)
527                                 (void) xfclose(e->e_lockfp, "sendenvelope lockfp", e->e_id);
528                         e->e_lockfp = NULL;
529 # endif
530
531                         /* make sure the parent doesn't own the envelope */
532                         e->e_id = NULL;
533
534                         /* catch intermediate zombie */
535                         (void) waitfor(pid);
536                         return;
537                 }
538
539                 /* double fork to avoid zombies */
540                 pid = fork();
541                 if (pid > 0)
542                         exit(EX_OK);
543
544                 /* be sure we are immune from the terminal */
545                 disconnect(2, e);
546
547                 /* prevent parent from waiting if there was an error */
548                 if (pid < 0)
549                 {
550 # if HASFLOCK
551                         e->e_flags |= EF_INQUEUE;
552 # else
553                         e->e_id = NULL;
554 # endif /* HASFLOCK */
555                         finis(TRUE, ExitStat);
556                 }
557
558                 /* be sure to give error messages in child */
559                 QuickAbort = FALSE;
560
561                 /*
562                 **  Close any cached connections.
563                 **
564                 **      We don't send the QUIT protocol because the parent
565                 **      still knows about the connection.
566                 **
567                 **      This should only happen when delivering an error
568                 **      message.
569                 */
570
571                 mci_flush(FALSE, NULL);
572
573                 /*
574                 **  Since the delivery may happen in a child and the parent
575                 **  does not wait, the parent may close the maps thereby
576                 **  removing any shared memory used by the map.  Therefore,
577                 **  open a copy of the maps for the delivery process.
578                 */
579
580                 initmaps(FALSE, e);
581
582 # if HASFLOCK
583                 break;
584 # else
585
586                 /*
587                 **  Now reacquire and run the various queue files.
588                 */
589
590                 for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
591                 {
592                         ENVELOPE *sibling = ee->e_sibling;
593
594                         (void) dowork(ee->e_id, FALSE, FALSE, ee);
595                         ee->e_sibling = sibling;
596                 }
597                 (void) dowork(e->e_id, FALSE, FALSE, e);
598                 finis(TRUE, ExitStat);
599 # endif /* !HASFLOCK */
600         }
601
602         sendenvelope(e, mode);
603         dropenvelope(e, TRUE);
604         for (ee = splitenv; ee != NULL; ee = ee->e_sibling)
605         {
606                 CurEnv = ee;
607                 if (mode != SM_VERIFY)
608                         openxscript(ee);
609                 sendenvelope(ee, mode);
610                 dropenvelope(ee, TRUE);
611         }
612         CurEnv = e;
613
614         Verbose = oldverbose;
615         if (mode == SM_FORK)
616                 finis(TRUE, ExitStat);
617 }
618
619 void
620 sendenvelope(e, mode)
621         register ENVELOPE *e;
622         int mode;
623 {
624         register ADDRESS *q;
625         bool didany;
626
627         if (tTd(13, 10))
628                 printf("sendenvelope(%s) e_flags=0x%lx\n",
629                         e->e_id == NULL ? "[NOQUEUE]" : e->e_id,
630                         e->e_flags);
631         if (LogLevel > 80)
632                 sm_syslog(LOG_DEBUG, e->e_id,
633                         "sendenvelope, flags=0x%x",
634                         e->e_flags);
635
636         /*
637         **  If we have had global, fatal errors, don't bother sending
638         **  the message at all if we are in SMTP mode.  Local errors
639         **  (e.g., a single address failing) will still cause the other
640         **  addresses to be sent.
641         */
642
643         if (bitset(EF_FATALERRS, e->e_flags) &&
644             (OpMode == MD_SMTP || OpMode == MD_DAEMON))
645         {
646                 e->e_flags |= EF_CLRQUEUE;
647                 return;
648         }
649
650         /*
651         **  Run through the list and send everything.
652         **
653         **      Set EF_GLOBALERRS so that error messages during delivery
654         **      result in returned mail.
655         */
656
657         e->e_nsent = 0;
658         e->e_flags |= EF_GLOBALERRS;
659         define(macid("{envid}", NULL), e->e_envid, e);
660         define(macid("{bodytype}", NULL), e->e_bodytype, e);
661         didany = FALSE;
662
663         /* now run through the queue */
664         for (q = e->e_sendqueue; q != NULL; q = q->q_next)
665         {
666 #if XDEBUG
667                 char wbuf[MAXNAME + 20];
668
669                 (void) snprintf(wbuf, sizeof wbuf, "sendall(%.*s)",
670                         MAXNAME, q->q_paddr);
671                 checkfd012(wbuf);
672 #endif
673                 if (mode == SM_VERIFY)
674                 {
675                         e->e_to = q->q_paddr;
676                         if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
677                         {
678                                 if (q->q_host != NULL && q->q_host[0] != '\0')
679                                         message("deliverable: mailer %s, host %s, user %s",
680                                                 q->q_mailer->m_name,
681                                                 q->q_host,
682                                                 q->q_user);
683                                 else
684                                         message("deliverable: mailer %s, user %s",
685                                                 q->q_mailer->m_name,
686                                                 q->q_user);
687                         }
688                 }
689                 else if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
690                 {
691                         extern int deliver __P((ENVELOPE *, ADDRESS *));
692
693 # if QUEUE
694                         /*
695                         **  Checkpoint the send list every few addresses
696                         */
697
698                         if (e->e_nsent >= CheckpointInterval)
699                         {
700                                 queueup(e, FALSE);
701                                 e->e_nsent = 0;
702                         }
703 # endif /* QUEUE */
704                         (void) deliver(e, q);
705                         didany = TRUE;
706                 }
707         }
708         if (didany)
709         {
710                 e->e_dtime = curtime();
711                 e->e_ntries++;
712         }
713
714 #if XDEBUG
715         checkfd012("end of sendenvelope");
716 #endif
717 }
718 \f/*
719 **  DUP_QUEUE_FILE -- duplicate a queue file into a split queue
720 **
721 **      Parameters:
722 **              e -- the existing envelope
723 **              ee -- the new envelope
724 **              type -- the queue file type (e.g., 'd')
725 **
726 **      Returns:
727 **              none
728 */
729
730 void
731 dup_queue_file(e, ee, type)
732         struct envelope *e, *ee;
733         int type;
734 {
735         char f1buf[MAXQFNAME], f2buf[MAXQFNAME];
736
737         ee->e_dfp = NULL;
738         ee->e_xfp = NULL;
739         snprintf(f1buf, sizeof f1buf, "%s", queuename(e, type));
740         snprintf(f2buf, sizeof f2buf, "%s", queuename(ee, type));
741         if (link(f1buf, f2buf) < 0)
742         {
743                 int saverrno = errno;
744
745                 syserr("sendall: link(%s, %s)", f1buf, f2buf);
746                 if (saverrno == EEXIST)
747                 {
748                         if (unlink(f2buf) < 0)
749                         {
750                                 syserr("!sendall: unlink(%s): permanent",
751                                         f2buf);
752                                 /*NOTREACHED*/
753                         }
754                         if (link(f1buf, f2buf) < 0)
755                         {
756                                 syserr("!sendall: link(%s, %s): permanent",
757                                         f1buf, f2buf);
758                                 /*NOTREACHED*/
759                         }
760                 }
761         }
762 }
763 \f/*
764 **  DOFORK -- do a fork, retrying a couple of times on failure.
765 **
766 **      This MUST be a macro, since after a vfork we are running
767 **      two processes on the same stack!!!
768 **
769 **      Parameters:
770 **              none.
771 **
772 **      Returns:
773 **              From a macro???  You've got to be kidding!
774 **
775 **      Side Effects:
776 **              Modifies the ==> LOCAL <== variable 'pid', leaving:
777 **                      pid of child in parent, zero in child.
778 **                      -1 on unrecoverable error.
779 **
780 **      Notes:
781 **              I'm awfully sorry this looks so awful.  That's
782 **              vfork for you.....
783 */
784
785 # define NFORKTRIES     5
786
787 # ifndef FORK
788 # define FORK   fork
789 # endif
790
791 # define DOFORK(fORKfN) \
792 {\
793         register int i;\
794 \
795         for (i = NFORKTRIES; --i >= 0; )\
796         {\
797                 pid = fORKfN();\
798                 if (pid >= 0)\
799                         break;\
800                 if (i > 0)\
801                         sleep((unsigned) NFORKTRIES - i);\
802         }\
803 }
804 \f/*
805 **  DOFORK -- simple fork interface to DOFORK.
806 **
807 **      Parameters:
808 **              none.
809 **
810 **      Returns:
811 **              pid of child in parent.
812 **              zero in child.
813 **              -1 on error.
814 **
815 **      Side Effects:
816 **              returns twice, once in parent and once in child.
817 */
818
819 int
820 dofork()
821 {
822         register pid_t pid = -1;
823
824         DOFORK(fork);
825         return (pid);
826 }
827 \f/*
828 **  DELIVER -- Deliver a message to a list of addresses.
829 **
830 **      This routine delivers to everyone on the same host as the
831 **      user on the head of the list.  It is clever about mailers
832 **      that don't handle multiple users.  It is NOT guaranteed
833 **      that it will deliver to all these addresses however -- so
834 **      deliver should be called once for each address on the
835 **      list.
836 **
837 **      Parameters:
838 **              e -- the envelope to deliver.
839 **              firstto -- head of the address list to deliver to.
840 **
841 **      Returns:
842 **              zero -- successfully delivered.
843 **              else -- some failure, see ExitStat for more info.
844 **
845 **      Side Effects:
846 **              The standard input is passed off to someone.
847 */
848
849 #ifndef NO_UID
850 # define NO_UID         -1
851 #endif
852 #ifndef NO_GID
853 # define NO_GID         -1
854 #endif
855
856 int
857 deliver(e, firstto)
858         register ENVELOPE *e;
859         ADDRESS *firstto;
860 {
861         char *host;                     /* host being sent to */
862         char *user;                     /* user being sent to */
863         char **pvp;
864         register char **mvp;
865         register char *p;
866         register MAILER *m;             /* mailer for this recipient */
867         ADDRESS *volatile ctladdr;
868         ADDRESS *volatile contextaddr = NULL;
869         register MCI *volatile mci;
870         register ADDRESS *to = firstto;
871         volatile bool clever = FALSE;   /* running user smtp to this mailer */
872         ADDRESS *volatile tochain = NULL; /* users chain in this mailer call */
873         int rcode;                      /* response code */
874         int lmtp_rcode = EX_OK;
875         char *firstsig;                 /* signature of firstto */
876         pid_t pid = -1;
877         char *volatile curhost;
878         register u_short port = 0;
879         time_t xstart;
880         bool suidwarn;
881         bool anyok;                     /* at least one address was OK */
882         bool goodmxfound = FALSE;       /* at least one MX was OK */
883         int mpvect[2];
884         int rpvect[2];
885         char *pv[MAXPV+1];
886         char tobuf[TOBUFSIZE];          /* text line of to people */
887         char buf[MAXNAME + 1];
888         char rpathbuf[MAXNAME + 1];     /* translated return path */
889         extern int checkcompat __P((ADDRESS *, ENVELOPE *));
890         extern void markfailure __P((ENVELOPE *, ADDRESS *, MCI *, int));
891
892         errno = 0;
893         if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags))
894                 return (0);
895
896         suidwarn = geteuid() == 0;
897
898 #if NAMED_BIND
899         /* unless interactive, try twice, over a minute */
900         if (OpMode == MD_DAEMON || OpMode == MD_SMTP)
901         {
902                 _res.retrans = 30;
903                 _res.retry = 2;
904         }
905 #endif
906
907         m = to->q_mailer;
908         host = to->q_host;
909         CurEnv = e;                     /* just in case */
910         e->e_statmsg = NULL;
911 #if SMTP
912         SmtpError[0] = '\0';
913 #endif
914         xstart = curtime();
915
916         if (tTd(10, 1))
917                 printf("\n--deliver, id=%s, mailer=%s, host=`%s', first user=`%s'\n",
918                         e->e_id, m->m_name, host, to->q_user);
919         if (tTd(10, 100))
920                 printopenfds(FALSE);
921
922         /*
923         **  Clear $&{client_*} macros if this is a bounce message to
924         **  prevent rejection by check_compat ruleset.
925         */
926         
927         if (bitset(EF_RESPONSE, e->e_flags))
928         {
929                 define(macid("{client_name}", NULL), "", e);
930                 define(macid("{client_addr}", NULL), "", e);
931                 define(macid("{client_port}", NULL), "", e);
932         }
933         
934         /*
935         **  Do initial argv setup.
936         **      Insert the mailer name.  Notice that $x expansion is
937         **      NOT done on the mailer name.  Then, if the mailer has
938         **      a picky -f flag, we insert it as appropriate.  This
939         **      code does not check for 'pv' overflow; this places a
940         **      manifest lower limit of 4 for MAXPV.
941         **              The from address rewrite is expected to make
942         **              the address relative to the other end.
943         */
944
945         /* rewrite from address, using rewriting rules */
946         rcode = EX_OK;
947         if (bitnset(M_UDBENVELOPE, e->e_from.q_mailer->m_flags))
948                 p = e->e_sender;
949         else
950                 p = e->e_from.q_paddr;
951         p = remotename(p, m, RF_SENDERADDR|RF_CANONICAL, &rcode, e);
952         if (strlen(p) >= (SIZE_T) sizeof rpathbuf)
953         {
954                 p = shortenstring(p, MAXSHORTSTR);
955                 syserr("remotename: huge return %s", p);
956         }
957         snprintf(rpathbuf, sizeof rpathbuf, "%s", p);
958         define('g', rpathbuf, e);               /* translated return path */
959         define('h', host, e);                   /* to host */
960         Errors = 0;
961         pvp = pv;
962         *pvp++ = m->m_argv[0];
963
964         /* insert -f or -r flag as appropriate */
965         if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
966         {
967                 if (bitnset(M_FOPT, m->m_flags))
968                         *pvp++ = "-f";
969                 else
970                         *pvp++ = "-r";
971                 *pvp++ = newstr(rpathbuf);
972         }
973
974         /*
975         **  Append the other fixed parts of the argv.  These run
976         **  up to the first entry containing "$u".  There can only
977         **  be one of these, and there are only a few more slots
978         **  in the pv after it.
979         */
980
981         for (mvp = m->m_argv; (p = *++mvp) != NULL; )
982         {
983                 /* can't use strchr here because of sign extension problems */
984                 while (*p != '\0')
985                 {
986                         if ((*p++ & 0377) == MACROEXPAND)
987                         {
988                                 if (*p == 'u')
989                                         break;
990                         }
991                 }
992
993                 if (*p != '\0')
994                         break;
995
996                 /* this entry is safe -- go ahead and process it */
997                 expand(*mvp, buf, sizeof buf, e);
998                 *pvp++ = newstr(buf);
999                 if (pvp >= &pv[MAXPV - 3])
1000                 {
1001                         syserr("554 Too many parameters to %s before $u", pv[0]);
1002                         return (-1);
1003                 }
1004         }
1005
1006         /*
1007         **  If we have no substitution for the user name in the argument
1008         **  list, we know that we must supply the names otherwise -- and
1009         **  SMTP is the answer!!
1010         */
1011
1012         if (*mvp == NULL)
1013         {
1014                 /* running SMTP */
1015 # if SMTP
1016                 clever = TRUE;
1017                 *pvp = NULL;
1018 # else /* SMTP */
1019                 /* oops!  we don't implement SMTP */
1020                 syserr("554 SMTP style mailer not implemented");
1021                 return (EX_SOFTWARE);
1022 # endif /* SMTP */
1023         }
1024
1025         /*
1026         **  At this point *mvp points to the argument with $u.  We
1027         **  run through our address list and append all the addresses
1028         **  we can.  If we run out of space, do not fret!  We can
1029         **  always send another copy later.
1030         */
1031
1032         tobuf[0] = '\0';
1033         e->e_to = tobuf;
1034         ctladdr = NULL;
1035         firstsig = hostsignature(firstto->q_mailer, firstto->q_host, e);
1036         for (; to != NULL; to = to->q_next)
1037         {
1038                 /* avoid sending multiple recipients to dumb mailers */
1039                 if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
1040                         break;
1041
1042                 /* if already sent or not for this host, don't send */
1043                 if (bitset(QDONTSEND|QBADADDR|QQUEUEUP, to->q_flags) ||
1044                     to->q_mailer != firstto->q_mailer ||
1045                     strcmp(hostsignature(to->q_mailer, to->q_host, e), firstsig) != 0)
1046                         continue;
1047
1048                 /* avoid overflowing tobuf */
1049                 if (sizeof tobuf < (strlen(to->q_paddr) + strlen(tobuf) + 2))
1050                         break;
1051
1052                 if (tTd(10, 1))
1053                 {
1054                         printf("\nsend to ");
1055                         printaddr(to, FALSE);
1056                 }
1057
1058                 /* compute effective uid/gid when sending */
1059                 if (bitnset(M_RUNASRCPT, to->q_mailer->m_flags))
1060                         contextaddr = ctladdr = getctladdr(to);
1061
1062                 if (tTd(10, 2))
1063                 {
1064                         printf("ctladdr=");
1065                         printaddr(ctladdr, FALSE);
1066                 }
1067
1068                 user = to->q_user;
1069                 e->e_to = to->q_paddr;
1070                 if (tTd(10, 5))
1071                 {
1072                         printf("deliver: QDONTSEND ");
1073                         printaddr(to, FALSE);
1074                 }
1075                 to->q_flags |= QDONTSEND;
1076
1077                 /*
1078                 **  Check to see that these people are allowed to
1079                 **  talk to each other.
1080                 */
1081
1082                 if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
1083                 {
1084                         e->e_flags |= EF_NO_BODY_RETN;
1085                         if (bitnset(M_LOCALMAILER, to->q_mailer->m_flags))
1086                                 to->q_status = "5.2.3";
1087                         else
1088                                 to->q_status = "5.3.4";
1089                         usrerr("552 Message is too large; %ld bytes max", m->m_maxsize);
1090                         markfailure(e, to, NULL, EX_UNAVAILABLE);
1091                         giveresponse(EX_UNAVAILABLE, m, NULL, ctladdr, xstart, e);
1092                         continue;
1093                 }
1094 #if NAMED_BIND
1095                 h_errno = 0;
1096 #endif
1097
1098                 /* do config file checking of compatibility */
1099                 rcode = rscheck("check_compat",
1100                                 e->e_from.q_paddr, to->q_paddr, e);
1101                 if (rcode == EX_OK)
1102                 {
1103                         /* do in-code checking if not discarding */
1104                         if (!bitset(EF_DISCARD, e->e_flags))
1105                                 rcode = checkcompat(to, e);
1106                 }
1107                 if (rcode != EX_OK)
1108                 {
1109                         markfailure(e, to, NULL, rcode);
1110                         giveresponse(rcode, m, NULL, ctladdr, xstart, e);
1111                         continue;
1112                 }
1113                 if (bitset(EF_DISCARD, e->e_flags))
1114                 {
1115                         if (tTd(10, 5))
1116                         {
1117                                 printf("deliver: discarding recipient ");
1118                                 printaddr(to, FALSE);
1119                         }
1120
1121                         /*
1122                         **  Remove discard bit to prevent discard of
1123                         **  future recipients
1124                         */
1125                         e->e_flags &= ~EF_DISCARD;
1126
1127                         continue;
1128                 }
1129
1130                 /*
1131                 **  Strip quote bits from names if the mailer is dumb
1132                 **      about them.
1133                 */
1134
1135                 if (bitnset(M_STRIPQ, m->m_flags))
1136                 {
1137                         stripquotes(user);
1138                         stripquotes(host);
1139                 }
1140
1141                 /* hack attack -- delivermail compatibility */
1142                 if (m == ProgMailer && *user == '|')
1143                         user++;
1144
1145                 /*
1146                 **  If an error message has already been given, don't
1147                 **      bother to send to this address.
1148                 **
1149                 **      >>>>>>>>>> This clause assumes that the local mailer
1150                 **      >> NOTE >> cannot do any further aliasing; that
1151                 **      >>>>>>>>>> function is subsumed by sendmail.
1152                 */
1153
1154                 if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
1155                         continue;
1156
1157                 /*
1158                 **  See if this user name is "special".
1159                 **      If the user name has a slash in it, assume that this
1160                 **      is a file -- send it off without further ado.  Note
1161                 **      that this type of addresses is not processed along
1162                 **      with the others, so we fudge on the To person.
1163                 */
1164
1165                 if (strcmp(m->m_mailer, "[FILE]") == 0)
1166                 {
1167                         define('u', user, e);   /* to user */
1168                         p = to->q_home;
1169                         if (p == NULL && ctladdr != NULL)
1170                                 p = ctladdr->q_home;
1171                         define('z', p, e);      /* user's home */
1172                         expand(m->m_argv[1], buf, sizeof buf, e);
1173                         if (strlen(buf) > 0)
1174                                 rcode = mailfile(buf, m, ctladdr, SFF_CREAT, e);
1175                         else
1176                         {
1177                                 syserr("empty filename specification for mailer %s",
1178                                        m->m_name);
1179                                 rcode = EX_CONFIG;
1180                         }
1181                         giveresponse(rcode, m, NULL, ctladdr, xstart, e);
1182                         markfailure(e, to, NULL, rcode);
1183                         e->e_nsent++;
1184                         if (rcode == EX_OK)
1185                         {
1186                                 to->q_flags |= QSENT;
1187                                 if (bitnset(M_LOCALMAILER, m->m_flags) &&
1188                                     bitset(QPINGONSUCCESS, to->q_flags))
1189                                 {
1190                                         to->q_flags |= QDELIVERED;
1191                                         to->q_status = "2.1.5";
1192                                         fprintf(e->e_xfp, "%s... Successfully delivered\n",
1193                                                 to->q_paddr);
1194                                 }
1195                         }
1196                         to->q_statdate = curtime();
1197                         markstats(e, to, FALSE);
1198                         continue;
1199                 }
1200
1201                 /*
1202                 **  Address is verified -- add this user to mailer
1203                 **  argv, and add it to the print list of recipients.
1204                 */
1205
1206                 /* link together the chain of recipients */
1207                 to->q_tchain = tochain;
1208                 tochain = to;
1209
1210                 /* create list of users for error messages */
1211                 (void) strcat(tobuf, ",");
1212                 (void) strcat(tobuf, to->q_paddr);
1213                 define('u', user, e);           /* to user */
1214                 p = to->q_home;
1215                 if (p == NULL && ctladdr != NULL)
1216                         p = ctladdr->q_home;
1217                 define('z', p, e);      /* user's home */
1218
1219                 /*
1220                 **  Expand out this user into argument list.
1221                 */
1222
1223                 if (!clever)
1224                 {
1225                         expand(*mvp, buf, sizeof buf, e);
1226                         *pvp++ = newstr(buf);
1227                         if (pvp >= &pv[MAXPV - 2])
1228                         {
1229                                 /* allow some space for trailing parms */
1230                                 break;
1231                         }
1232                 }
1233         }
1234
1235         /* see if any addresses still exist */
1236         if (tobuf[0] == '\0')
1237         {
1238                 define('g', (char *) NULL, e);
1239                 return (0);
1240         }
1241
1242         /* print out messages as full list */
1243         e->e_to = tobuf + 1;
1244
1245         /*
1246         **  Fill out any parameters after the $u parameter.
1247         */
1248
1249         while (!clever && *++mvp != NULL)
1250         {
1251                 expand(*mvp, buf, sizeof buf, e);
1252                 *pvp++ = newstr(buf);
1253                 if (pvp >= &pv[MAXPV])
1254                         syserr("554 deliver: pv overflow after $u for %s", pv[0]);
1255         }
1256         *pvp++ = NULL;
1257
1258         /*
1259         **  Call the mailer.
1260         **      The argument vector gets built, pipes
1261         **      are created as necessary, and we fork & exec as
1262         **      appropriate.
1263         **      If we are running SMTP, we just need to clean up.
1264         */
1265
1266         /*XXX this seems a bit wierd */
1267         if (ctladdr == NULL && m != ProgMailer && m != FileMailer &&
1268             bitset(QGOODUID, e->e_from.q_flags))
1269                 ctladdr = &e->e_from;
1270
1271 #if NAMED_BIND
1272         if (ConfigLevel < 2)
1273                 _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);   /* XXX */
1274 #endif
1275
1276         if (tTd(11, 1))
1277         {
1278                 printf("openmailer:");
1279                 printav(pv);
1280         }
1281         errno = 0;
1282 #if NAMED_BIND
1283         h_errno = 0;
1284 #endif
1285
1286         CurHostName = NULL;
1287
1288         /*
1289         **  Deal with the special case of mail handled through an IPC
1290         **  connection.
1291         **      In this case we don't actually fork.  We must be
1292         **      running SMTP for this to work.  We will return a
1293         **      zero pid to indicate that we are running IPC.
1294         **  We also handle a debug version that just talks to stdin/out.
1295         */
1296
1297         curhost = NULL;
1298         SmtpPhase = NULL;
1299         mci = NULL;
1300
1301 #if XDEBUG
1302         {
1303                 char wbuf[MAXLINE];
1304
1305                 /* make absolutely certain 0, 1, and 2 are in use */
1306                 snprintf(wbuf, sizeof wbuf, "%s... openmailer(%s)",
1307                         shortenstring(e->e_to, MAXSHORTSTR), m->m_name);
1308                 checkfd012(wbuf);
1309         }
1310 #endif
1311
1312         /* check for 8-bit available */
1313         if (bitset(EF_HAS8BIT, e->e_flags) &&
1314             bitnset(M_7BITS, m->m_flags) &&
1315             (bitset(EF_DONT_MIME, e->e_flags) ||
1316              !(bitset(MM_MIME8BIT, MimeMode) ||
1317                (bitset(EF_IS_MIME, e->e_flags) &&
1318                 bitset(MM_CVTMIME, MimeMode)))))
1319         {
1320                 usrerr("554 Cannot send 8-bit data to 7-bit destination");
1321                 rcode = EX_DATAERR;
1322                 e->e_status = "5.6.3";
1323                 goto give_up;
1324         }
1325
1326         if (tTd(62, 8))
1327                 checkfds("before delivery");
1328
1329         /* check for Local Person Communication -- not for mortals!!! */
1330         if (strcmp(m->m_mailer, "[LPC]") == 0)
1331         {
1332                 mci = (MCI *) xalloc(sizeof *mci);
1333                 bzero((char *) mci, sizeof *mci);
1334                 mci->mci_in = stdin;
1335                 mci->mci_out = stdout;
1336                 mci->mci_state = clever ? MCIS_OPENING : MCIS_OPEN;
1337                 mci->mci_mailer = m;
1338         }
1339         else if (strcmp(m->m_mailer, "[IPC]") == 0 ||
1340                  strcmp(m->m_mailer, "[TCP]") == 0)
1341         {
1342 #if DAEMON
1343                 register int i;
1344
1345                 if (pv[0] == NULL || pv[1] == NULL || pv[1][0] == '\0')
1346                 {
1347                         syserr("null host name for %s mailer", m->m_mailer);
1348                         rcode = EX_CONFIG;
1349                         goto give_up;
1350                 }
1351
1352                 CurHostName = pv[1];
1353                 curhost = hostsignature(m, pv[1], e);
1354
1355                 if (curhost == NULL || curhost[0] == '\0')
1356                 {
1357                         syserr("null host signature for %s", pv[1]);
1358                         rcode = EX_CONFIG;
1359                         goto give_up;
1360                 }
1361
1362                 if (!clever)
1363                 {
1364                         syserr("554 non-clever IPC");
1365                         rcode = EX_CONFIG;
1366                         goto give_up;
1367                 }
1368                 if (pv[2] != NULL)
1369                 {
1370                         port = htons(atoi(pv[2]));
1371                         if (port == 0)
1372                         {
1373                                 struct servent *sp = getservbyname(pv[2], "tcp");
1374
1375                                 if (sp == NULL)
1376                                         syserr("Service %s unknown", pv[2]);
1377                                 else
1378                                         port = sp->s_port;
1379                         }
1380                 }
1381 tryhost:
1382                 while (*curhost != '\0')
1383                 {
1384                         static char hostbuf[MAXNAME + 1];
1385                         extern int makeconnection __P((char *, u_short, MCI *, ENVELOPE *));
1386
1387                         /* pull the next host from the signature */
1388                         p = strchr(curhost, ':');
1389                         if (p == NULL)
1390                                 p = (char *) &curhost[strlen(curhost)];
1391                         if (p == curhost)
1392                         {
1393                                 syserr("deliver: null host name in signature");
1394                                 curhost++;
1395                                 continue;
1396                         }
1397                         i = p - curhost;
1398                         if (i >= sizeof hostbuf)
1399                                 i = sizeof hostbuf - 1;
1400                         strncpy(hostbuf, curhost, i);
1401                         hostbuf[i] = '\0';
1402                         if (*p != '\0')
1403                                 p++;
1404                         curhost = p;
1405
1406                         /* see if we already know that this host is fried */
1407                         CurHostName = hostbuf;
1408                         mci = mci_get(hostbuf, m);
1409                         if (mci->mci_state != MCIS_CLOSED)
1410                         {
1411                                 if (tTd(11, 1))
1412                                 {
1413                                         printf("openmailer: ");
1414                                         mci_dump(mci, FALSE);
1415                                 }
1416                                 CurHostName = mci->mci_host;
1417                                 message("Using cached %sSMTP connection to %s via %s...",
1418                                         bitset(MCIF_ESMTP, mci->mci_flags) ? "E" : "",
1419                                         hostbuf, m->m_name);
1420                                 break;
1421                         }
1422                         mci->mci_mailer = m;
1423                         if (mci->mci_exitstat != EX_OK)
1424                         {
1425                                 if (mci->mci_exitstat == EX_TEMPFAIL)
1426                                         goodmxfound = TRUE;
1427                                 continue;
1428                         }
1429
1430                         if (mci_lock_host(mci) != EX_OK)
1431                         {
1432                                 mci_setstat(mci, EX_TEMPFAIL, "4.4.5", NULL);
1433                                 goodmxfound = TRUE;
1434                                 continue;
1435                         }
1436
1437                         /* try the connection */
1438                         sm_setproctitle(TRUE, "%s %s: %s", e->e_id, hostbuf, "user open");
1439                         if (port == 0)
1440                                 message("Connecting to %s via %s...",
1441                                         hostbuf, m->m_name);
1442                         else
1443                                 message("Connecting to %s port %d via %s...",
1444                                         hostbuf, ntohs(port), m->m_name);
1445                         i = makeconnection(hostbuf, port, mci, e);
1446                         mci->mci_lastuse = curtime();
1447                         mci->mci_exitstat = i;
1448                         mci->mci_errno = errno;
1449 #if NAMED_BIND
1450                         mci->mci_herrno = h_errno;
1451 #endif
1452                         if (i == EX_OK)
1453                         {
1454                                 goodmxfound = TRUE;
1455                                 mci->mci_state = MCIS_OPENING;
1456                                 mci_cache(mci);
1457                                 if (TrafficLogFile != NULL)
1458                                         fprintf(TrafficLogFile, "%05d === CONNECT %s\n",
1459                                                 (int) getpid(), hostbuf);
1460                                 break;
1461                         }
1462                         else
1463                         {
1464                                 if (tTd(11, 1))
1465                                         printf("openmailer: makeconnection => stat=%d, errno=%d\n",
1466                                                 i, errno);
1467                                 if (i == EX_TEMPFAIL)
1468                                         goodmxfound = TRUE;
1469                                 mci_unlock_host(mci);
1470                         }
1471
1472                         /* enter status of this host */
1473                         setstat(i);
1474
1475                         /* should print some message here for -v mode */
1476                 }
1477                 if (mci == NULL)
1478                 {
1479                         syserr("deliver: no host name");
1480                         rcode = EX_SOFTWARE;
1481                         goto give_up;
1482                 }
1483                 mci->mci_pid = 0;
1484 #else /* no DAEMON */
1485                 syserr("554 openmailer: no IPC");
1486                 if (tTd(11, 1))
1487                         printf("openmailer: NULL\n");
1488                 rcode = EX_UNAVAILABLE;
1489                 goto give_up;
1490 #endif /* DAEMON */
1491         }
1492         else
1493         {
1494                 /* flush any expired connections */
1495                 (void) mci_scan(NULL);
1496                 mci = NULL;
1497
1498 #if SMTP
1499                 if (bitnset(M_LMTP, m->m_flags))
1500                 {
1501                         /* try to get a cached connection */
1502                         mci = mci_get(m->m_name, m);
1503                         if (mci->mci_host == NULL)
1504                                 mci->mci_host = m->m_name;
1505                         CurHostName = mci->mci_host;
1506                         if (mci->mci_state != MCIS_CLOSED)
1507                         {
1508                                 message("Using cached LMTP connection for %s...",
1509                                         m->m_name);
1510                                 goto do_transfer;
1511                         }
1512                 }
1513 #endif
1514
1515                 /* announce the connection to verbose listeners */
1516                 if (host == NULL || host[0] == '\0')
1517                         message("Connecting to %s...", m->m_name);
1518                 else
1519                         message("Connecting to %s via %s...", host, m->m_name);
1520                 if (TrafficLogFile != NULL)
1521                 {
1522                         char **av;
1523
1524                         fprintf(TrafficLogFile, "%05d === EXEC", (int) getpid());
1525                         for (av = pv; *av != NULL; av++)
1526                                 fprintf(TrafficLogFile, " %s", *av);
1527                         fprintf(TrafficLogFile, "\n");
1528                 }
1529
1530 #if XDEBUG
1531                 checkfd012("before creating mail pipe");
1532 #endif
1533
1534                 /* create a pipe to shove the mail through */
1535                 if (pipe(mpvect) < 0)
1536                 {
1537                         syserr("%s... openmailer(%s): pipe (to mailer)",
1538                                 shortenstring(e->e_to, MAXSHORTSTR), m->m_name);
1539                         if (tTd(11, 1))
1540                                 printf("openmailer: NULL\n");
1541                         rcode = EX_OSERR;
1542                         goto give_up;
1543                 }
1544
1545 #if XDEBUG
1546                 /* make sure we didn't get one of the standard I/O files */
1547                 if (mpvect[0] < 3 || mpvect[1] < 3)
1548                 {
1549                         syserr("%s... openmailer(%s): bogus mpvect %d %d",
1550                                 shortenstring(e->e_to, MAXSHORTSTR), m->m_name,
1551                                 mpvect[0], mpvect[1]);
1552                         printopenfds(TRUE);
1553                         if (tTd(11, 1))
1554                                 printf("openmailer: NULL\n");
1555                         rcode = EX_OSERR;
1556                         goto give_up;
1557                 }
1558
1559                 /* make sure system call isn't dead meat */
1560                 checkfdopen(mpvect[0], "mpvect[0]");
1561                 checkfdopen(mpvect[1], "mpvect[1]");
1562                 if (mpvect[0] == mpvect[1] ||
1563                     (e->e_lockfp != NULL &&
1564                      (mpvect[0] == fileno(e->e_lockfp) ||
1565                       mpvect[1] == fileno(e->e_lockfp))))
1566                 {
1567                         if (e->e_lockfp == NULL)
1568                                 syserr("%s... openmailer(%s): overlapping mpvect %d %d",
1569                                         shortenstring(e->e_to, MAXSHORTSTR),
1570                                         m->m_name, mpvect[0], mpvect[1]);
1571                         else
1572                                 syserr("%s... openmailer(%s): overlapping mpvect %d %d, lockfp = %d",
1573                                         shortenstring(e->e_to, MAXSHORTSTR),
1574                                         m->m_name, mpvect[0], mpvect[1],
1575                                         fileno(e->e_lockfp));
1576                 }
1577 #endif
1578
1579                 /* if this mailer speaks smtp, create a return pipe */
1580 #if SMTP
1581                 if (clever)
1582                 {
1583                         if (pipe(rpvect) < 0)
1584                         {
1585                                 syserr("%s... openmailer(%s): pipe (from mailer)",
1586                                         shortenstring(e->e_to, MAXSHORTSTR),
1587                                         m->m_name);
1588                                 (void) close(mpvect[0]);
1589                                 (void) close(mpvect[1]);
1590                                 if (tTd(11, 1))
1591                                         printf("openmailer: NULL\n");
1592                                 rcode = EX_OSERR;
1593                                 goto give_up;
1594                         }
1595 # if XDEBUG
1596                         checkfdopen(rpvect[0], "rpvect[0]");
1597                         checkfdopen(rpvect[1], "rpvect[1]");
1598 # endif
1599                 }
1600 #endif
1601
1602                 /*
1603                 **  Actually fork the mailer process.
1604                 **      DOFORK is clever about retrying.
1605                 **
1606                 **      Dispose of SIGCHLD signal catchers that may be laying
1607                 **      around so that endmail will get it.
1608                 */
1609
1610                 if (e->e_xfp != NULL)
1611                         (void) fflush(e->e_xfp);                /* for debugging */
1612                 (void) fflush(stdout);
1613                 (void) setsignal(SIGCHLD, SIG_DFL);
1614                 DOFORK(FORK);
1615                 /* pid is set by DOFORK */
1616                 if (pid < 0)
1617                 {
1618                         /* failure */
1619                         syserr("%s... openmailer(%s): cannot fork",
1620                                 shortenstring(e->e_to, MAXSHORTSTR), m->m_name);
1621                         (void) close(mpvect[0]);
1622                         (void) close(mpvect[1]);
1623 #if SMTP
1624                         if (clever)
1625                         {
1626                                 (void) close(rpvect[0]);
1627                                 (void) close(rpvect[1]);
1628                         }
1629 #endif
1630                         if (tTd(11, 1))
1631                                 printf("openmailer: NULL\n");
1632                         rcode = EX_OSERR;
1633                         goto give_up;
1634                 }
1635                 else if (pid == 0)
1636                 {
1637                         int i;
1638                         int saveerrno;
1639                         int new_euid = NO_UID;
1640                         int new_ruid = NO_UID;
1641                         int new_gid = NO_GID;
1642                         struct stat stb;
1643                         extern int DtableSize;
1644
1645                         if (e->e_lockfp != NULL)
1646                                 (void) close(fileno(e->e_lockfp));
1647
1648                         /* child -- set up input & exec mailer */
1649                         (void) setsignal(SIGINT, SIG_IGN);
1650                         (void) setsignal(SIGHUP, SIG_IGN);
1651                         (void) setsignal(SIGTERM, SIG_DFL);
1652
1653                         if (m != FileMailer || stat(tochain->q_user, &stb) < 0)
1654                                 stb.st_mode = 0;
1655
1656 #if HASSETUSERCONTEXT
1657                         /*
1658                         **  Set user resources.
1659                         */
1660
1661                         if (contextaddr != NULL)
1662                         {
1663                                 struct passwd *pwd;
1664
1665                                 if (contextaddr->q_ruser != NULL)
1666                                         pwd = sm_getpwnam(contextaddr->q_ruser);
1667                                 else
1668                                         pwd = sm_getpwnam(contextaddr->q_user);
1669                                 if (pwd != NULL)
1670                                         (void) setusercontext(NULL,
1671                                                 pwd, pwd->pw_uid,
1672                                                 LOGIN_SETRESOURCES|LOGIN_SETPRIORITY);
1673                         }
1674 #endif
1675
1676                         /* tweak niceness */
1677                         if (m->m_nice != 0)
1678                                 nice(m->m_nice);
1679
1680                         /* reset group id */
1681                         if (bitnset(M_SPECIFIC_UID, m->m_flags))
1682                                 new_gid = m->m_gid;
1683                         else if (bitset(S_ISGID, stb.st_mode))
1684                                 new_gid = stb.st_gid;
1685                         else if (ctladdr != NULL && ctladdr->q_gid != 0)
1686                         {
1687                                 if (!DontInitGroups)
1688                                 {
1689                                         char *u = ctladdr->q_ruser;
1690
1691                                         if (u == NULL)
1692                                                 u = ctladdr->q_user;
1693
1694                                         if (initgroups(u, ctladdr->q_gid) == -1 && suidwarn)
1695                                                 syserr("openmailer: initgroups(%s, %d) failed",
1696                                                         u, ctladdr->q_gid);
1697                                 }
1698                                 else
1699                                 {
1700                                         GIDSET_T gidset[1];
1701
1702                                         gidset[0] = ctladdr->q_gid;
1703                                         if (setgroups(1, gidset) == -1 && suidwarn)
1704                                                 syserr("openmailer: setgroups() failed");
1705                                 }
1706                                 new_gid = ctladdr->q_gid;
1707                         }
1708                         else
1709                         {
1710                                 if (!DontInitGroups)
1711                                 {
1712                                         if (initgroups(DefUser, DefGid) == -1 && suidwarn)
1713                                                 syserr("openmailer: initgroups(%s, %d) failed",
1714                                                         DefUser, DefGid);
1715                                 }
1716                                 else
1717                                 {
1718                                         GIDSET_T gidset[1];
1719
1720                                         gidset[0] = DefGid;
1721                                         if (setgroups(1, gidset) == -1 && suidwarn)
1722                                                 syserr("openmailer: setgroups() failed");
1723                                 }
1724                                 if (m->m_gid == 0)
1725                                         new_gid = DefGid;
1726                                 else
1727                                         new_gid = m->m_gid;
1728                         }
1729                         if (new_gid != NO_GID && setgid(new_gid) < 0 && suidwarn)
1730                                 syserr("openmailer: setgid(%ld) failed",
1731                                         (long) new_gid);
1732
1733                         /* reset user id */
1734                         endpwent();
1735                         if (bitnset(M_SPECIFIC_UID, m->m_flags))
1736                                 new_euid = m->m_uid;
1737                         else if (bitset(S_ISUID, stb.st_mode))
1738                                 new_ruid = stb.st_uid;
1739                         else if (ctladdr != NULL && ctladdr->q_uid != 0)
1740                                 new_ruid = ctladdr->q_uid;
1741                         else if (m->m_uid != 0)
1742                                 new_ruid = m->m_uid;
1743                         else
1744                                 new_ruid = DefUid;
1745                         if (new_euid != NO_UID)
1746                         {
1747                                 vendor_set_uid(new_euid);
1748 #if USESETEUID
1749                                 if (seteuid(new_euid) < 0 && suidwarn)
1750                                         syserr("openmailer: seteuid(%ld) failed",
1751                                                 (long) new_euid);
1752 #else
1753 # if HASSETREUID
1754                                 if (setreuid(new_ruid, new_euid) < 0 && suidwarn)
1755                                         syserr("openmailer: setreuid(%ld, %ld) failed",
1756                                                 (long) new_ruid, (long) new_euid);
1757 # else
1758                                 if (new_euid != geteuid() && setuid(new_euid) < 0 && suidwarn)
1759                                         syserr("openmailer: setuid(%ld) failed",
1760                                                 (long) new_euid);
1761 # endif
1762 #endif
1763                         }
1764                         else if (new_ruid != NO_UID)
1765                         {
1766                                 vendor_set_uid(new_ruid);
1767                                 if (setuid(new_ruid) < 0 && suidwarn)
1768                                         syserr("openmailer: setuid(%ld) failed",
1769                                                 (long) new_ruid);
1770                         }
1771
1772                         if (tTd(11, 2))
1773                                 printf("openmailer: running as r/euid=%d/%d\n",
1774                                         (int) getuid(), (int) geteuid());
1775
1776                         /* move into some "safe" directory */
1777                         if (m->m_execdir != NULL)
1778                         {
1779                                 char *q;
1780                                 char buf[MAXLINE + 1];
1781
1782                                 for (p = m->m_execdir; p != NULL; p = q)
1783                                 {
1784                                         q = strchr(p, ':');
1785                                         if (q != NULL)
1786                                                 *q = '\0';
1787                                         expand(p, buf, sizeof buf, e);
1788                                         if (q != NULL)
1789                                                 *q++ = ':';
1790                                         if (tTd(11, 20))
1791                                                 printf("openmailer: trydir %s\n",
1792                                                         buf);
1793                                         if (buf[0] != '\0' && chdir(buf) >= 0)
1794                                                 break;
1795                                 }
1796                         }
1797
1798                         /* arrange to filter std & diag output of command */
1799 #if SMTP
1800                         if (clever)
1801                         {
1802                                 (void) close(rpvect[0]);
1803                                 if (dup2(rpvect[1], STDOUT_FILENO) < 0)
1804                                 {
1805                                         syserr("%s... openmailer(%s): cannot dup pipe %d for stdout",
1806                                                 shortenstring(e->e_to, MAXSHORTSTR),
1807                                                 m->m_name, rpvect[1]);
1808                                         _exit(EX_OSERR);
1809                                 }
1810                                 (void) close(rpvect[1]);
1811                         }
1812                         else
1813                         {
1814                                 /* put mailer output in transcript */
1815                                 if (dup2(fileno(e->e_xfp), STDOUT_FILENO) < 0)
1816                                 {
1817                                         syserr("%s... openmailer(%s): cannot dup xscript %d for stdout",
1818                                                 shortenstring(e->e_to, MAXSHORTSTR),
1819                                                 m->m_name, fileno(e->e_xfp));
1820                                         _exit(EX_OSERR);
1821                                 }
1822                         }
1823 #endif
1824                         if (dup2(STDOUT_FILENO, STDERR_FILENO) < 0)
1825                         {
1826                                 syserr("%s... openmailer(%s): cannot dup stdout for stderr",
1827                                         shortenstring(e->e_to, MAXSHORTSTR),
1828                                         m->m_name);
1829                                 _exit(EX_OSERR);
1830                         }
1831
1832                         /* arrange to get standard input */
1833                         (void) close(mpvect[1]);
1834                         if (dup2(mpvect[0], STDIN_FILENO) < 0)
1835                         {
1836                                 syserr("%s... openmailer(%s): cannot dup pipe %d for stdin",
1837                                         shortenstring(e->e_to, MAXSHORTSTR),
1838                                         m->m_name, mpvect[0]);
1839                                 _exit(EX_OSERR);
1840                         }
1841                         (void) close(mpvect[0]);
1842
1843                         /* arrange for all the files to be closed */
1844                         for (i = 3; i < DtableSize; i++)
1845                         {
1846                                 register int j;
1847
1848                                 if ((j = fcntl(i, F_GETFD, 0)) != -1)
1849                                         (void) fcntl(i, F_SETFD, j | 1);
1850                         }
1851
1852                         /* run disconnected from terminal */
1853                         (void) setsid();
1854
1855                         /* try to execute the mailer */
1856                         execve(m->m_mailer, (ARGV_T) pv, (ARGV_T) UserEnviron);
1857                         saveerrno = errno;
1858                         syserr("Cannot exec %s", m->m_mailer);
1859                         if (bitnset(M_LOCALMAILER, m->m_flags) ||
1860                             transienterror(saveerrno))
1861                                 _exit(EX_OSERR);
1862                         _exit(EX_UNAVAILABLE);
1863                 }
1864
1865                 /*
1866                 **  Set up return value.
1867                 */
1868
1869                 if (mci == NULL)
1870                 {
1871                         mci = (MCI *) xalloc(sizeof *mci);
1872                         bzero((char *) mci, sizeof *mci);
1873                 }
1874                 mci->mci_mailer = m;
1875                 if (clever)
1876                 {
1877                         mci->mci_state = MCIS_OPENING;
1878                         mci_cache(mci);
1879                 }
1880                 else
1881                 {
1882                         mci->mci_state = MCIS_OPEN;
1883                 }
1884                 mci->mci_pid = pid;
1885                 (void) close(mpvect[0]);
1886                 mci->mci_out = fdopen(mpvect[1], "w");
1887                 if (mci->mci_out == NULL)
1888                 {
1889                         syserr("deliver: cannot create mailer output channel, fd=%d",
1890                                 mpvect[1]);
1891                         (void) close(mpvect[1]);
1892 #if SMTP
1893                         if (clever)
1894                         {
1895                                 (void) close(rpvect[0]);
1896                                 (void) close(rpvect[1]);
1897                         }
1898 #endif
1899                         rcode = EX_OSERR;
1900                         goto give_up;
1901                 }
1902 #if SMTP
1903                 if (clever)
1904                 {
1905                         (void) close(rpvect[1]);
1906                         mci->mci_in = fdopen(rpvect[0], "r");
1907                         if (mci->mci_in == NULL)
1908                         {
1909                                 syserr("deliver: cannot create mailer input channel, fd=%d",
1910                                         mpvect[1]);
1911                                 (void) close(rpvect[0]);
1912                                 fclose(mci->mci_out);
1913                                 mci->mci_out = NULL;
1914                                 rcode = EX_OSERR;
1915                                 goto give_up;
1916                         }
1917                 }
1918                 else
1919 #endif
1920                 {
1921                         mci->mci_flags |= MCIF_TEMP;
1922                         mci->mci_in = NULL;
1923                 }
1924         }
1925
1926         /*
1927         **  If we are in SMTP opening state, send initial protocol.
1928         */
1929
1930         if (bitnset(M_7BITS, m->m_flags) &&
1931             (!clever || mci->mci_state == MCIS_OPENING))
1932                 mci->mci_flags |= MCIF_7BIT;
1933 #if SMTP
1934         if (clever && mci->mci_state != MCIS_CLOSED)
1935         {
1936                 extern void smtpinit __P((MAILER *, MCI *, ENVELOPE *));
1937
1938                 smtpinit(m, mci, e);
1939         }
1940 #endif
1941
1942 do_transfer:
1943         /* clear out per-message flags from connection structure */
1944         mci->mci_flags &= ~(MCIF_CVT7TO8|MCIF_CVT8TO7);
1945
1946         if (bitset(EF_HAS8BIT, e->e_flags) &&
1947             !bitset(EF_DONT_MIME, e->e_flags) &&
1948             bitnset(M_7BITS, m->m_flags))
1949                 mci->mci_flags |= MCIF_CVT8TO7;
1950
1951 #if MIME7TO8
1952         if (bitnset(M_MAKE8BIT, m->m_flags) &&
1953             !bitset(MCIF_7BIT, mci->mci_flags) &&
1954             (p = hvalue("Content-Transfer-Encoding", e->e_header)) != NULL &&
1955              (strcasecmp(p, "quoted-printable") == 0 ||
1956               strcasecmp(p, "base64") == 0) &&
1957             (p = hvalue("Content-Type", e->e_header)) != NULL)
1958         {
1959                 /* may want to convert 7 -> 8 */
1960                 /* XXX should really parse it here -- and use a class XXX */
1961                 if (strncasecmp(p, "text/plain", 10) == 0 &&
1962                     (p[10] == '\0' || p[10] == ' ' || p[10] == ';'))
1963                         mci->mci_flags |= MCIF_CVT7TO8;
1964         }
1965 #endif
1966
1967         if (tTd(11, 1))
1968         {
1969                 printf("openmailer: ");
1970                 mci_dump(mci, FALSE);
1971         }
1972
1973         if (mci->mci_state != MCIS_OPEN)
1974         {
1975                 /* couldn't open the mailer */
1976                 rcode = mci->mci_exitstat;
1977                 errno = mci->mci_errno;
1978 #if NAMED_BIND
1979                 h_errno = mci->mci_herrno;
1980 #endif
1981                 if (rcode == EX_OK)
1982                 {
1983                         /* shouldn't happen */
1984                         syserr("554 deliver: mci=%lx rcode=%d errno=%d state=%d sig=%s",
1985                                 (long) mci, rcode, errno, mci->mci_state,
1986                                 firstsig);
1987                         mci_dump_all(TRUE);
1988                         rcode = EX_SOFTWARE;
1989                 }
1990 #if DAEMON
1991                 else if (curhost != NULL && *curhost != '\0')
1992                 {
1993                         /* try next MX site */
1994                         goto tryhost;
1995                 }
1996 #endif
1997         }
1998         else if (!clever)
1999         {
2000                 /*
2001                 **  Format and send message.
2002                 */
2003
2004                 mci->mci_contentlen = 0;
2005                 putfromline(mci, e);
2006                 (*e->e_puthdr)(mci, e->e_header, e, M87F_OUTER);
2007                 (*e->e_putbody)(mci, e, NULL);
2008
2009                 /* get the exit status */
2010                 rcode = endmailer(mci, e, pv);
2011         }
2012         else
2013 #if SMTP
2014         {
2015                 extern int smtpmailfrom __P((MAILER *, MCI *, ENVELOPE *));
2016                 extern int smtprcpt __P((ADDRESS *, MAILER *, MCI *, ENVELOPE *));
2017                 extern int smtpdata __P((MAILER *, MCI *, ENVELOPE *));
2018
2019                 /*
2020                 **  Send the MAIL FROM: protocol
2021                 */
2022
2023                 rcode = smtpmailfrom(m, mci, e);
2024                 if (rcode == EX_OK)
2025                 {
2026                         register char *t = tobuf;
2027                         register int i;
2028
2029                         /* send the recipient list */
2030                         tobuf[0] = '\0';
2031                         for (to = tochain; to != NULL; to = to->q_tchain)
2032                         {
2033                                 e->e_to = to->q_paddr;
2034                                 if (strlen(to->q_paddr) + (t - tobuf) + 2 > sizeof tobuf)
2035                                 {
2036                                         /* not enough room */
2037                                         continue;
2038                                 }
2039                                 else if ((i = smtprcpt(to, m, mci, e)) != EX_OK)
2040                                 {
2041                                         markfailure(e, to, mci, i);
2042                                         giveresponse(i, m, mci, ctladdr, xstart, e);
2043                                 }
2044                                 else
2045                                 {
2046                                         *t++ = ',';
2047                                         for (p = to->q_paddr; *p; *t++ = *p++)
2048                                                 continue;
2049                                         *t = '\0';
2050                                 }
2051                         }
2052
2053                         /* now send the data */
2054                         if (tobuf[0] == '\0')
2055                         {
2056                                 rcode = EX_OK;
2057                                 e->e_to = NULL;
2058                                 if (bitset(MCIF_CACHED, mci->mci_flags))
2059                                         smtprset(m, mci, e);
2060                         }
2061                         else
2062                         {
2063                                 e->e_to = tobuf + 1;
2064                                 rcode = smtpdata(m, mci, e);
2065                         }
2066                 }
2067 # if DAEMON
2068                 if (rcode == EX_TEMPFAIL && curhost != NULL && *curhost != '\0')
2069                 {
2070                         /* try next MX site */
2071                         goto tryhost;
2072                 }
2073 # endif
2074         }
2075 #else /* not SMTP */
2076         {
2077                 syserr("554 deliver: need SMTP compiled to use clever mailer");
2078                 rcode = EX_CONFIG;
2079                 goto give_up;
2080         }
2081 #endif /* SMTP */
2082 #if NAMED_BIND
2083         if (ConfigLevel < 2)
2084                 _res.options |= RES_DEFNAMES | RES_DNSRCH;      /* XXX */
2085 #endif
2086
2087         if (tTd(62, 1))
2088                 checkfds("after delivery");
2089
2090         /*
2091         **  Do final status disposal.
2092         **      We check for something in tobuf for the SMTP case.
2093         **      If we got a temporary failure, arrange to queue the
2094         **              addressees.
2095         */
2096
2097   give_up:
2098 #if SMTP
2099         if (bitnset(M_LMTP, m->m_flags))
2100         {
2101                 lmtp_rcode = rcode;
2102                 tobuf[0] = '\0';
2103                 anyok = FALSE;
2104         }
2105         else
2106 #endif
2107                 anyok = rcode == EX_OK;
2108
2109         for (to = tochain; to != NULL; to = to->q_tchain)
2110         {
2111                 /* see if address already marked */
2112                 if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
2113                         continue;
2114
2115 #if SMTP
2116                 /* if running LMTP, get the status for each address */
2117                 if (bitnset(M_LMTP, m->m_flags))
2118                 {
2119                         extern int smtpgetstat __P((MAILER *, MCI *, ENVELOPE *));
2120
2121                         if (lmtp_rcode == EX_OK)
2122                                 rcode = smtpgetstat(m, mci, e);
2123                         if (rcode == EX_OK)
2124                         {
2125                                 if (strlen(to->q_paddr) + strlen(tobuf) + 2 > sizeof tobuf)
2126                                 {
2127                                         syserr("LMTP tobuf overflow");
2128                                 }
2129                                 else
2130                                 {
2131                                         strcat(tobuf, ",");
2132                                         strcat(tobuf, to->q_paddr);
2133                                 }
2134                                 anyok = TRUE;
2135                         }
2136                         else
2137                         {
2138                                 e->e_to = to->q_paddr;
2139                                 markfailure(e, to, mci, rcode);
2140                                 giveresponse(rcode, m, mci, ctladdr, xstart, e);
2141                                 e->e_to = tobuf + 1;
2142                                 continue;
2143                         }
2144                 }
2145                 else
2146 #endif
2147                 {
2148                         /* mark bad addresses */
2149                         if (rcode != EX_OK)
2150                         {
2151                                 if (goodmxfound && rcode == EX_NOHOST)
2152                                         rcode = EX_TEMPFAIL;
2153                                 markfailure(e, to, mci, rcode);
2154                                 continue;
2155                         }
2156                 }
2157
2158                 /* successful delivery */
2159                 to->q_flags |= QSENT;
2160                 to->q_statdate = curtime();
2161                 e->e_nsent++;
2162                 if (bitnset(M_LOCALMAILER, m->m_flags) &&
2163                     bitset(QPINGONSUCCESS, to->q_flags))
2164                 {
2165                         to->q_flags |= QDELIVERED;
2166                         to->q_status = "2.1.5";
2167                         fprintf(e->e_xfp, "%s... Successfully delivered\n",
2168                                 to->q_paddr);
2169                 }
2170                 else if (bitset(QPINGONSUCCESS, to->q_flags) &&
2171                          bitset(QPRIMARY, to->q_flags) &&
2172                          !bitset(MCIF_DSN, mci->mci_flags))
2173                 {
2174                         to->q_flags |= QRELAYED;
2175                         fprintf(e->e_xfp, "%s... relayed; expect no further notifications\n",
2176                                 to->q_paddr);
2177                 }
2178         }
2179
2180 #if SMTP
2181         if (bitnset(M_LMTP, m->m_flags))
2182         {
2183                 /*
2184                 **  Global information applies to the last recipient only;
2185                 **  clear it out to avoid bogus errors.
2186                 */
2187
2188                 rcode = EX_OK;
2189                 e->e_statmsg = NULL;
2190
2191                 /* reset the mci state for the next transaction */
2192                 if (mci != NULL && mci->mci_state == MCIS_ACTIVE)
2193                         mci->mci_state = MCIS_OPEN;
2194         }
2195 #endif
2196
2197         if (tobuf[0] != '\0')
2198                 giveresponse(rcode, m, mci, ctladdr, xstart, e);
2199         if (anyok)
2200                 markstats(e, tochain, FALSE);
2201         mci_store_persistent(mci);
2202
2203 #if SMTP
2204         /* now close the connection */
2205         if (clever && mci != NULL && mci->mci_state != MCIS_CLOSED &&
2206             !bitset(MCIF_CACHED, mci->mci_flags))
2207                 smtpquit(m, mci, e);
2208 #endif
2209
2210         /*
2211         **  Restore state and return.
2212         */
2213
2214 #if XDEBUG
2215         {
2216                 char wbuf[MAXLINE];
2217
2218                 /* make absolutely certain 0, 1, and 2 are in use */
2219                 snprintf(wbuf, sizeof wbuf, "%s... end of deliver(%s)",
2220                         e->e_to == NULL ? "NO-TO-LIST"
2221                                         : shortenstring(e->e_to, MAXSHORTSTR),
2222                         m->m_name);
2223                 checkfd012(wbuf);
2224         }
2225 #endif
2226
2227         errno = 0;
2228         define('g', (char *) NULL, e);
2229         return (rcode);
2230 }
2231 \f/*
2232 **  MARKFAILURE -- mark a failure on a specific address.
2233 **
2234 **      Parameters:
2235 **              e -- the envelope we are sending.
2236 **              q -- the address to mark.
2237 **              mci -- mailer connection information.
2238 **              rcode -- the code signifying the particular failure.
2239 **
2240 **      Returns:
2241 **              none.
2242 **
2243 **      Side Effects:
2244 **              marks the address (and possibly the envelope) with the
2245 **                      failure so that an error will be returned or
2246 **                      the message will be queued, as appropriate.
2247 */
2248
2249 void
2250 markfailure(e, q, mci, rcode)
2251         register ENVELOPE *e;
2252         register ADDRESS *q;
2253         register MCI *mci;
2254         int rcode;
2255 {
2256         char *stat = NULL;
2257
2258         switch (rcode)
2259         {
2260           case EX_OK:
2261                 break;
2262
2263           case EX_TEMPFAIL:
2264           case EX_IOERR:
2265           case EX_OSERR:
2266                 q->q_flags |= QQUEUEUP;
2267                 q->q_flags &= ~QDONTSEND;
2268                 break;
2269
2270           default:
2271                 q->q_flags |= QBADADDR;
2272                 break;
2273         }
2274
2275         /* find most specific error code possible */
2276         if (mci != NULL && mci->mci_status != NULL)
2277         {
2278                 q->q_status = mci->mci_status;
2279                 if (mci->mci_rstatus != NULL)
2280                         q->q_rstatus = newstr(mci->mci_rstatus);
2281                 else
2282                         q->q_rstatus = NULL;
2283         }
2284         else if (e->e_status != NULL)
2285         {
2286                 q->q_status = e->e_status;
2287                 q->q_rstatus = NULL;
2288         }
2289         else
2290         {
2291                 switch (rcode)
2292                 {
2293                   case EX_USAGE:
2294                         stat = "5.5.4";
2295                         break;
2296
2297                   case EX_DATAERR:
2298                         stat = "5.5.2";
2299                         break;
2300
2301                   case EX_NOUSER:
2302                         stat = "5.1.1";
2303                         break;
2304
2305                   case EX_NOHOST:
2306                         stat = "5.1.2";
2307                         break;
2308
2309                   case EX_NOINPUT:
2310                   case EX_CANTCREAT:
2311                   case EX_NOPERM:
2312                         stat = "5.3.0";
2313                         break;
2314
2315                   case EX_UNAVAILABLE:
2316                   case EX_SOFTWARE:
2317                   case EX_OSFILE:
2318                   case EX_PROTOCOL:
2319                   case EX_CONFIG:
2320                         stat = "5.5.0";
2321                         break;
2322
2323                   case EX_OSERR:
2324                   case EX_IOERR:
2325                         stat = "4.5.0";
2326                         break;
2327
2328                   case EX_TEMPFAIL:
2329                         stat = "4.2.0";
2330                         break;
2331                 }
2332                 if (stat != NULL)
2333                         q->q_status = stat;
2334         }
2335
2336         q->q_statdate = curtime();
2337         if (CurHostName != NULL && CurHostName[0] != '\0')
2338                 q->q_statmta = newstr(CurHostName);
2339         if (rcode != EX_OK && q->q_rstatus == NULL &&
2340             q->q_mailer != NULL && q->q_mailer->m_diagtype != NULL &&
2341             strcasecmp(q->q_mailer->m_diagtype, "UNIX") == 0)
2342         {
2343                 char buf[30];
2344
2345                 (void) snprintf(buf, sizeof buf, "%d", rcode);
2346                 q->q_rstatus = newstr(buf);
2347         }
2348 }
2349 \f/*
2350 **  ENDMAILER -- Wait for mailer to terminate.
2351 **
2352 **      We should never get fatal errors (e.g., segmentation
2353 **      violation), so we report those specially.  For other
2354 **      errors, we choose a status message (into statmsg),
2355 **      and if it represents an error, we print it.
2356 **
2357 **      Parameters:
2358 **              pid -- pid of mailer.
2359 **              e -- the current envelope.
2360 **              pv -- the parameter vector that invoked the mailer
2361 **                      (for error messages).
2362 **
2363 **      Returns:
2364 **              exit code of mailer.
2365 **
2366 **      Side Effects:
2367 **              none.
2368 */
2369
2370 int
2371 endmailer(mci, e, pv)
2372         register MCI *mci;
2373         register ENVELOPE *e;
2374         char **pv;
2375 {
2376         int st;
2377
2378         mci_unlock_host(mci);
2379
2380         /* close any connections */
2381         if (mci->mci_in != NULL)
2382                 (void) xfclose(mci->mci_in, mci->mci_mailer->m_name, "mci_in");
2383         if (mci->mci_out != NULL)
2384                 (void) xfclose(mci->mci_out, mci->mci_mailer->m_name, "mci_out");
2385         mci->mci_in = mci->mci_out = NULL;
2386         mci->mci_state = MCIS_CLOSED;
2387
2388         /* in the IPC case there is nothing to wait for */
2389         if (mci->mci_pid == 0)
2390                 return (EX_OK);
2391
2392 #if _FFR_TIMEOUT_WAIT
2393         put a timeout around the wait
2394 #endif
2395
2396         /* wait for the mailer process to die and collect status */
2397         st = waitfor(mci->mci_pid);
2398         if (st == -1)
2399         {
2400                 syserr("endmailer %s: wait", mci->mci_mailer->m_name);
2401                 return (EX_SOFTWARE);
2402         }
2403
2404         if (WIFEXITED(st))
2405         {
2406                 /* normal death -- return status */
2407                 return (WEXITSTATUS(st));
2408         }
2409
2410         /* it died a horrid death */
2411         syserr("451 mailer %s died with signal %o",
2412                 mci->mci_mailer->m_name, st);
2413
2414         /* log the arguments */
2415         if (pv != NULL && e->e_xfp != NULL)
2416         {
2417                 register char **av;
2418
2419                 fprintf(e->e_xfp, "Arguments:");
2420                 for (av = pv; *av != NULL; av++)
2421                         fprintf(e->e_xfp, " %s", *av);
2422                 fprintf(e->e_xfp, "\n");
2423         }
2424
2425         ExitStat = EX_TEMPFAIL;
2426         return (EX_TEMPFAIL);
2427 }
2428 \f/*
2429 **  GIVERESPONSE -- Interpret an error response from a mailer
2430 **
2431 **      Parameters:
2432 **              stat -- the status code from the mailer (high byte
2433 **                      only; core dumps must have been taken care of
2434 **                      already).
2435 **              m -- the mailer info for this mailer.
2436 **              mci -- the mailer connection info -- can be NULL if the
2437 **                      response is given before the connection is made.
2438 **              ctladdr -- the controlling address for the recipient
2439 **                      address(es).
2440 **              xstart -- the transaction start time, for computing
2441 **                      transaction delays.
2442 **              e -- the current envelope.
2443 **
2444 **      Returns:
2445 **              none.
2446 **
2447 **      Side Effects:
2448 **              Errors may be incremented.
2449 **              ExitStat may be set.
2450 */
2451
2452 void
2453 giveresponse(stat, m, mci, ctladdr, xstart, e)
2454         int stat;
2455         register MAILER *m;
2456         register MCI *mci;
2457         ADDRESS *ctladdr;
2458         time_t xstart;
2459         ENVELOPE *e;
2460 {
2461         register const char *statmsg;
2462         extern char *SysExMsg[];
2463         register int i;
2464         extern int N_SysEx;
2465         char buf[MAXLINE];
2466
2467         if (e == NULL)
2468                 syserr("giveresponse: null envelope");
2469
2470         /*
2471         **  Compute status message from code.
2472         */
2473
2474         i = stat - EX__BASE;
2475         if (stat == 0)
2476         {
2477                 statmsg = "250 Sent";
2478                 if (e->e_statmsg != NULL)
2479                 {
2480                         (void) snprintf(buf, sizeof buf, "%s (%s)",
2481                                 statmsg, shortenstring(e->e_statmsg, 403));
2482                         statmsg = buf;
2483                 }
2484         }
2485         else if (i < 0 || i >= N_SysEx)
2486         {
2487                 (void) snprintf(buf, sizeof buf, "554 unknown mailer error %d",
2488                         stat);
2489                 stat = EX_UNAVAILABLE;
2490                 statmsg = buf;
2491         }
2492         else if (stat == EX_TEMPFAIL)
2493         {
2494                 char *bp = buf;
2495
2496                 snprintf(bp, SPACELEFT(buf, bp), "%s", SysExMsg[i] + 1);
2497                 bp += strlen(bp);
2498 #if NAMED_BIND
2499                 if (h_errno == TRY_AGAIN)
2500                         statmsg = errstring(h_errno+E_DNSBASE);
2501                 else
2502 #endif
2503                 {
2504                         if (errno != 0)
2505                                 statmsg = errstring(errno);
2506                         else
2507                         {
2508 #if SMTP
2509                                 statmsg = SmtpError;
2510 #else /* SMTP */
2511                                 statmsg = NULL;
2512 #endif /* SMTP */
2513                         }
2514                 }
2515                 if (statmsg != NULL && statmsg[0] != '\0')
2516                         snprintf(bp, SPACELEFT(buf, bp), ": %s", statmsg);
2517                 statmsg = buf;
2518         }
2519 #if NAMED_BIND
2520         else if (stat == EX_NOHOST && h_errno != 0)
2521         {
2522                 statmsg = errstring(h_errno + E_DNSBASE);
2523                 (void) snprintf(buf, sizeof buf, "%s (%s)",
2524                         SysExMsg[i] + 1, statmsg);
2525                 statmsg = buf;
2526         }
2527 #endif
2528         else
2529         {
2530                 statmsg = SysExMsg[i];
2531                 if (*statmsg++ == ':' && errno != 0)
2532                 {
2533                         (void) snprintf(buf, sizeof buf, "%s: %s",
2534                                 statmsg, errstring(errno));
2535                         statmsg = buf;
2536                 }
2537         }
2538
2539         /*
2540         **  Print the message as appropriate
2541         */
2542
2543         if (stat == EX_OK || stat == EX_TEMPFAIL)
2544         {
2545                 extern char MsgBuf[];
2546
2547                 message("%s", &statmsg[4]);
2548                 if (stat == EX_TEMPFAIL && e->e_xfp != NULL)
2549                         fprintf(e->e_xfp, "%s\n", &MsgBuf[4]);
2550         }
2551         else
2552         {
2553                 char mbuf[8];
2554
2555                 Errors++;
2556                 snprintf(mbuf, sizeof mbuf, "%.3s %%s", statmsg);
2557                 usrerr(mbuf, &statmsg[4]);
2558         }
2559
2560         /*
2561         **  Final cleanup.
2562         **      Log a record of the transaction.  Compute the new
2563         **      ExitStat -- if we already had an error, stick with
2564         **      that.
2565         */
2566
2567         if (OpMode != MD_VERIFY && !bitset(EF_VRFYONLY, e->e_flags) &&
2568             LogLevel > ((stat == EX_TEMPFAIL) ? 8 : (stat == EX_OK) ? 7 : 6))
2569                 logdelivery(m, mci, &statmsg[4], ctladdr, xstart, e);
2570
2571         if (tTd(11, 2))
2572                 printf("giveresponse: stat=%d, e->e_message=%s\n",
2573                         stat, e->e_message == NULL ? "<NULL>" : e->e_message);
2574
2575         if (stat != EX_TEMPFAIL)
2576                 setstat(stat);
2577         if (stat != EX_OK && (stat != EX_TEMPFAIL || e->e_message == NULL))
2578         {
2579                 if (e->e_message != NULL)
2580                         free(e->e_message);
2581                 e->e_message = newstr(&statmsg[4]);
2582         }
2583         errno = 0;
2584 #if NAMED_BIND
2585         h_errno = 0;
2586 #endif
2587 }
2588 \f/*
2589 **  LOGDELIVERY -- log the delivery in the system log
2590 **
2591 **      Care is taken to avoid logging lines that are too long, because
2592 **      some versions of syslog have an unfortunate proclivity for core
2593 **      dumping.  This is a hack, to be sure, that is at best empirical.
2594 **
2595 **      Parameters:
2596 **              m -- the mailer info.  Can be NULL for initial queue.
2597 **              mci -- the mailer connection info -- can be NULL if the
2598 **                      log is occuring when no connection is active.
2599 **              stat -- the message to print for the status.
2600 **              ctladdr -- the controlling address for the to list.
2601 **              xstart -- the transaction start time, used for
2602 **                      computing transaction delay.
2603 **              e -- the current envelope.
2604 **
2605 **      Returns:
2606 **              none
2607 **
2608 **      Side Effects:
2609 **              none
2610 */
2611
2612 void
2613 logdelivery(m, mci, stat, ctladdr, xstart, e)
2614         MAILER *m;
2615         register MCI *mci;
2616         const char *stat;
2617         ADDRESS *ctladdr;
2618         time_t xstart;
2619         register ENVELOPE *e;
2620 {
2621         register char *bp;
2622         register char *p;
2623         int l;
2624         char buf[1024];
2625
2626 #  if (SYSLOG_BUFSIZE) >= 256
2627         /* ctladdr: max 106 bytes */
2628         bp = buf;
2629         if (ctladdr != NULL)
2630         {
2631                 snprintf(bp, SPACELEFT(buf, bp), ", ctladdr=%s",
2632                         shortenstring(ctladdr->q_paddr, 83));
2633                 bp += strlen(bp);
2634                 if (bitset(QGOODUID, ctladdr->q_flags))
2635                 {
2636                         (void) snprintf(bp, SPACELEFT(buf, bp), " (%d/%d)",
2637                                         ctladdr->q_uid, ctladdr->q_gid);
2638                         bp += strlen(bp);
2639                 }
2640         }
2641
2642         /* delay & xdelay: max 41 bytes */
2643         snprintf(bp, SPACELEFT(buf, bp), ", delay=%s",
2644                 pintvl(curtime() - e->e_ctime, TRUE));
2645         bp += strlen(bp);
2646
2647         if (xstart != (time_t) 0)
2648         {
2649                 snprintf(bp, SPACELEFT(buf, bp), ", xdelay=%s",
2650                         pintvl(curtime() - xstart, TRUE));
2651                 bp += strlen(bp);
2652         }
2653
2654         /* mailer: assume about 19 bytes (max 10 byte mailer name) */
2655         if (m != NULL)
2656         {
2657                 snprintf(bp, SPACELEFT(buf, bp), ", mailer=%s", m->m_name);
2658                 bp += strlen(bp);
2659         }
2660
2661         /* relay: max 66 bytes for IPv4 addresses */
2662         if (mci != NULL && mci->mci_host != NULL)
2663         {
2664 # if DAEMON
2665                 extern SOCKADDR CurHostAddr;
2666 # endif
2667
2668                 snprintf(bp, SPACELEFT(buf, bp), ", relay=%s",
2669                         shortenstring(mci->mci_host, 40));
2670                 bp += strlen(bp);
2671
2672 # if DAEMON
2673                 if (CurHostAddr.sa.sa_family != 0)
2674                 {
2675                         snprintf(bp, SPACELEFT(buf, bp), " [%s]",
2676                                 anynet_ntoa(&CurHostAddr));
2677                 }
2678 # endif
2679         }
2680         else if (strcmp(stat, "queued") != 0)
2681         {
2682                 p = macvalue('h', e);
2683                 if (p != NULL && p[0] != '\0')
2684                 {
2685                         snprintf(bp, SPACELEFT(buf, bp), ", relay=%s",
2686                                 shortenstring(p, 40));
2687                 }
2688         }
2689         bp += strlen(bp);
2690
2691 #define STATLEN         (((SYSLOG_BUFSIZE) - 100) / 4)
2692 #if (STATLEN) < 63
2693 # undef STATLEN
2694 # define STATLEN        63
2695 #endif
2696 #if (STATLEN) > 203
2697 # undef STATLEN
2698 # define STATLEN        203
2699 #endif
2700
2701         /* stat: max 210 bytes */
2702         if ((bp - buf) > (sizeof buf - ((STATLEN) + 20)))
2703         {
2704                 /* desperation move -- truncate data */
2705                 bp = buf + sizeof buf - ((STATLEN) + 17);
2706                 strcpy(bp, "...");
2707                 bp += 3;
2708         }
2709
2710         (void) strcpy(bp, ", stat=");
2711         bp += strlen(bp);
2712
2713         (void) strcpy(bp, shortenstring(stat, (STATLEN)));
2714
2715         /* id, to: max 13 + TOBUFSIZE bytes */
2716         l = SYSLOG_BUFSIZE - 100 - strlen(buf);
2717         p = e->e_to;
2718         while (strlen(p) >= (SIZE_T) l)
2719         {
2720                 register char *q = strchr(p + l, ',');
2721
2722                 if (q == NULL)
2723                         break;
2724                 sm_syslog(LOG_INFO, e->e_id,
2725                         "to=%.*s [more]%s",
2726                         ++q - p, p, buf);
2727                 p = q;
2728         }
2729         sm_syslog(LOG_INFO, e->e_id, "to=%s%s", p, buf);
2730
2731 #  else         /* we have a very short log buffer size */
2732
2733         l = SYSLOG_BUFSIZE - 85;
2734         p = e->e_to;
2735         while (strlen(p) >= (SIZE_T) l)
2736         {
2737                 register char *q = strchr(p + l, ',');
2738
2739                 if (q == NULL)
2740                         break;
2741                 sm_syslog(LOG_INFO, e->e_id,
2742                         "to=%.*s [more]",
2743                         ++q - p, p);
2744                 p = q;
2745         }
2746         sm_syslog(LOG_INFO, e->e_id, "to=%s", p);
2747
2748         if (ctladdr != NULL)
2749         {
2750                 bp = buf;
2751                 snprintf(bp, SPACELEFT(buf, bp), "ctladdr=%s",
2752                         shortenstring(ctladdr->q_paddr, 83));
2753                 bp += strlen(bp);
2754                 if (bitset(QGOODUID, ctladdr->q_flags))
2755                 {
2756                         (void) snprintf(bp, SPACELEFT(buf, bp), " (%d/%d)",
2757                                         ctladdr->q_uid, ctladdr->q_gid);
2758                         bp += strlen(bp);
2759                 }
2760                 sm_syslog(LOG_INFO, e->e_id, "%s", buf);
2761         }
2762         bp = buf;
2763         snprintf(bp, SPACELEFT(buf, bp), "delay=%s",
2764                 pintvl(curtime() - e->e_ctime, TRUE));
2765         bp += strlen(bp);
2766         if (xstart != (time_t) 0)
2767         {
2768                 snprintf(bp, SPACELEFT(buf, bp), ", xdelay=%s",
2769                         pintvl(curtime() - xstart, TRUE));
2770                 bp += strlen(bp);
2771         }
2772
2773         if (m != NULL)
2774         {
2775                 snprintf(bp, SPACELEFT(buf, bp), ", mailer=%s", m->m_name);
2776                 bp += strlen(bp);
2777         }
2778         sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
2779
2780         buf[0] = '\0';
2781         bp = buf;
2782         if (mci != NULL && mci->mci_host != NULL)
2783         {
2784 # if DAEMON
2785                 extern SOCKADDR CurHostAddr;
2786 # endif
2787
2788                 snprintf(bp, SPACELEFT(buf, bp), "relay=%.100s", mci->mci_host);
2789                 bp += strlen(bp);
2790
2791 # if DAEMON
2792                 if (CurHostAddr.sa.sa_family != 0)
2793                         snprintf(bp, SPACELEFT(buf, bp), " [%.100s]",
2794                                 anynet_ntoa(&CurHostAddr));
2795 # endif
2796         }
2797         else if (strcmp(stat, "queued") != 0)
2798         {
2799                 p = macvalue('h', e);
2800                 if (p != NULL && p[0] != '\0')
2801                         snprintf(buf, sizeof buf, "relay=%.100s", p);
2802         }
2803         if (buf[0] != '\0')
2804                 sm_syslog(LOG_INFO, e->e_id, "%.1000s", buf);
2805
2806         sm_syslog(LOG_INFO, e->e_id, "stat=%s", shortenstring(stat, 63));
2807 #  endif /* short log buffer */
2808 }
2809 \f/*
2810 **  PUTFROMLINE -- output a UNIX-style from line (or whatever)
2811 **
2812 **      This can be made an arbitrary message separator by changing $l
2813 **
2814 **      One of the ugliest hacks seen by human eyes is contained herein:
2815 **      UUCP wants those stupid "remote from <host>" lines.  Why oh why
2816 **      does a well-meaning programmer such as myself have to deal with
2817 **      this kind of antique garbage????
2818 **
2819 **      Parameters:
2820 **              mci -- the connection information.
2821 **              e -- the envelope.
2822 **
2823 **      Returns:
2824 **              none
2825 **
2826 **      Side Effects:
2827 **              outputs some text to fp.
2828 */
2829
2830 void
2831 putfromline(mci, e)
2832         register MCI *mci;
2833         ENVELOPE *e;
2834 {
2835         char *template = UnixFromLine;
2836         char buf[MAXLINE];
2837         char xbuf[MAXLINE];
2838
2839         if (bitnset(M_NHDR, mci->mci_mailer->m_flags))
2840                 return;
2841
2842         mci->mci_flags |= MCIF_INHEADER;
2843
2844         if (bitnset(M_UGLYUUCP, mci->mci_mailer->m_flags))
2845         {
2846                 char *bang;
2847
2848                 expand("\201g", buf, sizeof buf, e);
2849                 bang = strchr(buf, '!');
2850                 if (bang == NULL)
2851                 {
2852                         char *at;
2853                         char hname[MAXNAME];
2854
2855                         /*
2856                         **  If we can construct a UUCP path, do so
2857                         */
2858
2859                         at = strrchr(buf, '@');
2860                         if (at == NULL)
2861                         {
2862                                 expand( "\201k", hname, sizeof hname, e);
2863                                 at = hname;
2864                         }
2865                         else
2866                                 *at++ = '\0';
2867                         (void) snprintf(xbuf, sizeof xbuf,
2868                                 "From %.800s  \201d remote from %.100s\n",
2869                                 buf, at);
2870                 }
2871                 else
2872                 {
2873                         *bang++ = '\0';
2874                         (void) snprintf(xbuf, sizeof xbuf,
2875                                 "From %.800s  \201d remote from %.100s\n",
2876                                 bang, buf);
2877                         template = xbuf;
2878                 }
2879         }
2880         expand(template, buf, sizeof buf, e);
2881         putxline(buf, strlen(buf), mci, PXLF_HEADER);
2882 }
2883 \f/*
2884 **  PUTBODY -- put the body of a message.
2885 **
2886 **      Parameters:
2887 **              mci -- the connection information.
2888 **              e -- the envelope to put out.
2889 **              separator -- if non-NULL, a message separator that must
2890 **                      not be permitted in the resulting message.
2891 **
2892 **      Returns:
2893 **              none.
2894 **
2895 **      Side Effects:
2896 **              The message is written onto fp.
2897 */
2898
2899 /* values for output state variable */
2900 #define OS_HEAD         0       /* at beginning of line */
2901 #define OS_CR           1       /* read a carriage return */
2902 #define OS_INLINE       2       /* putting rest of line */
2903
2904 void
2905 putbody(mci, e, separator)
2906         register MCI *mci;
2907         register ENVELOPE *e;
2908         char *separator;
2909 {
2910         char buf[MAXLINE];
2911         char *boundaries[MAXMIMENESTING + 1];
2912
2913         /*
2914         **  Output the body of the message
2915         */
2916
2917         if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
2918         {
2919                 char *df = queuename(e, 'd');
2920
2921                 e->e_dfp = fopen(df, "r");
2922                 if (e->e_dfp == NULL)
2923                         syserr("putbody: Cannot open %s for %s from %s",
2924                                 df, e->e_to, e->e_from.q_paddr);
2925         }
2926         if (e->e_dfp == NULL)
2927         {
2928                 if (bitset(MCIF_INHEADER, mci->mci_flags))
2929                 {
2930                         putline("", mci);
2931                         mci->mci_flags &= ~MCIF_INHEADER;
2932                 }
2933                 putline("<<< No Message Collected >>>", mci);
2934                 goto endofmessage;
2935         }
2936         if (e->e_dfino == (ino_t) 0)
2937         {
2938                 struct stat stbuf;
2939
2940                 if (fstat(fileno(e->e_dfp), &stbuf) < 0)
2941                         e->e_dfino = -1;
2942                 else
2943                 {
2944                         e->e_dfdev = stbuf.st_dev;
2945                         e->e_dfino = stbuf.st_ino;
2946                 }
2947         }
2948         rewind(e->e_dfp);
2949
2950 #if MIME8TO7
2951         if (bitset(MCIF_CVT8TO7, mci->mci_flags))
2952         {
2953                 /*
2954                 **  Do 8 to 7 bit MIME conversion.
2955                 */
2956
2957                 /* make sure it looks like a MIME message */
2958                 if (hvalue("MIME-Version", e->e_header) == NULL)
2959                         putline("MIME-Version: 1.0", mci);
2960
2961                 if (hvalue("Content-Type", e->e_header) == NULL)
2962                 {
2963                         snprintf(buf, sizeof buf,
2964                                 "Content-Type: text/plain; charset=%s",
2965                                 defcharset(e));
2966                         putline(buf, mci);
2967                 }
2968
2969                 /* now do the hard work */
2970                 boundaries[0] = NULL;
2971                 mci->mci_flags |= MCIF_INHEADER;
2972                 mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER);
2973         }
2974 # if MIME7TO8
2975         else if (bitset(MCIF_CVT7TO8, mci->mci_flags))
2976         {
2977                 mime7to8(mci, e->e_header, e);
2978         }
2979 # endif
2980         else if (MaxMimeHeaderLength > 0 || MaxMimeFieldLength > 0)
2981         {
2982                 /* Use mime8to7 to check multipart for MIME header overflows */
2983                 boundaries[0] = NULL;
2984                 mci->mci_flags |= MCIF_INHEADER;
2985                 mime8to7(mci, e->e_header, e, boundaries, M87F_OUTER|M87F_NO8TO7);
2986         }
2987         else
2988 #endif
2989         {
2990                 int ostate;
2991                 register char *bp;
2992                 register char *pbp;
2993                 register int c;
2994                 register char *xp;
2995                 int padc;
2996                 char *buflim;
2997                 int pos = 0;
2998                 size_t eol_len;
2999                 char peekbuf[10];
3000
3001                 if (bitset(MCIF_INHEADER, mci->mci_flags))
3002                 {
3003                         putline("", mci);
3004                         mci->mci_flags &= ~MCIF_INHEADER;
3005                 }
3006
3007                 /* determine end of buffer; allow for short mailer lines */
3008                 buflim = &buf[sizeof buf - 1];
3009                 if (mci->mci_mailer->m_linelimit > 0 &&
3010                     mci->mci_mailer->m_linelimit < sizeof buf - 1)
3011                         buflim = &buf[mci->mci_mailer->m_linelimit - 1];
3012                 eol_len = strlen(mci->mci_mailer->m_eol);
3013
3014                 /* copy temp file to output with mapping */
3015                 ostate = OS_HEAD;
3016                 bp = buf;
3017                 pbp = peekbuf;
3018                 while (!ferror(mci->mci_out))
3019                 {
3020                         if (pbp > peekbuf)
3021                                 c = *--pbp;
3022                         else if ((c = getc(e->e_dfp)) == EOF)
3023                                 break;
3024                         if (bitset(MCIF_7BIT, mci->mci_flags))
3025                                 c &= 0x7f;
3026                         switch (ostate)
3027                         {
3028                           case OS_HEAD:
3029 #if _FFR_NONULLS
3030                                 if (c == '\0' &&
3031                                     bitnset(M_NONULLS, mci->mci_mailer->m_flags))
3032                                         break;
3033 #endif
3034                                 if (c != '\r' && c != '\n' && bp < buflim)
3035                                 {
3036                                         *bp++ = c;
3037                                         break;
3038                                 }
3039
3040                                 /* check beginning of line for special cases */
3041                                 *bp = '\0';
3042                                 pos = 0;
3043                                 padc = EOF;
3044                                 if (buf[0] == 'F' &&
3045                                     bitnset(M_ESCFROM, mci->mci_mailer->m_flags) &&
3046                                     strncmp(buf, "From ", 5) == 0)
3047                                 {
3048                                         padc = '>';
3049                                 }
3050                                 if (buf[0] == '-' && buf[1] == '-' &&
3051                                     separator != NULL)
3052                                 {
3053                                         /* possible separator */
3054                                         int sl = strlen(separator);
3055
3056                                         if (strncmp(&buf[2], separator, sl) == 0)
3057                                                 padc = ' ';
3058                                 }
3059                                 if (buf[0] == '.' &&
3060                                     bitnset(M_XDOT, mci->mci_mailer->m_flags))
3061                                 {
3062                                         padc = '.';
3063                                 }
3064
3065                                 /* now copy out saved line */
3066                                 if (TrafficLogFile != NULL)
3067                                 {
3068                                         fprintf(TrafficLogFile, "%05d >>> ",
3069                                                 (int) getpid());
3070                                         if (padc != EOF)
3071                                                 putc(padc, TrafficLogFile);
3072                                         for (xp = buf; xp < bp; xp++)
3073                                                 putc(*xp, TrafficLogFile);
3074                                         if (c == '\n')
3075                                                 fputs(mci->mci_mailer->m_eol,
3076                                                       TrafficLogFile);
3077                                 }
3078                                 if (padc != EOF)
3079                                 {
3080                                         putc(padc, mci->mci_out);
3081                                         mci->mci_contentlen++;
3082                                         pos++;
3083                                 }
3084                                 for (xp = buf; xp < bp; xp++)
3085                                 {
3086                                         putc(*xp, mci->mci_out);
3087                                         mci->mci_contentlen++;
3088                                 }
3089                                 if (c == '\n')
3090                                 {
3091                                         fputs(mci->mci_mailer->m_eol,
3092                                               mci->mci_out);
3093                                         mci->mci_contentlen += eol_len;
3094                                         pos = 0;
3095                                 }
3096                                 else
3097                                 {
3098                                         pos += bp - buf;
3099                                         if (c != '\r')
3100                                                 *pbp++ = c;
3101                                 }
3102                                 bp = buf;
3103
3104                                 /* determine next state */
3105                                 if (c == '\n')
3106                                         ostate = OS_HEAD;
3107                                 else if (c == '\r')
3108                                         ostate = OS_CR;
3109                                 else
3110                                         ostate = OS_INLINE;
3111                                 continue;
3112
3113                           case OS_CR:
3114                                 if (c == '\n')
3115                                 {
3116                                         /* got CRLF */
3117                                         fputs(mci->mci_mailer->m_eol, mci->mci_out);
3118                                         mci->mci_contentlen += eol_len;
3119                                         if (TrafficLogFile != NULL)
3120                                         {
3121                                                 fputs(mci->mci_mailer->m_eol,
3122                                                       TrafficLogFile);
3123                                         }
3124                                         ostate = OS_HEAD;
3125                                         continue;
3126                                 }
3127
3128                                 /* had a naked carriage return */
3129                                 *pbp++ = c;
3130                                 c = '\r';
3131                                 ostate = OS_INLINE;
3132                                 goto putch;
3133
3134                           case OS_INLINE:
3135                                 if (c == '\r')
3136                                 {
3137                                         ostate = OS_CR;
3138                                         continue;
3139                                 }
3140 #if _FFR_NONULLS
3141                                 if (c == '\0' &&
3142                                     bitnset(M_NONULLS, mci->mci_mailer->m_flags))
3143                                         break;
3144 #endif
3145 putch:
3146                                 if (mci->mci_mailer->m_linelimit > 0 &&
3147                                     pos > mci->mci_mailer->m_linelimit &&
3148                                     c != '\n')
3149                                 {
3150                                         putc('!', mci->mci_out);
3151                                         mci->mci_contentlen++;
3152                                         fputs(mci->mci_mailer->m_eol, mci->mci_out);
3153                                         mci->mci_contentlen += eol_len;
3154                                         if (TrafficLogFile != NULL)
3155                                         {
3156                                                 fprintf(TrafficLogFile, "!%s",
3157                                                         mci->mci_mailer->m_eol);
3158                                         }
3159                                         ostate = OS_HEAD;
3160                                         *pbp++ = c;
3161                                         continue;
3162                                 }
3163                                 if (c == '\n')
3164                                 {
3165                                         if (TrafficLogFile != NULL)
3166                                                 fputs(mci->mci_mailer->m_eol,
3167                                                       TrafficLogFile);
3168                                         fputs(mci->mci_mailer->m_eol, mci->mci_out);
3169                                         mci->mci_contentlen += eol_len;
3170                                         pos = 0;
3171                                         ostate = OS_HEAD;
3172                                 }
3173                                 else
3174                                 {
3175                                         if (TrafficLogFile != NULL)
3176                                                 putc(c, TrafficLogFile);
3177                                         putc(c, mci->mci_out);
3178                                         mci->mci_contentlen++;
3179                                         pos++;
3180                                         ostate = OS_INLINE;
3181                                 }
3182                                 break;
3183                         }
3184                 }
3185
3186                 /* make sure we are at the beginning of a line */
3187                 if (bp > buf)
3188                 {
3189                         if (TrafficLogFile != NULL)
3190                         {
3191                                 for (xp = buf; xp < bp; xp++)
3192                                         putc(*xp, TrafficLogFile);
3193                         }
3194                         for (xp = buf; xp < bp; xp++)
3195                         {
3196                                 putc(*xp, mci->mci_out);
3197                                 mci->mci_contentlen++;
3198                         }
3199                         pos += bp - buf;
3200                 }
3201                 if (pos > 0)
3202                 {
3203                         if (TrafficLogFile != NULL)
3204                                 fputs(mci->mci_mailer->m_eol, TrafficLogFile);
3205                         fputs(mci->mci_mailer->m_eol, mci->mci_out);
3206                         mci->mci_contentlen += eol_len;
3207                 }
3208         }
3209
3210         if (ferror(e->e_dfp))
3211         {
3212                 syserr("putbody: df%s: read error", e->e_id);
3213                 ExitStat = EX_IOERR;
3214         }
3215
3216 endofmessage:
3217         /* some mailers want extra blank line at end of message */
3218         if (bitnset(M_BLANKEND, mci->mci_mailer->m_flags) &&
3219             buf[0] != '\0' && buf[0] != '\n')
3220                 putline("", mci);
3221
3222         (void) fflush(mci->mci_out);
3223         if (ferror(mci->mci_out) && errno != EPIPE)
3224         {
3225                 syserr("putbody: write error");
3226                 ExitStat = EX_IOERR;
3227         }
3228         errno = 0;
3229 }
3230 \f/*
3231 **  MAILFILE -- Send a message to a file.
3232 **
3233 **      If the file has the setuid/setgid bits set, but NO execute
3234 **      bits, sendmail will try to become the owner of that file
3235 **      rather than the real user.  Obviously, this only works if
3236 **      sendmail runs as root.
3237 **
3238 **      This could be done as a subordinate mailer, except that it
3239 **      is used implicitly to save messages in ~/dead.letter.  We
3240 **      view this as being sufficiently important as to include it
3241 **      here.  For example, if the system is dying, we shouldn't have
3242 **      to create another process plus some pipes to save the message.
3243 **
3244 **      Parameters:
3245 **              filename -- the name of the file to send to.
3246 **              mailer -- mailer definition for recipient -- if NULL,
3247 **                      use FileMailer.
3248 **              ctladdr -- the controlling address header -- includes
3249 **                      the userid/groupid to be when sending.
3250 **              sfflags -- flags for opening.
3251 **              e -- the current envelope.
3252 **
3253 **      Returns:
3254 **              The exit code associated with the operation.
3255 **
3256 **      Side Effects:
3257 **              none.
3258 */
3259
3260 static jmp_buf  CtxMailfileTimeout;
3261 static void     mailfiletimeout __P((void));
3262
3263 int
3264 mailfile(filename, mailer, ctladdr, sfflags, e)
3265         char *volatile filename;
3266         MAILER *volatile mailer;
3267         ADDRESS *ctladdr;
3268         volatile int sfflags;
3269         register ENVELOPE *e;
3270 {
3271         register FILE *f;
3272         register pid_t pid = -1;
3273         volatile int mode = ST_MODE_NOFILE;
3274         bool suidwarn = geteuid() == 0;
3275         char *p;
3276         EVENT *ev;
3277
3278         if (tTd(11, 1))
3279         {
3280                 printf("mailfile %s\n  ctladdr=", filename);
3281                 printaddr(ctladdr, FALSE);
3282         }
3283
3284         if (mailer == NULL)
3285                 mailer = FileMailer;
3286
3287         if (e->e_xfp != NULL)
3288                 fflush(e->e_xfp);
3289
3290         /*
3291         **  Special case /dev/null.  This allows us to restrict file
3292         **  delivery to regular files only.
3293         */
3294
3295         if (strcmp(filename, "/dev/null") == 0)
3296                 return EX_OK;
3297
3298         /* check for 8-bit available */
3299         if (bitset(EF_HAS8BIT, e->e_flags) &&
3300             bitnset(M_7BITS, mailer->m_flags) &&
3301             (bitset(EF_DONT_MIME, e->e_flags) ||
3302              !(bitset(MM_MIME8BIT, MimeMode) ||
3303                (bitset(EF_IS_MIME, e->e_flags) &&
3304                 bitset(MM_CVTMIME, MimeMode)))))
3305         {
3306                 usrerr("554 Cannot send 8-bit data to 7-bit destination");
3307                 e->e_status = "5.6.3";
3308                 return(EX_DATAERR);
3309         }
3310
3311         /*
3312         **  Fork so we can change permissions here.
3313         **      Note that we MUST use fork, not vfork, because of
3314         **      the complications of calling subroutines, etc.
3315         */
3316
3317         DOFORK(fork);
3318
3319         if (pid < 0)
3320                 return (EX_OSERR);
3321         else if (pid == 0)
3322         {
3323                 /* child -- actually write to file */
3324                 struct stat stb;
3325                 MCI mcibuf;
3326                 int err;
3327                 volatile int oflags = O_WRONLY|O_APPEND;
3328
3329                 if (e->e_lockfp != NULL)
3330                         (void) close(fileno(e->e_lockfp));
3331
3332                 (void) setsignal(SIGINT, SIG_DFL);
3333                 (void) setsignal(SIGHUP, SIG_DFL);
3334                 (void) setsignal(SIGTERM, SIG_DFL);
3335                 (void) umask(OldUmask);
3336                 e->e_to = filename;
3337                 ExitStat = EX_OK;
3338
3339                 if (setjmp(CtxMailfileTimeout) != 0)
3340                 {
3341                         exit(EX_TEMPFAIL);
3342                 }
3343
3344                 if (TimeOuts.to_fileopen > 0)
3345                         ev = setevent(TimeOuts.to_fileopen, mailfiletimeout, 0);
3346                 else
3347                         ev = NULL;
3348
3349 #ifdef HASLSTAT
3350                 if (bitset(DBS_FILEDELIVERYTOSYMLINK, DontBlameSendmail))
3351                         err = stat(filename, &stb);
3352                 else
3353                         err = lstat(filename, &stb);
3354                 if (err < 0)
3355 #else
3356                 if (stat(filename, &stb) < 0)
3357 #endif
3358                 {
3359                         stb.st_mode = ST_MODE_NOFILE;
3360                         mode = FileMode;
3361                         oflags |= O_CREAT|O_EXCL;
3362                 }
3363                 else if (bitset(S_IXUSR|S_IXGRP|S_IXOTH, stb.st_mode) ||
3364                          (!bitset(DBS_FILEDELIVERYTOHARDLINK, DontBlameSendmail) &&
3365                           stb.st_nlink != 1) ||
3366                          (SafeFileEnv != NULL && !S_ISREG(stb.st_mode)))
3367                         exit(EX_CANTCREAT);
3368                 if (mode == ST_MODE_NOFILE)
3369                         mode = stb.st_mode;
3370
3371                 /* limit the errors to those actually caused in the child */
3372                 errno = 0;
3373                 ExitStat = EX_OK;
3374
3375                 if (ctladdr != NULL || bitset(SFF_RUNASREALUID, sfflags))
3376                 {
3377                         /* ignore setuid and setgid bits */
3378                         mode &= ~(S_ISGID|S_ISUID);
3379                 }
3380
3381                 /* we have to open the dfile BEFORE setuid */
3382                 if (e->e_dfp == NULL && bitset(EF_HAS_DF, e->e_flags))
3383                 {
3384                         char *df = queuename(e, 'd');
3385
3386                         e->e_dfp = fopen(df, "r");
3387                         if (e->e_dfp == NULL)
3388                         {
3389                                 syserr("mailfile: Cannot open %s for %s from %s",
3390                                         df, e->e_to, e->e_from.q_paddr);
3391                         }
3392                 }
3393
3394                 /* select a new user to run as */
3395                 if (!bitset(SFF_RUNASREALUID, sfflags))
3396                 {
3397                         if (bitnset(M_SPECIFIC_UID, mailer->m_flags))
3398                         {
3399                                 RealUserName = NULL;
3400                                 RealUid = mailer->m_uid;
3401                         }
3402                         else if (bitset(S_ISUID, mode))
3403                         {
3404                                 RealUserName = NULL;
3405                                 RealUid = stb.st_uid;
3406                         }
3407                         else if (ctladdr != NULL && ctladdr->q_uid != 0)
3408                         {
3409                                 if (ctladdr->q_ruser != NULL)
3410                                         RealUserName = ctladdr->q_ruser;
3411                                 else
3412                                         RealUserName = ctladdr->q_user;
3413                                 RealUid = ctladdr->q_uid;
3414                         }
3415                         else if (mailer != NULL && mailer->m_uid != 0)
3416                         {
3417                                 RealUserName = DefUser;
3418                                 RealUid = mailer->m_uid;
3419                         }
3420                         else
3421                         {
3422                                 RealUserName = DefUser;
3423                                 RealUid = DefUid;
3424                         }
3425
3426                         /* select a new group to run as */
3427                         if (bitnset(M_SPECIFIC_UID, mailer->m_flags))
3428                                 RealGid = mailer->m_gid;
3429                         else if (bitset(S_ISGID, mode))
3430                                 RealGid = stb.st_gid;
3431                         else if (ctladdr != NULL && ctladdr->q_uid != 0)
3432                                 RealGid = ctladdr->q_gid;
3433                         else if (mailer != NULL && mailer->m_gid != 0)
3434                                 RealGid = mailer->m_gid;
3435                         else
3436                                 RealGid = DefGid;
3437                 }
3438
3439                 /* last ditch */
3440                 if (!bitset(SFF_ROOTOK, sfflags))
3441                 {
3442                         if (RealUid == 0)
3443                                 RealUid = DefUid;
3444                         if (RealGid == 0)
3445                                 RealGid = DefGid;
3446                 }
3447
3448                 /* set group id list (needs /etc/group access) */
3449                 if (RealUserName != NULL && !DontInitGroups)
3450                 {
3451                         if (initgroups(RealUserName, RealGid) == -1 && suidwarn)
3452                                 syserr("mailfile: initgroups(%s, %d) failed",
3453                                         RealUserName, RealGid);
3454                 }
3455                 else
3456                 {
3457                         GIDSET_T gidset[1];
3458
3459                         gidset[0] = RealGid;
3460                         if (setgroups(1, gidset) == -1 && suidwarn)
3461                                 syserr("mailfile: setgroups() failed");
3462                 }
3463
3464                 /* if you have a safe environment, go into it */
3465                 if (SafeFileEnv != NULL && SafeFileEnv[0] != '\0')
3466                 {
3467                         int i;
3468
3469                         if (chroot(SafeFileEnv) < 0)
3470                         {
3471                                 syserr("mailfile: Cannot chroot(%s)",
3472                                         SafeFileEnv);
3473                                 exit(EX_CANTCREAT);
3474                         }
3475                         i = strlen(SafeFileEnv);
3476                         if (strncmp(SafeFileEnv, filename, i) == 0)
3477                                 filename += i;
3478                 }
3479                 if (chdir("/") < 0)
3480                         syserr("mailfile: cannot chdir(/)");
3481
3482                 /* now reset the group and user ids */
3483                 endpwent();
3484                 if (setgid(RealGid) < 0 && suidwarn)
3485                         syserr("mailfile: setgid(%ld) failed", (long) RealGid);
3486                 vendor_set_uid(RealUid);
3487                 if (setuid(RealUid) < 0 && suidwarn)
3488                         syserr("mailfile: setuid(%ld) failed", (long) RealUid);
3489
3490                 /* move into some "safe" directory */
3491                 if (mailer->m_execdir != NULL)
3492                 {
3493                         char *q;
3494                         char buf[MAXLINE + 1];
3495
3496                         for (p = mailer->m_execdir; p != NULL; p = q)
3497                         {
3498                                 q = strchr(p, ':');
3499                                 if (q != NULL)
3500                                         *q = '\0';
3501                                 expand(p, buf, sizeof buf, e);
3502                                 if (q != NULL)
3503                                         *q++ = ':';
3504                                 if (tTd(11, 20))
3505                                         printf("mailfile: trydir %s\n",
3506                                                buf);
3507                                 if (buf[0] != '\0' && chdir(buf) >= 0)
3508                                         break;
3509                         }
3510                 }
3511
3512                 sfflags |= SFF_NOPATHCHECK;
3513                 if (!bitset(DBS_FILEDELIVERYTOSYMLINK, DontBlameSendmail))
3514                         sfflags |= SFF_NOSLINK;
3515                 if (!bitset(DBS_FILEDELIVERYTOHARDLINK, DontBlameSendmail))
3516                         sfflags |= SFF_NOHLINK;
3517                 sfflags &= ~SFF_OPENASROOT;
3518                 f = safefopen(filename, oflags, FileMode, sfflags);
3519                 if (f == NULL)
3520                 {
3521                         message("554 cannot open %s: %s",
3522                                 shortenstring(filename, MAXSHORTSTR),
3523                                 errstring(errno));
3524                         exit(EX_CANTCREAT);
3525                 }
3526                 if (filechanged(filename, fileno(f), &stb))
3527                 {
3528                         message("554 file changed after open");
3529                         exit(EX_CANTCREAT);
3530                 }
3531                 if (fstat(fileno(f), &stb) < 0)
3532                 {
3533                         message("554 cannot fstat %s", errstring(errno));
3534                         exit(EX_CANTCREAT);
3535                 }
3536
3537                 if (ev != NULL)
3538                         clrevent(ev);
3539
3540                 bzero(&mcibuf, sizeof mcibuf);
3541                 mcibuf.mci_mailer = mailer;
3542                 mcibuf.mci_out = f;
3543                 mcibuf.mci_contentlen = 0;
3544                 if (bitnset(M_7BITS, mailer->m_flags))
3545                         mcibuf.mci_flags |= MCIF_7BIT;
3546
3547                 /* clear out per-message flags from connection structure */
3548                 mcibuf.mci_flags &= ~(MCIF_CVT7TO8|MCIF_CVT8TO7);
3549
3550                 if (bitset(EF_HAS8BIT, e->e_flags) &&
3551                     !bitset(EF_DONT_MIME, e->e_flags) &&
3552                     bitnset(M_7BITS, mailer->m_flags))
3553                         mcibuf.mci_flags |= MCIF_CVT8TO7;
3554
3555 #if MIME7TO8
3556                 if (bitnset(M_MAKE8BIT, mailer->m_flags) &&
3557                     !bitset(MCIF_7BIT, mcibuf.mci_flags) &&
3558                     (p = hvalue("Content-Transfer-Encoding", e->e_header)) != NULL &&
3559                     (strcasecmp(p, "quoted-printable") == 0 ||
3560                      strcasecmp(p, "base64") == 0) &&
3561                     (p = hvalue("Content-Type", e->e_header)) != NULL)
3562                 {
3563                         /* may want to convert 7 -> 8 */
3564                         /* XXX should really parse it here -- and use a class XXX */
3565                         if (strncasecmp(p, "text/plain", 10) == 0 &&
3566                                 (p[10] == '\0' || p[10] == ' ' || p[10] == ';'))
3567                                 mcibuf.mci_flags |= MCIF_CVT7TO8;
3568                 }
3569 #endif
3570
3571                 putfromline(&mcibuf, e);
3572                 (*e->e_puthdr)(&mcibuf, e->e_header, e, M87F_OUTER);
3573                 (*e->e_putbody)(&mcibuf, e, NULL);
3574                 putline("\n", &mcibuf);
3575                 if (fflush(f) < 0 || ferror(f))
3576                 {
3577                         message("451 I/O error: %s", errstring(errno));
3578                         setstat(EX_IOERR);
3579                 }
3580
3581                 /* reset ISUID & ISGID bits for paranoid systems */
3582 #if HASFCHMOD
3583                 (void) fchmod(fileno(f), (MODE_T) stb.st_mode);
3584 #else
3585                 (void) chmod(filename, (MODE_T) stb.st_mode);
3586 #endif
3587                 (void) xfclose(f, "mailfile", filename);
3588                 (void) fflush(stdout);
3589                 setuid(RealUid);
3590                 exit(ExitStat);
3591                 /*NOTREACHED*/
3592         }
3593         else
3594         {
3595                 /* parent -- wait for exit status */
3596                 int st;
3597
3598                 st = waitfor(pid);
3599                 if (st == -1)
3600                 {
3601                         syserr("mailfile: %s: wait", mailer->m_name);
3602                         return (EX_SOFTWARE);
3603                 }
3604                 if (WIFEXITED(st))
3605                         return (WEXITSTATUS(st));
3606                 else
3607                 {
3608                         syserr("mailfile: %s: child died on signal %d",
3609                                mailer->m_name, st);
3610                         return (EX_UNAVAILABLE);
3611                 }
3612                 /*NOTREACHED*/
3613         }
3614         return EX_UNAVAILABLE;  /* avoid compiler warning on IRIX */
3615 }
3616
3617 static void
3618 mailfiletimeout()
3619 {
3620         longjmp(CtxMailfileTimeout, 1);
3621 }
3622 \f/*
3623 **  HOSTSIGNATURE -- return the "signature" for a host.
3624 **
3625 **      The signature describes how we are going to send this -- it
3626 **      can be just the hostname (for non-Internet hosts) or can be
3627 **      an ordered list of MX hosts.
3628 **
3629 **      Parameters:
3630 **              m -- the mailer describing this host.
3631 **              host -- the host name.
3632 **              e -- the current envelope.
3633 **
3634 **      Returns:
3635 **              The signature for this host.
3636 **
3637 **      Side Effects:
3638 **              Can tweak the symbol table.
3639 */
3640
3641 char *
3642 hostsignature(m, host, e)
3643         register MAILER *m;
3644         char *host;
3645         ENVELOPE *e;
3646 {
3647         register char *p;
3648         register STAB *s;
3649         int i;
3650         int len;
3651 #if NAMED_BIND
3652         int nmx;
3653         char *hp;
3654         char *endp;
3655         int oldoptions = _res.options;
3656         char *mxhosts[MAXMXHOSTS + 1];
3657 #endif
3658
3659         /*
3660         **  Check to see if this uses IPC -- if not, it can't have MX records.
3661         */
3662
3663         p = m->m_mailer;
3664         if (strcmp(p, "[IPC]") != 0 && strcmp(p, "[TCP]") != 0)
3665         {
3666                 /* just an ordinary mailer */
3667                 return host;
3668         }
3669
3670         /*
3671         **  Look it up in the symbol table.
3672         */
3673
3674         s = stab(host, ST_HOSTSIG, ST_ENTER);
3675         if (s->s_hostsig != NULL)
3676                 return s->s_hostsig;
3677
3678         /*
3679         **  Not already there -- create a signature.
3680         */
3681
3682 #if NAMED_BIND
3683         if (ConfigLevel < 2)
3684                 _res.options &= ~(RES_DEFNAMES | RES_DNSRCH);   /* XXX */
3685
3686         for (hp = host; hp != NULL; hp = endp)
3687         {
3688                 endp = strchr(hp, ':');
3689                 if (endp != NULL)
3690                         *endp = '\0';
3691
3692                 if (bitnset(M_NOMX, m->m_flags))
3693                 {
3694                         /* skip MX lookups */
3695                         nmx = 1;
3696                         mxhosts[0] = hp;
3697                 }
3698                 else
3699                 {
3700                         auto int rcode;
3701
3702                         nmx = getmxrr(hp, mxhosts, TRUE, &rcode);
3703                         if (nmx <= 0)
3704                         {
3705                                 register MCI *mci;
3706
3707                                 /* update the connection info for this host */
3708                                 mci = mci_get(hp, m);
3709                                 mci->mci_errno = errno;
3710                                 mci->mci_herrno = h_errno;
3711                                 mci->mci_lastuse = curtime();
3712                                 mci_setstat(mci, rcode, NULL, NULL);
3713
3714                                 /* use the original host name as signature */
3715                                 nmx = 1;
3716                                 mxhosts[0] = hp;
3717                         }
3718                 }
3719
3720                 len = 0;
3721                 for (i = 0; i < nmx; i++)
3722                 {
3723                         len += strlen(mxhosts[i]) + 1;
3724                 }
3725                 if (s->s_hostsig != NULL)
3726                         len += strlen(s->s_hostsig) + 1;
3727                 p = xalloc(len);
3728                 if (s->s_hostsig != NULL)
3729                 {
3730                         (void) strcpy(p, s->s_hostsig);
3731                         free(s->s_hostsig);
3732                         s->s_hostsig = p;
3733                         p += strlen(p);
3734                         *p++ = ':';
3735                 }
3736                 else
3737                         s->s_hostsig = p;
3738                 for (i = 0; i < nmx; i++)
3739                 {
3740                         if (i != 0)
3741                                 *p++ = ':';
3742                         strcpy(p, mxhosts[i]);
3743                         p += strlen(p);
3744                 }
3745                 if (endp != NULL)
3746                         *endp++ = ':';
3747         }
3748         makelower(s->s_hostsig);
3749         if (ConfigLevel < 2)
3750                 _res.options = oldoptions;
3751 #else
3752         /* not using BIND -- the signature is just the host name */
3753         s->s_hostsig = host;
3754 #endif
3755         if (tTd(17, 1))
3756                 printf("hostsignature(%s) = %s\n", host, s->s_hostsig);
3757         return s->s_hostsig;
3758 }