In PHP I've written a relatively simple mail delivery script. Here is the actual delivery portion:
private function SendMail($to, $subj) {
if(!$this->smtp) { $this->OpenSMTPSock(); }
fwrite($this->smtp, "MAIL FROM:<[email protected]>\r\n");
fwrite($this->smtp, "RCPT TO:<$to>\r\n");
fwrite($this->smtp, "DATA\r\n");
fwrite($this->smtp, "Received: from email.com by domain.com ; ".date("r")."\r\n");
fwrite($this->smtp, "Date: ".date("r")."\r\n");
fwrite($this->smtp, "From: ".$this->message["display_name"]." <[email protected]>\r\n");
fwrite($this->smtp, "Reply-to: ".$this->message["reply"]."\r\n");
fwrite($this->smtp, "Subject: $subj\r\n");
fwrite($this->smtp, "To: $to\r\n");
if($this->message["type"] == "H") {
fwrite($this->smtp, "content-type: text/html; charset=`iso-8859-1`");
fwrite($this->smtp, "\r\n".$this->m_html."\r\n");
}
if($this->message["type"] == "T") {
fwrite($this->smtp, "\r\n".$this->m_text."\r\n");
}
if($this->message["type"] == "B") {
echo "Sending multi part message\r\n";
$boundary = "_----------=_10167391337129230";
fwrite($this->smtp, "content-type: multipart/alternative; boundary=\"$boundary\"\r\n");
$outMsg = "This is a multi-part message in MIME format.\r\n";
$outMsg .= "--$boundary\r\nContent-Type: text/plain; charset=\"US-ASCII\"\r\n\n";
$outMsg .= "Content-Transfer-Encoding: 7bit\r\n\n";
$outMsg .= $this->m_text;
$outMsg .= "\r\n--$boundary\r\nContent-Type: text/html; charset=\"US-ASCII\"\r\n\n";
$outMsg .= $this->m_html;
$outMsg .= "\r\n--$boundary--";
fwrite($this->smtp, "Message: $outMsg\r\n");
}
fwrite($this->smtp, ".\r\n"); //This sends the message
$this->Log("Message sent to $to");
}
Here is where the socket is opened:
private function OpenSMTPSock() {
$this->Log("Attempting to open socket connection to SMTP host.");
$this->smtp = fsockopen("localhost", 25, $errno, $errstr, 30);
if(!$this->smtp) {
$this->Log("Failed to connect to SMTP server The following was observed.");
$this->Log("Fatal Error: $errno : $errstr");
exit;
}
else {
$this->Log("Connected to SMTP socket.");
fwrite($this->smtp, "HELO email.com\r\n");
}
}
*A destructor closes the socket Basically I loop through the list of recipients and send out a customized message to each one. It works perfectly until it gets to the last message, which doesn't get sent.
If I change $this->smtp to fopen("file", "w"), all the contents are there as expected. Additionally, if I then open that file and dump the contents into: telnet localhost 25 All the messages go out properly. Also, if I open the "file" within the PHP script, and write the lines into the socket, all messages go out as intended.
For the life of me, I can't figure out what is going wrong here. Halp!
Is your destructor sending the QUIT command? I concur that if everything is happening the way you think, the mail should have sent if the server returns the "250 OK" (does it after your last message? are you debugging this?). Try adding this to your code right after the 'CRLF.CRLF':
Maybe your class is having some sort of race condition with the buffer, the class is closing the connection before that final data in the buffer is sent. Adding a dummy NOOP to the chain might cause it to flush the previous bits out the pipe.