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