Source for file class.smtp.php
Documentation is available at class.smtp.php 
 .---------------------------------------------------------------------------.  
 |  Software: PHPMailer - PHP email class                                    |  
 |   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |  
 |      Info: http://phpmailer.sourceforge.net                               |  
 |   Support: http://sourceforge.net/projects/phpmailer/                     |  
 | ------------------------------------------------------------------------- |  
 |     Admin: Andy Prevost (project admininistrator)                         |  
 |   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |  
 |          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |  
 |   Founder: Brent R. Matzelle (original founder)                           |  
 | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |  
 | Copyright (c) 2001-2003, Brent R. Matzelle                                |  
 | ------------------------------------------------------------------------- |  
 |   License: Distributed under the Lesser General Public License (LGPL)     |  
 |            http://www.gnu.org/copyleft/lesser.html                        |  
 | This program is distributed in the hope that it will be useful - WITHOUT  |  
 | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |  
 | FITNESS FOR A PARTICULAR PURPOSE.                                         |  
 | ------------------------------------------------------------------------- |  
 | We offer a number of paid services (www.codeworxtech.com):                |  
 | - Web Hosting on highly optimized fast and secure servers                 |  
 | - Technology Consulting                                                   |  
 | - Oursourcing (highly qualified programmers and graphic designers)        |  
 '---------------------------------------------------------------------------'  
 * PHPMailer - PHP SMTP email transport class  
 * NOTE: Designed for use with PHP version 5 and up  
 * @package linea21.externals  
 * @copyright 2004 - 2008 Andy Prevost  
 * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)  
 * @version $Id: class.smtp.php 444 2009-05-05 11:22:26Z coolbru $  
 * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP  
 * commands except TURN which will always return a not implemented  
 * error. SMTP also provides some utility methods for sending mail  
 * original author: Chris Ryan  
   *  Sets whether debugging is turned on  
  public $do_debug;       // the level of debug to perform  
   *  Sets VERP use on/off (default is off)  
  /////////////////////////////////////////////////  
  // PROPERTIES, PRIVATE AND PROTECTED  
  /////////////////////////////////////////////////  
  private $smtp_conn; // the socket to the server  
  private $error;     // error if any on the last call  
  private $helo_rply; // the reply the server sent to us for HELO  
   * Initialize the class so that the data is in a known state.  
  /////////////////////////////////////////////////  
  /////////////////////////////////////////////////  
   * Connect to the server specified on the port specified.  
   * If the port is not specified use the default SMTP_PORT.  
   * If tval is specified then a connection will try and be  
   * established with the server for that number of seconds.  
   * If tval is not specified the default is 30 seconds to  
  public function Connect($host, $port =  0, $tval =  30) {  
    // set the error val to null so there is no confusion  
    // make sure we are __not__ connected  
      // already connected, generate error  
      $this->error =  array("error" =>  "Already connected to a server");  
    // connect to the smtp server  
    $this->smtp_conn =  @fsockopen($host,    // the host of the server  
    $port,    // the port to use  
    $errno,   // error number if any  
    $errstr,  // error message if any  
    $tval);   // give up after ? secs  
    // verify we connected properly  
    if(empty($this->smtp_conn)) {  
      $this->error =  array("error" =>  "Failed to connect to server",  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": $errstr ($errno)" .  $this->CRLF .  '<br />'; 
    // SMTP server can take longer to respond, give longer timeout for first read  
    // Windows does not have support for this timeout function  
    if(substr(PHP_OS, 0, 3) !=  "WIN")  
    $announce =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $announce .  $this->CRLF .  '<br />'; 
   * Initiate a TLS communication with the server.  
   * SMTP CODE 220 Ready to start TLS  
   * SMTP CODE 501 Syntax error (no parameters allowed)  
   * SMTP CODE 454 TLS not available due to temporary reason  
    $this->error =  null; # to avoid confusion  
    if(!$this->connected()) {  
      $this->error =  array("error" =>  "Called StartTLS() without being connected");  
    fputs($this->smtp_conn,"STARTTLS" .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
      array("error"     =>  "STARTTLS not accepted from server",  
               "smtp_msg"  =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
    // Begin encrypted connection  
   * Performs SMTP authentication.  Must be run after running the  
   * Hello() method.  Returns true if successfully authenticated.  
    fputs($this->smtp_conn,"AUTH LOGIN" .  $this->CRLF);  
    $rply =  $this->get_lines();  
      array("error" =>  "AUTH not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
    $rply =  $this->get_lines();  
      array("error" =>  "Username not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
    $rply =  $this->get_lines();  
      array("error" =>  "Password not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
   * Returns true if connected to a server otherwise false  
    if(!empty($this->smtp_conn)) {  
      if($sock_status["eof"]) {  
        // the socket is valid but we are not connected  
          echo  "SMTP -> NOTICE:" .  $this->CRLF .  "EOF caught while checking if connected"; 
      return true; // everything looks good  
   * Closes the socket and cleans up the state of the class.  
   * It is not considered good to use this function without  
   * first trying to use QUIT.  
  public function Close() {  
    $this->error =  null; // so there is no confusion  
    if(!empty($this->smtp_conn)) {  
      // close the connection and cleanup  
  /////////////////////////////////////////////////  
  /////////////////////////////////////////////////  
   * Issues a data command and sends the msg_data to the server  
   * finializing the mail transaction. $msg_data is the message  
   * that is to be send with the headers. Each header needs to be  
   * on a single line followed by a <CRLF> with the message headers  
   * and the message body being seperated by and additional <CRLF>.  
   * Implements rfc 821: DATA <CRLF>  
   * SMTP CODE INTERMEDIATE: 354  
   *     SMTP CODE FAILURE: 552,554,451,452  
   * SMTP CODE FAILURE: 451,554  
   * SMTP CODE ERROR  : 500,501,503,421  
  public function Data($msg_data) {  
    $this->error =  null; // so no confusion is caused  
    if(!$this->connected()) {  
              "error" =>  "Called Data() without being connected");  
    fputs($this->smtp_conn,"DATA" .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
      array("error" =>  "DATA command not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
    /* the server is ready to accept data!  
     * according to rfc 821 we should not send more than 1000  
     * characters on a single line so we will break the data up  
     * into lines by \r and/or \n then if needed we will break  
     * each of those into smaller lines to fit within the limit.  
     * in addition we will be looking for lines that start with  
     * a period '.' and append and additional period '.' to that  
     * line. NOTE: this does not count towards limit.  
    // normalize the line breaks so we know the explode works  
    /* we need to find a good way to determine is headers are  
     * in the msg_data or if it is a straight msg body  
     * currently I am assuming rfc 822 definitions of msg headers  
     * and if the first field of the first line (':' sperated)  
     * does not contain a space then it _should_ be a header  
     * and we can process all lines before a blank "" line as  
    if(!empty($field) &&  !strstr($field," ")) {  
    $max_line_length =  998; // used below; set here for ease in change  
    while(list (,$line) =  @each($lines)) {  
      if($line ==  "" &&  $in_headers) {  
      // ok we need to break this line up into several smaller lines  
      while(strlen($line) >  $max_line_length) {  
        // Patch to fix DOS attack  
          $pos =  $max_line_length -  1;  
          $lines_out[] =  substr($line,0,$pos);  
          $lines_out[] =  substr($line,0,$pos);  
          $line =  substr($line,$pos +  1);  
        /* if processing headers add a LWSP-char to the front of new line  
         * rfc 822 on long msg headers  
      // send the lines to the server  
      while(list (,$line_out) =  @each($lines_out)) {  
          if(substr($line_out, 0, 1) ==  ".") {  
            $line_out =  "." .  $line_out;  
        fputs($this->smtp_conn,$line_out .  $this->CRLF);  
    // message data has been sent  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
      array("error" =>  "DATA not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
   * Sends the HELO command to the smtp server.  
   * This makes sure that we and the server are in  
   * Implements from rfc 821: HELO <SP> <domain> <CRLF>  
   * SMTP CODE ERROR  : 500, 501, 504, 421  
  public function Hello($host =  '') {  
    $this->error =  null; // so no confusion is caused  
    if(!$this->connected()) {  
            "error" =>  "Called Hello() without being connected");  
    // if hostname for HELO was not specified send default  
      // determine appropriate default to send to server  
    // Send extended hello first (RFC 2821)  
    if(!$this->SendHello("EHLO", $host)) {  
      if(!$this->SendHello("HELO", $host)) {  
   * Sends a HELO/EHLO command.  
  private function SendHello($hello, $host) {  
    fputs($this->smtp_conn, $hello .  " " .  $host .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER: " .  $rply .  $this->CRLF .  '<br />'; 
      array("error" =>  $hello .  " not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
    $this->helo_rply =  $rply;  
   * Starts a mail transaction from the email address specified in  
   * $from. Returns true if successful or false otherwise. If True  
   * the mail transaction is started and then one or more Recipient  
   * commands may be called followed by a Data command.  
   * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>  
   * SMTP CODE SUCCESS: 552,451,452  
   * SMTP CODE SUCCESS: 500,501,421  
  public function Mail($from) {  
    $this->error =  null; // so no confusion is caused  
    if(!$this->connected()) {  
              "error" =>  "Called Mail() without being connected");  
    $useVerp =  ($this->do_verp ?  "XVERP" :  "");  
    fputs($this->smtp_conn,"MAIL FROM:<" .  $from .  ">" .  $useVerp .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
      array("error" =>  "MAIL not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
   * Sends the quit command to the server and then closes the socket  
   * if there is no error or the $close_on_error argument is true.  
   * Implements from rfc 821: QUIT <CRLF>  
  public function Quit($close_on_error =  true) {  
    $this->error =  null; // so there is no confusion  
    if(!$this->connected()) {  
              "error" =>  "Called Quit() without being connected");  
    // send the quit command to the server  
    fputs($this->smtp_conn,"quit" .  $this->CRLF);  
    // get any good-bye messages  
    $byemsg =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $byemsg .  $this->CRLF .  '<br />'; 
      // use e as a tmp var cause Close will overwrite $this->error  
      $e =  array("error" =>  "SMTP server rejected quit command",  
                 "smtp_rply" =>  substr($byemsg,4));  
        echo  "SMTP -> ERROR: " .  $e["error"] .  ": " .  $byemsg .  $this->CRLF .  '<br />'; 
    if(empty($e) ||  $close_on_error) {  
   * Sends the command RCPT to the SMTP server with the TO: argument of $to.  
   * Returns true if the recipient was accepted false if it was rejected.  
   * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>  
   * SMTP CODE SUCCESS: 250,251  
   * SMTP CODE FAILURE: 550,551,552,553,450,451,452  
   * SMTP CODE ERROR  : 500,501,503,421  
    $this->error =  null; // so no confusion is caused  
    if(!$this->connected()) {  
              "error" =>  "Called Recipient() without being connected");  
    fputs($this->smtp_conn,"RCPT TO:<" .  $to .  ">" .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
    if($code !=  250 &&  $code !=  251) {  
      array("error" =>  "RCPT not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
   * Sends the RSET command to abort and transaction that is  
   * currently in progress. Returns true if successful false  
   * Implements rfc 821: RSET <CRLF>  
   * SMTP CODE ERROR  : 500,501,504,421  
  public function Reset() {  
    $this->error =  null; // so no confusion is caused  
    if(!$this->connected()) {  
              "error" =>  "Called Reset() without being connected");  
    fputs($this->smtp_conn,"RSET" .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
      array("error" =>  "RSET failed",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
   * Starts a mail transaction from the email address specified in  
   * $from. Returns true if successful or false otherwise. If True  
   * the mail transaction is started and then one or more Recipient  
   * commands may be called followed by a Data command. This command  
   * will send the message to the users terminal if they are logged  
   * in and send them an email.  
   * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>  
   * SMTP CODE SUCCESS: 552,451,452  
   * SMTP CODE SUCCESS: 500,501,502,421  
    $this->error =  null; // so no confusion is caused  
    if(!$this->connected()) {  
          "error" =>  "Called SendAndMail() without being connected");  
    fputs($this->smtp_conn,"SAML FROM:" .  $from .  $this->CRLF);  
    $rply =  $this->get_lines();  
      echo  "SMTP -> FROM SERVER:" .  $rply .  $this->CRLF .  '<br />'; 
      array("error" =>  "SAML not accepted from server",  
              "smtp_msg" =>  substr($rply,4));  
        echo  "SMTP -> ERROR: " .  $this->error["error"] .  ": " .  $rply .  $this->CRLF .  '<br />'; 
   * This is an optional command for SMTP that this class does not  
   * support. This method is here to make the RFC821 Definition  
   * complete for this class and __may__ be implimented in the future  
   * Implements from rfc 821: TURN <CRLF>  
   * SMTP CODE ERROR  : 500, 503  
    $this->error =  array("error" =>  "This method, TURN, of the SMTP ".   
      echo  "SMTP -> NOTICE: " .  $this->error["error"] .  $this->CRLF .  '<br />'; 
  /////////////////////////////////////////////////  
  /////////////////////////////////////////////////  
   * Read in as many lines as possible  
   * either before eof or socket timeout occurs on the operation.  
   * With SMTP we can tell if we have more lines to read if the  
   * 4th character is '-' symbol. If it is a space then we don't  
   * need to read anything else.  
  private function get_lines() {  
    while($str =  @fgets($this->smtp_conn,515)) {  
        echo  "SMTP -> get_lines(): \$data was \"$data\"" .  $this->CRLF .  '<br />'; 
        echo  "SMTP -> get_lines(): \$str is \"$str\"" .  $this->CRLF .  '<br />'; 
        echo  "SMTP -> get_lines(): \$data is \"$data\"" .  $this->CRLF .  '<br />'; 
      // if 4th character is a space, we are done reading, break the loop  
      if(substr($str,3,1) ==  " ") { break; }  
 
 
        
       |