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