14796Seric # include <ctype.h> 24684Seric # include <sysexits.h> 34865Seric # include "sendmail.h" 44684Seric 55182Seric # ifndef SMTP 6*6980Seric SCCSID(@(#)usersmtp.c 3.9.1.1 05/29/82 (no SMTP)); 75182Seric # else SMTP 84684Seric 9*6980Seric SCCSID(@(#)usersmtp.c 3.9.1.1 05/29/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 */ 346051Seric 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 486051Seric SmtpIn = SmtpOut = NULL; 494865Seric SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn); 506051Seric if (SmtpPid < 0) 516051Seric { 526051Seric SmtpErrstat = ExitStat; 536051Seric # ifdef DEBUG 546051Seric if (Debug > 0) 556051Seric printf("smtpinit: cannot open: Errstat %d errno %d\n", 566051Seric SmtpErrstat, errno); 576051Seric # endif DEBUG 586051Seric return (ExitStat); 596051Seric } 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 88*6980Seric expand("$g", buf, &buf[sizeof buf - 1], CurEnv); 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 1156051Seric if (SmtpPid < 0) 1166051Seric return (SmtpErrstat); 1176051Seric 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. 133*6980Seric ** e -- the envelope for this message. 1344684Seric ** 1354684Seric ** Returns: 1364976Seric ** exit status corresponding to DATA command. 1374684Seric ** 1384684Seric ** Side Effects: 1394865Seric ** none. 1404684Seric */ 1414684Seric 142*6980Seric smtpfinish(m, e) 1434865Seric struct mailer *m; 144*6980Seric register ENVELOPE *e; 1454684Seric { 1464684Seric register int r; 1474684Seric 1486051Seric if (SmtpPid < 0) 1496051Seric return (SmtpErrstat); 1506051Seric 1514797Seric /* 1524797Seric ** Send the data. 1534797Seric ** Dot hiding is done here. 1544797Seric */ 1554797Seric 1564865Seric smtpmessage("DATA"); 1574796Seric r = reply(); 1584797Seric if (REPLYTYPE(r) == 4) 1594797Seric return (EX_TEMPFAIL); 1604684Seric if (r != 354) 1614684Seric return (EX_SOFTWARE); 162*6980Seric (*e->e_puthdr)(SmtpOut, m, CurEnv); 163*6980Seric fprintf(SmtpOut, "\n"); 164*6980Seric (*e->e_putbody)(SmtpOut, m, TRUE); 1654865Seric smtpmessage("."); 1664796Seric r = reply(); 1674797Seric if (REPLYTYPE(r) == 4) 1684797Seric return (EX_TEMPFAIL); 1694684Seric if (r != 250) 1704684Seric return (EX_SOFTWARE); 1714684Seric return (EX_OK); 1724684Seric } 1734684Seric /* 1744865Seric ** SMTPQUIT -- close the SMTP connection. 1754865Seric ** 1764865Seric ** Parameters: 1774865Seric ** name -- name of mailer we are quitting. 1784865Seric ** 1794865Seric ** Returns: 1804865Seric ** none. 1814865Seric ** 1824865Seric ** Side Effects: 1834865Seric ** sends the final protocol and closes the connection. 1844865Seric */ 1854865Seric 1864865Seric smtpquit(name) 1874865Seric char *name; 1884865Seric { 1894865Seric register int i; 1904865Seric 1916051Seric if (SmtpPid < 0) 1926051Seric { 1936051Seric i = SmtpErrstat; 1946051Seric } 1956051Seric else 1966051Seric { 1976051Seric smtpmessage("QUIT"); 1986051Seric (void) reply(); 1996051Seric (void) fclose(SmtpIn); 2006051Seric (void) fclose(SmtpOut); 2016051Seric i = endmailer(SmtpPid, name); 2026051Seric } 2034865Seric giveresponse(i, TRUE, LocalMailer); 2044865Seric } 2054865Seric /* 2064684Seric ** REPLY -- read arpanet reply 2074684Seric ** 2084684Seric ** Parameters: 2094796Seric ** none. 2104684Seric ** 2114684Seric ** Returns: 2124684Seric ** reply code it reads. 2134684Seric ** 2144684Seric ** Side Effects: 2154684Seric ** flushes the mail file. 2164684Seric */ 2174684Seric 2184796Seric reply() 2194684Seric { 2204865Seric (void) fflush(SmtpOut); 2214684Seric 2224796Seric if (Debug) 2234796Seric printf("reply\n"); 2244796Seric 2254684Seric /* read the input line */ 2264684Seric for (;;) 2274684Seric { 2284684Seric char buf[MAXLINE]; 2294684Seric register int r; 2304684Seric 2314865Seric if (fgets(buf, sizeof buf, SmtpIn) == NULL) 2324684Seric return (-1); 2334684Seric if (Verbose) 2344684Seric fputs(buf, stdout); 2354796Seric if (buf[3] == '-' || !isdigit(buf[0])) 2364684Seric continue; 2374684Seric r = atoi(buf); 2384684Seric if (r < 100) 2394684Seric continue; 2404684Seric return (r); 2414684Seric } 2424684Seric } 2434796Seric /* 2444865Seric ** SMTPMESSAGE -- send message to server 2454796Seric ** 2464796Seric ** Parameters: 2474796Seric ** f -- format 2484796Seric ** a, b, c -- parameters 2494796Seric ** 2504796Seric ** Returns: 2514796Seric ** none. 2524796Seric ** 2534796Seric ** Side Effects: 2544865Seric ** writes message to SmtpOut. 2554796Seric */ 2564796Seric 2574865Seric /*VARARGS1*/ 2584865Seric smtpmessage(f, a, b, c) 2594796Seric char *f; 2604796Seric { 2614796Seric char buf[100]; 2624796Seric 2634865Seric (void) sprintf(buf, f, a, b, c); 2644797Seric strcat(buf, "\r\n"); 2654796Seric if (Debug) 2664796Seric fputs(buf, stdout); 2674865Seric fputs(buf, SmtpOut); 2684796Seric } 2695182Seric 2705182Seric # endif SMTP 271