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