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