1 # include <ctype.h>
2 # include <sysexits.h>
3 # include "sendmail.h"
4 
5 # ifndef SMTP
6 SCCSID(@(#)usersmtp.c	3.11		05/31/82	(no SMTP));
7 # else SMTP
8 
9 SCCSID(@(#)usersmtp.c	3.11		05/31/82);
10 
11 /*
12 **  SMTPINIT -- initialize SMTP.
13 **
14 **	Opens the connection and sends the initial protocol.
15 **
16 **	Parameters:
17 **		m -- mailer to create connection to.
18 **		pvp -- pointer to parameter vector to pass to
19 **			the mailer.
20 **		ctladdr -- controlling address for this mailer.
21 **
22 **	Returns:
23 **		appropriate exit status -- EX_OK on success.
24 **
25 **	Side Effects:
26 **		creates connection and sends initial protocol.
27 */
28 
29 # define REPLYTYPE(r)	((r) / 100)
30 
31 static FILE	*SmtpOut;	/* output file */
32 static FILE	*SmtpIn;	/* input file */
33 static int	SmtpPid;	/* pid of mailer */
34 static int	SmtpErrstat;	/* error status if open fails */
35 
36 smtpinit(m, pvp, ctladdr)
37 	struct mailer *m;
38 	char **pvp;
39 	ADDRESS *ctladdr;
40 {
41 	register int r;
42 	char buf[MAXNAME];
43 
44 	/*
45 	**  Open the connection to the mailer.
46 	*/
47 
48 	SmtpIn = SmtpOut = NULL;
49 	SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn);
50 	if (SmtpPid < 0)
51 	{
52 		SmtpErrstat = ExitStat;
53 # ifdef DEBUG
54 		if (Debug > 0)
55 			printf("smtpinit: cannot open: Errstat %d errno %d\n",
56 			   SmtpErrstat, errno);
57 # endif DEBUG
58 		return (ExitStat);
59 	}
60 
61 	/*
62 	**  Get the greeting message.
63 	**	This should appear spontaneously.
64 	*/
65 
66 	r = reply();
67 	if (REPLYTYPE(r) != 2)
68 		return (EX_TEMPFAIL);
69 
70 	/*
71 	**  Send the HELO command.
72 	**	My mother taught me to always introduce myself, even
73 	**	if it is useless.
74 	*/
75 
76 	smtpmessage("HELO %s", HostName);
77 	r = reply();
78 	if (REPLYTYPE(r) == 5)
79 		return (EX_UNAVAILABLE);
80 	if (REPLYTYPE(r) != 2)
81 		return (EX_TEMPFAIL);
82 
83 	/*
84 	**  Send the MAIL command.
85 	**	Designates the sender.
86 	*/
87 
88 	expand("$g", buf, &buf[sizeof buf - 1], CurEnv);
89 	smtpmessage("MAIL From:<%s>", buf);
90 	r = reply();
91 	if (REPLYTYPE(r) == 4)
92 		return (EX_TEMPFAIL);
93 	if (r != 250)
94 		return (EX_SOFTWARE);
95 	return (EX_OK);
96 }
97 /*
98 **  SMTPRCPT -- designate recipient.
99 **
100 **	Parameters:
101 **		to -- address of recipient.
102 **
103 **	Returns:
104 **		exit status corresponding to recipient status.
105 **
106 **	Side Effects:
107 **		Sends the mail via SMTP.
108 */
109 
110 smtprcpt(to)
111 	ADDRESS *to;
112 {
113 	register int r;
114 
115 	if (SmtpPid < 0)
116 		return (SmtpErrstat);
117 
118 	smtpmessage("RCPT To:<%s>", to->q_user);
119 
120 	r = reply();
121 	if (REPLYTYPE(r) == 4)
122 		return (EX_TEMPFAIL);
123 	if (r != 250)
124 		return (EX_NOUSER);
125 
126 	return (EX_OK);
127 }
128 /*
129 **  SMTPFINISH -- finish up sending all the SMTP protocol.
130 **
131 **	Parameters:
132 **		m -- mailer being sent to.
133 **		e -- the envelope for this message.
134 **
135 **	Returns:
136 **		exit status corresponding to DATA command.
137 **
138 **	Side Effects:
139 **		none.
140 */
141 
142 smtpfinish(m, e)
143 	struct mailer *m;
144 	register ENVELOPE *e;
145 {
146 	register int r;
147 
148 	if (SmtpPid < 0)
149 		return (SmtpErrstat);
150 
151 	/*
152 	**  Send the data.
153 	**	Dot hiding is done here.
154 	*/
155 
156 	smtpmessage("DATA");
157 	r = reply();
158 	if (REPLYTYPE(r) == 4)
159 		return (EX_TEMPFAIL);
160 	if (r != 354)
161 		return (EX_SOFTWARE);
162 	(*e->e_puthdr)(SmtpOut, m, CurEnv);
163 	fprintf(SmtpOut, "\n");
164 	(*e->e_putbody)(SmtpOut, m, TRUE);
165 	smtpmessage(".");
166 	r = reply();
167 	if (REPLYTYPE(r) == 4)
168 		return (EX_TEMPFAIL);
169 	if (r != 250)
170 		return (EX_SOFTWARE);
171 	return (EX_OK);
172 }
173 /*
174 **  SMTPQUIT -- close the SMTP connection.
175 **
176 **	Parameters:
177 **		name -- name of mailer we are quitting.
178 **
179 **	Returns:
180 **		none.
181 **
182 **	Side Effects:
183 **		sends the final protocol and closes the connection.
184 */
185 
186 smtpquit(name)
187 	char *name;
188 {
189 	register int i;
190 
191 	if (SmtpPid < 0)
192 	{
193 		i = SmtpErrstat;
194 	}
195 	else
196 	{
197 		smtpmessage("QUIT");
198 		(void) reply();
199 		(void) fclose(SmtpIn);
200 		(void) fclose(SmtpOut);
201 		i = endmailer(SmtpPid, name);
202 	}
203 	giveresponse(i, TRUE, LocalMailer);
204 }
205 /*
206 **  REPLY -- read arpanet reply
207 **
208 **	Parameters:
209 **		none.
210 **
211 **	Returns:
212 **		reply code it reads.
213 **
214 **	Side Effects:
215 **		flushes the mail file.
216 */
217 
218 reply()
219 {
220 	(void) fflush(SmtpOut);
221 
222 	if (Debug)
223 		printf("reply\n");
224 
225 	/* read the input line */
226 	for (;;)
227 	{
228 		char buf[MAXLINE];
229 		register int r;
230 
231 		if (fgets(buf, sizeof buf, SmtpIn) == NULL)
232 			return (-1);
233 		if (Verbose)
234 			fputs(buf, stdout);
235 		if (buf[3] == '-' || !isdigit(buf[0]))
236 			continue;
237 		r = atoi(buf);
238 		if (r < 100)
239 			continue;
240 		return (r);
241 	}
242 }
243 /*
244 **  SMTPMESSAGE -- send message to server
245 **
246 **	Parameters:
247 **		f -- format
248 **		a, b, c -- parameters
249 **
250 **	Returns:
251 **		none.
252 **
253 **	Side Effects:
254 **		writes message to SmtpOut.
255 */
256 
257 /*VARARGS1*/
258 smtpmessage(f, a, b, c)
259 	char *f;
260 {
261 	char buf[100];
262 
263 	(void) sprintf(buf, f, a, b, c);
264 	(void) strcat(buf, "\r\n");
265 	if (Debug)
266 		fputs(buf, stdout);
267 	fputs(buf, SmtpOut);
268 }
269 
270 # endif SMTP
271