14796Seric # include <ctype.h> 24684Seric # include <sysexits.h> 34865Seric # include "sendmail.h" 44684Seric 55182Seric # ifndef SMTP 6*6051Seric SCCSID(@(#)usersmtp.c 3.9 03/06/82 (no SMTP)); 75182Seric # else SMTP 84684Seric 9*6051Seric SCCSID(@(#)usersmtp.c 3.9 03/06/82); 105182Seric 114684Seric /* 124865Seric ** SMTPINIT -- initialize SMTP. 134684Seric ** 144865Seric ** Opens the connection and sends the initial protocol. 154684Seric ** 164684Seric ** Parameters: 174865Seric ** m -- mailer to create connection to. 184865Seric ** pvp -- pointer to parameter vector to pass to 194865Seric ** the mailer. 204865Seric ** ctladdr -- controlling address for this mailer. 214684Seric ** 224684Seric ** Returns: 234865Seric ** appropriate exit status -- EX_OK on success. 244684Seric ** 254684Seric ** Side Effects: 264865Seric ** creates connection and sends initial protocol. 274684Seric */ 284684Seric 294865Seric # define REPLYTYPE(r) ((r) / 100) 304865Seric 314865Seric static FILE *SmtpOut; /* output file */ 324865Seric static FILE *SmtpIn; /* input file */ 334865Seric static int SmtpPid; /* pid of mailer */ 34*6051Seric static int SmtpErrstat; /* error status if open fails */ 354865Seric 364865Seric smtpinit(m, pvp, ctladdr) 374865Seric struct mailer *m; 384865Seric char **pvp; 394865Seric ADDRESS *ctladdr; 404684Seric { 414865Seric register int r; 424865Seric char buf[MAXNAME]; 434684Seric 444865Seric /* 454865Seric ** Open the connection to the mailer. 464865Seric */ 474684Seric 48*6051Seric SmtpIn = SmtpOut = NULL; 494865Seric SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn); 50*6051Seric if (SmtpPid < 0) 51*6051Seric { 52*6051Seric SmtpErrstat = ExitStat; 53*6051Seric # ifdef DEBUG 54*6051Seric if (Debug > 0) 55*6051Seric printf("smtpinit: cannot open: Errstat %d errno %d\n", 56*6051Seric SmtpErrstat, errno); 57*6051Seric # endif DEBUG 58*6051Seric return (ExitStat); 59*6051Seric } 604796Seric 614865Seric /* 624865Seric ** Get the greeting message. 634865Seric ** This should appear spontaneously. 644865Seric */ 654797Seric 664865Seric r = reply(); 674865Seric if (REPLYTYPE(r) != 2) 684865Seric return (EX_TEMPFAIL); 694684Seric 704865Seric /* 714976Seric ** Send the HELO command. 724976Seric ** My mother taught me to always introduce myself, even 734976Seric ** if it is useless. 744976Seric */ 754976Seric 764976Seric smtpmessage("HELO %s", HostName); 774976Seric r = reply(); 784976Seric if (REPLYTYPE(r) == 5) 794976Seric return (EX_UNAVAILABLE); 804976Seric if (REPLYTYPE(r) != 2) 814976Seric return (EX_TEMPFAIL); 824976Seric 834976Seric /* 844865Seric ** Send the MAIL command. 854865Seric ** Designates the sender. 864865Seric */ 874796Seric 884865Seric (void) expand("$g", buf, &buf[sizeof buf - 1]); 894865Seric smtpmessage("MAIL From:<%s>", buf); 904865Seric r = reply(); 914865Seric if (REPLYTYPE(r) == 4) 924865Seric return (EX_TEMPFAIL); 934865Seric if (r != 250) 944865Seric return (EX_SOFTWARE); 954865Seric return (EX_OK); 964684Seric } 974684Seric /* 984976Seric ** SMTPRCPT -- designate recipient. 994797Seric ** 1004797Seric ** Parameters: 1014865Seric ** to -- address of recipient. 1024797Seric ** 1034797Seric ** Returns: 1044865Seric ** exit status corresponding to recipient status. 1054797Seric ** 1064797Seric ** Side Effects: 1074865Seric ** Sends the mail via SMTP. 1084797Seric */ 1094797Seric 1104976Seric smtprcpt(to) 1114865Seric ADDRESS *to; 1124797Seric { 1134797Seric register int r; 1144797Seric 115*6051Seric if (SmtpPid < 0) 116*6051Seric return (SmtpErrstat); 117*6051Seric 1184976Seric smtpmessage("RCPT To:<%s>", to->q_user); 1194865Seric 1204797Seric r = reply(); 1214865Seric if (REPLYTYPE(r) == 4) 1224865Seric return (EX_TEMPFAIL); 1234865Seric if (r != 250) 1244865Seric return (EX_NOUSER); 1254797Seric 1264865Seric return (EX_OK); 1274797Seric } 1284797Seric /* 1294865Seric ** SMTPFINISH -- finish up sending all the SMTP protocol. 1304684Seric ** 1314684Seric ** Parameters: 1324865Seric ** m -- mailer being sent to. 1334865Seric ** editfcn -- a function to call to output the 1344865Seric ** text of the message with. 1354684Seric ** 1364684Seric ** Returns: 1374976Seric ** exit status corresponding to DATA command. 1384684Seric ** 1394684Seric ** Side Effects: 1404865Seric ** none. 1414684Seric */ 1424684Seric 1434865Seric smtpfinish(m, editfcn) 1444865Seric struct mailer *m; 1454865Seric int (*editfcn)(); 1464684Seric { 1474684Seric register int r; 1484684Seric 149*6051Seric if (SmtpPid < 0) 150*6051Seric return (SmtpErrstat); 151*6051Seric 1524797Seric /* 1534797Seric ** Send the data. 1544797Seric ** Dot hiding is done here. 1554797Seric */ 1564797Seric 1574865Seric smtpmessage("DATA"); 1584796Seric r = reply(); 1594797Seric if (REPLYTYPE(r) == 4) 1604797Seric return (EX_TEMPFAIL); 1614684Seric if (r != 354) 1624684Seric return (EX_SOFTWARE); 1634865Seric (*editfcn)(SmtpOut, m, TRUE); 1644865Seric smtpmessage("."); 1654796Seric r = reply(); 1664797Seric if (REPLYTYPE(r) == 4) 1674797Seric return (EX_TEMPFAIL); 1684684Seric if (r != 250) 1694684Seric return (EX_SOFTWARE); 1704684Seric return (EX_OK); 1714684Seric } 1724684Seric /* 1734865Seric ** SMTPQUIT -- close the SMTP connection. 1744865Seric ** 1754865Seric ** Parameters: 1764865Seric ** name -- name of mailer we are quitting. 1774865Seric ** 1784865Seric ** Returns: 1794865Seric ** none. 1804865Seric ** 1814865Seric ** Side Effects: 1824865Seric ** sends the final protocol and closes the connection. 1834865Seric */ 1844865Seric 1854865Seric smtpquit(name) 1864865Seric char *name; 1874865Seric { 1884865Seric register int i; 1894865Seric 190*6051Seric if (SmtpPid < 0) 191*6051Seric { 192*6051Seric i = SmtpErrstat; 193*6051Seric } 194*6051Seric else 195*6051Seric { 196*6051Seric smtpmessage("QUIT"); 197*6051Seric (void) reply(); 198*6051Seric (void) fclose(SmtpIn); 199*6051Seric (void) fclose(SmtpOut); 200*6051Seric i = endmailer(SmtpPid, name); 201*6051Seric } 2024865Seric giveresponse(i, TRUE, LocalMailer); 2034865Seric } 2044865Seric /* 2054684Seric ** REPLY -- read arpanet reply 2064684Seric ** 2074684Seric ** Parameters: 2084796Seric ** none. 2094684Seric ** 2104684Seric ** Returns: 2114684Seric ** reply code it reads. 2124684Seric ** 2134684Seric ** Side Effects: 2144684Seric ** flushes the mail file. 2154684Seric */ 2164684Seric 2174796Seric reply() 2184684Seric { 2194865Seric (void) fflush(SmtpOut); 2204684Seric 2214796Seric if (Debug) 2224796Seric printf("reply\n"); 2234796Seric 2244684Seric /* read the input line */ 2254684Seric for (;;) 2264684Seric { 2274684Seric char buf[MAXLINE]; 2284684Seric register int r; 2294684Seric 2304865Seric if (fgets(buf, sizeof buf, SmtpIn) == NULL) 2314684Seric return (-1); 2324684Seric if (Verbose) 2334684Seric fputs(buf, stdout); 2344796Seric if (buf[3] == '-' || !isdigit(buf[0])) 2354684Seric continue; 2364684Seric r = atoi(buf); 2374684Seric if (r < 100) 2384684Seric continue; 2394684Seric return (r); 2404684Seric } 2414684Seric } 2424796Seric /* 2434865Seric ** SMTPMESSAGE -- send message to server 2444796Seric ** 2454796Seric ** Parameters: 2464796Seric ** f -- format 2474796Seric ** a, b, c -- parameters 2484796Seric ** 2494796Seric ** Returns: 2504796Seric ** none. 2514796Seric ** 2524796Seric ** Side Effects: 2534865Seric ** writes message to SmtpOut. 2544796Seric */ 2554796Seric 2564865Seric /*VARARGS1*/ 2574865Seric smtpmessage(f, a, b, c) 2584796Seric char *f; 2594796Seric { 2604796Seric char buf[100]; 2614796Seric 2624865Seric (void) sprintf(buf, f, a, b, c); 2634797Seric strcat(buf, "\r\n"); 2644796Seric if (Debug) 2654796Seric fputs(buf, stdout); 2664865Seric fputs(buf, SmtpOut); 2674796Seric } 2685182Seric 2695182Seric # endif SMTP 270