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