summaryrefslogtreecommitdiffstats
path: root/src/etc/inc/smtp.inc
diff options
context:
space:
mode:
Diffstat (limited to 'src/etc/inc/smtp.inc')
-rw-r--r--src/etc/inc/smtp.inc862
1 files changed, 862 insertions, 0 deletions
diff --git a/src/etc/inc/smtp.inc b/src/etc/inc/smtp.inc
new file mode 100644
index 0000000..035a30a
--- /dev/null
+++ b/src/etc/inc/smtp.inc
@@ -0,0 +1,862 @@
+<?php
+/*
+ * smtp.php
+ *
+ * @(#) $Header$
+ *
+ */
+
+/*
+ pfSense_MODULE: notifications
+*/
+
+class smtp_class
+{
+ var $user="";
+ var $realm="";
+ var $password="";
+ var $workstation="";
+ var $authentication_mechanism="";
+ var $host_name="";
+ var $host_port=25;
+ var $ssl=0;
+ var $tls=0;
+ var $localhost="";
+ var $timeout=0;
+ var $data_timeout=0;
+ var $direct_delivery=0;
+ var $error="";
+ var $debug=0;
+ var $html_debug=0;
+ var $esmtp=1;
+ var $esmtp_host="";
+ var $esmtp_extensions=array();
+ var $maximum_piped_recipients=100;
+ var $exclude_address="";
+ var $getmxrr="GetMXRR";
+ var $pop3_auth_host="";
+ var $pop3_auth_port=110;
+
+ /* private variables - DO NOT ACCESS */
+
+ var $state="Disconnected";
+ var $connection=0;
+ var $pending_recipients=0;
+ var $next_token="";
+ var $direct_sender="";
+ var $connected_domain="";
+ var $result_code;
+ var $disconnected_error=0;
+
+ /* Private methods - DO NOT CALL */
+
+ Function Tokenize($string,$separator="")
+ {
+ if(!strcmp($separator,""))
+ {
+ $separator=$string;
+ $string=$this->next_token;
+ }
+ for($character=0;$character<strlen($separator);$character++)
+ {
+ if(GetType($position=strpos($string,$separator[$character]))=="integer")
+ $found=(IsSet($found) ? min($found,$position) : $position);
+ }
+ if(IsSet($found))
+ {
+ $this->next_token=substr($string,$found+1);
+ return(substr($string,0,$found));
+ }
+ else
+ {
+ $this->next_token="";
+ return($string);
+ }
+ }
+
+ Function OutputDebug($message)
+ {
+ $message.="\n";
+ if($this->html_debug)
+ $message=str_replace("\n","<br />\n",HtmlEntities($message));
+ echo $message;
+ flush();
+ }
+
+ Function SetDataAccessError($error)
+ {
+ $this->error=$error;
+ if(function_exists("socket_get_status"))
+ {
+ $status=socket_get_status($this->connection);
+ if($status["timed_out"])
+ $this->error.=gettext(": data access time out");
+ elseif($status["eof"])
+ {
+ $this->error.=gettext(": the server disconnected");
+ $this->disconnected_error=1;
+ }
+ }
+ }
+
+ Function GetLine()
+ {
+ for($line="";;)
+ {
+ if(feof($this->connection))
+ {
+ $this->error=gettext("reached the end of data while reading from the SMTP server connection");
+ return("");
+ }
+ if(GetType($data=@fgets($this->connection,100))!="string"
+ || strlen($data)==0)
+ {
+ $this->SetDataAccessError(gettext("it was not possible to read line from the SMTP server"));
+ return("");
+ }
+ $line.=$data;
+ $length=strlen($line);
+ if($length>=2
+ && substr($line,$length-2,2)=="\r\n")
+ {
+ $line=substr($line,0,$length-2);
+ if($this->debug)
+ $this->OutputDebug("S $line");
+ return($line);
+ }
+ }
+ }
+
+ Function PutLine($line)
+ {
+ if($this->debug)
+ $this->OutputDebug("C $line");
+ if(!@fputs($this->connection,"$line\r\n"))
+ {
+ $this->SetDataAccessError(gettext("it was not possible to send a line to the SMTP server"));
+ return(0);
+ }
+ return(1);
+ }
+
+ Function PutData(&$data)
+ {
+ if(strlen($data))
+ {
+ if($this->debug)
+ $this->OutputDebug("C $data");
+ if(!@fputs($this->connection,$data))
+ {
+ $this->SetDataAccessError(gettext("it was not possible to send data to the SMTP server"));
+ return(0);
+ }
+ }
+ return(1);
+ }
+
+ Function VerifyResultLines($code,&$responses)
+ {
+ $responses=array();
+ Unset($this->result_code);
+ while(strlen($line=$this->GetLine($this->connection)))
+ {
+ if(IsSet($this->result_code))
+ {
+ if(strcmp($this->Tokenize($line," -"),$this->result_code))
+ {
+ $this->error=$line;
+ return(0);
+ }
+ }
+ else
+ {
+ $this->result_code=$this->Tokenize($line," -");
+ if(GetType($code)=="array")
+ {
+ for($codes=0;$codes<count($code) && strcmp($this->result_code,$code[$codes]);$codes++);
+ if($codes>=count($code))
+ {
+ $this->error=$line;
+ return(0);
+ }
+ }
+ else
+ {
+ if(strcmp($this->result_code,$code))
+ {
+ $this->error=$line;
+ return(0);
+ }
+ }
+ }
+ $responses[]=$this->Tokenize("");
+ if(!strcmp($this->result_code,$this->Tokenize($line," ")))
+ return(1);
+ }
+ return(-1);
+ }
+
+ Function FlushRecipients()
+ {
+ if($this->pending_sender)
+ {
+ if($this->VerifyResultLines("250",$responses)<=0)
+ return(0);
+ $this->pending_sender=0;
+ }
+ for(;$this->pending_recipients;$this->pending_recipients--)
+ {
+ if($this->VerifyResultLines(array("250","251"),$responses)<=0)
+ return(0);
+ }
+ return(1);
+ }
+
+ Function ConnectToHost($domain, $port, $resolve_message)
+ {
+ if($this->ssl || $this->tls)
+ {
+ $version=explode(".",function_exists("phpversion") ? phpversion() : "3.0.7");
+ $php_version=intval($version[0])*1000000+intval($version[1])*1000+intval($version[2]);
+ if($php_version<4003000)
+ return(gettext("establishing SSL connections requires at least PHP version 4.3.0"));
+ if(!function_exists("extension_loaded")
+ || !extension_loaded("openssl"))
+ return(gettext("establishing SSL connections requires the OpenSSL extension enabled"));
+ }
+ if(preg_match('/^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$/',$domain))
+ $ip=$domain;
+ else
+ {
+ if($this->debug)
+ $this->OutputDebug($resolve_message);
+ if(!strcmp($ip=@gethostbyname($domain),$domain))
+ return(sprintf(gettext("could not resolve host \"%s\""), $domain));
+ }
+ if(strlen($this->exclude_address)
+ && !strcmp(@gethostbyname($this->exclude_address),$ip))
+ return(sprintf(gettext("domain \"%s\" resolved to an address excluded to be valid"), $domain));
+ if($this->debug)
+ $this->OutputDebug(sprintf(gettext('Connecting to host address "%1$s" port %2$s...'), $ip, $port));
+ if(($this->connection=($this->timeout ? @fsockopen(($this->ssl ? "ssl://" : "").$ip,$port,$errno,$error,$this->timeout) : @fsockopen(($this->ssl ? "ssl://" : "").$ip,$port))))
+ return("");
+ $error=($this->timeout ? strval($error) : "??");
+ switch($error)
+ {
+ case "-3":
+ return(gettext("-3 socket could not be created"));
+ case "-4":
+ return(sprintf(gettext("-4 dns lookup on hostname \"%s\" failed"), $domain));
+ case "-5":
+ return(gettext("-5 connection refused or timed out"));
+ case "-6":
+ return(gettext("-6 fdopen() call failed"));
+ case "-7":
+ return(gettext("-7 setvbuf() call failed"));
+ }
+ return(sprintf(gettext('could not connect to the host "%1$s": %2$s'), $domain, $error));
+ }
+
+ Function SASLAuthenticate($mechanisms, $credentials, &$authenticated, &$mechanism)
+ {
+ $authenticated=0;
+ if(!function_exists("class_exists")
+ || !class_exists("sasl_client_class"))
+ {
+ $this->error=gettext("it is not possible to authenticate using the specified mechanism because the SASL library class is not loaded");
+ return(0);
+ }
+ $sasl=new sasl_client_class;
+ $sasl->SetCredential("user",$credentials["user"]);
+ $sasl->SetCredential("password",$credentials["password"]);
+ if(IsSet($credentials["realm"]))
+ $sasl->SetCredential("realm",$credentials["realm"]);
+ if(IsSet($credentials["workstation"]))
+ $sasl->SetCredential("workstation",$credentials["workstation"]);
+ if(IsSet($credentials["mode"]))
+ $sasl->SetCredential("mode",$credentials["mode"]);
+ do
+ {
+ $status=$sasl->Start($mechanisms,$message,$interactions);
+ }
+ while($status==SASL_INTERACT);
+ switch($status)
+ {
+ case SASL_CONTINUE:
+ break;
+ case SASL_NOMECH:
+ if(strlen($this->authentication_mechanism))
+ {
+ $this->error=printf(gettext('authenticated mechanism %1$s may not be used: %2$s'), $this->authentication_mechanism, $sasl->error);
+ return(0);
+ }
+ break;
+ default:
+ $this->error=gettext("Could not start the SASL authentication client:") . " ".$sasl->error;
+ return(0);
+ }
+ if(strlen($mechanism=$sasl->mechanism))
+ {
+ if($this->PutLine("AUTH ".$sasl->mechanism.(IsSet($message) ? " ".base64_encode($message) : ""))==0)
+ {
+ $this->error=gettext("Could not send the AUTH command");
+ return(0);
+ }
+ if(!$this->VerifyResultLines(array("235","334"),$responses))
+ return(0);
+ switch($this->result_code)
+ {
+ case "235":
+ $response="";
+ $authenticated=1;
+ break;
+ case "334":
+ $response=base64_decode($responses[0]);
+ break;
+ default:
+ $this->error=gettext("Authentication error:") . " ".$responses[0];
+ return(0);
+ }
+ for(;!$authenticated;)
+ {
+ do
+ {
+ $status=$sasl->Step($response,$message,$interactions);
+ }
+ while($status==SASL_INTERACT);
+ switch($status)
+ {
+ case SASL_CONTINUE:
+ if($this->PutLine(base64_encode($message))==0)
+ {
+ $this->error=gettext("Could not send the authentication step message");
+ return(0);
+ }
+ if(!$this->VerifyResultLines(array("235","334"),$responses))
+ return(0);
+ switch($this->result_code)
+ {
+ case "235":
+ $response="";
+ $authenticated=1;
+ break;
+ case "334":
+ $response=base64_decode($responses[0]);
+ break;
+ default:
+ $this->error=gettext("Authentication error:") . " ".$responses[0];
+ return(0);
+ }
+ break;
+ default:
+ $this->error=gettext("Could not process the SASL authentication step:") . " ".$sasl->error;
+ return(0);
+ }
+ }
+ }
+ return(1);
+ }
+
+ /* Public methods */
+
+ Function Connect($domain="")
+ {
+ if(strcmp($this->state,"Disconnected"))
+ {
+ $this->error=gettext("connection is already established");
+ return(0);
+ }
+ $this->disconnected_error=0;
+ $this->error=$error="";
+ $this->esmtp_host="";
+ $this->esmtp_extensions=array();
+ $hosts=array();
+ if($this->direct_delivery)
+ {
+ if(strlen($domain)==0)
+ return(1);
+ $hosts=$weights=$mxhosts=array();
+ $getmxrr=$this->getmxrr;
+ if(function_exists($getmxrr)
+ && $getmxrr($domain,$hosts,$weights))
+ {
+ for($host=0;$host<count($hosts);$host++)
+ $mxhosts[$weights[$host]]=$hosts[$host];
+ KSort($mxhosts);
+ for(Reset($mxhosts),$host=0;$host<count($mxhosts);Next($mxhosts),$host++)
+ $hosts[$host]=$mxhosts[Key($mxhosts)];
+ }
+ else
+ {
+ if(strcmp(@gethostbyname($domain),$domain)!=0)
+ $hosts[]=$domain;
+ }
+ }
+ else
+ {
+ if(strlen($this->host_name))
+ $hosts[]=$this->host_name;
+ if(strlen($this->pop3_auth_host))
+ {
+ $user=$this->user;
+ if(strlen($user)==0)
+ {
+ $this->error=gettext("it was not specified the POP3 authentication user");
+ return(0);
+ }
+ $password=$this->password;
+ if(strlen($password)==0)
+ {
+ $this->error=gettext("it was not specified the POP3 authentication password");
+ return(0);
+ }
+ $domain=$this->pop3_auth_host;
+ $this->error=$this->ConnectToHost($domain, $this->pop3_auth_port, sprintf(gettext("Resolving POP3 authentication host \"%s\"..."), $domain));
+ if(strlen($this->error))
+ return(0);
+ if(strlen($response=$this->GetLine())==0)
+ return(0);
+ if(strcmp($this->Tokenize($response," "),"+OK"))
+ {
+ $this->error=gettext("POP3 authentication server greeting was not found");
+ return(0);
+ }
+ if(!$this->PutLine("USER ".$this->user)
+ || strlen($response=$this->GetLine())==0)
+ return(0);
+ if(strcmp($this->Tokenize($response," "),"+OK"))
+ {
+ $this->error=gettext("POP3 authentication user was not accepted:") . " ".$this->Tokenize("\r\n");
+ return(0);
+ }
+ if(!$this->PutLine("PASS ".$password)
+ || strlen($response=$this->GetLine())==0)
+ return(0);
+ if(strcmp($this->Tokenize($response," "),"+OK"))
+ {
+ $this->error=gettext("POP3 authentication password was not accepted:") . " ".$this->Tokenize("\r\n");
+ return(0);
+ }
+ fclose($this->connection);
+ $this->connection=0;
+ }
+ }
+ if(count($hosts)==0)
+ {
+ $this->error=gettext("could not determine the SMTP to connect");
+ return(0);
+ }
+ for($host=0, $error="not connected";strlen($error) && $host<count($hosts);$host++)
+ {
+ $domain=$hosts[$host];
+ $error=$this->ConnectToHost($domain, $this->host_port, sprintf(gettext("Resolving SMTP server domain \"%s\"..."), $domain));
+ }
+ if(strlen($error))
+ {
+ $this->error=$error;
+ return(0);
+ }
+ $timeout=($this->data_timeout ? $this->data_timeout : $this->timeout);
+ if($timeout
+ && function_exists("socket_set_timeout"))
+ socket_set_timeout($this->connection,$timeout,0);
+ if($this->debug)
+ $this->OutputDebug(sprintf(gettext("Connected to SMTP server \"%s\"."), $domain));
+ if($this->VerifyResultLines("220",$responses)>0)
+ {
+ // Send our HELLO
+ $success = $this->hello($this->hostname());
+ if ($this->tls)
+ $success = $this->startTLS();
+
+ if($success
+ && strlen($this->user)
+ && strlen($this->pop3_auth_host)==0)
+ {
+ if(!IsSet($this->esmtp_extensions["AUTH"]))
+ {
+ $this->error = gettext("server does not require authentication");
+ $success=0;
+ }
+ else
+ {
+ if(strlen($this->authentication_mechanism))
+ $mechanisms=array($this->authentication_mechanism);
+ else
+ {
+ $mechanisms=array();
+ for($authentication=$this->Tokenize($this->esmtp_extensions["AUTH"]," ");strlen($authentication);$authentication=$this->Tokenize(" "))
+ $mechanisms[]=$authentication;
+ }
+ $credentials=array(
+ "user"=>$this->user,
+ "password"=>$this->password
+ );
+ if(strlen($this->realm))
+ $credentials["realm"]=$this->realm;
+ if(strlen($this->workstation))
+ $credentials["workstation"]=$this->workstation;
+ $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
+ if(!$success
+ && !strcmp($mechanism,"PLAIN"))
+ {
+ /*
+ * Author: Russell Robinson, 25 May 2003, http://www.tectite.com/
+ * Purpose: Try various AUTH PLAIN authentication methods.
+ */
+ $mechanisms=array("PLAIN");
+ $credentials=array(
+ "user"=>$this->user,
+ "password"=>$this->password
+ );
+ if(strlen($this->realm))
+ {
+ /*
+ * According to: http://www.sendmail.org/~ca/email/authrealms.html#authpwcheck_method
+ * some sendmails won't accept the realm, so try again without it
+ */
+ $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
+ }
+ if(!$success)
+ {
+ /*
+ * It was seen an EXIM configuration like this:
+ * user^password^unused
+ */
+ $credentials["mode"]=SASL_PLAIN_EXIM_DOCUMENTATION_MODE;
+ $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
+ }
+ if(!$success)
+ {
+ /*
+ * ... though: http://exim.work.de/exim-html-3.20/doc/html/spec_36.html
+ * specifies: ^user^password
+ */
+ $credentials["mode"]=SASL_PLAIN_EXIM_MODE;
+ $success=$this->SASLAuthenticate($mechanisms,$credentials,$authenticated,$mechanism);
+ }
+ }
+ if($success
+ && strlen($mechanism)==0)
+ {
+ $this->error=gettext("it is not supported any of the authentication mechanisms required by the server");
+ $success=0;
+ }
+ }
+ }
+ }
+ if($success)
+ {
+ $this->state="Connected";
+ $this->connected_domain=$domain;
+ }
+ else
+ {
+ fclose($this->connection);
+ $this->connection=0;
+ }
+ return($success);
+ }
+
+ Function hostname() {
+ if(!strcmp($localhost=$this->localhost,"")
+ && !strcmp($localhost=getenv("SERVER_NAME"),"")
+ && !strcmp($localhost=getenv("HOST"),"")
+ && !strcmp($localhost=getenv("HOSTNAME"),"")
+ && !strcmp($localhost=gethostname(),""))
+ $localhost="localhost";
+
+ return $localhost;
+ }
+
+ Function hello()
+ {
+ $success = 0;
+ $fallback = 1;
+ if ($this->esmtp || strlen($this->user)) {
+ if ($this->PutLine("EHLO ".$this->hostname())) {
+ if (($success_code = $this->VerifyResultLines("250",$responses)) > 0) {
+ $this->esmtp_host = $this->Tokenize($responses[0]," ");
+ for($response=1;$response<count($responses);$response++) {
+ $extension = strtoupper($this->Tokenize($responses[$response]," "));
+ $this->esmtp_extensions[$extension]=$this->Tokenize("");
+ }
+ $success = 1;
+ $fallback = 0;
+ } else {
+ if ($success_code == 0) {
+ $code = $this->Tokenize($this->error," -");
+ switch($code) {
+ case "421":
+ $fallback=0;
+ break;
+ }
+ }
+ }
+ } else
+ $fallback=0;
+ }
+
+ if ($fallback) {
+ if ($this->PutLine("HELO $localhost") && $this->VerifyResultLines("250",$responses)>0)
+ $success=1;
+ }
+ return $success;
+ }
+
+ Function startTLS() {
+ if ($this->PutLine("STARTTLS") && $this->VerifyResultLines("220",$responses)>0) {
+ if (!stream_socket_enable_crypto($this->connection,true,STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
+ return false;
+ } else {
+ // Resend HELO since session has been reset
+ return $this->hello($this->hostname);
+ }
+ } else
+ return false;
+ }
+
+ Function MailFrom($sender)
+ {
+ if($this->direct_delivery)
+ {
+ switch($this->state)
+ {
+ case "Disconnected":
+ $this->direct_sender=$sender;
+ return(1);
+ case "Connected":
+ $sender=$this->direct_sender;
+ break;
+ default:
+ $this->error=gettext("direct delivery connection is already established and sender is already set");
+ return(0);
+ }
+ }
+ else
+ {
+ if(strcmp($this->state,"Connected"))
+ {
+ $this->error=gettext("connection is not in the initial state");
+ return(0);
+ }
+ }
+ $this->error="";
+ if(!$this->PutLine("MAIL FROM:<$sender>"))
+ return(0);
+ if(!IsSet($this->esmtp_extensions["PIPELINING"])
+ && $this->VerifyResultLines("250",$responses)<=0)
+ return(0);
+ $this->state="SenderSet";
+ if(IsSet($this->esmtp_extensions["PIPELINING"]))
+ $this->pending_sender=1;
+ $this->pending_recipients=0;
+ return(1);
+ }
+
+ Function SetRecipient($recipient)
+ {
+ if($this->direct_delivery)
+ {
+ if(GetType($at=strrpos($recipient,"@"))!="integer")
+ return(gettext("it was not specified a valid direct recipient"));
+ $domain=substr($recipient,$at+1);
+ switch($this->state)
+ {
+ case "Disconnected":
+ if(!$this->Connect($domain))
+ return(0);
+ if(!$this->MailFrom(""))
+ {
+ $error=$this->error;
+ $this->Disconnect();
+ $this->error=$error;
+ return(0);
+ }
+ break;
+ case "SenderSet":
+ case "RecipientSet":
+ if(strcmp($this->connected_domain,$domain))
+ {
+ $this->error=gettext("it is not possible to deliver directly to recipients of different domains");
+ return(0);
+ }
+ break;
+ default:
+ $this->error=gettext("connection is already established and the recipient is already set");
+ return(0);
+ }
+ }
+ else
+ {
+ switch($this->state)
+ {
+ case "SenderSet":
+ case "RecipientSet":
+ break;
+ default:
+ $this->error=gettext("connection is not in the recipient setting state");
+ return(0);
+ }
+ }
+ $this->error="";
+ if(!$this->PutLine("RCPT TO:<$recipient>"))
+ return(0);
+ if(IsSet($this->esmtp_extensions["PIPELINING"]))
+ {
+ $this->pending_recipients++;
+ if($this->pending_recipients>=$this->maximum_piped_recipients)
+ {
+ if(!$this->FlushRecipients())
+ return(0);
+ }
+ }
+ else
+ {
+ if($this->VerifyResultLines(array("250","251"),$responses)<=0)
+ return(0);
+ }
+ $this->state="RecipientSet";
+ return(1);
+ }
+
+ Function StartData()
+ {
+ if(strcmp($this->state,"RecipientSet"))
+ {
+ $this->error=gettext("connection is not in the start sending data state");
+ return(0);
+ }
+ $this->error="";
+ if(!$this->PutLine("DATA"))
+ return(0);
+ if($this->pending_recipients)
+ {
+ if(!$this->FlushRecipients())
+ return(0);
+ }
+ if($this->VerifyResultLines("354",$responses)<=0)
+ return(0);
+ $this->state="SendingData";
+ return(1);
+ }
+
+ Function PrepareData(&$data,&$output,$preg=1)
+ {
+ if($preg
+ && function_exists("preg_replace"))
+ $output=preg_replace(array("/\n\n|\r\r/","/(^|[^\r])\n/","/\r([^\n]|\$)/D","/(^|\n)\\./"),array("\r\n\r\n","\\1\r\n","\r\n\\1","\\1.."),$data);
+ else
+ $output=ereg_replace("(^|\n)\\.","\\1..",ereg_replace("\r([^\n]|\$)","\r\n\\1",ereg_replace("(^|[^\r])\n","\\1\r\n",ereg_replace("\n\n|\r\r","\r\n\r\n",$data))));
+ }
+
+ Function SendData($data)
+ {
+ if(strcmp($this->state,"SendingData"))
+ {
+ $this->error=gettext("connection is not in the sending data state");
+ return(0);
+ }
+ $this->error="";
+ return($this->PutData($data));
+ }
+
+ Function EndSendingData()
+ {
+ if(strcmp($this->state,"SendingData"))
+ {
+ $this->error=gettext("connection is not in the sending data state");
+ return(0);
+ }
+ $this->error="";
+ if(!$this->PutLine("\r\n.")
+ || $this->VerifyResultLines("250",$responses)<=0)
+ return(0);
+ $this->state="Connected";
+ return(1);
+ }
+
+ Function ResetConnection()
+ {
+ switch($this->state)
+ {
+ case "Connected":
+ return(1);
+ case "SendingData":
+ $this->error="can not reset the connection while sending data";
+ return(0);
+ case "Disconnected":
+ $this->error="can not reset the connection before it is established";
+ return(0);
+ }
+ $this->error="";
+ if(!$this->PutLine("RSET")
+ || $this->VerifyResultLines("250",$responses)<=0)
+ return(0);
+ $this->state="Connected";
+ return(1);
+ }
+
+ Function Disconnect($quit=1)
+ {
+ if(!strcmp($this->state,"Disconnected"))
+ {
+ $this->error=gettext("it was not previously established a SMTP connection");
+ return(0);
+ }
+ $this->error="";
+ if(!strcmp($this->state,"Connected")
+ && $quit
+ && (!$this->PutLine("QUIT")
+ || ($this->VerifyResultLines("221",$responses)<=0
+ && !$this->disconnected_error)))
+ return(0);
+ if($this->disconnected_error)
+ $this->disconnected_error=0;
+ else
+ fclose($this->connection);
+ $this->connection=0;
+ $this->state="Disconnected";
+ if($this->debug)
+ $this->OutputDebug("Disconnected.");
+ return(1);
+ }
+
+ Function SendMessage($sender,$recipients,$headers,$body)
+ {
+ if(($success=$this->Connect()))
+ {
+ if(($success=$this->MailFrom($sender)))
+ {
+ for($recipient=0;$recipient<count($recipients);$recipient++)
+ {
+ if(!($success=$this->SetRecipient($recipients[$recipient])))
+ break;
+ }
+ if($success
+ && ($success=$this->StartData()))
+ {
+ for($header_data="",$header=0;$header<count($headers);$header++)
+ $header_data.=$headers[$header]."\r\n";
+ if(($success=$this->SendData($header_data."\r\n")))
+ {
+ $this->PrepareData($body,$body_data);
+ $success=$this->SendData($body_data);
+ }
+ if($success)
+ $success=$this->EndSendingData();
+ }
+ }
+ $error=$this->error;
+ $disconnect_success=$this->Disconnect($success);
+ if($success)
+ $success=$disconnect_success;
+ else
+ $this->error=$error;
+ }
+ return($success);
+ }
+
+};
+
+?>
OpenPOWER on IntegriCloud