1 # include <ctype.h>
2 # include <sysexits.h>
3 # include "sendmail.h"
4 
5 # ifndef SMTP
6 SCCSID(@(#)usersmtp.c	3.12		06/19/82	(no SMTP));
7 # else SMTP
8 
9 SCCSID(@(#)usersmtp.c	3.12		06/19/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 **		showresp -- if set, give a response message.
179 **
180 **	Returns:
181 **		none.
182 **
183 **	Side Effects:
184 **		sends the final protocol and closes the connection.
185 */
186 
187 smtpquit(name, showresp)
188 	char *name;
189 	bool showresp;
190 {
191 	register int i;
192 
193 	if (SmtpPid < 0)
194 		return;
195 	smtpmessage("QUIT");
196 	(void) reply();
197 	(void) fclose(SmtpIn);
198 	(void) fclose(SmtpOut);
199 	i = endmailer(SmtpPid, name);
200 	if (showresp)
201 		giveresponse(i, TRUE, LocalMailer);
202 }
203 /*
204 **  REPLY -- read arpanet reply
205 **
206 **	Parameters:
207 **		none.
208 **
209 **	Returns:
210 **		reply code it reads.
211 **
212 **	Side Effects:
213 **		flushes the mail file.
214 */
215 
216 reply()
217 {
218 	(void) fflush(SmtpOut);
219 
220 	if (Debug)
221 		printf("reply\n");
222 
223 	/* read the input line */
224 	for (;;)
225 	{
226 		char buf[MAXLINE];
227 		register int r;
228 
229 		if (fgets(buf, sizeof buf, SmtpIn) == NULL)
230 			return (-1);
231 		if (Verbose && !HoldErrs)
232 			fputs(buf, stdout);
233 		fputs(buf, Xscript);
234 		if (buf[3] == '-' || !isdigit(buf[0]))
235 			continue;
236 		r = atoi(buf);
237 		if (r < 100)
238 			continue;
239 		return (r);
240 	}
241 }
242 /*
243 **  SMTPMESSAGE -- send message to server
244 **
245 **	Parameters:
246 **		f -- format
247 **		a, b, c -- parameters
248 **
249 **	Returns:
250 **		none.
251 **
252 **	Side Effects:
253 **		writes message to SmtpOut.
254 */
255 
256 /*VARARGS1*/
257 smtpmessage(f, a, b, c)
258 	char *f;
259 {
260 	char buf[100];
261 
262 	(void) sprintf(buf, f, a, b, c);
263 	if (Debug || (Verbose && !HoldErrs))
264 		printf(">>> %s\n", buf);
265 	fprintf(Xscript, ">>> %s\n", buf);
266 	fprintf(SmtpOut, "%s\r\n", buf);
267 }
268 
269 # endif SMTP
270