14796Seric # include <ctype.h>
24684Seric # include <wellknown.h>
34684Seric # include <sysexits.h>
44865Seric # include "sendmail.h"
54684Seric 
6*5182Seric # ifndef SMTP
7*5182Seric static char	SccsId[] =	"@(#)usersmtp.c	3.6	12/05/81	(no SMTP)";
8*5182Seric # else SMTP
94684Seric 
10*5182Seric static char	SccsId[] =	"@(#)usersmtp.c	3.6	12/05/81";
11*5182Seric 
124684Seric /*
134865Seric **  SMTPINIT -- initialize SMTP.
144684Seric **
154865Seric **	Opens the connection and sends the initial protocol.
164684Seric **
174684Seric **	Parameters:
184865Seric **		m -- mailer to create connection to.
194865Seric **		pvp -- pointer to parameter vector to pass to
204865Seric **			the mailer.
214865Seric **		ctladdr -- controlling address for this mailer.
224684Seric **
234684Seric **	Returns:
244865Seric **		appropriate exit status -- EX_OK on success.
254684Seric **
264684Seric **	Side Effects:
274865Seric **		creates connection and sends initial protocol.
284684Seric */
294684Seric 
304865Seric # define REPLYTYPE(r)	((r) / 100)
314865Seric 
324865Seric static FILE	*SmtpOut;	/* output file */
334865Seric static FILE	*SmtpIn;	/* input file */
344865Seric static int	SmtpPid;	/* pid of mailer */
354865Seric 
364865Seric smtpinit(m, pvp, ctladdr)
374865Seric 	struct mailer *m;
384865Seric 	char **pvp;
394865Seric 	ADDRESS *ctladdr;
404684Seric {
414865Seric 	register int r;
424865Seric 	char buf[MAXNAME];
434684Seric 
444865Seric 	/*
454865Seric 	**  Open the connection to the mailer.
464865Seric 	*/
474684Seric 
484865Seric 	SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn);
494796Seric 
504865Seric 	/*
514865Seric 	**  Get the greeting message.
524865Seric 	**	This should appear spontaneously.
534865Seric 	*/
544797Seric 
554865Seric 	r = reply();
564865Seric 	if (REPLYTYPE(r) != 2)
574865Seric 		return (EX_TEMPFAIL);
584684Seric 
594865Seric 	/*
604976Seric 	**  Send the HELO command.
614976Seric 	**	My mother taught me to always introduce myself, even
624976Seric 	**	if it is useless.
634976Seric 	*/
644976Seric 
654976Seric 	smtpmessage("HELO %s", HostName);
664976Seric 	r = reply();
674976Seric 	if (REPLYTYPE(r) == 5)
684976Seric 		return (EX_UNAVAILABLE);
694976Seric 	if (REPLYTYPE(r) != 2)
704976Seric 		return (EX_TEMPFAIL);
714976Seric 
724976Seric 	/*
734865Seric 	**  Send the MAIL command.
744865Seric 	**	Designates the sender.
754865Seric 	*/
764796Seric 
774865Seric 	(void) expand("$g", buf, &buf[sizeof buf - 1]);
784865Seric 	smtpmessage("MAIL From:<%s>", buf);
794865Seric 	r = reply();
804865Seric 	if (REPLYTYPE(r) == 4)
814865Seric 		return (EX_TEMPFAIL);
824865Seric 	if (r != 250)
834865Seric 		return (EX_SOFTWARE);
844865Seric 	return (EX_OK);
854684Seric }
864684Seric /*
874976Seric **  SMTPRCPT -- designate recipient.
884797Seric **
894797Seric **	Parameters:
904865Seric **		to -- address of recipient.
914797Seric **
924797Seric **	Returns:
934865Seric **		exit status corresponding to recipient status.
944797Seric **
954797Seric **	Side Effects:
964865Seric **		Sends the mail via SMTP.
974797Seric */
984797Seric 
994976Seric smtprcpt(to)
1004865Seric 	ADDRESS *to;
1014797Seric {
1024797Seric 	register int r;
1034797Seric 
1044976Seric 	smtpmessage("RCPT To:<%s>", to->q_user);
1054865Seric 
1064797Seric 	r = reply();
1074865Seric 	if (REPLYTYPE(r) == 4)
1084865Seric 		return (EX_TEMPFAIL);
1094865Seric 	if (r != 250)
1104865Seric 		return (EX_NOUSER);
1114797Seric 
1124865Seric 	return (EX_OK);
1134797Seric }
1144797Seric /*
1154865Seric **  SMTPFINISH -- finish up sending all the SMTP protocol.
1164684Seric **
1174684Seric **	Parameters:
1184865Seric **		m -- mailer being sent to.
1194865Seric **		editfcn -- a function to call to output the
1204865Seric **			text of the message with.
1214684Seric **
1224684Seric **	Returns:
1234976Seric **		exit status corresponding to DATA command.
1244684Seric **
1254684Seric **	Side Effects:
1264865Seric **		none.
1274684Seric */
1284684Seric 
1294865Seric smtpfinish(m, editfcn)
1304865Seric 	struct mailer *m;
1314865Seric 	int (*editfcn)();
1324684Seric {
1334684Seric 	register int r;
1344684Seric 
1354797Seric 	/*
1364797Seric 	**  Send the data.
1374797Seric 	**	Dot hiding is done here.
1384797Seric 	*/
1394797Seric 
1404865Seric 	smtpmessage("DATA");
1414796Seric 	r = reply();
1424797Seric 	if (REPLYTYPE(r) == 4)
1434797Seric 		return (EX_TEMPFAIL);
1444684Seric 	if (r != 354)
1454684Seric 		return (EX_SOFTWARE);
1464865Seric 	(*editfcn)(SmtpOut, m, TRUE);
1474865Seric 	smtpmessage(".");
1484796Seric 	r = reply();
1494797Seric 	if (REPLYTYPE(r) == 4)
1504797Seric 		return (EX_TEMPFAIL);
1514684Seric 	if (r != 250)
1524684Seric 		return (EX_SOFTWARE);
1534684Seric 	return (EX_OK);
1544684Seric }
1554684Seric /*
1564865Seric **  SMTPQUIT -- close the SMTP connection.
1574865Seric **
1584865Seric **	Parameters:
1594865Seric **		name -- name of mailer we are quitting.
1604865Seric **
1614865Seric **	Returns:
1624865Seric **		none.
1634865Seric **
1644865Seric **	Side Effects:
1654865Seric **		sends the final protocol and closes the connection.
1664865Seric */
1674865Seric 
1684865Seric smtpquit(name)
1694865Seric 	char *name;
1704865Seric {
1714865Seric 	register int i;
1724865Seric 
1734865Seric 	smtpmessage("QUIT");
1744865Seric 	(void) reply();
1754865Seric 	(void) fclose(SmtpIn);
1764865Seric 	(void) fclose(SmtpOut);
1774865Seric 	i = endmailer(SmtpPid, name);
1784865Seric 	giveresponse(i, TRUE, LocalMailer);
1794865Seric }
1804865Seric /*
1814684Seric **  REPLY -- read arpanet reply
1824684Seric **
1834684Seric **	Parameters:
1844796Seric **		none.
1854684Seric **
1864684Seric **	Returns:
1874684Seric **		reply code it reads.
1884684Seric **
1894684Seric **	Side Effects:
1904684Seric **		flushes the mail file.
1914684Seric */
1924684Seric 
1934796Seric reply()
1944684Seric {
1954865Seric 	(void) fflush(SmtpOut);
1964684Seric 
1974796Seric 	if (Debug)
1984796Seric 		printf("reply\n");
1994796Seric 
2004684Seric 	/* read the input line */
2014684Seric 	for (;;)
2024684Seric 	{
2034684Seric 		char buf[MAXLINE];
2044684Seric 		register int r;
2054684Seric 
2064865Seric 		if (fgets(buf, sizeof buf, SmtpIn) == NULL)
2074684Seric 			return (-1);
2084684Seric 		if (Verbose)
2094684Seric 			fputs(buf, stdout);
2104796Seric 		if (buf[3] == '-' || !isdigit(buf[0]))
2114684Seric 			continue;
2124684Seric 		r = atoi(buf);
2134684Seric 		if (r < 100)
2144684Seric 			continue;
2154684Seric 		return (r);
2164684Seric 	}
2174684Seric }
2184796Seric /*
2194865Seric **  SMTPMESSAGE -- send message to server
2204796Seric **
2214796Seric **	Parameters:
2224796Seric **		f -- format
2234796Seric **		a, b, c -- parameters
2244796Seric **
2254796Seric **	Returns:
2264796Seric **		none.
2274796Seric **
2284796Seric **	Side Effects:
2294865Seric **		writes message to SmtpOut.
2304796Seric */
2314796Seric 
2324865Seric /*VARARGS1*/
2334865Seric smtpmessage(f, a, b, c)
2344796Seric 	char *f;
2354796Seric {
2364796Seric 	char buf[100];
2374796Seric 
2384865Seric 	(void) sprintf(buf, f, a, b, c);
2394797Seric 	strcat(buf, "\r\n");
2404796Seric 	if (Debug)
2414796Seric 		fputs(buf, stdout);
2424865Seric 	fputs(buf, SmtpOut);
2434796Seric }
244*5182Seric 
245*5182Seric # endif SMTP
246