/* -*- LPC -*- */ /* * $Locker: $ * $Id: smtp.c,v 1.4 2000/11/02 06:38:12 ceres Exp $ * $Log: smtp.c,v $ * Revision 1.4 2000/11/02 06:38:12 ceres * It needed a FQDN for our current sendmail config * * Revision 1.3 2000/02/18 17:21:39 turrican * Let Sendmail determine the FQDN * * Revision 1.2 1998/05/22 12:14:34 turrican * Added possibility of multiple recipients. * * Revision 1.1 1998/01/06 05:20:37 ceres * Initial revision * */ /* * SMTP client, written by Turrican@Discworld. * Created 4-2-96. */ #include <network.h> #include <mail.h> #include <mime.h> #include "smtp.h" inherit CLIENT; private nosave mixed *data = ({}); private nosave string *messages = ({}); private nosave int fd = -1; protected void create() { client::create(); client::SetSocketType(STREAM); client::SetDestructOnClose(1); } void eventWrite(string mess) { return client::eventWrite(fd, mess); } void eventSendMail(mixed to, string from, string mess) { if (!to || !from || !mess) { return; } if (stringp(to)) { data += ({ ({ "MAIL FROM:<" + from + ".discworld@discworld.imaginary.com>\r\n", "RCPT TO:<" + to + ">\r\n", "DATA\r\n" }) }); } else if (arrayp(to) && sizeof(to)) { string *tmpdata; tmpdata = ({ "MAIL FROM:<" + from + ".discworld@discworld.imaginary.com>\r\n" }); tmpdata += map(to, (: "RCPT TO:<" + $1 + ">\r\n" :)); tmpdata += ({ "DATA\r\n" }); data += ({ tmpdata }); } else { return; } mess = MIME->rewrite_header(mess); mess = replace(mess, ({"\n.", "\n..", "\n", "\r\n"})); messages += ({ mess }); if (fd > 0) { return; } if ((fd = eventCreateSocket(SMTP_HOST, SMTP_PORT)) < 0) { data = data[0..<2]; messages = messages[0..<2]; } } protected void eventSuccess() { if (sizeof(data) && sizeof(data[0])) { TP(sprintf("SMTP: Writing %s\n", data[0][0])); eventWrite(data[0][0]); data[0] = data[0][1..]; } else if (sizeof(data) && !sizeof(data[0])) { TP("SMTP: No more data, next message.\n"); data = data[1..]; if (!sizeof(data)) { TP(sprintf("SMTP: Writing QUIT\n")); eventWrite("QUIT\r\n"); } else eventSuccess(); } } protected void eventOKToSendMail() { if (sizeof(messages) && messages[0] && (strlen(messages[0]) > 0)) { TP("SMTP: Sending mail message.\n"); eventWrite(messages[0] + "\n.\n"); messages = messages[1..]; } else { TP("SMTP: No message...\n"); messages = messages[1..]; eventWrite("RSET\r\n"); } } protected void eventForward(string who) { if (who && who != "") { TP(sprintf("SMTP: Forwarding to %s.\n", who)); eventWrite("RSET\r\n"); eventWrite(sprintf("RCPT TO:<%s>\r\n", who)); } else { TP("SMTP: Told to forward, but no forwardee...\n"); eventWrite("QUIT\r\n"); } } protected void eventRead(int fd, string mess) { string forward; if (!mess) return; mess = replace_string(mess, "\r", ""); switch (mess[0..2]) { case "220": eventWrite(sprintf("HELO %s\r\n", MUD_IP_NAME)); break; case "250": case "251": eventSuccess(); break; case "354": eventOKToSendMail(); break; case "421": case "450": case "451": case "452": case "500": case "501": case "502": case "503": case "504": case "550": case "552": case "553": case "554": TP(sprintf("<FATAL> SMTP: %s", mess)); eventWrite("QUIT\r\n"); break; case "551": if (sscanf(mess, "%*s<%s>%*s", forward) != 3) { TP(sprintf("SMTP: %s", mess)); break; } eventForward(forward); break; default: break; } }