14796Seric # include <ctype.h>
24684Seric # include <wellknown.h>
34684Seric # include <sysexits.h>
4*4865Seric # include "sendmail.h"
54684Seric 
6*4865Seric static char	SccsId[] =	"@(#)usersmtp.c	3.4	11/11/81";
74684Seric 
84684Seric /*
9*4865Seric **  SMTPINIT -- initialize SMTP.
104684Seric **
11*4865Seric **	Opens the connection and sends the initial protocol.
124684Seric **
134684Seric **	Parameters:
14*4865Seric **		m -- mailer to create connection to.
15*4865Seric **		pvp -- pointer to parameter vector to pass to
16*4865Seric **			the mailer.
17*4865Seric **		ctladdr -- controlling address for this mailer.
184684Seric **
194684Seric **	Returns:
20*4865Seric **		appropriate exit status -- EX_OK on success.
214684Seric **
224684Seric **	Side Effects:
23*4865Seric **		creates connection and sends initial protocol.
244684Seric */
254684Seric 
26*4865Seric # define REPLYTYPE(r)	((r) / 100)
27*4865Seric 
28*4865Seric static FILE	*SmtpOut;	/* output file */
29*4865Seric static FILE	*SmtpIn;	/* input file */
30*4865Seric static int	SmtpPid;	/* pid of mailer */
31*4865Seric 
32*4865Seric smtpinit(m, pvp, ctladdr)
33*4865Seric 	struct mailer *m;
34*4865Seric 	char **pvp;
35*4865Seric 	ADDRESS *ctladdr;
364684Seric {
37*4865Seric 	register int r;
38*4865Seric 	char buf[MAXNAME];
394684Seric 
40*4865Seric 	/*
41*4865Seric 	**  Open the connection to the mailer.
42*4865Seric 	*/
434684Seric 
44*4865Seric 	SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn);
454796Seric 
46*4865Seric 	/*
47*4865Seric 	**  Get the greeting message.
48*4865Seric 	**	This should appear spontaneously.
49*4865Seric 	*/
504797Seric 
51*4865Seric 	r = reply();
52*4865Seric 	if (REPLYTYPE(r) != 2)
53*4865Seric 		return (EX_TEMPFAIL);
544684Seric 
55*4865Seric 	/*
56*4865Seric 	**  Send the MAIL command.
57*4865Seric 	**	Designates the sender.
58*4865Seric 	*/
594796Seric 
60*4865Seric 	(void) expand("$g", buf, &buf[sizeof buf - 1]);
61*4865Seric 	smtpmessage("MAIL From:<%s>", buf);
62*4865Seric 	r = reply();
63*4865Seric 	if (REPLYTYPE(r) == 4)
64*4865Seric 		return (EX_TEMPFAIL);
65*4865Seric 	if (r != 250)
66*4865Seric 		return (EX_SOFTWARE);
67*4865Seric 	return (EX_OK);
684684Seric }
694684Seric /*
70*4865Seric **  SMTPMRCP -- designate recipient.
714797Seric **
724797Seric **	Parameters:
73*4865Seric **		to -- address of recipient.
744797Seric **
754797Seric **	Returns:
76*4865Seric **		exit status corresponding to recipient status.
774797Seric **
784797Seric **	Side Effects:
79*4865Seric **		Sends the mail via SMTP.
804797Seric */
814797Seric 
82*4865Seric smtpmrcp(to)
83*4865Seric 	ADDRESS *to;
844797Seric {
854797Seric 	register int r;
864797Seric 
87*4865Seric 	smtpmessage("MRCP To:<%s>", to->q_user);
88*4865Seric 
894797Seric 	r = reply();
90*4865Seric 	if (REPLYTYPE(r) == 4)
91*4865Seric 		return (EX_TEMPFAIL);
92*4865Seric 	if (r != 250)
93*4865Seric 		return (EX_NOUSER);
944797Seric 
95*4865Seric 	return (EX_OK);
964797Seric }
974797Seric /*
98*4865Seric **  SMTPFINISH -- finish up sending all the SMTP protocol.
994684Seric **
1004684Seric **	Parameters:
101*4865Seric **		m -- mailer being sent to.
102*4865Seric **		editfcn -- a function to call to output the
103*4865Seric **			text of the message with.
1044684Seric **
1054684Seric **	Returns:
106*4865Seric **		exit status corresponding to DOIT command.
1074684Seric **
1084684Seric **	Side Effects:
109*4865Seric **		none.
1104684Seric */
1114684Seric 
112*4865Seric smtpfinish(m, editfcn)
113*4865Seric 	struct mailer *m;
114*4865Seric 	int (*editfcn)();
1154684Seric {
1164684Seric 	register int r;
1174684Seric 
1184797Seric 	/*
1194797Seric 	**  Send the data.
1204797Seric 	**	Dot hiding is done here.
1214797Seric 	*/
1224797Seric 
123*4865Seric 	smtpmessage("DATA");
1244796Seric 	r = reply();
1254797Seric 	if (REPLYTYPE(r) == 4)
1264797Seric 		return (EX_TEMPFAIL);
1274684Seric 	if (r != 354)
1284684Seric 		return (EX_SOFTWARE);
129*4865Seric 	(*editfcn)(SmtpOut, m, TRUE);
130*4865Seric 	smtpmessage(".");
1314796Seric 	r = reply();
1324797Seric 	if (REPLYTYPE(r) == 4)
1334797Seric 		return (EX_TEMPFAIL);
1344684Seric 	if (r != 250)
1354684Seric 		return (EX_SOFTWARE);
1364684Seric 
1374797Seric 	/*
1384797Seric 	**  Make the actual delivery happen.
1394797Seric 	*/
1404797Seric 
141*4865Seric 	smtpmessage("DOIT");
1424796Seric 	r = reply();
1434684Seric 	if (r != 250)
1444684Seric 		return (EX_TEMPFAIL);
1454684Seric 
1464684Seric 	return (EX_OK);
1474684Seric }
1484684Seric /*
149*4865Seric **  SMTPQUIT -- close the SMTP connection.
150*4865Seric **
151*4865Seric **	Parameters:
152*4865Seric **		name -- name of mailer we are quitting.
153*4865Seric **
154*4865Seric **	Returns:
155*4865Seric **		none.
156*4865Seric **
157*4865Seric **	Side Effects:
158*4865Seric **		sends the final protocol and closes the connection.
159*4865Seric */
160*4865Seric 
161*4865Seric smtpquit(name)
162*4865Seric 	char *name;
163*4865Seric {
164*4865Seric 	register int i;
165*4865Seric 
166*4865Seric 	smtpmessage("QUIT");
167*4865Seric 	(void) reply();
168*4865Seric 	(void) fclose(SmtpIn);
169*4865Seric 	(void) fclose(SmtpOut);
170*4865Seric 	i = endmailer(SmtpPid, name);
171*4865Seric 	giveresponse(i, TRUE, LocalMailer);
172*4865Seric }
173*4865Seric /*
1744684Seric **  REPLY -- read arpanet reply
1754684Seric **
1764684Seric **	Parameters:
1774796Seric **		none.
1784684Seric **
1794684Seric **	Returns:
1804684Seric **		reply code it reads.
1814684Seric **
1824684Seric **	Side Effects:
1834684Seric **		flushes the mail file.
1844684Seric */
1854684Seric 
1864796Seric reply()
1874684Seric {
188*4865Seric 	(void) fflush(SmtpOut);
1894684Seric 
1904796Seric 	if (Debug)
1914796Seric 		printf("reply\n");
1924796Seric 
1934684Seric 	/* read the input line */
1944684Seric 	for (;;)
1954684Seric 	{
1964684Seric 		char buf[MAXLINE];
1974684Seric 		register int r;
1984684Seric 
199*4865Seric 		if (fgets(buf, sizeof buf, SmtpIn) == NULL)
2004684Seric 			return (-1);
2014684Seric 		if (Verbose)
2024684Seric 			fputs(buf, stdout);
2034796Seric 		if (buf[3] == '-' || !isdigit(buf[0]))
2044684Seric 			continue;
2054684Seric 		r = atoi(buf);
2064684Seric 		if (r < 100)
2074684Seric 			continue;
2084684Seric 		return (r);
2094684Seric 	}
2104684Seric }
2114796Seric /*
212*4865Seric **  SMTPMESSAGE -- send message to server
2134796Seric **
2144796Seric **	Parameters:
2154796Seric **		f -- format
2164796Seric **		a, b, c -- parameters
2174796Seric **
2184796Seric **	Returns:
2194796Seric **		none.
2204796Seric **
2214796Seric **	Side Effects:
222*4865Seric **		writes message to SmtpOut.
2234796Seric */
2244796Seric 
225*4865Seric /*VARARGS1*/
226*4865Seric smtpmessage(f, a, b, c)
2274796Seric 	char *f;
2284796Seric {
2294796Seric 	char buf[100];
2304796Seric 
231*4865Seric 	(void) sprintf(buf, f, a, b, c);
2324797Seric 	strcat(buf, "\r\n");
2334796Seric 	if (Debug)
2344796Seric 		fputs(buf, stdout);
235*4865Seric 	fputs(buf, SmtpOut);
2364796Seric }
237