1 # include <ctype.h>
2 # include <sysexits.h>
3 # include "sendmail.h"
4 
5 # ifndef SMTP
6 SCCSID(@(#)usersmtp.c	3.9		03/06/82	(no SMTP));
7 # else SMTP
8 
9 SCCSID(@(#)usersmtp.c	3.9		03/06/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 	(void) expand("$g", buf, &buf[sizeof buf - 1]);
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 **		editfcn -- a function to call to output the
134 **			text of the message with.
135 **
136 **	Returns:
137 **		exit status corresponding to DATA command.
138 **
139 **	Side Effects:
140 **		none.
141 */
142 
143 smtpfinish(m, editfcn)
144 	struct mailer *m;
145 	int (*editfcn)();
146 {
147 	register int r;
148 
149 	if (SmtpPid < 0)
150 		return (SmtpErrstat);
151 
152 	/*
153 	**  Send the data.
154 	**	Dot hiding is done here.
155 	*/
156 
157 	smtpmessage("DATA");
158 	r = reply();
159 	if (REPLYTYPE(r) == 4)
160 		return (EX_TEMPFAIL);
161 	if (r != 354)
162 		return (EX_SOFTWARE);
163 	(*editfcn)(SmtpOut, m, TRUE);
164 	smtpmessage(".");
165 	r = reply();
166 	if (REPLYTYPE(r) == 4)
167 		return (EX_TEMPFAIL);
168 	if (r != 250)
169 		return (EX_SOFTWARE);
170 	return (EX_OK);
171 }
172 /*
173 **  SMTPQUIT -- close the SMTP connection.
174 **
175 **	Parameters:
176 **		name -- name of mailer we are quitting.
177 **
178 **	Returns:
179 **		none.
180 **
181 **	Side Effects:
182 **		sends the final protocol and closes the connection.
183 */
184 
185 smtpquit(name)
186 	char *name;
187 {
188 	register int i;
189 
190 	if (SmtpPid < 0)
191 	{
192 		i = SmtpErrstat;
193 	}
194 	else
195 	{
196 		smtpmessage("QUIT");
197 		(void) reply();
198 		(void) fclose(SmtpIn);
199 		(void) fclose(SmtpOut);
200 		i = endmailer(SmtpPid, name);
201 	}
202 	giveresponse(i, TRUE, LocalMailer);
203 }
204 /*
205 **  REPLY -- read arpanet reply
206 **
207 **	Parameters:
208 **		none.
209 **
210 **	Returns:
211 **		reply code it reads.
212 **
213 **	Side Effects:
214 **		flushes the mail file.
215 */
216 
217 reply()
218 {
219 	(void) fflush(SmtpOut);
220 
221 	if (Debug)
222 		printf("reply\n");
223 
224 	/* read the input line */
225 	for (;;)
226 	{
227 		char buf[MAXLINE];
228 		register int r;
229 
230 		if (fgets(buf, sizeof buf, SmtpIn) == NULL)
231 			return (-1);
232 		if (Verbose)
233 			fputs(buf, stdout);
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 	strcat(buf, "\r\n");
264 	if (Debug)
265 		fputs(buf, stdout);
266 	fputs(buf, SmtpOut);
267 }
268 
269 # endif SMTP
270