Source for file class.smtp.php

Documentation is available at class.smtp.php

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

Documentation generated on Sun, 04 Apr 2010 22:43:39 +0200 by phpDocumentor 1.4.1