[ Index ]

PHP Cross Reference of BuddyPress

title

Body

[close]

/src/bp-forums/bbpress/bb-includes/backpress/ -> class.mailer-smtp.php (source)

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


Generated: Sun Apr 28 01:01:05 2024 Cross-referenced by PHPXref 0.7.1