. */ /** * Deliver messages using SMTP */ class Deliver_SMTP { var $domain="localhost"; var $host="localhost"; var $port=25; function mail($to, $subject, $message, $from, $additional_headers="", $additional_parameters="") { if( $stream=$this->initStream($from, $to) ) { if( strpos(strtolower($additional_headers),"subject:")===false ) $additional_headers="Subject: ".$subject."\n".$additional_headers; if( strpos(strtolower($additional_headers),"from:")===false ) $additional_headers="From: ".$from."\n".$additional_headers; $additional_headers.="\n\n"; $this->preWriteToStream($additional_headers); $this->writeToStream($stream, $additional_headers); $this->preWriteToStream($message); $this->writeToStream($stream, $message); return $this->finalizeStream($stream); } return false; } function preWriteToStream(&$s) { if( $s ) { if ($s{0} == '.') $s = '.' . $s; $s = str_replace("\n.","\n..",$s); } } function initStream($from, $to) { $to.=","; $to_list=array(); $a=0; $b=strpos($to, ",", $a); while( !($b===false) ) { $to_list[]=substr($to, $a, $b-$a); $a=$b+1; $b=strpos($to, ",", $a); } $stream = @fsockopen($this->host, $this->port, $errorNumber, $errorString); if (!$stream) { $this->dlv_msg = $errorString; $this->dlv_ret_nr = $errorNumber; return false; } $tmp = fgets($stream, 1024); if ($this->errorCheck($tmp, $stream)) { return false; } $helohost = $this->domain; /* Lets introduce ourselves */ fputs($stream, "EHLO $helohost\r\n"); $tmp = fgets($stream,1024); if ($this->errorCheck($tmp,$stream)) { // fall back to HELO if EHLO is n ot supported if ($this->dlv_ret_nr == '500') { fputs($stream, "HELO $helohost\r\n"); $tmp = fgets($stream,1024); if ($this->errorCheck($tmp,$stream)) { return false; } } else { return false; } } /* Ok, who is sending the message? */ fputs($stream, 'MAIL FROM:<'.$from.">\r\n"); $tmp = fgets($stream, 1024); if ($this->errorCheck($tmp, $stream)) { return false; } /* send who the recipients are */ for ($i = 0, $cnt = count($to_list); $i < $cnt; $i++) { fputs($stream, 'RCPT TO:<'.$to_list[$i].">\r\n"); $tmp = fgets($stream, 1024); if ($this->errorCheck($tmp, $stream)) { return false; } } /* Lets start sending the actual message */ fputs($stream, "DATA\r\n"); $tmp = fgets($stream, 1024); if ($this->errorCheck($tmp, $stream)) { return false; } return $stream; } function writeToStream($stream, $data) { fputs($stream, $data); } function finalizeStream($stream) { fputs($stream, "\r\n.\r\n"); /* end the DATA part */ $tmp = fgets($stream, 1024); $this->errorCheck($tmp, $stream); if ($this->dlv_ret_nr != 250) { return false; } fputs($stream, "QUIT\r\n"); /* log off */ fclose($stream); return true; } /* check if an SMTP reply is an error and set an error message) */ function errorCheck($line, $smtpConnection) { $err_num = substr($line, 0, 3); $this->dlv_ret_nr = $err_num; $server_msg = substr($line, 4); while(substr($line, 0, 4) == ($err_num.'-')) { $line = fgets($smtpConnection, 1024); $server_msg .= substr($line, 4); } if ( ((int) $err_num{0}) < 4) { return false; } switch ($err_num) { case '421': $message = _("Service not available, closing channel"); break; case '432': $message = _("A password transition is needed"); break; case '450': $message = _("Requested mail action not taken: mailbox unavailable"); break; case '451': $message = _("Requested action aborted: error in processing"); break; case '452': $message = _("Requested action not taken: insufficient system storage"); break; case '454': $message = _("Temporary authentication failure"); break; case '500': $message = _("Syntax error; command not recognized"); break; case '501': $message = _("Syntax error in parameters or arguments"); break; case '502': $message = _("Command not implemented"); break; case '503': $message = _("Bad sequence of commands"); break; case '504': $message = _("Command parameter not implemented"); break; case '530': $message = _("Authentication required"); break; case '534': $message = _("Authentication mechanism is too weak"); break; case '535': $message = _("Authentication failed"); break; case '538': $message = _("Encryption required for requested authentication mechanism"); break; case '550': $message = _("Requested action not taken: mailbox unavailable"); break; case '551': $message = _("User not local; please try forwarding"); break; case '552': $message = _("Requested mail action aborted: exceeding storage allocation"); break; case '553': $message = _("Requested action not taken: mailbox name not allowed"); break; case '554': $message = _("Transaction failed"); break; default: $message = _("Unknown response"); break; } $this->dlv_msg = $message; $this->dlv_server_msg = nl2br(htmlspecialchars($server_msg)); return true; } } ?>