1: # include <signal.h>
   2: # include <errno.h>
   3: # include "sendmail.h"
   4: # include <sys/stat.h>
   5: 
   6: SCCSID(@(#)deliver.c	4.2		8/28/83);
   7: 
   8: /*
   9: **  DELIVER -- Deliver a message to a list of addresses.
  10: **
  11: **	This routine delivers to everyone on the same host as the
  12: **	user on the head of the list.  It is clever about mailers
  13: **	that don't handle multiple users.  It is NOT guaranteed
  14: **	that it will deliver to all these addresses however -- so
  15: **	deliver should be called once for each address on the
  16: **	list.
  17: **
  18: **	Parameters:
  19: **		e -- the envelope to deliver.
  20: **		firstto -- head of the address list to deliver to.
  21: **
  22: **	Returns:
  23: **		zero -- successfully delivered.
  24: **		else -- some failure, see ExitStat for more info.
  25: **
  26: **	Side Effects:
  27: **		The standard input is passed off to someone.
  28: */
  29: 
  30: deliver(e, firstto)
  31:     register ENVELOPE *e;
  32:     ADDRESS *firstto;
  33: {
  34:     char *host;         /* host being sent to */
  35:     char *user;         /* user being sent to */
  36:     char **pvp;
  37:     register char **mvp;
  38:     register char *p;
  39:     register MAILER *m;     /* mailer for this recipient */
  40:     ADDRESS *ctladdr;
  41:     register ADDRESS *to = firstto;
  42:     bool clever = FALSE;        /* running user smtp to this mailer */
  43:     ADDRESS *tochain = NULL;    /* chain of users in this mailer call */
  44:     register int rcode;     /* response code */
  45:     char *pv[MAXPV+1];
  46:     char tobuf[MAXLINE-50];     /* text line of to people */
  47:     char buf[MAXNAME];
  48:     char tfrombuf[MAXNAME];     /* translated from person */
  49:     extern bool checkcompat();
  50:     extern ADDRESS *getctladdr();
  51:     extern char *remotename();
  52: 
  53:     errno = 0;
  54:     if (bitset(QDONTSEND, to->q_flags))
  55:         return (0);
  56: 
  57:     m = to->q_mailer;
  58:     host = to->q_host;
  59: 
  60: # ifdef DEBUG
  61:     if (tTd(10, 1))
  62:         printf("\n--deliver, mailer=%d, host=`%s', first user=`%s'\n",
  63:             m->m_mno, host, to->q_user);
  64: # endif DEBUG
  65: 
  66:     /*
  67: 	**  If this mailer is expensive, and if we don't want to make
  68: 	**  connections now, just mark these addresses and return.
  69: 	**	This is useful if we want to batch connections to
  70: 	**	reduce load.  This will cause the messages to be
  71: 	**	queued up, and a daemon will come along to send the
  72: 	**	messages later.
  73: 	**		This should be on a per-mailer basis.
  74: 	*/
  75: 
  76:     if (NoConnect && !QueueRun && bitnset(M_EXPENSIVE, m->m_flags) &&
  77:         !Verbose)
  78:     {
  79:         for (; to != NULL; to = to->q_next)
  80:         {
  81:             if (bitset(QDONTSEND, to->q_flags) || to->q_mailer != m)
  82:                 continue;
  83:             to->q_flags |= QQUEUEUP|QDONTSEND;
  84:             e->e_to = to->q_paddr;
  85:             message(Arpa_Info, "queued");
  86:             if (LogLevel > 4)
  87:                 logdelivery("queued");
  88:         }
  89:         e->e_to = NULL;
  90:         return (0);
  91:     }
  92: 
  93:     /*
  94: 	**  Do initial argv setup.
  95: 	**	Insert the mailer name.  Notice that $x expansion is
  96: 	**	NOT done on the mailer name.  Then, if the mailer has
  97: 	**	a picky -f flag, we insert it as appropriate.  This
  98: 	**	code does not check for 'pv' overflow; this places a
  99: 	**	manifest lower limit of 4 for MAXPV.
 100: 	**		The from address rewrite is expected to make
 101: 	**		the address relative to the other end.
 102: 	*/
 103: 
 104:     /* rewrite from address, using rewriting rules */
 105:     expand("$f", buf, &buf[sizeof buf - 1], e);
 106:     (void) strcpy(tfrombuf, remotename(buf, m, TRUE, TRUE));
 107: 
 108:     define('g', tfrombuf, e);       /* translated sender address */
 109:     define('h', host, e);           /* to host */
 110:     Errors = 0;
 111:     pvp = pv;
 112:     *pvp++ = m->m_argv[0];
 113: 
 114:     /* insert -f or -r flag as appropriate */
 115:     if (FromFlag && (bitnset(M_FOPT, m->m_flags) || bitnset(M_ROPT, m->m_flags)))
 116:     {
 117:         if (bitnset(M_FOPT, m->m_flags))
 118:             *pvp++ = "-f";
 119:         else
 120:             *pvp++ = "-r";
 121:         expand("$g", buf, &buf[sizeof buf - 1], e);
 122:         *pvp++ = newstr(buf);
 123:     }
 124: 
 125:     /*
 126: 	**  Append the other fixed parts of the argv.  These run
 127: 	**  up to the first entry containing "$u".  There can only
 128: 	**  be one of these, and there are only a few more slots
 129: 	**  in the pv after it.
 130: 	*/
 131: 
 132:     for (mvp = m->m_argv; (p = *++mvp) != NULL; )
 133:     {
 134:         while ((p = index(p, '$')) != NULL)
 135:             if (*++p == 'u')
 136:                 break;
 137:         if (p != NULL)
 138:             break;
 139: 
 140:         /* this entry is safe -- go ahead and process it */
 141:         expand(*mvp, buf, &buf[sizeof buf - 1], e);
 142:         *pvp++ = newstr(buf);
 143:         if (pvp >= &pv[MAXPV - 3])
 144:         {
 145:             syserr("Too many parameters to %s before $u", pv[0]);
 146:             return (-1);
 147:         }
 148:     }
 149: 
 150:     /*
 151: 	**  If we have no substitution for the user name in the argument
 152: 	**  list, we know that we must supply the names otherwise -- and
 153: 	**  SMTP is the answer!!
 154: 	*/
 155: 
 156:     if (*mvp == NULL)
 157:     {
 158:         /* running SMTP */
 159: # ifdef SMTP
 160:         clever = TRUE;
 161:         *pvp = NULL;
 162: # else SMTP
 163:         /* oops!  we don't implement SMTP */
 164:         syserr("SMTP style mailer");
 165:         return (EX_SOFTWARE);
 166: # endif SMTP
 167:     }
 168: 
 169:     /*
 170: 	**  At this point *mvp points to the argument with $u.  We
 171: 	**  run through our address list and append all the addresses
 172: 	**  we can.  If we run out of space, do not fret!  We can
 173: 	**  always send another copy later.
 174: 	*/
 175: 
 176:     tobuf[0] = '\0';
 177:     e->e_to = tobuf;
 178:     ctladdr = NULL;
 179:     for (; to != NULL; to = to->q_next)
 180:     {
 181:         /* avoid sending multiple recipients to dumb mailers */
 182:         if (tobuf[0] != '\0' && !bitnset(M_MUSER, m->m_flags))
 183:             break;
 184: 
 185:         /* if already sent or not for this host, don't send */
 186:         if (bitset(QDONTSEND, to->q_flags) ||
 187:             strcmp(to->q_host, host) != 0 ||
 188:             to->q_mailer != firstto->q_mailer)
 189:             continue;
 190: 
 191:         /* avoid overflowing tobuf */
 192:         if (sizeof tobuf - (strlen(to->q_paddr) + strlen(tobuf) + 2) < 0)
 193:             break;
 194: 
 195: # ifdef DEBUG
 196:         if (tTd(10, 1))
 197:         {
 198:             printf("\nsend to ");
 199:             printaddr(to, FALSE);
 200:         }
 201: # endif DEBUG
 202: 
 203:         /* compute effective uid/gid when sending */
 204:         if (to->q_mailer == ProgMailer)
 205:             ctladdr = getctladdr(to);
 206: 
 207:         user = to->q_user;
 208:         e->e_to = to->q_paddr;
 209:         to->q_flags |= QDONTSEND;
 210: 
 211:         /*
 212: 		**  Check to see that these people are allowed to
 213: 		**  talk to each other.
 214: 		*/
 215: 
 216:         if (m->m_maxsize != 0 && e->e_msgsize > m->m_maxsize)
 217:         {
 218:             usrerr("Message is too large; %ld bytes max", m->m_maxsize);
 219:             NoReturn = TRUE;
 220:             giveresponse(EX_UNAVAILABLE, m, e);
 221:             continue;
 222:         }
 223:         if (!checkcompat(to))
 224:         {
 225:             giveresponse(EX_UNAVAILABLE, m, e);
 226:             continue;
 227:         }
 228: 
 229:         /*
 230: 		**  Strip quote bits from names if the mailer is dumb
 231: 		**	about them.
 232: 		*/
 233: 
 234:         if (bitnset(M_STRIPQ, m->m_flags))
 235:         {
 236:             stripquotes(user, TRUE);
 237:             stripquotes(host, TRUE);
 238:         }
 239:         else
 240:         {
 241:             stripquotes(user, FALSE);
 242:             stripquotes(host, FALSE);
 243:         }
 244: 
 245:         /* hack attack -- delivermail compatibility */
 246:         if (m == ProgMailer && *user == '|')
 247:             user++;
 248: 
 249:         /*
 250: 		**  If an error message has already been given, don't
 251: 		**	bother to send to this address.
 252: 		**
 253: 		**	>>>>>>>>>> This clause assumes that the local mailer
 254: 		**	>> NOTE >> cannot do any further aliasing; that
 255: 		**	>>>>>>>>>> function is subsumed by sendmail.
 256: 		*/
 257: 
 258:         if (bitset(QBADADDR|QQUEUEUP, to->q_flags))
 259:             continue;
 260: 
 261:         /* save statistics.... */
 262:         markstats(e, to);
 263: 
 264:         /*
 265: 		**  See if this user name is "special".
 266: 		**	If the user name has a slash in it, assume that this
 267: 		**	is a file -- send it off without further ado.  Note
 268: 		**	that this type of addresses is not processed along
 269: 		**	with the others, so we fudge on the To person.
 270: 		*/
 271: 
 272:         if (m == LocalMailer)
 273:         {
 274:             if (user[0] == '/')
 275:             {
 276:                 rcode = mailfile(user, getctladdr(to));
 277:                 giveresponse(rcode, m, e);
 278:                 continue;
 279:             }
 280:         }
 281: 
 282:         /*
 283: 		**  Address is verified -- add this user to mailer
 284: 		**  argv, and add it to the print list of recipients.
 285: 		*/
 286: 
 287:         /* link together the chain of recipients */
 288:         to->q_tchain = tochain;
 289:         tochain = to;
 290: 
 291:         /* create list of users for error messages */
 292:         (void) strcat(tobuf, ",");
 293:         (void) strcat(tobuf, to->q_paddr);
 294:         define('u', user, e);       /* to user */
 295:         define('z', to->q_home, e); /* user's home */
 296: 
 297:         /*
 298: 		**  Expand out this user into argument list.
 299: 		*/
 300: 
 301:         if (!clever)
 302:         {
 303:             expand(*mvp, buf, &buf[sizeof buf - 1], e);
 304:             *pvp++ = newstr(buf);
 305:             if (pvp >= &pv[MAXPV - 2])
 306:             {
 307:                 /* allow some space for trailing parms */
 308:                 break;
 309:             }
 310:         }
 311:     }
 312: 
 313:     /* see if any addresses still exist */
 314:     if (tobuf[0] == '\0')
 315:     {
 316:         define('g', (char *) NULL, e);
 317:         return (0);
 318:     }
 319: 
 320:     /* print out messages as full list */
 321:     e->e_to = tobuf + 1;
 322: 
 323:     /*
 324: 	**  Fill out any parameters after the $u parameter.
 325: 	*/
 326: 
 327:     while (!clever && *++mvp != NULL)
 328:     {
 329:         expand(*mvp, buf, &buf[sizeof buf - 1], e);
 330:         *pvp++ = newstr(buf);
 331:         if (pvp >= &pv[MAXPV])
 332:             syserr("deliver: pv overflow after $u for %s", pv[0]);
 333:     }
 334:     *pvp++ = NULL;
 335: 
 336:     /*
 337: 	**  Call the mailer.
 338: 	**	The argument vector gets built, pipes
 339: 	**	are created as necessary, and we fork & exec as
 340: 	**	appropriate.
 341: 	**	If we are running SMTP, we just need to clean up.
 342: 	*/
 343: 
 344:     message(Arpa_Info, "Connecting to %s.%s...", host, m->m_name);
 345: 
 346:     if (ctladdr == NULL)
 347:         ctladdr = &e->e_from;
 348: # ifdef SMTP
 349:     if (clever)
 350:     {
 351:         /* send the initial SMTP protocol */
 352:         rcode = smtpinit(m, pv);
 353: 
 354:         if (rcode == EX_OK)
 355:         {
 356:             /* send the recipient list */
 357:             tobuf[0] = '\0';
 358:             for (to = tochain; to != NULL; to = to->q_tchain)
 359:             {
 360:                 int i;
 361: 
 362:                 e->e_to = to->q_paddr;
 363:                 i = smtprcpt(to, m);
 364:                 if (i != EX_OK)
 365:                 {
 366:                     markfailure(e, to, i);
 367:                     giveresponse(i, m, e);
 368:                 }
 369:                 else
 370:                 {
 371:                     strcat(tobuf, ",");
 372:                     strcat(tobuf, to->q_paddr);
 373:                 }
 374:             }
 375: 
 376:             /* now send the data */
 377:             if (tobuf[0] == '\0')
 378:                 e->e_to = NULL;
 379:             else
 380:             {
 381:                 e->e_to = tobuf + 1;
 382:                 rcode = smtpdata(m, e);
 383:             }
 384: 
 385:             /* now close the connection */
 386:             smtpquit(pv[0], m);
 387:         }
 388:     }
 389:     else
 390: # endif SMTP
 391:         rcode = sendoff(e, m, pv, ctladdr);
 392: 
 393:     /*
 394: 	**  Do final status disposal.
 395: 	**	We check for something in tobuf for the SMTP case.
 396: 	**	If we got a temporary failure, arrange to queue the
 397: 	**		addressees.
 398: 	*/
 399: 
 400:     if (tobuf[0] != '\0')
 401:         giveresponse(rcode, m, e);
 402:     if (rcode != EX_OK)
 403:     {
 404:         for (to = tochain; to != NULL; to = to->q_tchain)
 405:             markfailure(e, to, rcode);
 406:     }
 407: 
 408:     errno = 0;
 409:     define('g', (char *) NULL, e);
 410:     return (rcode);
 411: }
 412: /*
 413: **  MARKFAILURE -- mark a failure on a specific address.
 414: **
 415: **	Parameters:
 416: **		e -- the envelope we are sending.
 417: **		q -- the address to mark.
 418: **		rcode -- the code signifying the particular failure.
 419: **
 420: **	Returns:
 421: **		none.
 422: **
 423: **	Side Effects:
 424: **		marks the address (and possibly the envelope) with the
 425: **			failure so that an error will be returned or
 426: **			the message will be queued, as appropriate.
 427: */
 428: 
 429: markfailure(e, q, rcode)
 430:     register ENVELOPE *e;
 431:     register ADDRESS *q;
 432:     int rcode;
 433: {
 434:     if (rcode == EX_OK)
 435:         return;
 436:     else if (rcode != EX_TEMPFAIL)
 437:         q->q_flags |= QBADADDR;
 438:     else if (curtime() > e->e_ctime + TimeOut)
 439:     {
 440:         extern char *pintvl();
 441:         char buf[MAXLINE];
 442: 
 443:         if (!bitset(EF_TIMEOUT, e->e_flags))
 444:         {
 445:             (void) sprintf(buf, "Cannot send message for %s",
 446:                 pintvl(TimeOut, FALSE));
 447:             if (e->e_message != NULL)
 448:                 free(e->e_message);
 449:             e->e_message = newstr(buf);
 450:             message(Arpa_Info, buf);
 451:         }
 452:         q->q_flags |= QBADADDR;
 453:         e->e_flags |= EF_TIMEOUT;
 454:     }
 455:     else
 456:         q->q_flags |= QQUEUEUP;
 457: }
 458: /*
 459: **  DOFORK -- do a fork, retrying a couple of times on failure.
 460: **
 461: **	This MUST be a macro, since after a vfork we are running
 462: **	two processes on the same stack!!!
 463: **
 464: **	Parameters:
 465: **		none.
 466: **
 467: **	Returns:
 468: **		From a macro???  You've got to be kidding!
 469: **
 470: **	Side Effects:
 471: **		Modifies the ==> LOCAL <== variable 'pid', leaving:
 472: **			pid of child in parent, zero in child.
 473: **			-1 on unrecoverable error.
 474: **
 475: **	Notes:
 476: **		I'm awfully sorry this looks so awful.  That's
 477: **		vfork for you.....
 478: */
 479: 
 480: # define NFORKTRIES 5
 481: # ifdef VMUNIX
 482: # define XFORK  vfork
 483: # else VMUNIX
 484: # define XFORK  fork
 485: # endif VMUNIX
 486: 
 487: # define DOFORK(fORKfN) \
 488: {\
 489:     register int i;\
 490: \
 491:     for (i = NFORKTRIES; i-- > 0; )\
 492:     {\
 493:         pid = fORKfN();\
 494:         if (pid >= 0)\
 495:             break;\
 496:         sleep(NFORKTRIES - i);\
 497:     }\
 498: }
 499: /*
 500: **  DOFORK -- simple fork interface to DOFORK.
 501: **
 502: **	Parameters:
 503: **		none.
 504: **
 505: **	Returns:
 506: **		pid of child in parent.
 507: **		zero in child.
 508: **		-1 on error.
 509: **
 510: **	Side Effects:
 511: **		returns twice, once in parent and once in child.
 512: */
 513: 
 514: dofork()
 515: {
 516:     register int pid;
 517: 
 518:     DOFORK(fork);
 519:     return (pid);
 520: }
 521: /*
 522: **  SENDOFF -- send off call to mailer & collect response.
 523: **
 524: **	Parameters:
 525: **		e -- the envelope to mail.
 526: **		m -- mailer descriptor.
 527: **		pvp -- parameter vector to send to it.
 528: **		ctladdr -- an address pointer controlling the
 529: **			user/groupid etc. of the mailer.
 530: **
 531: **	Returns:
 532: **		exit status of mailer.
 533: **
 534: **	Side Effects:
 535: **		none.
 536: */
 537: 
 538: sendoff(e, m, pvp, ctladdr)
 539:     register ENVELOPE *e;
 540:     MAILER *m;
 541:     char **pvp;
 542:     ADDRESS *ctladdr;
 543: {
 544:     auto FILE *mfile;
 545:     auto FILE *rfile;
 546:     register int i;
 547:     int pid;
 548: 
 549:     /*
 550: 	**  Create connection to mailer.
 551: 	*/
 552: 
 553:     pid = openmailer(m, pvp, ctladdr, FALSE, &mfile, &rfile);
 554:     if (pid < 0)
 555:         return (-1);
 556: 
 557:     /*
 558: 	**  Format and send message.
 559: 	*/
 560: 
 561:     putfromline(mfile, m);
 562:     (*e->e_puthdr)(mfile, m, e);
 563:     putline("\n", mfile, m);
 564:     (*e->e_putbody)(mfile, m, e);
 565:     (void) fclose(mfile);
 566: 
 567:     i = endmailer(pid, pvp[0]);
 568: 
 569:     /* arrange a return receipt if requested */
 570:     if (e->e_receiptto != NULL && bitnset(M_LOCAL, m->m_flags))
 571:     {
 572:         e->e_flags |= EF_SENDRECEIPT;
 573:         /* do we want to send back more info? */
 574:     }
 575: 
 576:     return (i);
 577: }
 578: /*
 579: **  ENDMAILER -- Wait for mailer to terminate.
 580: **
 581: **	We should never get fatal errors (e.g., segmentation
 582: **	violation), so we report those specially.  For other
 583: **	errors, we choose a status message (into statmsg),
 584: **	and if it represents an error, we print it.
 585: **
 586: **	Parameters:
 587: **		pid -- pid of mailer.
 588: **		name -- name of mailer (for error messages).
 589: **
 590: **	Returns:
 591: **		exit code of mailer.
 592: **
 593: **	Side Effects:
 594: **		none.
 595: */
 596: 
 597: endmailer(pid, name)
 598:     int pid;
 599:     char *name;
 600: {
 601:     int st;
 602: 
 603:     /* in the IPC case there is nothing to wait for */
 604:     if (pid == 0)
 605:         return (EX_OK);
 606: 
 607:     /* wait for the mailer process to die and collect status */
 608:     st = waitfor(pid);
 609:     if (st == -1)
 610:     {
 611:         syserr("endmailer %s: wait", name);
 612:         return (EX_SOFTWARE);
 613:     }
 614: 
 615:     /* see if it died a horrid death */
 616:     if ((st & 0377) != 0)
 617:     {
 618:         syserr("endmailer %s: stat %o", name, st);
 619:         ExitStat = EX_UNAVAILABLE;
 620:         return (EX_UNAVAILABLE);
 621:     }
 622: 
 623:     /* normal death -- return status */
 624:     st = (st >> 8) & 0377;
 625:     return (st);
 626: }
 627: /*
 628: **  OPENMAILER -- open connection to mailer.
 629: **
 630: **	Parameters:
 631: **		m -- mailer descriptor.
 632: **		pvp -- parameter vector to pass to mailer.
 633: **		ctladdr -- controlling address for user.
 634: **		clever -- create a full duplex connection.
 635: **		pmfile -- pointer to mfile (to mailer) connection.
 636: **		prfile -- pointer to rfile (from mailer) connection.
 637: **
 638: **	Returns:
 639: **		pid of mailer ( > 0 ).
 640: **		-1 on error.
 641: **		zero on an IPC connection.
 642: **
 643: **	Side Effects:
 644: **		creates a mailer in a subprocess.
 645: */
 646: 
 647: openmailer(m, pvp, ctladdr, clever, pmfile, prfile)
 648:     MAILER *m;
 649:     char **pvp;
 650:     ADDRESS *ctladdr;
 651:     bool clever;
 652:     FILE **pmfile;
 653:     FILE **prfile;
 654: {
 655:     int pid;
 656:     int mpvect[2];
 657:     int rpvect[2];
 658:     FILE *mfile;
 659:     FILE *rfile;
 660:     extern FILE *fdopen();
 661: 
 662: # ifdef DEBUG
 663:     if (tTd(11, 1))
 664:     {
 665:         printf("openmailer:");
 666:         printav(pvp);
 667:     }
 668: # endif DEBUG
 669:     errno = 0;
 670: 
 671:     /*
 672: 	**  Deal with the special case of mail handled through an IPC
 673: 	**  connection.
 674: 	**	In this case we don't actually fork.  We must be
 675: 	**	running SMTP for this to work.  We will return a
 676: 	**	zero pid to indicate that we are running IPC.
 677: 	**  We also handle a debug version that just talks to stdin/out.
 678: 	*/
 679: 
 680: #ifdef DEBUG
 681:     /* check for Local Person Communication -- not for mortals!!! */
 682:     if (strcmp(m->m_mailer, "[LPC]") == 0)
 683:     {
 684:         *pmfile = stdout;
 685:         *prfile = stdin;
 686:         return (0);
 687:     }
 688: #endif DEBUG
 689: 
 690:     if (strcmp(m->m_mailer, "[IPC]") == 0)
 691:     {
 692: #ifdef DAEMON
 693:         register int i;
 694:         register u_short port;
 695: 
 696:         if (!clever)
 697:             syserr("non-clever IPC");
 698:         if (pvp[2] != NULL)
 699:             port = atoi(pvp[2]);
 700:         else
 701:             port = 0;
 702:         i = makeconnection(pvp[1], port, pmfile, prfile);
 703:         if (i != EX_OK)
 704:         {
 705:             ExitStat = i;
 706:             return (-1);
 707:         }
 708:         else
 709:             return (0);
 710: #else DAEMON
 711:         syserr("openmailer: no IPC");
 712:         return (-1);
 713: #endif DAEMON
 714:     }
 715: 
 716:     /* create a pipe to shove the mail through */
 717:     if (pipe(mpvect) < 0)
 718:     {
 719:         syserr("openmailer: pipe (to mailer)");
 720:         return (-1);
 721:     }
 722: 
 723: #ifdef SMTP
 724:     /* if this mailer speaks smtp, create a return pipe */
 725:     if (clever && pipe(rpvect) < 0)
 726:     {
 727:         syserr("openmailer: pipe (from mailer)");
 728:         (void) close(mpvect[0]);
 729:         (void) close(mpvect[1]);
 730:         return (-1);
 731:     }
 732: #endif SMTP
 733: 
 734:     /*
 735: 	**  Actually fork the mailer process.
 736: 	**	DOFORK is clever about retrying.
 737: 	*/
 738: 
 739:     if (CurEnv->e_xfp != NULL)
 740:         (void) fflush(CurEnv->e_xfp);       /* for debugging */
 741:     (void) fflush(stdout);
 742:     DOFORK(XFORK);
 743:     /* pid is set by DOFORK */
 744:     if (pid < 0)
 745:     {
 746:         /* failure */
 747:         syserr("openmailer: cannot fork");
 748:         (void) close(mpvect[0]);
 749:         (void) close(mpvect[1]);
 750: #ifdef SMTP
 751:         if (clever)
 752:         {
 753:             (void) close(rpvect[0]);
 754:             (void) close(rpvect[1]);
 755:         }
 756: #endif SMTP
 757:         return (-1);
 758:     }
 759:     else if (pid == 0)
 760:     {
 761:         /* child -- set up input & exec mailer */
 762:         /* make diagnostic output be standard output */
 763:         (void) signal(SIGINT, SIG_IGN);
 764:         (void) signal(SIGHUP, SIG_IGN);
 765:         (void) signal(SIGTERM, SIG_DFL);
 766: 
 767:         /* arrange to filter standard & diag output of command */
 768:         if (clever)
 769:         {
 770:             (void) close(rpvect[0]);
 771:             (void) close(1);
 772:             (void) dup(rpvect[1]);
 773:             (void) close(rpvect[1]);
 774:         }
 775:         else if (OpMode == MD_SMTP || HoldErrs)
 776:         {
 777:             /* put mailer output in transcript */
 778:             (void) close(1);
 779:             (void) dup(fileno(CurEnv->e_xfp));
 780:         }
 781:         (void) close(2);
 782:         (void) dup(1);
 783: 
 784:         /* arrange to get standard input */
 785:         (void) close(mpvect[1]);
 786:         (void) close(0);
 787:         if (dup(mpvect[0]) < 0)
 788:         {
 789:             syserr("Cannot dup to zero!");
 790:             _exit(EX_OSERR);
 791:         }
 792:         (void) close(mpvect[0]);
 793:         if (!bitnset(M_RESTR, m->m_flags))
 794:         {
 795:             if (ctladdr->q_uid == 0)
 796:             {
 797:                 (void) setgid(DefGid);
 798:                 (void) setuid(DefUid);
 799:             }
 800:             else
 801:             {
 802:                 (void) setgid(ctladdr->q_gid);
 803:                 (void) setuid(ctladdr->q_uid);
 804:             }
 805:         }
 806: 
 807:         /*
 808: 		**  We have to be careful with vfork - we can't mung up the
 809: 		**  memory but we don't want the mailer to inherit any extra
 810: 		**  open files.  Chances are the mailer won't
 811: 		**  care about an extra file, but then again you never know.
 812: 		**  Actually, we would like to close(fileno(pwf)), but it's
 813: 		**  declared static so we can't.  But if we fclose(pwf), which
 814: 		**  is what endpwent does, it closes it in the parent too and
 815: 		**  the next getpwnam will be slower.  If you have a weird
 816: 		**  mailer that chokes on the extra file you should do the
 817: 		**  endpwent().			-MRH
 818: 		**
 819: 		**  Similar comments apply to log.  However, openlog is
 820: 		**  clever enough to set the FIOCLEX mode on the file,
 821: 		**  so it will be closed automatically on the exec.
 822: 		*/
 823: 
 824:         closeall();
 825: 
 826:         /* try to execute the mailer */
 827:         execv(m->m_mailer, pvp);
 828: 
 829:         /* syserr fails because log is closed */
 830:         /* syserr("Cannot exec %s", m->m_mailer); */
 831:         printf("Cannot exec '%s' errno=%d\n", m->m_mailer, errno);
 832:         (void) fflush(stdout);
 833:         _exit(EX_UNAVAILABLE);
 834:     }
 835: 
 836:     /*
 837: 	**  Set up return value.
 838: 	*/
 839: 
 840:     (void) close(mpvect[0]);
 841:     mfile = fdopen(mpvect[1], "w");
 842:     if (clever)
 843:     {
 844:         (void) close(rpvect[1]);
 845:         rfile = fdopen(rpvect[0], "r");
 846:     }
 847: 
 848:     *pmfile = mfile;
 849:     *prfile = rfile;
 850: 
 851:     return (pid);
 852: }
 853: /*
 854: **  GIVERESPONSE -- Interpret an error response from a mailer
 855: **
 856: **	Parameters:
 857: **		stat -- the status code from the mailer (high byte
 858: **			only; core dumps must have been taken care of
 859: **			already).
 860: **		m -- the mailer descriptor for this mailer.
 861: **
 862: **	Returns:
 863: **		none.
 864: **
 865: **	Side Effects:
 866: **		Errors may be incremented.
 867: **		ExitStat may be set.
 868: */
 869: 
 870: giveresponse(stat, m, e)
 871:     int stat;
 872:     register MAILER *m;
 873:     ENVELOPE *e;
 874: {
 875:     register char *statmsg;
 876:     extern char *SysExMsg[];
 877:     register int i;
 878:     extern int N_SysEx;
 879:     char buf[MAXLINE];
 880: 
 881: #ifdef lint
 882:     if (m == NULL)
 883:         return;
 884: #endif lint
 885: 
 886:     /*
 887: 	**  Compute status message from code.
 888: 	*/
 889: 
 890:     i = stat - EX__BASE;
 891:     if (stat == 0)
 892:         statmsg = "250 Sent";
 893:     else if (i < 0 || i > N_SysEx)
 894:     {
 895:         (void) sprintf(buf, "554 unknown mailer error %d", stat);
 896:         stat = EX_UNAVAILABLE;
 897:         statmsg = buf;
 898:     }
 899:     else if (stat == EX_TEMPFAIL)
 900:     {
 901:         extern char *sys_errlist[];
 902:         extern int sys_nerr;
 903: 
 904:         (void) strcpy(buf, SysExMsg[i]);
 905:         if (errno != 0)
 906:         {
 907:             (void) strcat(buf, ": ");
 908:             if (errno > 0 && errno < sys_nerr)
 909:                 (void) strcat(buf, sys_errlist[errno]);
 910:             else
 911:             {
 912:                 char xbuf[30];
 913: 
 914:                 (void) sprintf(xbuf, "Error %d", errno);
 915:                 (void) strcat(buf, xbuf);
 916:             }
 917:         }
 918:         statmsg = buf;
 919:     }
 920:     else
 921:         statmsg = SysExMsg[i];
 922: 
 923:     /*
 924: 	**  Print the message as appropriate
 925: 	*/
 926: 
 927:     if (stat == EX_OK || stat == EX_TEMPFAIL)
 928:         message(Arpa_Info, &statmsg[4]);
 929:     else
 930:     {
 931:         Errors++;
 932:         usrerr(statmsg);
 933:     }
 934: 
 935:     /*
 936: 	**  Final cleanup.
 937: 	**	Log a record of the transaction.  Compute the new
 938: 	**	ExitStat -- if we already had an error, stick with
 939: 	**	that.
 940: 	*/
 941: 
 942:     if (LogLevel > ((stat == 0 || stat == EX_TEMPFAIL) ? 3 : 2))
 943:         logdelivery(&statmsg[4]);
 944: 
 945:     if (stat != EX_TEMPFAIL)
 946:         setstat(stat);
 947:     if (stat != EX_OK)
 948:     {
 949:         if (e->e_message != NULL)
 950:             free(e->e_message);
 951:         e->e_message = newstr(&statmsg[4]);
 952:     }
 953:     errno = 0;
 954: }
 955: /*
 956: **  LOGDELIVERY -- log the delivery in the system log
 957: **
 958: **	Parameters:
 959: **		stat -- the message to print for the status
 960: **
 961: **	Returns:
 962: **		none
 963: **
 964: **	Side Effects:
 965: **		none
 966: */
 967: 
 968: logdelivery(stat)
 969:     char *stat;
 970: {
 971:     extern char *pintvl();
 972: 
 973: # ifdef LOG
 974:     syslog(LOG_INFO, "%s: to=%s, delay=%s, stat=%s", CurEnv->e_id,
 975:            CurEnv->e_to, pintvl(curtime() - CurEnv->e_ctime, TRUE), stat);
 976: # endif LOG
 977: }
 978: /*
 979: **  PUTFROMLINE -- output a UNIX-style from line (or whatever)
 980: **
 981: **	This can be made an arbitrary message separator by changing $l
 982: **
 983: **	One of the ugliest hacks seen by human eyes is
 984: **	contained herein: UUCP wants those stupid
 985: **	"emote from <host>" lines.  Why oh why does a
 986: **	well-meaning programmer such as myself have to
 987: **	deal with this kind of antique garbage????
 988: **
 989: **	Parameters:
 990: **		fp -- the file to output to.
 991: **		m -- the mailer describing this entry.
 992: **
 993: **	Returns:
 994: **		none
 995: **
 996: **	Side Effects:
 997: **		outputs some text to fp.
 998: */
 999: 
1000: putfromline(fp, m)
1001:     register FILE *fp;
1002:     register MAILER *m;
1003: {
1004:     char *template = "$l\n";
1005:     char buf[MAXLINE];
1006: 
1007:     if (bitnset(M_NHDR, m->m_flags))
1008:         return;
1009: 
1010: # ifdef UGLYUUCP
1011:     if (bitnset(M_UGLYUUCP, m->m_flags))
1012:     {
1013:         char *bang;
1014:         char xbuf[MAXLINE];
1015: 
1016:         expand("$g", buf, &buf[sizeof buf - 1], CurEnv);
1017:         bang = index(buf, '!');
1018:         if (bang == NULL)
1019:             syserr("No ! in UUCP! (%s)", buf);
1020:         else
1021:         {
1022:             *bang++ = '\0';
1023:             (void) sprintf(xbuf, "From %s  $d remote from %s\n", bang, buf);
1024:             template = xbuf;
1025:         }
1026:     }
1027: # endif UGLYUUCP
1028:     expand(template, buf, &buf[sizeof buf - 1], CurEnv);
1029:     putline(buf, fp, m);
1030: }
1031: /*
1032: **  PUTBODY -- put the body of a message.
1033: **
1034: **	Parameters:
1035: **		fp -- file to output onto.
1036: **		m -- a mailer descriptor to control output format.
1037: **		e -- the envelope to put out.
1038: **
1039: **	Returns:
1040: **		none.
1041: **
1042: **	Side Effects:
1043: **		The message is written onto fp.
1044: */
1045: 
1046: putbody(fp, m, e)
1047:     FILE *fp;
1048:     MAILER *m;
1049:     register ENVELOPE *e;
1050: {
1051:     char buf[MAXLINE];
1052: 
1053:     /*
1054: 	**  Output the body of the message
1055: 	*/
1056: 
1057:     if (e->e_dfp == NULL)
1058:     {
1059:         if (e->e_df != NULL)
1060:         {
1061:             e->e_dfp = fopen(e->e_df, "r");
1062:             if (e->e_dfp == NULL)
1063:                 syserr("Cannot open %s", e->e_df);
1064:         }
1065:         else
1066:             putline("<<< No Message Collected >>>", fp, m);
1067:     }
1068:     if (e->e_dfp != NULL)
1069:     {
1070:         rewind(e->e_dfp);
1071:         while (!ferror(fp) && fgets(buf, sizeof buf, e->e_dfp) != NULL)
1072:             putline(buf, fp, m);
1073: 
1074:         if (ferror(e->e_dfp))
1075:         {
1076:             syserr("putbody: read error");
1077:             ExitStat = EX_IOERR;
1078:         }
1079:     }
1080: 
1081:     (void) fflush(fp);
1082:     if (ferror(fp) && errno != EPIPE)
1083:     {
1084:         syserr("putbody: write error");
1085:         ExitStat = EX_IOERR;
1086:     }
1087:     errno = 0;
1088: }
1089: /*
1090: **  MAILFILE -- Send a message to a file.
1091: **
1092: **	If the file has the setuid/setgid bits set, but NO execute
1093: **	bits, sendmail will try to become the owner of that file
1094: **	rather than the real user.  Obviously, this only works if
1095: **	sendmail runs as root.
1096: **
1097: **	This could be done as a subordinate mailer, except that it
1098: **	is used implicitly to save messages in ~/dead.letter.  We
1099: **	view this as being sufficiently important as to include it
1100: **	here.  For example, if the system is dying, we shouldn't have
1101: **	to create another process plus some pipes to save the message.
1102: **
1103: **	Parameters:
1104: **		filename -- the name of the file to send to.
1105: **		ctladdr -- the controlling address header -- includes
1106: **			the userid/groupid to be when sending.
1107: **
1108: **	Returns:
1109: **		The exit code associated with the operation.
1110: **
1111: **	Side Effects:
1112: **		none.
1113: */
1114: 
1115: mailfile(filename, ctladdr)
1116:     char *filename;
1117:     ADDRESS *ctladdr;
1118: {
1119:     register FILE *f;
1120:     register int pid;
1121: 
1122:     /*
1123: 	**  Fork so we can change permissions here.
1124: 	**	Note that we MUST use fork, not vfork, because of
1125: 	**	the complications of calling subroutines, etc.
1126: 	*/
1127: 
1128:     DOFORK(fork);
1129: 
1130:     if (pid < 0)
1131:         return (EX_OSERR);
1132:     else if (pid == 0)
1133:     {
1134:         /* child -- actually write to file */
1135:         struct stat stb;
1136: 
1137:         (void) signal(SIGINT, SIG_DFL);
1138:         (void) signal(SIGHUP, SIG_DFL);
1139:         (void) signal(SIGTERM, SIG_DFL);
1140:         umask(OldUmask);
1141:         if (stat(filename, &stb) < 0)
1142:         {
1143:             errno = 0;
1144:             stb.st_mode = 0666;
1145:         }
1146:         if (bitset(0111, stb.st_mode))
1147:             exit(EX_CANTCREAT);
1148:         if (ctladdr == NULL)
1149:             ctladdr = &CurEnv->e_from;
1150:         if (!bitset(S_ISGID, stb.st_mode) || setgid(stb.st_gid) < 0)
1151:         {
1152:             if (ctladdr->q_uid == 0)
1153:                 (void) setgid(DefGid);
1154:             else
1155:                 (void) setgid(ctladdr->q_gid);
1156:         }
1157:         if (!bitset(S_ISUID, stb.st_mode) || setuid(stb.st_uid) < 0)
1158:         {
1159:             if (ctladdr->q_uid == 0)
1160:                 (void) setuid(DefUid);
1161:             else
1162:                 (void) setuid(ctladdr->q_uid);
1163:         }
1164:         f = dfopen(filename, "a");
1165:         if (f == NULL)
1166:             exit(EX_CANTCREAT);
1167: 
1168:         putfromline(f, ProgMailer);
1169:         (*CurEnv->e_puthdr)(f, ProgMailer, CurEnv);
1170:         putline("\n", f, ProgMailer);
1171:         (*CurEnv->e_putbody)(f, ProgMailer, CurEnv);
1172:         putline("\n", f, ProgMailer);
1173:         (void) fclose(f);
1174:         (void) fflush(stdout);
1175: 
1176:         /* reset ISUID & ISGID bits for paranoid systems */
1177:         (void) chmod(filename, (int) stb.st_mode);
1178:         exit(EX_OK);
1179:         /*NOTREACHED*/
1180:     }
1181:     else
1182:     {
1183:         /* parent -- wait for exit status */
1184:         int st;
1185: 
1186:         st = waitfor(pid);
1187:         if ((st & 0377) != 0)
1188:             return (EX_UNAVAILABLE);
1189:         else
1190:             return ((st >> 8) & 0377);
1191:     }
1192: }
1193: /*
1194: **  SENDALL -- actually send all the messages.
1195: **
1196: **	Parameters:
1197: **		e -- the envelope to send.
1198: **		mode -- the delivery mode to use.  If SM_DEFAULT, use
1199: **			the current SendMode.
1200: **
1201: **	Returns:
1202: **		none.
1203: **
1204: **	Side Effects:
1205: **		Scans the send lists and sends everything it finds.
1206: **		Delivers any appropriate error messages.
1207: **		If we are running in a non-interactive mode, takes the
1208: **			appropriate action.
1209: */
1210: 
1211: sendall(e, mode)
1212:     ENVELOPE *e;
1213:     char mode;
1214: {
1215:     register ADDRESS *q;
1216:     bool oldverbose;
1217:     int pid;
1218: 
1219:     /* determine actual delivery mode */
1220:     if (mode == SM_DEFAULT)
1221:     {
1222:         extern int QueueLA;
1223: 
1224:         if (getla() > QueueLA)
1225:             mode = SM_QUEUE;
1226:         else
1227:             mode = SendMode;
1228:     }
1229: 
1230: #ifdef DEBUG
1231:     if (tTd(13, 1))
1232:     {
1233:         printf("\nSENDALL: mode %c, sendqueue:\n", mode);
1234:         printaddr(e->e_sendqueue, TRUE);
1235:     }
1236: #endif DEBUG
1237: 
1238:     /*
1239: 	**  Do any preprocessing necessary for the mode we are running.
1240: 	**	Check to make sure the hop count is reasonable.
1241: 	**	Delete sends to the sender in mailing lists.
1242: 	*/
1243: 
1244:     CurEnv = e;
1245: 
1246:     if (e->e_hopcount > MAXHOP)
1247:     {
1248:         syserr("sendall: too many hops (%d max)", MAXHOP);
1249:         return;
1250:     }
1251: 
1252:     if (!MeToo)
1253:     {
1254:         extern ADDRESS *recipient();
1255: 
1256:         e->e_from.q_flags |= QDONTSEND;
1257:         (void) recipient(&e->e_from, &e->e_sendqueue);
1258:     }
1259: 
1260: # ifdef QUEUE
1261:     if ((mode == SM_QUEUE || mode == SM_FORK ||
1262:          (mode != SM_VERIFY && SuperSafe)) &&
1263:         !bitset(EF_INQUEUE, e->e_flags))
1264:         queueup(e, TRUE, mode == SM_QUEUE);
1265: #endif QUEUE
1266: 
1267:     oldverbose = Verbose;
1268:     switch (mode)
1269:     {
1270:       case SM_VERIFY:
1271:         Verbose = TRUE;
1272:         break;
1273: 
1274:       case SM_QUEUE:
1275:         e->e_flags |= EF_INQUEUE|EF_KEEPQUEUE;
1276:         return;
1277: 
1278:       case SM_FORK:
1279:         if (e->e_xfp != NULL)
1280:             (void) fflush(e->e_xfp);
1281:         pid = fork();
1282:         if (pid < 0)
1283:         {
1284:             mode = SM_DELIVER;
1285:             break;
1286:         }
1287:         else if (pid > 0)
1288:         {
1289:             /* be sure we leave the temp files to our child */
1290:             e->e_id = e->e_df = NULL;
1291:             return;
1292:         }
1293: 
1294:         /* double fork to avoid zombies */
1295:         if (fork() > 0)
1296:             exit(EX_OK);
1297: 
1298:         /* be sure we are immune from the terminal */
1299:         disconnect(FALSE);
1300: 
1301:         break;
1302:     }
1303: 
1304:     /*
1305: 	**  Run through the list and send everything.
1306: 	*/
1307: 
1308:     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
1309:     {
1310:         if (mode == SM_VERIFY)
1311:         {
1312:             e->e_to = q->q_paddr;
1313:             if (!bitset(QDONTSEND|QBADADDR, q->q_flags))
1314:                 message(Arpa_Info, "deliverable");
1315:         }
1316:         else
1317:             (void) deliver(e, q);
1318:     }
1319:     Verbose = oldverbose;
1320: 
1321:     /*
1322: 	**  Now run through and check for errors.
1323: 	*/
1324: 
1325:     if (mode == SM_VERIFY)
1326:         return;
1327: 
1328:     for (q = e->e_sendqueue; q != NULL; q = q->q_next)
1329:     {
1330:         register ADDRESS *qq;
1331: 
1332: # ifdef DEBUG
1333:         if (tTd(13, 3))
1334:         {
1335:             printf("Checking ");
1336:             printaddr(q, FALSE);
1337:         }
1338: # endif DEBUG
1339: 
1340:         /* only send errors if the message failed */
1341:         if (!bitset(QBADADDR, q->q_flags))
1342:             continue;
1343: 
1344:         /* we have an address that failed -- find the parent */
1345:         for (qq = q; qq != NULL; qq = qq->q_alias)
1346:         {
1347:             char obuf[MAXNAME + 6];
1348:             extern char *aliaslookup();
1349: 
1350:             /* we can only have owners for local addresses */
1351:             if (!bitnset(M_LOCAL, qq->q_mailer->m_flags))
1352:                 continue;
1353: 
1354:             /* see if the owner list exists */
1355:             (void) strcpy(obuf, "owner-");
1356:             if (strncmp(qq->q_user, "owner-", 6) == 0)
1357:                 (void) strcat(obuf, "owner");
1358:             else
1359:                 (void) strcat(obuf, qq->q_user);
1360:             if (aliaslookup(obuf) == NULL)
1361:                 continue;
1362: 
1363: # ifdef DEBUG
1364:             if (tTd(13, 4))
1365:                 printf("Errors to %s\n", obuf);
1366: # endif DEBUG
1367: 
1368:             /* owner list exists -- add it to the error queue */
1369:             sendtolist(obuf, (ADDRESS *) NULL, &e->e_errorqueue);
1370:             ErrorMode = EM_MAIL;
1371:             break;
1372:         }
1373: 
1374:         /* if we did not find an owner, send to the sender */
1375:         if (qq == NULL && bitset(QBADADDR, q->q_flags))
1376:             sendtolist(e->e_from.q_paddr, qq, &e->e_errorqueue);
1377:     }
1378: 
1379:     if (mode == SM_FORK)
1380:         finis();
1381: }

Defined functions

deliver defined in line 30; used 2 times
endmailer defined in line 597; used 2 times
giveresponse defined in line 870; never used
logdelivery defined in line 968; used 3 times
mailfile defined in line 1115; used 1 times
markfailure defined in line 429; used 2 times
openmailer defined in line 647; used 2 times
putfromline defined in line 1000; used 2 times
sendoff defined in line 538; used 1 times

Defined macros

DOFORK defined in line 487; used 3 times
NFORKTRIES defined in line 480; used 2 times
XFORK defined in line 484; used 1 times
Last modified: 1983-12-11
Generated: 2016-12-26
Generated by src2html V0.67
page hit count: 3233
Valid CSS Valid XHTML 1.0 Strict