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