[ Index ]

PHP Cross Reference of Wordpress 2.9.1

title

Body

[close]

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

   1  <?php
   2  /*~ class.smtp.php
   3  .---------------------------------------------------------------------------.
   4  |  Software: PHPMailer - PHP email class                                    |
   5  |   Version: 2.0.4                                                          |
   6  |   Contact: via sourceforge.net support pages (also www.codeworxtech.com)  |
   7  |      Info: http://phpmailer.sourceforge.net                               |
   8  |   Support: http://sourceforge.net/projects/phpmailer/                     |
   9  | ------------------------------------------------------------------------- |
  10  |    Author: Andy Prevost (project admininistrator)                         |
  11  |    Author: Brent R. Matzelle (original founder)                           |
  12  | Copyright (c) 2004-2007, Andy Prevost. All Rights Reserved.               |
  13  | Copyright (c) 2001-2003, Brent R. Matzelle                                |
  14  | ------------------------------------------------------------------------- |
  15  |   License: Distributed under the Lesser General Public License (LGPL)     |
  16  |            http://www.gnu.org/copyleft/lesser.html                        |
  17  | This program is distributed in the hope that it will be useful - WITHOUT  |
  18  | ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or     |
  19  | FITNESS FOR A PARTICULAR PURPOSE.                                         |
  20  | ------------------------------------------------------------------------- |
  21  | We offer a number of paid services (www.codeworxtech.com):                |
  22  | - Web Hosting on highly optimized fast and secure servers                 |
  23  | - Technology Consulting                                                   |
  24  | - Oursourcing (highly qualified programmers and graphic designers)        |
  25  '---------------------------------------------------------------------------'
  26   */
  27  /**
  28   * SMTP is rfc 821 compliant and implements all the rfc 821 SMTP
  29   * commands except TURN which will always return a not implemented
  30   * error. SMTP also provides some utility methods for sending mail
  31   * to an SMTP server.
  32   * @package PHPMailer
  33   * @author Chris Ryan
  34   */
  35  
  36  class SMTP
  37  {
  38    /**
  39     *  SMTP server port
  40     *  @var int
  41     */
  42    var $SMTP_PORT = 25;
  43  
  44    /**
  45     *  SMTP reply line ending
  46     *  @var string
  47     */
  48    var $CRLF = "\r\n";
  49  
  50    /**
  51     *  Sets whether debugging is turned on
  52     *  @var bool
  53     */
  54    var $do_debug;       # the level of debug to perform
  55  
  56    /**
  57     *  Sets VERP use on/off (default is off)
  58     *  @var bool
  59     */
  60    var $do_verp = false;
  61  
  62    /**#@+
  63     * @access private
  64     */
  65    var $smtp_conn;      # the socket to the server
  66    var $error;          # error if any on the last call
  67    var $helo_rply;      # the reply the server sent to us for HELO
  68    /**#@-*/
  69  
  70    /**
  71     * Initialize the class so that the data is in a known state.
  72     * @access public
  73     * @return void
  74     */
  75    function SMTP() {
  76      $this->smtp_conn = 0;
  77      $this->error = null;
  78      $this->helo_rply = null;
  79  
  80      $this->do_debug = 0;
  81    }
  82  
  83    /*************************************************************
  84     *                    CONNECTION FUNCTIONS                  *
  85     ***********************************************************/
  86  
  87    /**
  88     * Connect to the server specified on the port specified.
  89     * If the port is not specified use the default SMTP_PORT.
  90     * If tval is specified then a connection will try and be
  91     * established with the server for that number of seconds.
  92     * If tval is not specified the default is 30 seconds to
  93     * try on the connection.
  94     *
  95     * SMTP CODE SUCCESS: 220
  96     * SMTP CODE FAILURE: 421
  97     * @access public
  98     * @return bool
  99     */
 100    function Connect($host,$port=0,$tval=30) {
 101      # set the error val to null so there is no confusion
 102      $this->error = null;
 103  
 104      # make sure we are __not__ connected
 105      if($this->connected()) {
 106        # ok we are connected! what should we do?
 107        # for now we will just give an error saying we
 108        # are already connected
 109        $this->error = array("error" => "Already connected to a server");
 110        return false;
 111      }
 112  
 113      if(empty($port)) {
 114        $port = $this->SMTP_PORT;
 115      }
 116  
 117      #connect to the smtp server
 118      $this->smtp_conn = fsockopen($host,    # the host of the server
 119                                   $port,    # the port to use
 120                                   $errno,   # error number if any
 121                                   $errstr,  # error message if any
 122                                   $tval);   # give up after ? secs
 123      # verify we connected properly
 124      if(empty($this->smtp_conn)) {
 125        $this->error = array("error" => "Failed to connect to server",
 126                             "errno" => $errno,
 127                             "errstr" => $errstr);
 128        if($this->do_debug >= 1) {
 129          echo "SMTP -> ERROR: " . $this->error["error"] .
 130                   ": $errstr ($errno)" . $this->CRLF;
 131        }
 132        return false;
 133      }
 134  
 135      # sometimes the SMTP server takes a little longer to respond
 136      # so we will give it a longer timeout for the first read
 137      // Windows still does not have support for this timeout function
 138      if(substr(PHP_OS, 0, 3) != "WIN")
 139       socket_set_timeout($this->smtp_conn, $tval, 0);
 140  
 141      # get any announcement stuff
 142      $announce = $this->get_lines();
 143  
 144      # set the timeout  of any socket functions at 1/10 of a second
 145      //if(function_exists("socket_set_timeout"))
 146      //   socket_set_timeout($this->smtp_conn, 0, 100000);
 147  
 148      if($this->do_debug >= 2) {
 149        echo "SMTP -> FROM SERVER:" . $this->CRLF . $announce;
 150      }
 151  
 152      return true;
 153    }
 154  
 155    /**
 156     * Performs SMTP authentication.  Must be run after running the
 157     * Hello() method.  Returns true if successfully authenticated.
 158     * @access public
 159     * @return bool
 160     */
 161    function Authenticate($username, $password) {
 162      // Start authentication
 163      fputs($this->smtp_conn,"AUTH LOGIN" . $this->CRLF);
 164  
 165      $rply = $this->get_lines();
 166      $code = substr($rply,0,3);
 167  
 168      if($code != 334) {
 169        $this->error =
 170          array("error" => "AUTH not accepted from server",
 171                "smtp_code" => $code,
 172                "smtp_msg" => substr($rply,4));
 173        if($this->do_debug >= 1) {
 174          echo "SMTP -> ERROR: " . $this->error["error"] .
 175                   ": " . $rply . $this->CRLF;
 176        }
 177        return false;
 178      }
 179  
 180      // Send encoded username
 181      fputs($this->smtp_conn, base64_encode($username) . $this->CRLF);
 182  
 183      $rply = $this->get_lines();
 184      $code = substr($rply,0,3);
 185  
 186      if($code != 334) {
 187        $this->error =
 188          array("error" => "Username not accepted from server",
 189                "smtp_code" => $code,
 190                "smtp_msg" => substr($rply,4));
 191        if($this->do_debug >= 1) {
 192          echo "SMTP -> ERROR: " . $this->error["error"] .
 193                   ": " . $rply . $this->CRLF;
 194        }
 195        return false;
 196      }
 197  
 198      // Send encoded password
 199      fputs($this->smtp_conn, base64_encode($password) . $this->CRLF);
 200  
 201      $rply = $this->get_lines();
 202      $code = substr($rply,0,3);
 203  
 204      if($code != 235) {
 205        $this->error =
 206          array("error" => "Password not accepted from server",
 207                "smtp_code" => $code,
 208                "smtp_msg" => substr($rply,4));
 209        if($this->do_debug >= 1) {
 210          echo "SMTP -> ERROR: " . $this->error["error"] .
 211                   ": " . $rply . $this->CRLF;
 212        }
 213        return false;
 214      }
 215  
 216      return true;
 217    }
 218  
 219    /**
 220     * Returns true if connected to a server otherwise false
 221     * @access private
 222     * @return bool
 223     */
 224    function Connected() {
 225      if(!empty($this->smtp_conn)) {
 226        $sock_status = socket_get_status($this->smtp_conn);
 227        if($sock_status["eof"]) {
 228          # hmm this is an odd situation... the socket is
 229          # valid but we are not connected anymore
 230          if($this->do_debug >= 1) {
 231              echo "SMTP -> NOTICE:" . $this->CRLF .
 232                   "EOF caught while checking if connected";
 233          }
 234          $this->Close();
 235          return false;
 236        }
 237        return true; # everything looks good
 238      }
 239      return false;
 240    }
 241  
 242    /**
 243     * Closes the socket and cleans up the state of the class.
 244     * It is not considered good to use this function without
 245     * first trying to use QUIT.
 246     * @access public
 247     * @return void
 248     */
 249    function Close() {
 250      $this->error = null; # so there is no confusion
 251      $this->helo_rply = null;
 252      if(!empty($this->smtp_conn)) {
 253        # close the connection and cleanup
 254        fclose($this->smtp_conn);
 255        $this->smtp_conn = 0;
 256      }
 257    }
 258  
 259    /***************************************************************
 260     *                        SMTP COMMANDS                       *
 261     *************************************************************/
 262  
 263    /**
 264     * Issues a data command and sends the msg_data to the server
 265     * finializing the mail transaction. $msg_data is the message
 266     * that is to be send with the headers. Each header needs to be
 267     * on a single line followed by a <CRLF> with the message headers
 268     * and the message body being seperated by and additional <CRLF>.
 269     *
 270     * Implements rfc 821: DATA <CRLF>
 271     *
 272     * SMTP CODE INTERMEDIATE: 354
 273     *     [data]
 274     *     <CRLF>.<CRLF>
 275     *     SMTP CODE SUCCESS: 250
 276     *     SMTP CODE FAILURE: 552,554,451,452
 277     * SMTP CODE FAILURE: 451,554
 278     * SMTP CODE ERROR  : 500,501,503,421
 279     * @access public
 280     * @return bool
 281     */
 282    function Data($msg_data) {
 283      $this->error = null; # so no confusion is caused
 284  
 285      if(!$this->connected()) {
 286        $this->error = array(
 287                "error" => "Called Data() without being connected");
 288        return false;
 289      }
 290  
 291      fputs($this->smtp_conn,"DATA" . $this->CRLF);
 292  
 293      $rply = $this->get_lines();
 294      $code = substr($rply,0,3);
 295  
 296      if($this->do_debug >= 2) {
 297        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 298      }
 299  
 300      if($code != 354) {
 301        $this->error =
 302          array("error" => "DATA command not accepted from server",
 303                "smtp_code" => $code,
 304                "smtp_msg" => substr($rply,4));
 305        if($this->do_debug >= 1) {
 306          echo "SMTP -> ERROR: " . $this->error["error"] .
 307                   ": " . $rply . $this->CRLF;
 308        }
 309        return false;
 310      }
 311  
 312      # the server is ready to accept data!
 313      # according to rfc 821 we should not send more than 1000
 314      # including the CRLF
 315      # characters on a single line so we will break the data up
 316      # into lines by \r and/or \n then if needed we will break
 317      # each of those into smaller lines to fit within the limit.
 318      # in addition we will be looking for lines that start with
 319      # a period '.' and append and additional period '.' to that
 320      # line. NOTE: this does not count towards are limit.
 321  
 322      # normalize the line breaks so we know the explode works
 323      $msg_data = str_replace("\r\n","\n",$msg_data);
 324      $msg_data = str_replace("\r","\n",$msg_data);
 325      $lines = explode("\n",$msg_data);
 326  
 327      # we need to find a good way to determine is headers are
 328      # in the msg_data or if it is a straight msg body
 329      # currently I am assuming rfc 822 definitions of msg headers
 330      # and if the first field of the first line (':' sperated)
 331      # does not contain a space then it _should_ be a header
 332      # and we can process all lines before a blank "" line as
 333      # headers.
 334      $field = substr($lines[0],0,strpos($lines[0],":"));
 335      $in_headers = false;
 336      if(!empty($field) && !strstr($field," ")) {
 337        $in_headers = true;
 338      }
 339  
 340      $max_line_length = 998; # used below; set here for ease in change
 341  
 342      while(list(,$line) = @each($lines)) {
 343        $lines_out = null;
 344        if($line == "" && $in_headers) {
 345          $in_headers = false;
 346        }
 347        # ok we need to break this line up into several
 348        # smaller lines
 349        while(strlen($line) > $max_line_length) {
 350          $pos = strrpos(substr($line,0,$max_line_length)," ");
 351  
 352          # Patch to fix DOS attack
 353          if(!$pos) {
 354            $pos = $max_line_length - 1;
 355          }
 356  
 357          $lines_out[] = substr($line,0,$pos);
 358          $line = substr($line,$pos + 1);
 359          # if we are processing headers we need to
 360          # add a LWSP-char to the front of the new line
 361          # rfc 822 on long msg headers
 362          if($in_headers) {
 363            $line = "\t" . $line;
 364          }
 365        }
 366        $lines_out[] = $line;
 367  
 368        # now send the lines to the server
 369        while(list(,$line_out) = @each($lines_out)) {
 370          if(strlen($line_out) > 0)
 371          {
 372            if(substr($line_out, 0, 1) == ".") {
 373              $line_out = "." . $line_out;
 374            }
 375          }
 376          fputs($this->smtp_conn,$line_out . $this->CRLF);
 377        }
 378      }
 379  
 380      # ok all the message data has been sent so lets get this
 381      # over with aleady
 382      fputs($this->smtp_conn, $this->CRLF . "." . $this->CRLF);
 383  
 384      $rply = $this->get_lines();
 385      $code = substr($rply,0,3);
 386  
 387      if($this->do_debug >= 2) {
 388        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 389      }
 390  
 391      if($code != 250) {
 392        $this->error =
 393          array("error" => "DATA not accepted from server",
 394                "smtp_code" => $code,
 395                "smtp_msg" => substr($rply,4));
 396        if($this->do_debug >= 1) {
 397          echo "SMTP -> ERROR: " . $this->error["error"] .
 398                   ": " . $rply . $this->CRLF;
 399        }
 400        return false;
 401      }
 402      return true;
 403    }
 404  
 405    /**
 406     * Expand takes the name and asks the server to list all the
 407     * people who are members of the _list_. Expand will return
 408     * back and array of the result or false if an error occurs.
 409     * Each value in the array returned has the format of:
 410     *     [ <full-name> <sp> ] <path>
 411     * The definition of <path> is defined in rfc 821
 412     *
 413     * Implements rfc 821: EXPN <SP> <string> <CRLF>
 414     *
 415     * SMTP CODE SUCCESS: 250
 416     * SMTP CODE FAILURE: 550
 417     * SMTP CODE ERROR  : 500,501,502,504,421
 418     * @access public
 419     * @return string array
 420     */
 421    function Expand($name) {
 422      $this->error = null; # so no confusion is caused
 423  
 424      if(!$this->connected()) {
 425        $this->error = array(
 426              "error" => "Called Expand() without being connected");
 427        return false;
 428      }
 429  
 430      fputs($this->smtp_conn,"EXPN " . $name . $this->CRLF);
 431  
 432      $rply = $this->get_lines();
 433      $code = substr($rply,0,3);
 434  
 435      if($this->do_debug >= 2) {
 436        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 437      }
 438  
 439      if($code != 250) {
 440        $this->error =
 441          array("error" => "EXPN not accepted from server",
 442                "smtp_code" => $code,
 443                "smtp_msg" => substr($rply,4));
 444        if($this->do_debug >= 1) {
 445          echo "SMTP -> ERROR: " . $this->error["error"] .
 446                   ": " . $rply . $this->CRLF;
 447        }
 448        return false;
 449      }
 450  
 451      # parse the reply and place in our array to return to user
 452      $entries = explode($this->CRLF,$rply);
 453      while(list(,$l) = @each($entries)) {
 454        $list[] = substr($l,4);
 455      }
 456  
 457      return $list;
 458    }
 459  
 460    /**
 461     * Sends the HELO command to the smtp server.
 462     * This makes sure that we and the server are in
 463     * the same known state.
 464     *
 465     * Implements from rfc 821: HELO <SP> <domain> <CRLF>
 466     *
 467     * SMTP CODE SUCCESS: 250
 468     * SMTP CODE ERROR  : 500, 501, 504, 421
 469     * @access public
 470     * @return bool
 471     */
 472    function Hello($host="") {
 473      $this->error = null; # so no confusion is caused
 474  
 475      if(!$this->connected()) {
 476        $this->error = array(
 477              "error" => "Called Hello() without being connected");
 478        return false;
 479      }
 480  
 481      # if a hostname for the HELO was not specified determine
 482      # a suitable one to send
 483      if(empty($host)) {
 484        # we need to determine some sort of appopiate default
 485        # to send to the server
 486        $host = "localhost";
 487      }
 488  
 489      // Send extended hello first (RFC 2821)
 490      if(!$this->SendHello("EHLO", $host))
 491      {
 492        if(!$this->SendHello("HELO", $host))
 493            return false;
 494      }
 495  
 496      return true;
 497    }
 498  
 499    /**
 500     * Sends a HELO/EHLO command.
 501     * @access private
 502     * @return bool
 503     */
 504    function SendHello($hello, $host) {
 505      fputs($this->smtp_conn, $hello . " " . $host . $this->CRLF);
 506  
 507      $rply = $this->get_lines();
 508      $code = substr($rply,0,3);
 509  
 510      if($this->do_debug >= 2) {
 511        echo "SMTP -> FROM SERVER: " . $this->CRLF . $rply;
 512      }
 513  
 514      if($code != 250) {
 515        $this->error =
 516          array("error" => $hello . " not accepted from server",
 517                "smtp_code" => $code,
 518                "smtp_msg" => substr($rply,4));
 519        if($this->do_debug >= 1) {
 520          echo "SMTP -> ERROR: " . $this->error["error"] .
 521                   ": " . $rply . $this->CRLF;
 522        }
 523        return false;
 524      }
 525  
 526      $this->helo_rply = $rply;
 527  
 528      return true;
 529    }
 530  
 531    /**
 532     * Gets help information on the keyword specified. If the keyword
 533     * is not specified then returns generic help, ussually contianing
 534     * A list of keywords that help is available on. This function
 535     * returns the results back to the user. It is up to the user to
 536     * handle the returned data. If an error occurs then false is
 537     * returned with $this->error set appropiately.
 538     *
 539     * Implements rfc 821: HELP [ <SP> <string> ] <CRLF>
 540     *
 541     * SMTP CODE SUCCESS: 211,214
 542     * SMTP CODE ERROR  : 500,501,502,504,421
 543     * @access public
 544     * @return string
 545     */
 546    function Help($keyword="") {
 547      $this->error = null; # to avoid confusion
 548  
 549      if(!$this->connected()) {
 550        $this->error = array(
 551                "error" => "Called Help() without being connected");
 552        return false;
 553      }
 554  
 555      $extra = "";
 556      if(!empty($keyword)) {
 557        $extra = " " . $keyword;
 558      }
 559  
 560      fputs($this->smtp_conn,"HELP" . $extra . $this->CRLF);
 561  
 562      $rply = $this->get_lines();
 563      $code = substr($rply,0,3);
 564  
 565      if($this->do_debug >= 2) {
 566        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 567      }
 568  
 569      if($code != 211 && $code != 214) {
 570        $this->error =
 571          array("error" => "HELP not accepted from server",
 572                "smtp_code" => $code,
 573                "smtp_msg" => substr($rply,4));
 574        if($this->do_debug >= 1) {
 575          echo "SMTP -> ERROR: " . $this->error["error"] .
 576                   ": " . $rply . $this->CRLF;
 577        }
 578        return false;
 579      }
 580  
 581      return $rply;
 582    }
 583  
 584    /**
 585     * Starts a mail transaction from the email address specified in
 586     * $from. Returns true if successful or false otherwise. If True
 587     * the mail transaction is started and then one or more Recipient
 588     * commands may be called followed by a Data command.
 589     *
 590     * Implements rfc 821: MAIL <SP> FROM:<reverse-path> <CRLF>
 591     *
 592     * SMTP CODE SUCCESS: 250
 593     * SMTP CODE SUCCESS: 552,451,452
 594     * SMTP CODE SUCCESS: 500,501,421
 595     * @access public
 596     * @return bool
 597     */
 598    function Mail($from) {
 599      $this->error = null; # so no confusion is caused
 600  
 601      if(!$this->connected()) {
 602        $this->error = array(
 603                "error" => "Called Mail() without being connected");
 604        return false;
 605      }
 606  
 607      $useVerp = ($this->do_verp ? "XVERP" : "");
 608      fputs($this->smtp_conn,"MAIL FROM:<" . $from . ">" . $useVerp . $this->CRLF);
 609  
 610      $rply = $this->get_lines();
 611      $code = substr($rply,0,3);
 612  
 613      if($this->do_debug >= 2) {
 614        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 615      }
 616  
 617      if($code != 250) {
 618        $this->error =
 619          array("error" => "MAIL not accepted from server",
 620                "smtp_code" => $code,
 621                "smtp_msg" => substr($rply,4));
 622        if($this->do_debug >= 1) {
 623          echo "SMTP -> ERROR: " . $this->error["error"] .
 624                   ": " . $rply . $this->CRLF;
 625        }
 626        return false;
 627      }
 628      return true;
 629    }
 630  
 631    /**
 632     * Sends the command NOOP to the SMTP server.
 633     *
 634     * Implements from rfc 821: NOOP <CRLF>
 635     *
 636     * SMTP CODE SUCCESS: 250
 637     * SMTP CODE ERROR  : 500, 421
 638     * @access public
 639     * @return bool
 640     */
 641    function Noop() {
 642      $this->error = null; # so no confusion is caused
 643  
 644      if(!$this->connected()) {
 645        $this->error = array(
 646                "error" => "Called Noop() without being connected");
 647        return false;
 648      }
 649  
 650      fputs($this->smtp_conn,"NOOP" . $this->CRLF);
 651  
 652      $rply = $this->get_lines();
 653      $code = substr($rply,0,3);
 654  
 655      if($this->do_debug >= 2) {
 656        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 657      }
 658  
 659      if($code != 250) {
 660        $this->error =
 661          array("error" => "NOOP not accepted from server",
 662                "smtp_code" => $code,
 663                "smtp_msg" => substr($rply,4));
 664        if($this->do_debug >= 1) {
 665          echo "SMTP -> ERROR: " . $this->error["error"] .
 666                   ": " . $rply . $this->CRLF;
 667        }
 668        return false;
 669      }
 670      return true;
 671    }
 672  
 673    /**
 674     * Sends the quit command to the server and then closes the socket
 675     * if there is no error or the $close_on_error argument is true.
 676     *
 677     * Implements from rfc 821: QUIT <CRLF>
 678     *
 679     * SMTP CODE SUCCESS: 221
 680     * SMTP CODE ERROR  : 500
 681     * @access public
 682     * @return bool
 683     */
 684    function Quit($close_on_error=true) {
 685      $this->error = null; # so there is no confusion
 686  
 687      if(!$this->connected()) {
 688        $this->error = array(
 689                "error" => "Called Quit() without being connected");
 690        return false;
 691      }
 692  
 693      # send the quit command to the server
 694      fputs($this->smtp_conn,"quit" . $this->CRLF);
 695  
 696      # get any good-bye messages
 697      $byemsg = $this->get_lines();
 698  
 699      if($this->do_debug >= 2) {
 700        echo "SMTP -> FROM SERVER:" . $this->CRLF . $byemsg;
 701      }
 702  
 703      $rval = true;
 704      $e = null;
 705  
 706      $code = substr($byemsg,0,3);
 707      if($code != 221) {
 708        # use e as a tmp var cause Close will overwrite $this->error
 709        $e = array("error" => "SMTP server rejected quit command",
 710                   "smtp_code" => $code,
 711                   "smtp_rply" => substr($byemsg,4));
 712        $rval = false;
 713        if($this->do_debug >= 1) {
 714          echo "SMTP -> ERROR: " . $e["error"] . ": " .
 715                   $byemsg . $this->CRLF;
 716        }
 717      }
 718  
 719      if(empty($e) || $close_on_error) {
 720        $this->Close();
 721      }
 722  
 723      return $rval;
 724    }
 725  
 726    /**
 727     * Sends the command RCPT to the SMTP server with the TO: argument of $to.
 728     * Returns true if the recipient was accepted false if it was rejected.
 729     *
 730     * Implements from rfc 821: RCPT <SP> TO:<forward-path> <CRLF>
 731     *
 732     * SMTP CODE SUCCESS: 250,251
 733     * SMTP CODE FAILURE: 550,551,552,553,450,451,452
 734     * SMTP CODE ERROR  : 500,501,503,421
 735     * @access public
 736     * @return bool
 737     */
 738    function Recipient($to) {
 739      $this->error = null; # so no confusion is caused
 740  
 741      if(!$this->connected()) {
 742        $this->error = array(
 743                "error" => "Called Recipient() without being connected");
 744        return false;
 745      }
 746  
 747      fputs($this->smtp_conn,"RCPT TO:<" . $to . ">" . $this->CRLF);
 748  
 749      $rply = $this->get_lines();
 750      $code = substr($rply,0,3);
 751  
 752      if($this->do_debug >= 2) {
 753        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 754      }
 755  
 756      if($code != 250 && $code != 251) {
 757        $this->error =
 758          array("error" => "RCPT not accepted from server",
 759                "smtp_code" => $code,
 760                "smtp_msg" => substr($rply,4));
 761        if($this->do_debug >= 1) {
 762          echo "SMTP -> ERROR: " . $this->error["error"] .
 763                   ": " . $rply . $this->CRLF;
 764        }
 765        return false;
 766      }
 767      return true;
 768    }
 769  
 770    /**
 771     * Sends the RSET command to abort and transaction that is
 772     * currently in progress. Returns true if successful false
 773     * otherwise.
 774     *
 775     * Implements rfc 821: RSET <CRLF>
 776     *
 777     * SMTP CODE SUCCESS: 250
 778     * SMTP CODE ERROR  : 500,501,504,421
 779     * @access public
 780     * @return bool
 781     */
 782    function Reset() {
 783      $this->error = null; # so no confusion is caused
 784  
 785      if(!$this->connected()) {
 786        $this->error = array(
 787                "error" => "Called Reset() without being connected");
 788        return false;
 789      }
 790  
 791      fputs($this->smtp_conn,"RSET" . $this->CRLF);
 792  
 793      $rply = $this->get_lines();
 794      $code = substr($rply,0,3);
 795  
 796      if($this->do_debug >= 2) {
 797        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 798      }
 799  
 800      if($code != 250) {
 801        $this->error =
 802          array("error" => "RSET failed",
 803                "smtp_code" => $code,
 804                "smtp_msg" => substr($rply,4));
 805        if($this->do_debug >= 1) {
 806          echo "SMTP -> ERROR: " . $this->error["error"] .
 807                   ": " . $rply . $this->CRLF;
 808        }
 809        return false;
 810      }
 811  
 812      return true;
 813    }
 814  
 815    /**
 816     * Starts a mail transaction from the email address specified in
 817     * $from. Returns true if successful or false otherwise. If True
 818     * the mail transaction is started and then one or more Recipient
 819     * commands may be called followed by a Data command. This command
 820     * will send the message to the users terminal if they are logged
 821     * in.
 822     *
 823     * Implements rfc 821: SEND <SP> FROM:<reverse-path> <CRLF>
 824     *
 825     * SMTP CODE SUCCESS: 250
 826     * SMTP CODE SUCCESS: 552,451,452
 827     * SMTP CODE SUCCESS: 500,501,502,421
 828     * @access public
 829     * @return bool
 830     */
 831    function Send($from) {
 832      $this->error = null; # so no confusion is caused
 833  
 834      if(!$this->connected()) {
 835        $this->error = array(
 836                "error" => "Called Send() without being connected");
 837        return false;
 838      }
 839  
 840      fputs($this->smtp_conn,"SEND FROM:" . $from . $this->CRLF);
 841  
 842      $rply = $this->get_lines();
 843      $code = substr($rply,0,3);
 844  
 845      if($this->do_debug >= 2) {
 846        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 847      }
 848  
 849      if($code != 250) {
 850        $this->error =
 851          array("error" => "SEND not accepted from server",
 852                "smtp_code" => $code,
 853                "smtp_msg" => substr($rply,4));
 854        if($this->do_debug >= 1) {
 855          echo "SMTP -> ERROR: " . $this->error["error"] .
 856                   ": " . $rply . $this->CRLF;
 857        }
 858        return false;
 859      }
 860      return true;
 861    }
 862  
 863    /**
 864     * Starts a mail transaction from the email address specified in
 865     * $from. Returns true if successful or false otherwise. If True
 866     * the mail transaction is started and then one or more Recipient
 867     * commands may be called followed by a Data command. This command
 868     * will send the message to the users terminal if they are logged
 869     * in and send them an email.
 870     *
 871     * Implements rfc 821: SAML <SP> FROM:<reverse-path> <CRLF>
 872     *
 873     * SMTP CODE SUCCESS: 250
 874     * SMTP CODE SUCCESS: 552,451,452
 875     * SMTP CODE SUCCESS: 500,501,502,421
 876     * @access public
 877     * @return bool
 878     */
 879    function SendAndMail($from) {
 880      $this->error = null; # so no confusion is caused
 881  
 882      if(!$this->connected()) {
 883        $this->error = array(
 884            "error" => "Called SendAndMail() without being connected");
 885        return false;
 886      }
 887  
 888      fputs($this->smtp_conn,"SAML FROM:" . $from . $this->CRLF);
 889  
 890      $rply = $this->get_lines();
 891      $code = substr($rply,0,3);
 892  
 893      if($this->do_debug >= 2) {
 894        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 895      }
 896  
 897      if($code != 250) {
 898        $this->error =
 899          array("error" => "SAML not accepted from server",
 900                "smtp_code" => $code,
 901                "smtp_msg" => substr($rply,4));
 902        if($this->do_debug >= 1) {
 903          echo "SMTP -> ERROR: " . $this->error["error"] .
 904                   ": " . $rply . $this->CRLF;
 905        }
 906        return false;
 907      }
 908      return true;
 909    }
 910  
 911    /**
 912     * Starts a mail transaction from the email address specified in
 913     * $from. Returns true if successful or false otherwise. If True
 914     * the mail transaction is started and then one or more Recipient
 915     * commands may be called followed by a Data command. This command
 916     * will send the message to the users terminal if they are logged
 917     * in or mail it to them if they are not.
 918     *
 919     * Implements rfc 821: SOML <SP> FROM:<reverse-path> <CRLF>
 920     *
 921     * SMTP CODE SUCCESS: 250
 922     * SMTP CODE SUCCESS: 552,451,452
 923     * SMTP CODE SUCCESS: 500,501,502,421
 924     * @access public
 925     * @return bool
 926     */
 927    function SendOrMail($from) {
 928      $this->error = null; # so no confusion is caused
 929  
 930      if(!$this->connected()) {
 931        $this->error = array(
 932            "error" => "Called SendOrMail() without being connected");
 933        return false;
 934      }
 935  
 936      fputs($this->smtp_conn,"SOML FROM:" . $from . $this->CRLF);
 937  
 938      $rply = $this->get_lines();
 939      $code = substr($rply,0,3);
 940  
 941      if($this->do_debug >= 2) {
 942        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
 943      }
 944  
 945      if($code != 250) {
 946        $this->error =
 947          array("error" => "SOML not accepted from server",
 948                "smtp_code" => $code,
 949                "smtp_msg" => substr($rply,4));
 950        if($this->do_debug >= 1) {
 951          echo "SMTP -> ERROR: " . $this->error["error"] .
 952                   ": " . $rply . $this->CRLF;
 953        }
 954        return false;
 955      }
 956      return true;
 957    }
 958  
 959    /**
 960     * This is an optional command for SMTP that this class does not
 961     * support. This method is here to make the RFC821 Definition
 962     * complete for this class and __may__ be implimented in the future
 963     *
 964     * Implements from rfc 821: TURN <CRLF>
 965     *
 966     * SMTP CODE SUCCESS: 250
 967     * SMTP CODE FAILURE: 502
 968     * SMTP CODE ERROR  : 500, 503
 969     * @access public
 970     * @return bool
 971     */
 972    function Turn() {
 973      $this->error = array("error" => "This method, TURN, of the SMTP ".
 974                                      "is not implemented");
 975      if($this->do_debug >= 1) {
 976        echo "SMTP -> NOTICE: " . $this->error["error"] . $this->CRLF;
 977      }
 978      return false;
 979    }
 980  
 981    /**
 982     * Verifies that the name is recognized by the server.
 983     * Returns false if the name could not be verified otherwise
 984     * the response from the server is returned.
 985     *
 986     * Implements rfc 821: VRFY <SP> <string> <CRLF>
 987     *
 988     * SMTP CODE SUCCESS: 250,251
 989     * SMTP CODE FAILURE: 550,551,553
 990     * SMTP CODE ERROR  : 500,501,502,421
 991     * @access public
 992     * @return int
 993     */
 994    function Verify($name) {
 995      $this->error = null; # so no confusion is caused
 996  
 997      if(!$this->connected()) {
 998        $this->error = array(
 999                "error" => "Called Verify() without being connected");
1000        return false;
1001      }
1002  
1003      fputs($this->smtp_conn,"VRFY " . $name . $this->CRLF);
1004  
1005      $rply = $this->get_lines();
1006      $code = substr($rply,0,3);
1007  
1008      if($this->do_debug >= 2) {
1009        echo "SMTP -> FROM SERVER:" . $this->CRLF . $rply;
1010      }
1011  
1012      if($code != 250 && $code != 251) {
1013        $this->error =
1014          array("error" => "VRFY failed on name '$name'",
1015                "smtp_code" => $code,
1016                "smtp_msg" => substr($rply,4));
1017        if($this->do_debug >= 1) {
1018          echo "SMTP -> ERROR: " . $this->error["error"] .
1019                   ": " . $rply . $this->CRLF;
1020        }
1021        return false;
1022      }
1023      return $rply;
1024    }
1025  
1026    /*******************************************************************
1027     *                       INTERNAL FUNCTIONS                       *
1028     ******************************************************************/
1029  
1030    /**
1031     * Read in as many lines as possible
1032     * either before eof or socket timeout occurs on the operation.
1033     * With SMTP we can tell if we have more lines to read if the
1034     * 4th character is '-' symbol. If it is a space then we don't
1035     * need to read anything else.
1036     * @access private
1037     * @return string
1038     */
1039    function get_lines() {
1040      $data = "";
1041      while($str = @fgets($this->smtp_conn,515)) {
1042        if($this->do_debug >= 4) {
1043          echo "SMTP -> get_lines(): \$data was \"$data\"" .
1044                   $this->CRLF;
1045          echo "SMTP -> get_lines(): \$str is \"$str\"" .
1046                   $this->CRLF;
1047        }
1048        $data .= $str;
1049        if($this->do_debug >= 4) {
1050          echo "SMTP -> get_lines(): \$data is \"$data\"" . $this->CRLF;
1051        }
1052        # if the 4th character is a space then we are done reading
1053        # so just break the loop
1054        if(substr($str,3,1) == " ") { break; }
1055      }
1056      return $data;
1057    }
1058  
1059  }
1060  
1061  
1062   ?>


Generated: Fri Jan 8 00:19:48 2010 Cross-referenced by PHPXref 0.7