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