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