Guest User

class.smtp.php

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