[ Index ]

PHP Cross Reference of BackPress

title

Body

[close]

/includes/ -> class.mailer-smtp.php (source)

   1  <?php
   2  // Last sync [WP19849]
   3  
   4  /*~ class.smtp.php
   5  .---------------------------------------------------------------------------.
   6  |  Software: PHPMailer - PHP email class                                    |
   7  |   Version: 5.2.1                                                          |
   8  |      Site: https://code.google.com/a/apache-extras.org/p/phpmailer/       |
   9  | ------------------------------------------------------------------------- |
  10  |     Admin: Jim Jagielski (project admininistrator)                        |
  11  |   Authors: Andy Prevost (codeworxtech) codeworxtech@users.sourceforge.net |
  12  |          : Marcus Bointon (coolbru) coolbru@users.sourceforge.net         |
  13  |          : Jim Jagielski (jimjag) jimjag@gmail.com                        |
  14  |   Founder: Brent R. Matzelle (original founder)                           |
  15  | Copyright (c) 2010-2012, Jim Jagielski. All Rights Reserved.              |
  16  | Copyright (c) 2004-2009, Andy Prevost. All Rights Reserved.               |
  17  | Copyright (c) 2001-2003, Brent R. Matzelle                                |
  18  | ------------------------------------------------------------------------- |
  19  |   License: Distributed under the Lesser General Public License (LGPL)     |
  20  |            http://www.gnu.org/copyleft/lesser.html                        |
  21  | This program is distributed in the hope that it will be useful - WITHOUT  |
  22  | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
  23  | FITNESS FOR A PARTICULAR PURPOSE.                                         |
  24  '---------------------------------------------------------------------------'
  25  */
  26  
  27  /**
  28   * PHPMailer - PHP SMTP email transport class
  29   * NOTE: Designed for use with PHP version 5 and up
  30   * @package PHPMailer
  31   * @author Andy Prevost
  32   * @author Marcus Bointon
  33   * @copyright 2004 - 2008 Andy Prevost
  34   * @author Jim Jagielski
  35   * @copyright 2010 - 2012 Jim Jagielski
  36   * @license http://www.gnu.org/copyleft/lesser.html Distributed under the Lesser General Public License (LGPL)
  37   * @version $Id: class.smtp.php 450 2010-06-23 16:46:33Z coolbru $
  38   */
  39  
  40  /**
  41   * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
  42   * commands except TURN which will always return a not implemented
  43   * error. SMTP also provides some utility methods for sending mail
  44   * to an SMTP server.
  45   * original author: Chris Ryan
  46   */
  47  
  48  class SMTP {
  49    /**
  50     *  SMTP server port
  51     *  @var int
  52     */
  53    public $SMTP_PORT = 25;
  54  
  55    /**
  56     *  SMTP reply line ending
  57     *  @var string
  58     */
  59    public $CRLF = "\r\n";
  60  
  61    /**
  62     *  Sets whether debugging is turned on
  63     *  @var bool
  64     */
  65    public $do_debug;       // the level of debug to perform
  66  
  67    /**
  68     *  Sets VERP use on/off (default is off)
  69     *  @var bool
  70     */
  71    public $do_verp = false;
  72  
  73    /**
  74     * Sets the SMTP PHPMailer Version number
  75     * @var string
  76     */
  77    public $Version         = '5.2.1';
  78  
  79    /////////////////////////////////////////////////
  80    // PROPERTIES, PRIVATE AND PROTECTED
  81    /////////////////////////////////////////////////
  82  
  83    private $smtp_conn; // the socket to the server
  84    private $error;     // error if any on the last call
  85    private $helo_rply; // the reply the server sent to us for HELO
  86  
  87    /**
  88     * Initialize the class so that the data is in a known state.
  89     * @access public
  90     * @return void
  91     */
  92    public function __construct() {
  93      $this->smtp_conn = 0;
  94      $this->error = null;
  95      $this->helo_rply = null;
  96  
  97      $this->do_debug = 0;
  98    }
  99  
 100    /////////////////////////////////////////////////
 101    // CONNECTION FUNCTIONS
 102    /////////////////////////////////////////////////
 103  
 104    /**
 105     * Connect to the server specified on the port specified.
 106     * If the port is not specified use the default SMTP_PORT.
 107     * If tval is specified then a connection will try and be
 108     * established with the server for that number of seconds.
 109     * If tval is not specified the default is 30 seconds to
 110     * try on the connection.
 111     *
 112     * SMTP CODE SUCCESS: 220
 113     * SMTP CODE FAILURE: 421
 114     * @access public
 115     * @return bool
 116     */
 117    public function Connect($host, $port = 0, $tval = 30) {
 118      // set the error val to null so there is no confusion
 119      $this->error = null;
 120  
 121      // make sure we are __not__ connected
 122      if($this->connected()) {
 123        // already connected, generate error
 124        $this->error = array("error" => "Already connected to a server");
 125        return false;
 126      }
 127  
 128      if(empty($port)) {
 129        $port = $this->SMTP_PORT;
 130      }
 131  
 132      // connect to the smtp server
 133      $this->smtp_conn = @fsockopen($host,    // the host of the server
 134                                   $port,    // the port to use
 135                                   $errno,   // error number if any
 136                                   $errstr,  // error message if any
 137                                   $tval);   // give up after ? secs
 138      // verify we connected properly
 139      if(empty($this->smtp_conn)) {
 140        $this->error = array("error" => "Failed to connect to server",
 141                             "errno" => $errno,
 142                             "errstr" => $errstr);
 143        if($this->do_debug >= 1) {
 144          echo "SMTP -> ERROR: " . $this->error["error"] . ": $errstr ($errno)" . $this->CRLF . '<br />';
 145        }
 146        return false;
 147      }
 148  
 149      // SMTP server can take longer to respond, give longer timeout for first read
 150      // Windows does not have support for this timeout function
 151      if(substr(PHP_OS, 0, 3) != "WIN")
 152       socket_set_timeout($this->smtp_conn, $tval, 0);
 153  
 154      // get any announcement
 155      $announce = $this->get_lines();
 156  
 157      if($this->do_debug >= 2) {
 158        echo "SMTP -> FROM SERVER:" . $announce . $this->CRLF . '<br />';
 159      }
 160  
 161      return true;
 162    }
 163  
 164    /**
 165     * Initiate a TLS communication with the server.
 166     *
 167     * SMTP CODE 220 Ready to start TLS
 168     * SMTP CODE 501 Syntax error (no parameters allowed)
 169     * SMTP CODE 454 TLS not available due to temporary reason
 170     * @access public
 171     * @return bool success
 172     */
 173    public function StartTLS() {
 174      $this->error = null; # to avoid confusion
 175  
 176      if(!$this->connected()) {
 177        $this->error = array("error" => "Called StartTLS() without being connected");
 178        return false;
 179      }
 180  
 181      fputs($this->smtp_conn,"STARTTLS" . $this->CRLF);
 182  
 183      $rply = $this->get_lines();
 184      $code = substr($rply,0,3);
 185  
 186      if($this->do_debug >= 2) {
 187        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 188      }
 189  
 190      if($code != 220) {
 191        $this->error =
 192           array("error"     => "STARTTLS not accepted from server",
 193                 "smtp_code" => $code,
 194                 "smtp_msg"  => substr($rply,4));
 195        if($this->do_debug >= 1) {
 196          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 197        }
 198        return false;
 199      }
 200  
 201      // Begin encrypted connection
 202      if(!stream_socket_enable_crypto($this->smtp_conn, true, STREAM_CRYPTO_METHOD_TLS_CLIENT)) {
 203        return false;
 204      }
 205  
 206      return true;
 207    }
 208  
 209    /**
 210     * Performs SMTP authentication.  Must be run after running the
 211     * Hello() method.  Returns true if successfully authenticated.
 212     * @access public
 213     * @return bool
 214     */
 215    public function Authenticate($username, $password) {
 216      // Start authentication
 217      fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
 218  
 219      $rply = $this->get_lines();
 220      $code = substr($rply,0,3);
 221  
 222      if($code != 334) {
 223        $this->error =
 224          array("error" => "AUTH not accepted from server",
 225                "smtp_code" => $code,
 226                "smtp_msg" => substr($rply,4));
 227        if($this->do_debug >= 1) {
 228          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 229        }
 230        return false;
 231      }
 232  
 233      // Send encoded username
 234      fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
 235  
 236      $rply = $this->get_lines();
 237      $code = substr($rply,0,3);
 238  
 239      if($code != 334) {
 240        $this->error =
 241          array("error" => "Username not accepted from server",
 242                "smtp_code" => $code,
 243                "smtp_msg" => substr($rply,4));
 244        if($this->do_debug >= 1) {
 245          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 246        }
 247        return false;
 248      }
 249  
 250      // Send encoded password
 251      fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
 252  
 253      $rply = $this->get_lines();
 254      $code = substr($rply,0,3);
 255  
 256      if($code != 235) {
 257        $this->error =
 258          array("error" => "Password not accepted from server",
 259                "smtp_code" => $code,
 260                "smtp_msg" => substr($rply,4));
 261        if($this->do_debug >= 1) {
 262          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 263        }
 264        return false;
 265      }
 266  
 267      return true;
 268    }
 269  
 270    /**
 271     * Returns true if connected to a server otherwise false
 272     * @access public
 273     * @return bool
 274     */
 275    public function Connected() {
 276      if(!empty($this->smtp_conn)) {
 277        $sock_status = socket_get_status($this->smtp_conn);
 278        if($sock_status["eof"]) {
 279          // the socket is valid but we are not connected
 280          if($this->do_debug >= 1) {
 281              echo "SMTP -> NOTICE:" . $this->CRLF . "EOF caught while checking if connected";
 282          }
 283          $this->Close();
 284          return false;
 285        }
 286        return true; // everything looks good
 287      }
 288      return false;
 289    }
 290  
 291    /**
 292     * Closes the socket and cleans up the state of the class.
 293     * It is not considered good to use this function without
 294     * first trying to use QUIT.
 295     * @access public
 296     * @return void
 297     */
 298    public function Close() {
 299      $this->error = null; // so there is no confusion
 300      $this->helo_rply = null;
 301      if(!empty($this->smtp_conn)) {
 302        // close the connection and cleanup
 303        fclose($this->smtp_conn);
 304        $this->smtp_conn = 0;
 305      }
 306    }
 307  
 308    /////////////////////////////////////////////////
 309    // SMTP COMMANDS
 310    /////////////////////////////////////////////////
 311  
 312    /**
 313     * Issues a data command and sends the msg_data to the server
 314     * finializing the mail transaction. $msg_data is the message
 315     * that is to be send with the headers. Each header needs to be
 316     * on a single line followed by a <CRLF> with the message headers
 317     * and the message body being seperated by and additional <CRLF>.
 318     *
 319     * Implements rfc 821: DATA <CRLF>
 320     *
 321     * SMTP CODE INTERMEDIATE: 354
 322     *     [data]
 323     *     <CRLF>.<CRLF>
 324     *     SMTP CODE SUCCESS: 250
 325     *     SMTP CODE FAILURE: 552,554,451,452
 326     * SMTP CODE FAILURE: 451,554
 327     * SMTP CODE ERROR  : 500,501,503,421
 328     * @access public
 329     * @return bool
 330     */
 331    public function Data($msg_data) {
 332      $this->error = null; // so no confusion is caused
 333  
 334      if(!$this->connected()) {
 335        $this->error = array(
 336                "error" => "Called Data() without being connected");
 337        return false;
 338      }
 339  
 340      fputs($this->smtp_conn,"DATA" . $this->CRLF);
 341  
 342      $rply = $this->get_lines();
 343      $code = substr($rply,0,3);
 344  
 345      if($this->do_debug >= 2) {
 346        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 347      }
 348  
 349      if($code != 354) {
 350        $this->error =
 351          array("error" => "DATA command not accepted from server",
 352                "smtp_code" => $code,
 353                "smtp_msg" => substr($rply,4));
 354        if($this->do_debug >= 1) {
 355          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 356        }
 357        return false;
 358      }
 359  
 360      /* the server is ready to accept data!
 361       * according to rfc 821 we should not send more than 1000
 362       * including the CRLF
 363       * characters on a single line so we will break the data up
 364       * into lines by \r and/or \n then if needed we will break
 365       * each of those into smaller lines to fit within the limit.
 366       * in addition we will be looking for lines that start with
 367       * a period '.' and append and additional period '.' to that
 368       * line. NOTE: this does not count towards limit.
 369       */
 370  
 371      // normalize the line breaks so we know the explode works
 372      $msg_data = str_replace("\r\n","\n",$msg_data);
 373      $msg_data = str_replace("\r","\n",$msg_data);
 374      $lines = explode("\n",$msg_data);
 375  
 376      /* we need to find a good way to determine is headers are
 377       * in the msg_data or if it is a straight msg body
 378       * currently I am assuming rfc 822 definitions of msg headers
 379       * and if the first field of the first line (':' sperated)
 380       * does not contain a space then it _should_ be a header
 381       * and we can process all lines before a blank "" line as
 382       * headers.
 383       */
 384  
 385      $field = substr($lines[0],0,strpos($lines[0],":"));
 386      $in_headers = false;
 387      if(!empty($field) && !strstr($field," ")) {
 388        $in_headers = true;
 389      }
 390  
 391      $max_line_length = 998; // used below; set here for ease in change
 392  
 393      while(list(,$line) = @each($lines)) {
 394        $lines_out = null;
 395        if($line == "" && $in_headers) {
 396          $in_headers = false;
 397        }
 398        // ok we need to break this line up into several smaller lines
 399        while(strlen($line) > $max_line_length) {
 400          $pos = strrpos(substr($line,0,$max_line_length)," ");
 401  
 402          // Patch to fix DOS attack
 403          if(!$pos) {
 404            $pos = $max_line_length - 1;
 405            $lines_out[] = substr($line,0,$pos);
 406            $line = substr($line,$pos);
 407          } else {
 408            $lines_out[] = substr($line,0,$pos);
 409            $line = substr($line,$pos + 1);
 410          }
 411  
 412          /* if processing headers add a LWSP-char to the front of new line
 413           * rfc 822 on long msg headers
 414           */
 415          if($in_headers) {
 416            $line = "\t" . $line;
 417          }
 418        }
 419        $lines_out[] = $line;
 420  
 421        // send the lines to the server
 422        while(list(,$line_out) = @each($lines_out)) {
 423          if(strlen($line_out) > 0)
 424          {
 425            if(substr($line_out, 0, 1) == ".") {
 426              $line_out = "." . $line_out;
 427            }
 428          }
 429          fputs($this->smtp_conn,$line_out . $this->CRLF);
 430        }
 431      }
 432  
 433      // message data has been sent
 434      fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
 435  
 436      $rply = $this->get_lines();
 437      $code = substr($rply,0,3);
 438  
 439      if($this->do_debug >= 2) {
 440        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 441      }
 442  
 443      if($code != 250) {
 444        $this->error =
 445          array("error" => "DATA not accepted from server",
 446                "smtp_code" => $code,
 447                "smtp_msg" => substr($rply,4));
 448        if($this->do_debug >= 1) {
 449          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 450        }
 451        return false;
 452      }
 453      return true;
 454    }
 455  
 456    /**
 457     * Sends the HELO command to the smtp server.
 458     * This makes sure that we and the server are in
 459     * the same known state.
 460     *
 461     * Implements from rfc 821: HELO <SP> <domain> <CRLF>
 462     *
 463     * SMTP CODE SUCCESS: 250
 464     * SMTP CODE ERROR  : 500, 501, 504, 421
 465     * @access public
 466     * @return bool
 467     */
 468    public function Hello($host = '') {
 469      $this->error = null; // so no confusion is caused
 470  
 471      if(!$this->connected()) {
 472        $this->error = array(
 473              "error" => "Called Hello() without being connected");
 474        return false;
 475      }
 476  
 477      // if hostname for HELO was not specified send default
 478      if(empty($host)) {
 479        // determine appropriate default to send to server
 480        $host = "localhost";
 481      }
 482  
 483      // Send extended hello first (RFC 2821)
 484      if(!$this->SendHello("EHLO", $host)) {
 485        if(!$this->SendHello("HELO", $host)) {
 486          return false;
 487        }
 488      }
 489  
 490      return true;
 491    }
 492  
 493    /**
 494     * Sends a HELO/EHLO command.
 495     * @access private
 496     * @return bool
 497     */
 498    private function SendHello($hello, $host) {
 499      fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
 500  
 501      $rply = $this->get_lines();
 502      $code = substr($rply,0,3);
 503  
 504      if($this->do_debug >= 2) {
 505        echo "SMTP -> FROM SERVER: " . $rply . $this->CRLF . '<br />';
 506      }
 507  
 508      if($code != 250) {
 509        $this->error =
 510          array("error" => $hello . " not accepted from server",
 511                "smtp_code" => $code,
 512                "smtp_msg" => substr($rply,4));
 513        if($this->do_debug >= 1) {
 514          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 515        }
 516        return false;
 517      }
 518  
 519      $this->helo_rply = $rply;
 520  
 521      return true;
 522    }
 523  
 524    /**
 525     * Starts a mail transaction from the email address specified in
 526     * $from. Returns true if successful or false otherwise. If True
 527     * the mail transaction is started and then one or more Recipient
 528     * commands may be called followed by a Data command.
 529     *
 530     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
 531     *
 532     * SMTP CODE SUCCESS: 250
 533     * SMTP CODE SUCCESS: 552,451,452
 534     * SMTP CODE SUCCESS: 500,501,421
 535     * @access public
 536     * @return bool
 537     */
 538    public function Mail($from) {
 539      $this->error = null; // so no confusion is caused
 540  
 541      if(!$this->connected()) {
 542        $this->error = array(
 543                "error" => "Called Mail() without being connected");
 544        return false;
 545      }
 546  
 547      $useVerp = ($this->do_verp ? "XVERP" : "");
 548      fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
 549  
 550      $rply = $this->get_lines();
 551      $code = substr($rply,0,3);
 552  
 553      if($this->do_debug >= 2) {
 554        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 555      }
 556  
 557      if($code != 250) {
 558        $this->error =
 559          array("error" => "MAIL not accepted from server",
 560                "smtp_code" => $code,
 561                "smtp_msg" => substr($rply,4));
 562        if($this->do_debug >= 1) {
 563          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 564        }
 565        return false;
 566      }
 567      return true;
 568    }
 569  
 570    /**
 571     * Sends the quit command to the server and then closes the socket
 572     * if there is no error or the $close_on_error argument is true.
 573     *
 574     * Implements from rfc 821: QUIT <CRLF>
 575     *
 576     * SMTP CODE SUCCESS: 221
 577     * SMTP CODE ERROR  : 500
 578     * @access public
 579     * @return bool
 580     */
 581    public function Quit($close_on_error = true) {
 582      $this->error = null; // so there is no confusion
 583  
 584      if(!$this->connected()) {
 585        $this->error = array(
 586                "error" => "Called Quit() without being connected");
 587        return false;
 588      }
 589  
 590      // send the quit command to the server
 591      fputs($this->smtp_conn,"quit" . $this->CRLF);
 592  
 593      // get any good-bye messages
 594      $byemsg = $this->get_lines();
 595  
 596      if($this->do_debug >= 2) {
 597        echo "SMTP -> FROM SERVER:" . $byemsg . $this->CRLF . '<br />';
 598      }
 599  
 600      $rval = true;
 601      $e = null;
 602  
 603      $code = substr($byemsg,0,3);
 604      if($code != 221) {
 605        // use e as a tmp var cause Close will overwrite $this->error
 606        $e = array("error" => "SMTP server rejected quit command",
 607                   "smtp_code" => $code,
 608                   "smtp_rply" => substr($byemsg,4));
 609        $rval = false;
 610        if($this->do_debug >= 1) {
 611          echo "SMTP -> ERROR: " . $e["error"] . ": " . $byemsg . $this->CRLF . '<br />';
 612        }
 613      }
 614  
 615      if(empty($e) || $close_on_error) {
 616        $this->Close();
 617      }
 618  
 619      return $rval;
 620    }
 621  
 622    /**
 623     * Sends the command RCPT to the SMTP server with the TO: argument of $to.
 624     * Returns true if the recipient was accepted false if it was rejected.
 625     *
 626     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
 627     *
 628     * SMTP CODE SUCCESS: 250,251
 629     * SMTP CODE FAILURE: 550,551,552,553,450,451,452
 630     * SMTP CODE ERROR  : 500,501,503,421
 631     * @access public
 632     * @return bool
 633     */
 634    public function Recipient($to) {
 635      $this->error = null; // so no confusion is caused
 636  
 637      if(!$this->connected()) {
 638        $this->error = array(
 639                "error" => "Called Recipient() without being connected");
 640        return false;
 641      }
 642  
 643      fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
 644  
 645      $rply = $this->get_lines();
 646      $code = substr($rply,0,3);
 647  
 648      if($this->do_debug >= 2) {
 649        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 650      }
 651  
 652      if($code != 250 && $code != 251) {
 653        $this->error =
 654          array("error" => "RCPT not accepted from server",
 655                "smtp_code" => $code,
 656                "smtp_msg" => substr($rply,4));
 657        if($this->do_debug >= 1) {
 658          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 659        }
 660        return false;
 661      }
 662      return true;
 663    }
 664  
 665    /**
 666     * Sends the RSET command to abort and transaction that is
 667     * currently in progress. Returns true if successful false
 668     * otherwise.
 669     *
 670     * Implements rfc 821: RSET <CRLF>
 671     *
 672     * SMTP CODE SUCCESS: 250
 673     * SMTP CODE ERROR  : 500,501,504,421
 674     * @access public
 675     * @return bool
 676     */
 677    public function Reset() {
 678      $this->error = null; // so no confusion is caused
 679  
 680      if(!$this->connected()) {
 681        $this->error = array(
 682                "error" => "Called Reset() without being connected");
 683        return false;
 684      }
 685  
 686      fputs($this->smtp_conn,"RSET" . $this->CRLF);
 687  
 688      $rply = $this->get_lines();
 689      $code = substr($rply,0,3);
 690  
 691      if($this->do_debug >= 2) {
 692        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 693      }
 694  
 695      if($code != 250) {
 696        $this->error =
 697          array("error" => "RSET failed",
 698                "smtp_code" => $code,
 699                "smtp_msg" => substr($rply,4));
 700        if($this->do_debug >= 1) {
 701          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 702        }
 703        return false;
 704      }
 705  
 706      return true;
 707    }
 708  
 709    /**
 710     * Starts a mail transaction from the email address specified in
 711     * $from. Returns true if successful or false otherwise. If True
 712     * the mail transaction is started and then one or more Recipient
 713     * commands may be called followed by a Data command. This command
 714     * will send the message to the users terminal if they are logged
 715     * in and send them an email.
 716     *
 717     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
 718     *
 719     * SMTP CODE SUCCESS: 250
 720     * SMTP CODE SUCCESS: 552,451,452
 721     * SMTP CODE SUCCESS: 500,501,502,421
 722     * @access public
 723     * @return bool
 724     */
 725    public function SendAndMail($from) {
 726      $this->error = null; // so no confusion is caused
 727  
 728      if(!$this->connected()) {
 729        $this->error = array(
 730            "error" => "Called SendAndMail() without being connected");
 731        return false;
 732      }
 733  
 734      fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
 735  
 736      $rply = $this->get_lines();
 737      $code = substr($rply,0,3);
 738  
 739      if($this->do_debug >= 2) {
 740        echo "SMTP -> FROM SERVER:" . $rply . $this->CRLF . '<br />';
 741      }
 742  
 743      if($code != 250) {
 744        $this->error =
 745          array("error" => "SAML not accepted from server",
 746                "smtp_code" => $code,
 747                "smtp_msg" => substr($rply,4));
 748        if($this->do_debug >= 1) {
 749          echo "SMTP -> ERROR: " . $this->error["error"] . ": " . $rply . $this->CRLF . '<br />';
 750        }
 751        return false;
 752      }
 753      return true;
 754    }
 755  
 756    /**
 757     * This is an optional command for SMTP that this class does not
 758     * support. This method is here to make the RFC821 Definition
 759     * complete for this class and __may__ be implimented in the future
 760     *
 761     * Implements from rfc 821: TURN <CRLF>
 762     *
 763     * SMTP CODE SUCCESS: 250
 764     * SMTP CODE FAILURE: 502
 765     * SMTP CODE ERROR  : 500, 503
 766     * @access public
 767     * @return bool
 768     */
 769    public function Turn() {
 770      $this->error = array("error" => "This method, TURN, of the SMTP ".
 771                                      "is not implemented");
 772      if($this->do_debug >= 1) {
 773        echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF . '<br />';
 774      }
 775      return false;
 776    }
 777  
 778    /**
 779    * Get the current error
 780    * @access public
 781    * @return array
 782    */
 783    public function getError() {
 784      return $this->error;
 785    }
 786  
 787    /////////////////////////////////////////////////
 788    // INTERNAL FUNCTIONS
 789    /////////////////////////////////////////////////
 790  
 791    /**
 792     * Read in as many lines as possible
 793     * either before eof or socket timeout occurs on the operation.
 794     * With SMTP we can tell if we have more lines to read if the
 795     * 4th character is '-' symbol. If it is a space then we don't
 796     * need to read anything else.
 797     * @access private
 798     * @return string
 799     */
 800    private function get_lines() {
 801      $data = "";
 802      while(!feof($this->smtp_conn)) {
 803        $str = @fgets($this->smtp_conn,515);
 804        if($this->do_debug >= 4) {
 805          echo "SMTP -> get_lines(): \$data was \"$data\"" . $this->CRLF . '<br />';
 806          echo "SMTP -> get_lines(): \$str is \"$str\"" . $this->CRLF . '<br />';
 807        }
 808        $data .= $str;
 809        if($this->do_debug >= 4) {
 810          echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF . '<br />';
 811        }
 812        // if 4th character is a space, we are done reading, break the loop
 813        if(substr($str,3,1) == " ") { break; }
 814      }
 815      return $data;
 816    }
 817  
 818  }
 819  


Generated: Wed Dec 19 01:01:51 2018 Cross-referenced by PHPXref 0.7.1