14796Seric # include <ctype.h> 24684Seric # include <wellknown.h> 34684Seric # include <sysexits.h> 4*4865Seric # include "sendmail.h" 54684Seric 6*4865Seric static char SccsId[] = "@(#)usersmtp.c 3.4 11/11/81"; 74684Seric 84684Seric /* 9*4865Seric ** SMTPINIT -- initialize SMTP. 104684Seric ** 11*4865Seric ** Opens the connection and sends the initial protocol. 124684Seric ** 134684Seric ** Parameters: 14*4865Seric ** m -- mailer to create connection to. 15*4865Seric ** pvp -- pointer to parameter vector to pass to 16*4865Seric ** the mailer. 17*4865Seric ** ctladdr -- controlling address for this mailer. 184684Seric ** 194684Seric ** Returns: 20*4865Seric ** appropriate exit status -- EX_OK on success. 214684Seric ** 224684Seric ** Side Effects: 23*4865Seric ** creates connection and sends initial protocol. 244684Seric */ 254684Seric 26*4865Seric # define REPLYTYPE(r) ((r) / 100) 27*4865Seric 28*4865Seric static FILE *SmtpOut; /* output file */ 29*4865Seric static FILE *SmtpIn; /* input file */ 30*4865Seric static int SmtpPid; /* pid of mailer */ 31*4865Seric 32*4865Seric smtpinit(m, pvp, ctladdr) 33*4865Seric struct mailer *m; 34*4865Seric char **pvp; 35*4865Seric ADDRESS *ctladdr; 364684Seric { 37*4865Seric register int r; 38*4865Seric char buf[MAXNAME]; 394684Seric 40*4865Seric /* 41*4865Seric ** Open the connection to the mailer. 42*4865Seric */ 434684Seric 44*4865Seric SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn); 454796Seric 46*4865Seric /* 47*4865Seric ** Get the greeting message. 48*4865Seric ** This should appear spontaneously. 49*4865Seric */ 504797Seric 51*4865Seric r = reply(); 52*4865Seric if (REPLYTYPE(r) != 2) 53*4865Seric return (EX_TEMPFAIL); 544684Seric 55*4865Seric /* 56*4865Seric ** Send the MAIL command. 57*4865Seric ** Designates the sender. 58*4865Seric */ 594796Seric 60*4865Seric (void) expand("$g", buf, &buf[sizeof buf - 1]); 61*4865Seric smtpmessage("MAIL From:<%s>", buf); 62*4865Seric r = reply(); 63*4865Seric if (REPLYTYPE(r) == 4) 64*4865Seric return (EX_TEMPFAIL); 65*4865Seric if (r != 250) 66*4865Seric return (EX_SOFTWARE); 67*4865Seric return (EX_OK); 684684Seric } 694684Seric /* 70*4865Seric ** SMTPMRCP -- designate recipient. 714797Seric ** 724797Seric ** Parameters: 73*4865Seric ** to -- address of recipient. 744797Seric ** 754797Seric ** Returns: 76*4865Seric ** exit status corresponding to recipient status. 774797Seric ** 784797Seric ** Side Effects: 79*4865Seric ** Sends the mail via SMTP. 804797Seric */ 814797Seric 82*4865Seric smtpmrcp(to) 83*4865Seric ADDRESS *to; 844797Seric { 854797Seric register int r; 864797Seric 87*4865Seric smtpmessage("MRCP To:<%s>", to->q_user); 88*4865Seric 894797Seric r = reply(); 90*4865Seric if (REPLYTYPE(r) == 4) 91*4865Seric return (EX_TEMPFAIL); 92*4865Seric if (r != 250) 93*4865Seric return (EX_NOUSER); 944797Seric 95*4865Seric return (EX_OK); 964797Seric } 974797Seric /* 98*4865Seric ** SMTPFINISH -- finish up sending all the SMTP protocol. 994684Seric ** 1004684Seric ** Parameters: 101*4865Seric ** m -- mailer being sent to. 102*4865Seric ** editfcn -- a function to call to output the 103*4865Seric ** text of the message with. 1044684Seric ** 1054684Seric ** Returns: 106*4865Seric ** exit status corresponding to DOIT command. 1074684Seric ** 1084684Seric ** Side Effects: 109*4865Seric ** none. 1104684Seric */ 1114684Seric 112*4865Seric smtpfinish(m, editfcn) 113*4865Seric struct mailer *m; 114*4865Seric int (*editfcn)(); 1154684Seric { 1164684Seric register int r; 1174684Seric 1184797Seric /* 1194797Seric ** Send the data. 1204797Seric ** Dot hiding is done here. 1214797Seric */ 1224797Seric 123*4865Seric smtpmessage("DATA"); 1244796Seric r = reply(); 1254797Seric if (REPLYTYPE(r) == 4) 1264797Seric return (EX_TEMPFAIL); 1274684Seric if (r != 354) 1284684Seric return (EX_SOFTWARE); 129*4865Seric (*editfcn)(SmtpOut, m, TRUE); 130*4865Seric smtpmessage("."); 1314796Seric r = reply(); 1324797Seric if (REPLYTYPE(r) == 4) 1334797Seric return (EX_TEMPFAIL); 1344684Seric if (r != 250) 1354684Seric return (EX_SOFTWARE); 1364684Seric 1374797Seric /* 1384797Seric ** Make the actual delivery happen. 1394797Seric */ 1404797Seric 141*4865Seric smtpmessage("DOIT"); 1424796Seric r = reply(); 1434684Seric if (r != 250) 1444684Seric return (EX_TEMPFAIL); 1454684Seric 1464684Seric return (EX_OK); 1474684Seric } 1484684Seric /* 149*4865Seric ** SMTPQUIT -- close the SMTP connection. 150*4865Seric ** 151*4865Seric ** Parameters: 152*4865Seric ** name -- name of mailer we are quitting. 153*4865Seric ** 154*4865Seric ** Returns: 155*4865Seric ** none. 156*4865Seric ** 157*4865Seric ** Side Effects: 158*4865Seric ** sends the final protocol and closes the connection. 159*4865Seric */ 160*4865Seric 161*4865Seric smtpquit(name) 162*4865Seric char *name; 163*4865Seric { 164*4865Seric register int i; 165*4865Seric 166*4865Seric smtpmessage("QUIT"); 167*4865Seric (void) reply(); 168*4865Seric (void) fclose(SmtpIn); 169*4865Seric (void) fclose(SmtpOut); 170*4865Seric i = endmailer(SmtpPid, name); 171*4865Seric giveresponse(i, TRUE, LocalMailer); 172*4865Seric } 173*4865Seric /* 1744684Seric ** REPLY -- read arpanet reply 1754684Seric ** 1764684Seric ** Parameters: 1774796Seric ** none. 1784684Seric ** 1794684Seric ** Returns: 1804684Seric ** reply code it reads. 1814684Seric ** 1824684Seric ** Side Effects: 1834684Seric ** flushes the mail file. 1844684Seric */ 1854684Seric 1864796Seric reply() 1874684Seric { 188*4865Seric (void) fflush(SmtpOut); 1894684Seric 1904796Seric if (Debug) 1914796Seric printf("reply\n"); 1924796Seric 1934684Seric /* read the input line */ 1944684Seric for (;;) 1954684Seric { 1964684Seric char buf[MAXLINE]; 1974684Seric register int r; 1984684Seric 199*4865Seric if (fgets(buf, sizeof buf, SmtpIn) == NULL) 2004684Seric return (-1); 2014684Seric if (Verbose) 2024684Seric fputs(buf, stdout); 2034796Seric if (buf[3] == '-' || !isdigit(buf[0])) 2044684Seric continue; 2054684Seric r = atoi(buf); 2064684Seric if (r < 100) 2074684Seric continue; 2084684Seric return (r); 2094684Seric } 2104684Seric } 2114796Seric /* 212*4865Seric ** SMTPMESSAGE -- send message to server 2134796Seric ** 2144796Seric ** Parameters: 2154796Seric ** f -- format 2164796Seric ** a, b, c -- parameters 2174796Seric ** 2184796Seric ** Returns: 2194796Seric ** none. 2204796Seric ** 2214796Seric ** Side Effects: 222*4865Seric ** writes message to SmtpOut. 2234796Seric */ 2244796Seric 225*4865Seric /*VARARGS1*/ 226*4865Seric smtpmessage(f, a, b, c) 2274796Seric char *f; 2284796Seric { 2294796Seric char buf[100]; 2304796Seric 231*4865Seric (void) sprintf(buf, f, a, b, c); 2324797Seric strcat(buf, "\r\n"); 2334796Seric if (Debug) 2344796Seric fputs(buf, stdout); 235*4865Seric fputs(buf, SmtpOut); 2364796Seric } 237