14796Seric # include <ctype.h> 24684Seric # include <wellknown.h> 34684Seric # include <sysexits.h> 44865Seric # include "sendmail.h" 54684Seric 6*5182Seric # ifndef SMTP 7*5182Seric static char SccsId[] = "@(#)usersmtp.c 3.6 12/05/81 (no SMTP)"; 8*5182Seric # else SMTP 94684Seric 10*5182Seric static char SccsId[] = "@(#)usersmtp.c 3.6 12/05/81"; 11*5182Seric 124684Seric /* 134865Seric ** SMTPINIT -- initialize SMTP. 144684Seric ** 154865Seric ** Opens the connection and sends the initial protocol. 164684Seric ** 174684Seric ** Parameters: 184865Seric ** m -- mailer to create connection to. 194865Seric ** pvp -- pointer to parameter vector to pass to 204865Seric ** the mailer. 214865Seric ** ctladdr -- controlling address for this mailer. 224684Seric ** 234684Seric ** Returns: 244865Seric ** appropriate exit status -- EX_OK on success. 254684Seric ** 264684Seric ** Side Effects: 274865Seric ** creates connection and sends initial protocol. 284684Seric */ 294684Seric 304865Seric # define REPLYTYPE(r) ((r) / 100) 314865Seric 324865Seric static FILE *SmtpOut; /* output file */ 334865Seric static FILE *SmtpIn; /* input file */ 344865Seric static int SmtpPid; /* pid of mailer */ 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 484865Seric SmtpPid = openmailer(m, pvp, ctladdr, TRUE, &SmtpOut, &SmtpIn); 494796Seric 504865Seric /* 514865Seric ** Get the greeting message. 524865Seric ** This should appear spontaneously. 534865Seric */ 544797Seric 554865Seric r = reply(); 564865Seric if (REPLYTYPE(r) != 2) 574865Seric return (EX_TEMPFAIL); 584684Seric 594865Seric /* 604976Seric ** Send the HELO command. 614976Seric ** My mother taught me to always introduce myself, even 624976Seric ** if it is useless. 634976Seric */ 644976Seric 654976Seric smtpmessage("HELO %s", HostName); 664976Seric r = reply(); 674976Seric if (REPLYTYPE(r) == 5) 684976Seric return (EX_UNAVAILABLE); 694976Seric if (REPLYTYPE(r) != 2) 704976Seric return (EX_TEMPFAIL); 714976Seric 724976Seric /* 734865Seric ** Send the MAIL command. 744865Seric ** Designates the sender. 754865Seric */ 764796Seric 774865Seric (void) expand("$g", buf, &buf[sizeof buf - 1]); 784865Seric smtpmessage("MAIL From:<%s>", buf); 794865Seric r = reply(); 804865Seric if (REPLYTYPE(r) == 4) 814865Seric return (EX_TEMPFAIL); 824865Seric if (r != 250) 834865Seric return (EX_SOFTWARE); 844865Seric return (EX_OK); 854684Seric } 864684Seric /* 874976Seric ** SMTPRCPT -- designate recipient. 884797Seric ** 894797Seric ** Parameters: 904865Seric ** to -- address of recipient. 914797Seric ** 924797Seric ** Returns: 934865Seric ** exit status corresponding to recipient status. 944797Seric ** 954797Seric ** Side Effects: 964865Seric ** Sends the mail via SMTP. 974797Seric */ 984797Seric 994976Seric smtprcpt(to) 1004865Seric ADDRESS *to; 1014797Seric { 1024797Seric register int r; 1034797Seric 1044976Seric smtpmessage("RCPT To:<%s>", to->q_user); 1054865Seric 1064797Seric r = reply(); 1074865Seric if (REPLYTYPE(r) == 4) 1084865Seric return (EX_TEMPFAIL); 1094865Seric if (r != 250) 1104865Seric return (EX_NOUSER); 1114797Seric 1124865Seric return (EX_OK); 1134797Seric } 1144797Seric /* 1154865Seric ** SMTPFINISH -- finish up sending all the SMTP protocol. 1164684Seric ** 1174684Seric ** Parameters: 1184865Seric ** m -- mailer being sent to. 1194865Seric ** editfcn -- a function to call to output the 1204865Seric ** text of the message with. 1214684Seric ** 1224684Seric ** Returns: 1234976Seric ** exit status corresponding to DATA command. 1244684Seric ** 1254684Seric ** Side Effects: 1264865Seric ** none. 1274684Seric */ 1284684Seric 1294865Seric smtpfinish(m, editfcn) 1304865Seric struct mailer *m; 1314865Seric int (*editfcn)(); 1324684Seric { 1334684Seric register int r; 1344684Seric 1354797Seric /* 1364797Seric ** Send the data. 1374797Seric ** Dot hiding is done here. 1384797Seric */ 1394797Seric 1404865Seric smtpmessage("DATA"); 1414796Seric r = reply(); 1424797Seric if (REPLYTYPE(r) == 4) 1434797Seric return (EX_TEMPFAIL); 1444684Seric if (r != 354) 1454684Seric return (EX_SOFTWARE); 1464865Seric (*editfcn)(SmtpOut, m, TRUE); 1474865Seric smtpmessage("."); 1484796Seric r = reply(); 1494797Seric if (REPLYTYPE(r) == 4) 1504797Seric return (EX_TEMPFAIL); 1514684Seric if (r != 250) 1524684Seric return (EX_SOFTWARE); 1534684Seric return (EX_OK); 1544684Seric } 1554684Seric /* 1564865Seric ** SMTPQUIT -- close the SMTP connection. 1574865Seric ** 1584865Seric ** Parameters: 1594865Seric ** name -- name of mailer we are quitting. 1604865Seric ** 1614865Seric ** Returns: 1624865Seric ** none. 1634865Seric ** 1644865Seric ** Side Effects: 1654865Seric ** sends the final protocol and closes the connection. 1664865Seric */ 1674865Seric 1684865Seric smtpquit(name) 1694865Seric char *name; 1704865Seric { 1714865Seric register int i; 1724865Seric 1734865Seric smtpmessage("QUIT"); 1744865Seric (void) reply(); 1754865Seric (void) fclose(SmtpIn); 1764865Seric (void) fclose(SmtpOut); 1774865Seric i = endmailer(SmtpPid, name); 1784865Seric giveresponse(i, TRUE, LocalMailer); 1794865Seric } 1804865Seric /* 1814684Seric ** REPLY -- read arpanet reply 1824684Seric ** 1834684Seric ** Parameters: 1844796Seric ** none. 1854684Seric ** 1864684Seric ** Returns: 1874684Seric ** reply code it reads. 1884684Seric ** 1894684Seric ** Side Effects: 1904684Seric ** flushes the mail file. 1914684Seric */ 1924684Seric 1934796Seric reply() 1944684Seric { 1954865Seric (void) fflush(SmtpOut); 1964684Seric 1974796Seric if (Debug) 1984796Seric printf("reply\n"); 1994796Seric 2004684Seric /* read the input line */ 2014684Seric for (;;) 2024684Seric { 2034684Seric char buf[MAXLINE]; 2044684Seric register int r; 2054684Seric 2064865Seric if (fgets(buf, sizeof buf, SmtpIn) == NULL) 2074684Seric return (-1); 2084684Seric if (Verbose) 2094684Seric fputs(buf, stdout); 2104796Seric if (buf[3] == '-' || !isdigit(buf[0])) 2114684Seric continue; 2124684Seric r = atoi(buf); 2134684Seric if (r < 100) 2144684Seric continue; 2154684Seric return (r); 2164684Seric } 2174684Seric } 2184796Seric /* 2194865Seric ** SMTPMESSAGE -- send message to server 2204796Seric ** 2214796Seric ** Parameters: 2224796Seric ** f -- format 2234796Seric ** a, b, c -- parameters 2244796Seric ** 2254796Seric ** Returns: 2264796Seric ** none. 2274796Seric ** 2284796Seric ** Side Effects: 2294865Seric ** writes message to SmtpOut. 2304796Seric */ 2314796Seric 2324865Seric /*VARARGS1*/ 2334865Seric smtpmessage(f, a, b, c) 2344796Seric char *f; 2354796Seric { 2364796Seric char buf[100]; 2374796Seric 2384865Seric (void) sprintf(buf, f, a, b, c); 2394797Seric strcat(buf, "\r\n"); 2404796Seric if (Debug) 2414796Seric fputs(buf, stdout); 2424865Seric fputs(buf, SmtpOut); 2434796Seric } 244*5182Seric 245*5182Seric # endif SMTP 246