122716Sdist /*
234921Sbostic  * Copyright (c) 1983 Eric P. Allman
333731Sbostic  * Copyright (c) 1988 Regents of the University of California.
433731Sbostic  * All rights reserved.
533731Sbostic  *
642831Sbostic  * %sccs.include.redist.c%
733731Sbostic  */
822716Sdist 
933731Sbostic # include "sendmail.h"
1022716Sdist 
1133731Sbostic #ifndef lint
1233731Sbostic #ifdef SMTP
13*57734Seric static char sccsid[] = "@(#)usersmtp.c	6.4 (Berkeley) 01/28/93 (with SMTP)";
1433731Sbostic #else
15*57734Seric static char sccsid[] = "@(#)usersmtp.c	6.4 (Berkeley) 01/28/93 (without SMTP)";
1633731Sbostic #endif
1733731Sbostic #endif /* not lint */
1833731Sbostic 
194684Seric # include <sysexits.h>
2021065Seric # include <errno.h>
214684Seric 
2233731Sbostic # ifdef SMTP
234684Seric 
244684Seric /*
259391Seric **  USERSMTP -- run SMTP protocol from the user end.
269391Seric **
279391Seric **	This protocol is described in RFC821.
289391Seric */
299391Seric 
309391Seric #define REPLYTYPE(r)	((r) / 100)		/* first digit of reply code */
319391Seric #define REPLYCLASS(r)	(((r) / 10) % 10)	/* second digit of reply code */
329391Seric #define SMTPCLOSING	421			/* "Service Shutting Down" */
339391Seric 
3414900Seric char	SmtpMsgBuffer[MAXLINE];		/* buffer for commands */
3510054Seric char	SmtpReplyBuffer[MAXLINE];	/* buffer for replies */
3621065Seric char	SmtpError[MAXLINE] = "";	/* save failure error messages */
3710054Seric int	SmtpPid;			/* pid of mailer */
389391Seric /*
394865Seric **  SMTPINIT -- initialize SMTP.
404684Seric **
414865Seric **	Opens the connection and sends the initial protocol.
424684Seric **
434684Seric **	Parameters:
444865Seric **		m -- mailer to create connection to.
454865Seric **		pvp -- pointer to parameter vector to pass to
464865Seric **			the mailer.
474684Seric **
484684Seric **	Returns:
4954967Seric **		none.
504684Seric **
514684Seric **	Side Effects:
524865Seric **		creates connection and sends initial protocol.
534684Seric */
544684Seric 
5554967Seric smtpinit(m, mci, e)
564865Seric 	struct mailer *m;
5754967Seric 	register MCI *mci;
5853751Seric 	ENVELOPE *e;
594684Seric {
604865Seric 	register int r;
6114886Seric 	EVENT *gte;
6252107Seric 	extern STAB *stab();
6354967Seric 	extern MCI *openmailer();
644684Seric 
6557379Seric 	if (tTd(17, 1))
6657379Seric 	{
6757379Seric 		printf("smtpinit ");
6857379Seric 		mci_dump(mci);
6957379Seric 	}
7057379Seric 
714865Seric 	/*
724865Seric 	**  Open the connection to the mailer.
734865Seric 	*/
744684Seric 
7521065Seric 	SmtpError[0] = '\0';
7657379Seric 	CurHostName = mci->mci_host;		/* XXX UGLY XXX */
7754967Seric 	switch (mci->mci_state)
786051Seric 	{
7954967Seric 	  case MCIS_ACTIVE:
8054967Seric 		/* need to clear old information */
8154967Seric 		smtprset(m, mci, e);
82*57734Seric 		/* fall through */
8315139Seric 
8454967Seric 	  case MCIS_OPEN:
8554967Seric 		return;
8654967Seric 
8754967Seric 	  case MCIS_ERROR:
8854967Seric 	  case MCIS_SSD:
8954967Seric 		/* shouldn't happen */
9054967Seric 		smtpquit(m, mci, e);
91*57734Seric 		/* fall through */
9254967Seric 
9354967Seric 	  case MCIS_CLOSED:
9454967Seric 		syserr("smtpinit: state CLOSED");
9554967Seric 		return;
9654967Seric 
9754967Seric 	  case MCIS_OPENING:
9854967Seric 		break;
996051Seric 	}
1004796Seric 
10157379Seric 	SmtpPhase = mci->mci_phase = "user open";
10254967Seric 	mci->mci_state = MCIS_OPENING;
10354967Seric 
1044865Seric 	/*
1054865Seric 	**  Get the greeting message.
10614913Seric 	**	This should appear spontaneously.  Give it five minutes to
10714886Seric 	**	happen.
1084865Seric 	*/
1094797Seric 
11057379Seric 	SmtpPhase = mci->mci_phase = "greeting wait";
11153751Seric 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
11257379Seric 	r = reply(m, mci, e, (time_t) 300);
1138005Seric 	if (r < 0 || REPLYTYPE(r) != 2)
11452104Seric 		goto tempfail1;
1154684Seric 
1164865Seric 	/*
1174976Seric 	**  Send the HELO command.
1187963Seric 	**	My mother taught me to always introduce myself.
1194976Seric 	*/
1204976Seric 
12153751Seric 	smtpmessage("HELO %s", m, mci, MyHostName);
12257379Seric 	SmtpPhase = mci->mci_phase = "HELO wait";
12353751Seric 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
12457379Seric 	r = reply(m, mci, e, ReadTimeout);
1258005Seric 	if (r < 0)
12652104Seric 		goto tempfail1;
1278005Seric 	else if (REPLYTYPE(r) == 5)
12814913Seric 		goto unavailable;
1297963Seric 	else if (REPLYTYPE(r) != 2)
13052104Seric 		goto tempfail1;
1314976Seric 
1324976Seric 	/*
1339315Seric 	**  If this is expected to be another sendmail, send some internal
1349315Seric 	**  commands.
1359315Seric 	*/
1369315Seric 
13710688Seric 	if (bitnset(M_INTERNAL, m->m_flags))
1389315Seric 	{
1399315Seric 		/* tell it to be verbose */
14053751Seric 		smtpmessage("VERB", m, mci);
14157379Seric 		r = reply(m, mci, e, ReadTimeout);
1429315Seric 		if (r < 0)
14352104Seric 			goto tempfail2;
1449315Seric 	}
1459315Seric 
14653751Seric 	mci->mci_state = MCIS_OPEN;
14754967Seric 	return;
14853751Seric 
14953751Seric   tempfail1:
15053751Seric   tempfail2:
15153751Seric 	mci->mci_exitstat = EX_TEMPFAIL;
15257379Seric 	if (mci->mci_errno == 0)
15357379Seric 		mci->mci_errno = errno;
15457379Seric 	if (mci->mci_state != MCIS_CLOSED)
15557379Seric 		smtpquit(m, mci, e);
15654967Seric 	return;
15753751Seric 
15853751Seric   unavailable:
15953751Seric 	mci->mci_exitstat = EX_UNAVAILABLE;
16053751Seric 	mci->mci_errno = errno;
16153751Seric 	smtpquit(m, mci, e);
16254967Seric 	return;
16353751Seric }
16453751Seric 
16553751Seric smtpmailfrom(m, mci, e)
16653751Seric 	struct mailer *m;
16754967Seric 	MCI *mci;
16853751Seric 	ENVELOPE *e;
16953751Seric {
17053751Seric 	int r;
17153751Seric 	char buf[MAXNAME];
17253751Seric 
1739315Seric 	/*
1744865Seric 	**  Send the MAIL command.
1754865Seric 	**	Designates the sender.
1764865Seric 	*/
1774796Seric 
17853751Seric 	mci->mci_state = MCIS_ACTIVE;
17953751Seric 
18053751Seric 	expand("\001<", buf, &buf[sizeof buf - 1], e);
18153751Seric 	if (e->e_from.q_mailer == LocalMailer ||
18210688Seric 	    !bitnset(M_FROMPATH, m->m_flags))
1838436Seric 	{
18453751Seric 		smtpmessage("MAIL From:<%s>", m, mci, buf);
1858436Seric 	}
1868436Seric 	else
1878436Seric 	{
18853751Seric 		smtpmessage("MAIL From:<@%s%c%s>", m, mci, MyHostName,
18910308Seric 			buf[0] == '@' ? ',' : ':', buf);
1908436Seric 	}
19157379Seric 	SmtpPhase = mci->mci_phase = "MAIL wait";
19253751Seric 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
19357379Seric 	r = reply(m, mci, e, ReadTimeout);
1948005Seric 	if (r < 0 || REPLYTYPE(r) == 4)
19553751Seric 	{
19653751Seric 		mci->mci_exitstat = EX_TEMPFAIL;
19753751Seric 		mci->mci_errno = errno;
19853751Seric 		smtpquit(m, mci, e);
19953751Seric 		return EX_TEMPFAIL;
20053751Seric 	}
2017963Seric 	else if (r == 250)
20253751Seric 	{
20353751Seric 		mci->mci_exitstat = EX_OK;
20453751Seric 		return EX_OK;
20553751Seric 	}
2067963Seric 	else if (r == 552)
20753751Seric 	{
20853751Seric 		/* signal service unavailable */
20953751Seric 		mci->mci_exitstat = EX_UNAVAILABLE;
21053751Seric 		smtpquit(m, mci, e);
21153751Seric 		return EX_UNAVAILABLE;
21253751Seric 	}
21314913Seric 
21414913Seric 	/* protocol error -- close up */
21553751Seric 	smtpquit(m, mci, e);
21653751Seric 	mci->mci_exitstat = EX_PROTOCOL;
21753751Seric 	return EX_PROTOCOL;
2184684Seric }
2194684Seric /*
2204976Seric **  SMTPRCPT -- designate recipient.
2214797Seric **
2224797Seric **	Parameters:
2234865Seric **		to -- address of recipient.
22410175Seric **		m -- the mailer we are sending to.
22557379Seric **		mci -- the connection info for this transaction.
22657379Seric **		e -- the envelope for this transaction.
2274797Seric **
2284797Seric **	Returns:
2294865Seric **		exit status corresponding to recipient status.
2304797Seric **
2314797Seric **	Side Effects:
2324865Seric **		Sends the mail via SMTP.
2334797Seric */
2344797Seric 
23553751Seric smtprcpt(to, m, mci, e)
2364865Seric 	ADDRESS *to;
23710175Seric 	register MAILER *m;
23854967Seric 	MCI *mci;
23953751Seric 	ENVELOPE *e;
2404797Seric {
2414797Seric 	register int r;
2424797Seric 
24353751Seric 	smtpmessage("RCPT To:<%s>", m, mci, to->q_user);
2444865Seric 
24557379Seric 	SmtpPhase = mci->mci_phase = "RCPT wait";
24653751Seric 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
24757379Seric 	r = reply(m, mci, e, ReadTimeout);
2488005Seric 	if (r < 0 || REPLYTYPE(r) == 4)
2494865Seric 		return (EX_TEMPFAIL);
2507963Seric 	else if (REPLYTYPE(r) == 2)
2517963Seric 		return (EX_OK);
2527964Seric 	else if (r == 550 || r == 551 || r == 553)
2537964Seric 		return (EX_NOUSER);
2547964Seric 	else if (r == 552 || r == 554)
2557964Seric 		return (EX_UNAVAILABLE);
2567964Seric 	return (EX_PROTOCOL);
2574797Seric }
2584797Seric /*
25910175Seric **  SMTPDATA -- send the data and clean up the transaction.
2604684Seric **
2614684Seric **	Parameters:
2624865Seric **		m -- mailer being sent to.
2636980Seric **		e -- the envelope for this message.
2644684Seric **
2654684Seric **	Returns:
2664976Seric **		exit status corresponding to DATA command.
2674684Seric **
2684684Seric **	Side Effects:
2694865Seric **		none.
2704684Seric */
2714684Seric 
27253740Seric smtpdata(m, mci, e)
2734865Seric 	struct mailer *m;
27454967Seric 	register MCI *mci;
2756980Seric 	register ENVELOPE *e;
2764684Seric {
2774684Seric 	register int r;
2784684Seric 
2794797Seric 	/*
2804797Seric 	**  Send the data.
28110175Seric 	**	First send the command and check that it is ok.
28210175Seric 	**	Then send the data.
28310175Seric 	**	Follow it up with a dot to terminate.
28410175Seric 	**	Finally get the results of the transaction.
2854797Seric 	*/
2864797Seric 
28710175Seric 	/* send the command and check ok to proceed */
28853751Seric 	smtpmessage("DATA", m, mci);
28957379Seric 	SmtpPhase = mci->mci_phase = "DATA wait";
29053751Seric 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
29157379Seric 	r = reply(m, mci, e, ReadTimeout);
2928005Seric 	if (r < 0 || REPLYTYPE(r) == 4)
2934797Seric 		return (EX_TEMPFAIL);
2947963Seric 	else if (r == 554)
2957963Seric 		return (EX_UNAVAILABLE);
2967963Seric 	else if (r != 354)
2977964Seric 		return (EX_PROTOCOL);
29810175Seric 
29910175Seric 	/* now output the actual message */
30053751Seric 	(*e->e_puthdr)(mci->mci_out, m, e);
30153740Seric 	putline("\n", mci->mci_out, m);
30253751Seric 	(*e->e_putbody)(mci->mci_out, m, e);
30310175Seric 
30410175Seric 	/* terminate the message */
30553740Seric 	fprintf(mci->mci_out, ".%s", m->m_eol);
30610215Seric 	if (Verbose && !HoldErrs)
30710215Seric 		nmessage(Arpa_Info, ">>> .");
30810175Seric 
30910175Seric 	/* check for the results of the transaction */
31057379Seric 	SmtpPhase = mci->mci_phase = "result wait";
31153751Seric 	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);
31257379Seric 	r = reply(m, mci, e, ReadTimeout);
31353751Seric 	if (r < 0)
3144797Seric 		return (EX_TEMPFAIL);
31553751Seric 	mci->mci_state = MCIS_OPEN;
31653751Seric 	if (REPLYTYPE(r) == 4)
31753751Seric 		return (EX_TEMPFAIL);
3187963Seric 	else if (r == 250)
3197963Seric 		return (EX_OK);
3207963Seric 	else if (r == 552 || r == 554)
3217963Seric 		return (EX_UNAVAILABLE);
3227964Seric 	return (EX_PROTOCOL);
3234684Seric }
3244684Seric /*
3254865Seric **  SMTPQUIT -- close the SMTP connection.
3264865Seric **
3274865Seric **	Parameters:
32815535Seric **		m -- a pointer to the mailer.
3294865Seric **
3304865Seric **	Returns:
3314865Seric **		none.
3324865Seric **
3334865Seric **	Side Effects:
3344865Seric **		sends the final protocol and closes the connection.
3354865Seric */
3364865Seric 
33753751Seric smtpquit(m, mci, e)
33853751Seric 	register MAILER *m;
33954967Seric 	register MCI *mci;
34053751Seric 	ENVELOPE *e;
3414865Seric {
3429391Seric 	int i;
3434865Seric 
34454967Seric 	/* send the quit message if we haven't gotten I/O error */
34553751Seric 	if (mci->mci_state != MCIS_ERROR)
3469391Seric 	{
34753751Seric 		smtpmessage("QUIT", m, mci);
34857379Seric 		(void) reply(m, mci, e, ReadTimeout);
34953740Seric 		if (mci->mci_state == MCIS_CLOSED)
35010159Seric 			return;
3519391Seric 	}
3529391Seric 
35352676Seric 	/* now actually close the connection and pick up the zombie */
35452676Seric 	i = endmailer(mci, m->m_argv[0]);
3559391Seric 	if (i != EX_OK)
35615535Seric 		syserr("smtpquit %s: stat %d", m->m_argv[0], i);
3574865Seric }
3584865Seric /*
35954967Seric **  SMTPRSET -- send a RSET (reset) command
36054967Seric */
36154967Seric 
36254967Seric smtprset(m, mci, e)
36354967Seric 	register MAILER *m;
36454967Seric 	register MCI *mci;
36554967Seric 	ENVELOPE *e;
36654967Seric {
36754967Seric 	int r;
36854967Seric 
36954967Seric 	smtpmessage("RSET", m, mci);
370*57734Seric 	r = reply(m, mci, e, (time_t) 300);
371*57734Seric 	if (r < 0)
372*57734Seric 		mci->mci_state = MCIS_ERROR;
37354967Seric 	else if (REPLYTYPE(r) == 2)
374*57734Seric 	{
375*57734Seric 		mci->mci_state = MCIS_OPEN;
376*57734Seric 		return;
377*57734Seric 	}
378*57734Seric 	smtpquit(m, mci, e);
37954967Seric }
38054967Seric /*
38154967Seric **  SMTPNOOP -- send a NOOP (no operation) command to check the connection state
38254967Seric */
38354967Seric 
38454967Seric smtpnoop(mci)
38554967Seric 	register MCI *mci;
38654967Seric {
38754967Seric 	int r;
38854967Seric 	MAILER *m = mci->mci_mailer;
38954967Seric 	extern ENVELOPE BlankEnvelope;
39054967Seric 	ENVELOPE *e = &BlankEnvelope;
39154967Seric 
39254967Seric 	smtpmessage("NOOP", m, mci);
39357379Seric 	r = reply(m, mci, e, ReadTimeout);
39454967Seric 	if (REPLYTYPE(r) != 2)
39554967Seric 		smtpquit(m, mci, e);
39654967Seric 	return r;
39754967Seric }
39854967Seric /*
3994684Seric **  REPLY -- read arpanet reply
4004684Seric **
4014684Seric **	Parameters:
40210175Seric **		m -- the mailer we are reading the reply from.
40357379Seric **		mci -- the mailer connection info structure.
40457379Seric **		e -- the current envelope.
40557379Seric **		timeout -- the timeout for reads.
4064684Seric **
4074684Seric **	Returns:
4084684Seric **		reply code it reads.
4094684Seric **
4104684Seric **	Side Effects:
4114684Seric **		flushes the mail file.
4124684Seric */
4134684Seric 
41457379Seric reply(m, mci, e, timeout)
41553751Seric 	MAILER *m;
41654967Seric 	MCI *mci;
41753751Seric 	ENVELOPE *e;
4184684Seric {
41957379Seric 	if (mci->mci_out != NULL)
42057379Seric 		(void) fflush(mci->mci_out);
4214684Seric 
4227677Seric 	if (tTd(18, 1))
4234796Seric 		printf("reply\n");
4244796Seric 
4257356Seric 	/*
4267356Seric 	**  Read the input line, being careful not to hang.
4277356Seric 	*/
4287356Seric 
4294684Seric 	for (;;)
4304684Seric 	{
4314684Seric 		register int r;
4327356Seric 		register char *p;
43353751Seric 		extern time_t curtime();
4344684Seric 
4357685Seric 		/* actually do the read */
43653751Seric 		if (e->e_xfp != NULL)
43753751Seric 			(void) fflush(e->e_xfp);	/* for debugging */
4387356Seric 
43910054Seric 		/* if we are in the process of closing just give the code */
44053740Seric 		if (mci->mci_state == MCIS_CLOSED)
44110054Seric 			return (SMTPCLOSING);
44210054Seric 
44310054Seric 		/* get the line from the other side */
44457379Seric 		p = sfgets(SmtpReplyBuffer, sizeof SmtpReplyBuffer, mci->mci_in,
44557379Seric 			   timeout);
44653751Seric 		mci->mci_lastuse = curtime();
44753751Seric 
44810054Seric 		if (p == NULL)
44910131Seric 		{
45010148Seric 			extern char MsgBuf[];		/* err.c */
45110148Seric 			extern char Arpa_TSyserr[];	/* conf.c */
45210148Seric 
45321065Seric 			/* if the remote end closed early, fake an error */
45421065Seric 			if (errno == 0)
45521065Seric # ifdef ECONNRESET
45621065Seric 				errno = ECONNRESET;
45756795Seric # else /* ECONNRESET */
45821065Seric 				errno = EPIPE;
45956795Seric # endif /* ECONNRESET */
46021065Seric 
46157379Seric 			mci->mci_errno = errno;
46257642Seric 			mci->mci_exitstat = EX_TEMPFAIL;
46357642Seric 			message(Arpa_TSyserr, "%s: reply: read error from %s",
46457642Seric 				e->e_id == NULL ? "NOQUEUE" : e->e_id,
46557203Seric 				mci->mci_host);
46610420Seric 			/* if debugging, pause so we can see state */
46710420Seric 			if (tTd(18, 100))
46810420Seric 				pause();
46910148Seric # ifdef LOG
47057203Seric 			if (LogLevel > 0)
47157203Seric 				syslog(LOG_INFO, "%s", &MsgBuf[4]);
47256795Seric # endif /* LOG */
47354967Seric 			mci->mci_state = MCIS_ERROR;
47453751Seric 			smtpquit(m, mci, e);
47510054Seric 			return (-1);
47610131Seric 		}
47710054Seric 		fixcrlf(SmtpReplyBuffer, TRUE);
47810054Seric 
47956795Seric 		if (e->e_xfp != NULL && strchr("45", SmtpReplyBuffer[0]) != NULL)
48014900Seric 		{
48114900Seric 			/* serious error -- log the previous command */
48214900Seric 			if (SmtpMsgBuffer[0] != '\0')
48353751Seric 				fprintf(e->e_xfp, ">>> %s\n", SmtpMsgBuffer);
48414900Seric 			SmtpMsgBuffer[0] = '\0';
48514900Seric 
48614900Seric 			/* now log the message as from the other side */
48753751Seric 			fprintf(e->e_xfp, "<<< %s\n", SmtpReplyBuffer);
48814900Seric 		}
48914900Seric 
49014900Seric 		/* display the input for verbose mode */
4917229Seric 		if (Verbose && !HoldErrs)
4929391Seric 			nmessage(Arpa_Info, "%s", SmtpReplyBuffer);
4937356Seric 
4947356Seric 		/* if continuation is required, we can go on */
4959391Seric 		if (SmtpReplyBuffer[3] == '-' || !isdigit(SmtpReplyBuffer[0]))
4964684Seric 			continue;
4977356Seric 
4987356Seric 		/* decode the reply code */
4999391Seric 		r = atoi(SmtpReplyBuffer);
5007356Seric 
5017356Seric 		/* extra semantics: 0xx codes are "informational" */
5024684Seric 		if (r < 100)
5034684Seric 			continue;
5047356Seric 
5059391Seric 		/* reply code 421 is "Service Shutting Down" */
50653740Seric 		if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD)
5079391Seric 		{
50810054Seric 			/* send the quit protocol */
50953740Seric 			mci->mci_state = MCIS_SSD;
51053751Seric 			smtpquit(m, mci, e);
5119391Seric 		}
5129391Seric 
51321065Seric 		/* save temporary failure messages for posterity */
51421065Seric 		if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')
51521065Seric 			(void) strcpy(SmtpError, &SmtpReplyBuffer[4]);
51621065Seric 
5174684Seric 		return (r);
5184684Seric 	}
5194684Seric }
5204796Seric /*
5214865Seric **  SMTPMESSAGE -- send message to server
5224796Seric **
5234796Seric **	Parameters:
5244796Seric **		f -- format
52510175Seric **		m -- the mailer to control formatting.
5264796Seric **		a, b, c -- parameters
5274796Seric **
5284796Seric **	Returns:
5294796Seric **		none.
5304796Seric **
5314796Seric **	Side Effects:
53253740Seric **		writes message to mci->mci_out.
5334796Seric */
5344796Seric 
5354865Seric /*VARARGS1*/
53657642Seric #ifdef __STDC__
53757642Seric smtpmessage(char *f, MAILER *m, MCI *mci, ...)
53857642Seric #else
53957642Seric smtpmessage(f, m, mci, va_alist)
5404796Seric 	char *f;
54110175Seric 	MAILER *m;
54254967Seric 	MCI *mci;
54357642Seric 	va_dcl
54457642Seric #endif
5454796Seric {
54656852Seric 	VA_LOCAL_DECL
54756852Seric 
54857135Seric 	VA_START(mci);
54956852Seric 	(void) vsprintf(SmtpMsgBuffer, f, ap);
55056852Seric 	VA_END;
5517677Seric 	if (tTd(18, 1) || (Verbose && !HoldErrs))
55214900Seric 		nmessage(Arpa_Info, ">>> %s", SmtpMsgBuffer);
55353740Seric 	if (mci->mci_out != NULL)
55453740Seric 		fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer,
55554967Seric 			m == NULL ? "\r\n" : m->m_eol);
5564796Seric }
5575182Seric 
55856795Seric # endif /* SMTP */
559