⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 usersmtp.c

📁 早期freebsd实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	return (EX_PROTOCOL);}/***  SMTPDATA -- send the data and clean up the transaction.****	Parameters:**		m -- mailer being sent to.**		e -- the envelope for this message.****	Returns:**		exit status corresponding to DATA command.****	Side Effects:**		none.*/static jmp_buf	CtxDataTimeout;static int	datatimeout();smtpdata(m, mci, e)	struct mailer *m;	register MCI *mci;	register ENVELOPE *e;{	register int r;	register EVENT *ev;	time_t timeout;	/*	**  Send the data.	**	First send the command and check that it is ok.	**	Then send the data.	**	Follow it up with a dot to terminate.	**	Finally get the results of the transaction.	*/	/* send the command and check ok to proceed */	smtpmessage("DATA", m, mci);	SmtpPhase = mci->mci_phase = "client DATA 354";	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);	r = reply(m, mci, e, TimeOuts.to_datainit, NULL);	if (r < 0 || REPLYTYPE(r) == 4)	{		smtpquit(m, mci, e);		return (EX_TEMPFAIL);	}	else if (r == 554)	{		smtprset(m, mci, e);		return (EX_UNAVAILABLE);	}	else if (r != 354)	{#ifdef LOG		if (LogLevel > 1)		{			syslog(LOG_CRIT, "%s: SMTP DATA-1 protocol error: %s",				e->e_id, SmtpReplyBuffer);		}#endif		smtprset(m, mci, e);		return (EX_PROTOCOL);	}	/*	**  Set timeout around data writes.  Make it at least large	**  enough for DNS timeouts on all recipients plus some fudge	**  factor.  The main thing is that it should not be infinite.	*/	if (setjmp(CtxDataTimeout) != 0)	{		mci->mci_errno = errno;		mci->mci_exitstat = EX_TEMPFAIL;		mci->mci_state = MCIS_ERROR;		syserr("451 timeout writing message to %s", mci->mci_host);		smtpquit(m, mci, e);		return EX_TEMPFAIL;	}	timeout = e->e_msgsize / 16;	if (timeout < (time_t) 60)		timeout = (time_t) 60;	timeout += e->e_nrcpts * 90;	ev = setevent(timeout, datatimeout, 0);	/* now output the actual message */	(*e->e_puthdr)(mci, e);	putline("\n", mci);	(*e->e_putbody)(mci, e, NULL);	clrevent(ev);	if (ferror(mci->mci_out))	{		/* error during processing -- don't send the dot */		mci->mci_errno = EIO;		mci->mci_exitstat = EX_IOERR;		mci->mci_state = MCIS_ERROR;		smtpquit(m, mci, e);		return EX_IOERR;	}	/* terminate the message */	fprintf(mci->mci_out, ".%s", m->m_eol);	if (TrafficLogFile != NULL)		fprintf(TrafficLogFile, "%05d >>> .\n", getpid());	if (Verbose)		nmessage(">>> .");	/* check for the results of the transaction */	SmtpPhase = mci->mci_phase = "client DATA 250";	setproctitle("%s %s: %s", e->e_id, CurHostName, mci->mci_phase);	r = reply(m, mci, e, TimeOuts.to_datafinal, NULL);	if (r < 0)	{		smtpquit(m, mci, e);		return (EX_TEMPFAIL);	}	mci->mci_state = MCIS_OPEN;	e->e_statmsg = newstr(&SmtpReplyBuffer[4]);	if (REPLYTYPE(r) == 4)		return (EX_TEMPFAIL);	else if (r == 250)		return (EX_OK);	else if (r == 552 || r == 554)		return (EX_UNAVAILABLE);#ifdef LOG	if (LogLevel > 1)	{		syslog(LOG_CRIT, "%s: SMTP DATA-2 protocol error: %s",			e->e_id, SmtpReplyBuffer);	}#endif	return (EX_PROTOCOL);}static intdatatimeout(){	longjmp(CtxDataTimeout, 1);}/***  SMTPQUIT -- close the SMTP connection.****	Parameters:**		m -- a pointer to the mailer.****	Returns:**		none.****	Side Effects:**		sends the final protocol and closes the connection.*/smtpquit(m, mci, e)	register MAILER *m;	register MCI *mci;	ENVELOPE *e;{	bool oldSuprErrs = SuprErrs;	/*	**	Suppress errors here -- we may be processing a different	**	job when we do the quit connection, and we don't want the 	**	new job to be penalized for something that isn't it's	**	problem.	*/	SuprErrs = TRUE;	/* send the quit message if we haven't gotten I/O error */	if (mci->mci_state != MCIS_ERROR)	{		SmtpPhase = "client QUIT";		smtpmessage("QUIT", m, mci);		(void) reply(m, mci, e, TimeOuts.to_quit, NULL);		SuprErrs = oldSuprErrs;		if (mci->mci_state == MCIS_CLOSED)		{			SuprErrs = oldSuprErrs;			return;		}	}	/* now actually close the connection and pick up the zombie */	(void) endmailer(mci, e, NULL);	SuprErrs = oldSuprErrs;}/***  SMTPRSET -- send a RSET (reset) command*/smtprset(m, mci, e)	register MAILER *m;	register MCI *mci;	ENVELOPE *e;{	int r;	SmtpPhase = "client RSET";	smtpmessage("RSET", m, mci);	r = reply(m, mci, e, TimeOuts.to_rset, NULL);	if (r < 0)		mci->mci_state = MCIS_ERROR;	else if (REPLYTYPE(r) == 2)	{		mci->mci_state = MCIS_OPEN;		return;	}	smtpquit(m, mci, e);}/***  SMTPPROBE -- check the connection state*/smtpprobe(mci)	register MCI *mci;{	int r;	MAILER *m = mci->mci_mailer;	extern ENVELOPE BlankEnvelope;	ENVELOPE *e = &BlankEnvelope;	SmtpPhase = "client probe";	smtpmessage("RSET", m, mci);	r = reply(m, mci, e, TimeOuts.to_miscshort, NULL);	if (r < 0 || REPLYTYPE(r) != 2)		smtpquit(m, mci, e);	return r;}/***  REPLY -- read arpanet reply****	Parameters:**		m -- the mailer we are reading the reply from.**		mci -- the mailer connection info structure.**		e -- the current envelope.**		timeout -- the timeout for reads.**		pfunc -- processing function for second and subsequent**			lines of response -- if null, no special**			processing is done.****	Returns:**		reply code it reads.****	Side Effects:**		flushes the mail file.*/reply(m, mci, e, timeout, pfunc)	MAILER *m;	MCI *mci;	ENVELOPE *e;	time_t timeout;	void (*pfunc)();{	register char *bufp;	register int r;	bool firstline = TRUE;	char junkbuf[MAXLINE];	if (mci->mci_out != NULL)		(void) fflush(mci->mci_out);	if (tTd(18, 1))		printf("reply\n");	/*	**  Read the input line, being careful not to hang.	*/	for (bufp = SmtpReplyBuffer;; bufp = junkbuf)	{		register char *p;		extern time_t curtime();		/* actually do the read */		if (e->e_xfp != NULL)			(void) fflush(e->e_xfp);	/* for debugging */		/* if we are in the process of closing just give the code */		if (mci->mci_state == MCIS_CLOSED)			return (SMTPCLOSING);		if (mci->mci_out != NULL)			fflush(mci->mci_out);		/* get the line from the other side */		p = sfgets(bufp, MAXLINE, mci->mci_in, timeout, SmtpPhase);		mci->mci_lastuse = curtime();		if (p == NULL)		{			bool oldholderrs;			extern char MsgBuf[];		/* err.c */			/* if the remote end closed early, fake an error */			if (errno == 0)# ifdef ECONNRESET				errno = ECONNRESET;# else /* ECONNRESET */				errno = EPIPE;# endif /* ECONNRESET */			mci->mci_errno = errno;			mci->mci_exitstat = EX_TEMPFAIL;			oldholderrs = HoldErrs;			HoldErrs = TRUE;			usrerr("451 reply: read error from %s", mci->mci_host);			/* if debugging, pause so we can see state */			if (tTd(18, 100))				pause();			mci->mci_state = MCIS_ERROR;			smtpquit(m, mci, e);#ifdef XDEBUG			{				char wbuf[MAXLINE];				char *p = wbuf;				if (e->e_to != NULL)				{					sprintf(p, "%s... ", e->e_to);					p += strlen(p);				}				sprintf(p, "reply(%s) during %s",					mci->mci_host, SmtpPhase);				checkfd012(wbuf);			}#endif			HoldErrs = oldholderrs;			return (-1);		}		fixcrlf(bufp, TRUE);		/* EHLO failure is not a real error */		if (e->e_xfp != NULL && (bufp[0] == '4' ||		    (bufp[0] == '5' && strncmp(SmtpMsgBuffer, "EHLO", 4) != 0)))		{			/* serious error -- log the previous command */			if (SmtpNeedIntro)			{				/* inform user who we are chatting with */				fprintf(CurEnv->e_xfp,					"... while talking to %s:\n",					CurHostName);				SmtpNeedIntro = FALSE;			}			if (SmtpMsgBuffer[0] != '\0')				fprintf(e->e_xfp, ">>> %s\n", SmtpMsgBuffer);			SmtpMsgBuffer[0] = '\0';			/* now log the message as from the other side */			fprintf(e->e_xfp, "<<< %s\n", bufp);		}		/* display the input for verbose mode */		if (Verbose)			nmessage("050 %s", bufp);		/* process the line */		if (pfunc != NULL && !firstline)			(*pfunc)(bufp, m, mci, e);		firstline = FALSE;		/* if continuation is required, we can go on */		if (bufp[3] == '-')			continue;		/* ignore improperly formated input */		if (!(isascii(bufp[0]) && isdigit(bufp[0])))			continue;		/* decode the reply code */		r = atoi(bufp);		/* extra semantics: 0xx codes are "informational" */		if (r >= 100)			break;	}	/*	**  Now look at SmtpReplyBuffer -- only care about the first	**  line of the response from here on out.	*/	/* save temporary failure messages for posterity */	if (SmtpReplyBuffer[0] == '4' && SmtpError[0] == '\0')		(void) strcpy(SmtpError, SmtpReplyBuffer);	/* reply code 421 is "Service Shutting Down" */	if (r == SMTPCLOSING && mci->mci_state != MCIS_SSD)	{		/* send the quit protocol */		mci->mci_state = MCIS_SSD;		smtpquit(m, mci, e);	}	return (r);}/***  SMTPMESSAGE -- send message to server****	Parameters:**		f -- format**		m -- the mailer to control formatting.**		a, b, c -- parameters****	Returns:**		none.****	Side Effects:**		writes message to mci->mci_out.*//*VARARGS1*/#ifdef __STDC__smtpmessage(char *f, MAILER *m, MCI *mci, ...)#elsesmtpmessage(f, m, mci, va_alist)	char *f;	MAILER *m;	MCI *mci;	va_dcl#endif{	VA_LOCAL_DECL	VA_START(mci);	(void) vsprintf(SmtpMsgBuffer, f, ap);	VA_END;	if (tTd(18, 1) || Verbose)		nmessage(">>> %s", SmtpMsgBuffer);	if (TrafficLogFile != NULL)		fprintf(TrafficLogFile, "%05d >>> %s\n", getpid(), SmtpMsgBuffer);	if (mci->mci_out != NULL)	{		fprintf(mci->mci_out, "%s%s", SmtpMsgBuffer,			m == NULL ? "\r\n" : m->m_eol);	}	else if (tTd(18, 1))	{		printf("smtpmessage: NULL mci_out\n");	}}# endif /* SMTP */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -