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