module dinc.deliver.External; private import dinc.Deliver; class External : Deliver { import dinc.Message; import dinc.deliver.Smtp; import dinc.Dinc; import std.socket; import std.socketstream; import std.file; import std.process; import std.date; import std.stdio; import dinc.deliver.MxRecord; InternetAddress address; this(Message m, char[] domain) { super (m,domain); } void send() { // this needs to catch errors... // and perhap's queue stuff if the remote server is slow.... auto records = MxRecord.lookup(domain); if (!records) { message.queueSend(localParts,domain); return; } foreach(record;records) { // we are not very specific here on failure - what if one address of many fails. try { this.address = new InternetAddress(record.name, 25); auto Socket socket = new TcpSocket(address); //socket.setTimeout (timeout); FIXME auto ss = new SocketStream(socket); auto smtp = new Smtp(ss); sendExpect(null, 220); helo(dinc.Dinc.options.getString("smtp-hostname")); mailFrom(from); char[][] failedrcpts; foreach(rcpt;localParts) { try { rcptTo(rcpt ~ "@" ~ domain); } catch (Exception e) { failedrcpts ~= rcpt; } } if (failedrcpts.length == localParts.length) { throw new Exception("Sending failed"); // try next host... } data(message.dataAsString()); ss.close(); if (failedrcpts) { message.queueSend(failedrcpts,domain); } return; } catch(Exception e) { // try next. // logging? continue; } } // failed to send .. queue it.. message.queueSend(localParts,domain); //writefln("MX=%s=", mx); // open a socket to the server, then send it.. // we may need to think about } }