minor fixes (handle errs on root with -p, and always
[unix-history] / usr / src / usr.sbin / sendmail / src / usersmtp.c
CommitLineData
42281a7d 1# include <ctype.h>
d2eb2478 2# include <sysexits.h>
e6b0a75b 3# include "sendmail.h"
d2eb2478 4
884a20cb 5# ifndef SMTP
65a4771c 6SCCSID(@(#)usersmtp.c 3.12 %G% (no SMTP));
884a20cb
EA
7# else SMTP
8
65a4771c 9SCCSID(@(#)usersmtp.c 3.12 %G%);
d2eb2478
EA
10
11/*
e6b0a75b 12** SMTPINIT -- initialize SMTP.
d2eb2478 13**
e6b0a75b 14** Opens the connection and sends the initial protocol.
d2eb2478
EA
15**
16** Parameters:
e6b0a75b
EA
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.
d2eb2478
EA
21**
22** Returns:
e6b0a75b 23** appropriate exit status -- EX_OK on success.
d2eb2478
EA
24**
25** Side Effects:
e6b0a75b 26** creates connection and sends initial protocol.
d2eb2478
EA
27*/
28
e6b0a75b
EA
29# define REPLYTYPE(r) ((r) / 100)
30
31static FILE *SmtpOut; /* output file */
32static FILE *SmtpIn; /* input file */
33static int SmtpPid; /* pid of mailer */
1ea752a1 34static int SmtpErrstat; /* error status if open fails */
e6b0a75b
EA
35
36smtpinit(m, pvp, ctladdr)
37 struct mailer *m;
38 char **pvp;
39 ADDRESS *ctladdr;
d2eb2478 40{
e6b0a75b
EA
41 register int r;
42 char buf[MAXNAME];
d2eb2478 43
e6b0a75b
EA
44 /*
45 ** Open the connection to the mailer.
46 */
d2eb2478 47
1ea752a1 48 SmtpIn = SmtpOut = NULL;
e6b0a75b 49 SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn);
1ea752a1
EA
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 }
d2eb2478 60
e6b0a75b
EA
61 /*
62 ** Get the greeting message.
63 ** This should appear spontaneously.
64 */
3c6123ce 65
e6b0a75b
EA
66 r = reply();
67 if (REPLYTYPE(r) != 2)
68 return (EX_TEMPFAIL);
42281a7d 69
4a4ebe09
EA
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
e6b0a75b
EA
83 /*
84 ** Send the MAIL command.
85 ** Designates the sender.
86 */
42281a7d 87
dd1fe05b 88 expand("$g", buf, &buf[sizeof buf - 1], CurEnv);
e6b0a75b
EA
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);
d2eb2478
EA
96}
97\f/*
4a4ebe09 98** SMTPRCPT -- designate recipient.
3c6123ce
EA
99**
100** Parameters:
e6b0a75b 101** to -- address of recipient.
3c6123ce
EA
102**
103** Returns:
e6b0a75b 104** exit status corresponding to recipient status.
3c6123ce
EA
105**
106** Side Effects:
e6b0a75b 107** Sends the mail via SMTP.
3c6123ce
EA
108*/
109
4a4ebe09 110smtprcpt(to)
e6b0a75b 111 ADDRESS *to;
3c6123ce
EA
112{
113 register int r;
114
1ea752a1
EA
115 if (SmtpPid < 0)
116 return (SmtpErrstat);
117
4a4ebe09 118 smtpmessage("RCPT To:<%s>", to->q_user);
e6b0a75b 119
3c6123ce 120 r = reply();
e6b0a75b
EA
121 if (REPLYTYPE(r) == 4)
122 return (EX_TEMPFAIL);
123 if (r != 250)
124 return (EX_NOUSER);
3c6123ce 125
e6b0a75b 126 return (EX_OK);
3c6123ce
EA
127}
128\f/*
e6b0a75b 129** SMTPFINISH -- finish up sending all the SMTP protocol.
d2eb2478
EA
130**
131** Parameters:
e6b0a75b 132** m -- mailer being sent to.
dd1fe05b 133** e -- the envelope for this message.
d2eb2478
EA
134**
135** Returns:
4a4ebe09 136** exit status corresponding to DATA command.
d2eb2478
EA
137**
138** Side Effects:
e6b0a75b 139** none.
d2eb2478
EA
140*/
141
dd1fe05b 142smtpfinish(m, e)
e6b0a75b 143 struct mailer *m;
dd1fe05b 144 register ENVELOPE *e;
d2eb2478
EA
145{
146 register int r;
d2eb2478 147
1ea752a1
EA
148 if (SmtpPid < 0)
149 return (SmtpErrstat);
150
3c6123ce
EA
151 /*
152 ** Send the data.
153 ** Dot hiding is done here.
154 */
155
e6b0a75b 156 smtpmessage("DATA");
42281a7d 157 r = reply();
3c6123ce
EA
158 if (REPLYTYPE(r) == 4)
159 return (EX_TEMPFAIL);
d2eb2478
EA
160 if (r != 354)
161 return (EX_SOFTWARE);
dd1fe05b
EA
162 (*e->e_puthdr)(SmtpOut, m, CurEnv);
163 fprintf(SmtpOut, "\n");
164 (*e->e_putbody)(SmtpOut, m, TRUE);
e6b0a75b 165 smtpmessage(".");
42281a7d 166 r = reply();
3c6123ce
EA
167 if (REPLYTYPE(r) == 4)
168 return (EX_TEMPFAIL);
d2eb2478
EA
169 if (r != 250)
170 return (EX_SOFTWARE);
d2eb2478
EA
171 return (EX_OK);
172}
173\f/*
e6b0a75b
EA
174** SMTPQUIT -- close the SMTP connection.
175**
176** Parameters:
177** name -- name of mailer we are quitting.
65a4771c 178** showresp -- if set, give a response message.
e6b0a75b
EA
179**
180** Returns:
181** none.
182**
183** Side Effects:
184** sends the final protocol and closes the connection.
185*/
186
65a4771c 187smtpquit(name, showresp)
e6b0a75b 188 char *name;
65a4771c 189 bool showresp;
e6b0a75b
EA
190{
191 register int i;
192
1ea752a1 193 if (SmtpPid < 0)
65a4771c
EA
194 return;
195 smtpmessage("QUIT");
196 (void) reply();
197 (void) fclose(SmtpIn);
198 (void) fclose(SmtpOut);
199 i = endmailer(SmtpPid, name);
200 if (showresp)
201 giveresponse(i, TRUE, LocalMailer);
e6b0a75b
EA
202}
203\f/*
d2eb2478
EA
204** REPLY -- read arpanet reply
205**
206** Parameters:
42281a7d 207** none.
d2eb2478
EA
208**
209** Returns:
210** reply code it reads.
211**
212** Side Effects:
213** flushes the mail file.
214*/
215
42281a7d 216reply()
d2eb2478 217{
e6b0a75b 218 (void) fflush(SmtpOut);
42281a7d
EA
219
220 if (Debug)
221 printf("reply\n");
d2eb2478
EA
222
223 /* read the input line */
224 for (;;)
225 {
226 char buf[MAXLINE];
227 register int r;
228
e6b0a75b 229 if (fgets(buf, sizeof buf, SmtpIn) == NULL)
d2eb2478 230 return (-1);
65a4771c 231 if (Verbose && !HoldErrs)
d2eb2478 232 fputs(buf, stdout);
65a4771c 233 fputs(buf, Xscript);
42281a7d 234 if (buf[3] == '-' || !isdigit(buf[0]))
d2eb2478
EA
235 continue;
236 r = atoi(buf);
237 if (r < 100)
238 continue;
239 return (r);
240 }
241}
42281a7d 242\f/*
e6b0a75b 243** SMTPMESSAGE -- send message to server
42281a7d
EA
244**
245** Parameters:
246** f -- format
247** a, b, c -- parameters
248**
249** Returns:
250** none.
251**
252** Side Effects:
e6b0a75b 253** writes message to SmtpOut.
42281a7d
EA
254*/
255
e6b0a75b
EA
256/*VARARGS1*/
257smtpmessage(f, a, b, c)
42281a7d
EA
258 char *f;
259{
260 char buf[100];
261
e6b0a75b 262 (void) sprintf(buf, f, a, b, c);
65a4771c
EA
263 if (Debug || (Verbose && !HoldErrs))
264 printf(">>> %s\n", buf);
265 fprintf(Xscript, ">>> %s\n", buf);
266 fprintf(SmtpOut, "%s\r\n", buf);
42281a7d 267}
884a20cb
EA
268
269# endif SMTP