Net_SMTP
[ class tree: Net_SMTP ] [ index: Net_SMTP ] [ all elements ]

Source for file SMTP.php

Documentation is available at SMTP.php

  1. <?php
  2. /* vim: set expandtab softtabstop=4 tabstop=4 shiftwidth=4: */
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Chuck Hagenbuch <chuck@horde.org>                           |
  17. // |          Jon Parise <jon@php.net>                                    |
  18. // |          Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>      |
  19. // +----------------------------------------------------------------------+
  20. //
  21. // $Id: SMTP.php,v 1.54 2005/08/16 03:44:15 jon Exp $
  22.  
  23. require_once 'PEAR.php';
  24. require_once 'Net/Socket.php';
  25.  
  26. /**
  27.  * Provides an implementation of the SMTP protocol using PEAR's
  28.  * Net_Socket:: class.
  29.  *
  30.  * @package Net_SMTP
  31.  * @author  Chuck Hagenbuch <chuck@horde.org>
  32.  * @author  Jon Parise <jon@php.net>
  33.  * @author  Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>
  34.  *
  35.  * @example basic.php   A basic implementation of the Net_SMTP package.
  36.  */
  37. class Net_SMTP
  38. {
  39.  
  40.     /**
  41.      * The server to connect to.
  42.      * @var string 
  43.      * @access public
  44.      */
  45.     var $host = 'localhost';
  46.  
  47.     /**
  48.      * The port to connect to.
  49.      * @var int 
  50.      * @access public
  51.      */
  52.     var $port = 25;
  53.  
  54.     /**
  55.      * The value to give when sending EHLO or HELO.
  56.      * @var string 
  57.      * @access public
  58.      */
  59.     var $localhost = 'localhost';
  60.  
  61.     /**
  62.      * List of supported authentication methods, in preferential order.
  63.      * @var array 
  64.      * @access public
  65.      */
  66.     var $auth_methods = array('DIGEST-MD5''CRAM-MD5''LOGIN''PLAIN');
  67.  
  68.     /**
  69.      * Should debugging output be enabled?
  70.      * @var boolean 
  71.      * @access private
  72.      */
  73.     var $_debug = false;
  74.  
  75.     /**
  76.      * The socket resource being used to connect to the SMTP server.
  77.      * @var resource 
  78.      * @access private
  79.      */
  80.     var $_socket = null;
  81.  
  82.     /**
  83.      * The most recent server response code.
  84.      * @var int 
  85.      * @access private
  86.      */
  87.     var $_code = -1;
  88.  
  89.     /**
  90.      * The most recent server response arguments.
  91.      * @var array 
  92.      * @access private
  93.      */
  94.     var $_arguments = array();
  95.  
  96.     /**
  97.      * Stores detected features of the SMTP server.
  98.      * @var array 
  99.      * @access private
  100.      */
  101.     var $_esmtp = array();
  102.  
  103.     /**
  104.      * Instantiates a new Net_SMTP object, overriding any defaults
  105.      * with parameters that are passed in.
  106.      *
  107.      * If you have SSL support in PHP, you can connect to a server
  108.      * over SSL using an 'ssl://' prefix:
  109.      *
  110.      *   // 465 is a common smtps port.
  111.      *   $smtp = new Net_SMTP('ssl://mail.host.com', 465);
  112.      *   $smtp->connect();
  113.      *
  114.      * @param string  $host       The server to connect to.
  115.      * @param integer $port       The port to connect to.
  116.      * @param string  $localhost  The value to give when sending EHLO or HELO.
  117.      *
  118.      * @access  public
  119.      * @since   1.0
  120.      */
  121.     function Net_SMTP($host = null$port = null$localhost = null)
  122.     {
  123.         if (isset($host)) $this->host = $host;
  124.         if (isset($port)) $this->port = $port;
  125.         if (isset($localhost)) $this->localhost = $localhost;
  126.  
  127.         $this->_socket &new Net_Socket();
  128.  
  129.         /*
  130.          * Include the Auth_SASL package.  If the package is not available,
  131.          * we disable the authentication methods that depend upon it.
  132.          */
  133.         if ((@include_once 'Auth/SASL.php'=== false{
  134.             $pos array_search('DIGEST-MD5'$this->auth_methods);
  135.             unset($this->auth_methods[$pos]);
  136.             $pos array_search('CRAM-MD5'$this->auth_methods);
  137.             unset($this->auth_methods[$pos]);
  138.         }
  139.     }
  140.  
  141.     /**
  142.      * Set the value of the debugging flag.
  143.      *
  144.      * @param   boolean $debug      New value for the debugging flag.
  145.      *
  146.      * @access  public
  147.      * @since   1.1.0
  148.      */
  149.     function setDebug($debug)
  150.     {
  151.         $this->_debug $debug;
  152.     }
  153.  
  154.     /**
  155.      * Send the given string of data to the server.
  156.      *
  157.      * @param   string  $data       The string of data to send.
  158.      *
  159.      * @return  mixed   True on success or a PEAR_Error object on failure.
  160.      *
  161.      * @access  private
  162.      * @since   1.1.0
  163.      */
  164.     function _send($data)
  165.     {
  166.         if ($this->_debug{
  167.             echo "DEBUG: Send: $data\n";
  168.         }
  169.  
  170.         if (PEAR::isError($error $this->_socket->write($data))) {
  171.             return PEAR::raiseError('Failed to write to socket: ' .
  172.                                     $error->getMessage());
  173.         }
  174.  
  175.         return true;
  176.     }
  177.  
  178.     /**
  179.      * Send a command to the server with an optional string of
  180.      * arguments.  A carriage return / linefeed (CRLF) sequence will
  181.      * be appended to each command string before it is sent to the
  182.      * SMTP server - an error will be thrown if the command string
  183.      * already contains any newline characters. Use _send() for
  184.      * commands that must contain newlines.
  185.      *
  186.      * @param   string  $command    The SMTP command to send to the server.
  187.      * @param   string  $args       A string of optional arguments to append
  188.      *                               to the command.
  189.      *
  190.      * @return  mixed   The result of the _send() call.
  191.      *
  192.      * @access  private
  193.      * @since   1.1.0
  194.      */
  195.     function _put($command$args '')
  196.     {
  197.         if (!empty($args)) {
  198.             $command .= ' ' $args;
  199.         }
  200.  
  201.         if (strcspn($command"\r\n"!== strlen($command)) {
  202.             return PEAR::raiseError('Commands cannot contain newlines');
  203.         }
  204.  
  205.         return $this->_send($command "\r\n");
  206.     }
  207.  
  208.     /**
  209.      * Read a reply from the SMTP server.  The reply consists of a response
  210.      * code and a response message.
  211.      *
  212.      * @param   mixed   $valid      The set of valid response codes.  These
  213.      *                               may be specified as an array of integer
  214.      *                               values or as a single integer value.
  215.      *
  216.      * @return  mixed   True if the server returned a valid response code or
  217.      *                   a PEAR_Error object is an error condition is reached.
  218.      *
  219.      * @access  private
  220.      * @since   1.1.0
  221.      *
  222.      * @see     getResponse
  223.      */
  224.     function _parseResponse($valid)
  225.     {
  226.         $this->_code = -1;
  227.         $this->_arguments = array();
  228.  
  229.         while ($line $this->_socket->readLine()) {
  230.             if ($this->_debug{
  231.                 echo "DEBUG: Recv: $line\n";
  232.             }
  233.  
  234.             /* If we receive an empty line, the connection has been closed. */
  235.             if (empty($line)) {
  236.                 $this->disconnect();
  237.                 return PEAR::raiseError('Connection was unexpectedly closed');
  238.             }
  239.  
  240.             /* Read the code and store the rest in the arguments array. */
  241.             $code substr($line03);
  242.             $this->_arguments[trim(substr($line4));
  243.  
  244.             /* Check the syntax of the response code. */
  245.             if (is_numeric($code)) {
  246.                 $this->_code = (int)$code;
  247.             else {
  248.                 $this->_code = -1;
  249.                 break;
  250.             }
  251.  
  252.             /* If this is not a multiline response, we're done. */
  253.             if (substr($line31!= '-'{
  254.                 break;
  255.             }
  256.         }
  257.  
  258.         /* Compare the server's response code with the valid code. */
  259.         if (is_int($valid&& ($this->_code === $valid)) {
  260.             return true;
  261.         }
  262.  
  263.         /* If we were given an array of valid response codes, check each one. */
  264.         if (is_array($valid)) {
  265.             foreach ($valid as $valid_code{
  266.                 if ($this->_code === $valid_code{
  267.                     return true;
  268.                 }
  269.             }
  270.         }
  271.  
  272.         return PEAR::raiseError('Invalid response code received from server');
  273.     }
  274.  
  275.     /**
  276.      * Return a 2-tuple containing the last response from the SMTP server.
  277.      *
  278.      * @return  array   A two-element array: the first element contains the
  279.      *                   response code as an integer and the second element
  280.      *                   contains the response's arguments as a string.
  281.      *
  282.      * @access  public
  283.      * @since   1.1.0
  284.      */
  285.     function getResponse()
  286.     {
  287.         return array($this->_codejoin("\n"$this->_arguments));
  288.     }
  289.  
  290.     /**
  291.      * Attempt to connect to the SMTP server.
  292.      *
  293.      * @param   int     $timeout    The timeout value (in seconds) for the
  294.      *                               socket connection.
  295.      * @param   bool    $persistent Should a persistent socket connection
  296.      *                               be used?
  297.      *
  298.      * @return mixed Returns a PEAR_Error with an error message on any
  299.      *                kind of failure, or true on success.
  300.      * @access public
  301.      * @since  1.0
  302.      */
  303.     function connect($timeout = null$persistent = false)
  304.     {
  305.         $result $this->_socket->connect($this->host$this->port,
  306.                                           $persistent$timeout);
  307.         if (PEAR::isError($result)) {
  308.             return PEAR::raiseError('Failed to connect socket: ' .
  309.                                     $result->getMessage());
  310.         }
  311.  
  312.         if (PEAR::isError($error $this->_parseResponse(220))) {
  313.             return $error;
  314.         }
  315.         if (PEAR::isError($error $this->_negotiate())) {
  316.             return $error;
  317.         }
  318.  
  319.         return true;
  320.     }
  321.  
  322.     /**
  323.      * Attempt to disconnect from the SMTP server.
  324.      *
  325.      * @return mixed Returns a PEAR_Error with an error message on any
  326.      *                kind of failure, or true on success.
  327.      * @access public
  328.      * @since  1.0
  329.      */
  330.     function disconnect()
  331.     {
  332.         if (PEAR::isError($error $this->_put('QUIT'))) {
  333.             return $error;
  334.         }
  335.         if (PEAR::isError($error $this->_parseResponse(221))) {
  336.             return $error;
  337.         }
  338.         if (PEAR::isError($error $this->_socket->disconnect())) {
  339.             return PEAR::raiseError('Failed to disconnect socket: ' .
  340.                                     $error->getMessage());
  341.         }
  342.  
  343.         return true;
  344.     }
  345.  
  346.     /**
  347.      * Attempt to send the EHLO command and obtain a list of ESMTP
  348.      * extensions available, and failing that just send HELO.
  349.      *
  350.      * @return mixed Returns a PEAR_Error with an error message on any
  351.      *                kind of failure, or true on success.
  352.      *
  353.      * @access private
  354.      * @since  1.1.0
  355.      */
  356.     function _negotiate()
  357.     {
  358.         if (PEAR::isError($error $this->_put('EHLO'$this->localhost))) {
  359.             return $error;
  360.         }
  361.  
  362.         if (PEAR::isError($this->_parseResponse(250))) {
  363.             /* If we receive a 503 response, we're already authenticated. */
  364.             if ($this->_code === 503{
  365.                 return true;
  366.             }
  367.  
  368.             /* If the EHLO failed, try the simpler HELO command. */
  369.             if (PEAR::isError($error $this->_put('HELO'$this->localhost))) {
  370.                 return $error;
  371.             }
  372.             if (PEAR::isError($this->_parseResponse(250))) {
  373.                 return PEAR::raiseError('HELO was not accepted: '$this->_code);
  374.             }
  375.  
  376.             return true;
  377.         }
  378.  
  379.         foreach ($this->_arguments as $argument{
  380.             $verb strtok($argument' ');
  381.             $arguments substr($argumentstrlen($verb+ 1,
  382.                                 strlen($argumentstrlen($verb- 1);
  383.             $this->_esmtp[$verb$arguments;
  384.         }
  385.  
  386.         return true;
  387.     }
  388.  
  389.     /**
  390.      * Returns the name of the best authentication method that the server
  391.      * has advertised.
  392.      *
  393.      * @return mixed    Returns a string containing the name of the best
  394.      *                   supported authentication method or a PEAR_Error object
  395.      *                   if a failure condition is encountered.
  396.      * @access private
  397.      * @since  1.1.0
  398.      */
  399.     function _getBestAuthMethod()
  400.     {
  401.         $available_methods explode(' '$this->_esmtp['AUTH']);
  402.  
  403.         foreach ($this->auth_methods as $method{
  404.             if (in_array($method$available_methods)) {
  405.                 return $method;
  406.             }
  407.         }
  408.  
  409.         return PEAR::raiseError('No supported authentication methods');
  410.     }
  411.  
  412.     /**
  413.      * Attempt to do SMTP authentication.
  414.      *
  415.      * @param string The userid to authenticate as.
  416.      * @param string The password to authenticate with.
  417.      * @param string The requested authentication method.  If none is
  418.      *                specified, the best supported method will be used.
  419.      *
  420.      * @return mixed Returns a PEAR_Error with an error message on any
  421.      *                kind of failure, or true on success.
  422.      * @access public
  423.      * @since  1.0
  424.      */
  425.     function auth($uid$pwd $method '')
  426.     {
  427.         if (empty($this->_esmtp['AUTH'])) {
  428.             return PEAR::raiseError('SMTP server does no support authentication');
  429.         }
  430.  
  431.         /* If no method has been specified, get the name of the best
  432.          * supported method advertised by the SMTP server. */
  433.         if (empty($method)) {
  434.             if (PEAR::isError($method $this->_getBestAuthMethod())) {
  435.                 /* Return the PEAR_Error object from _getBestAuthMethod(). */
  436.                 return $method;
  437.             }
  438.         else {
  439.             $method strtoupper($method);
  440.             if (!in_array($method$this->auth_methods)) {
  441.                 return PEAR::raiseError("$method is not a supported authentication method");
  442.             }
  443.         }
  444.  
  445.         switch ($method{
  446.             case 'DIGEST-MD5':
  447.                 $result $this->_authDigest_MD5($uid$pwd);
  448.                 break;
  449.             case 'CRAM-MD5':
  450.                 $result $this->_authCRAM_MD5($uid$pwd);
  451.                 break;
  452.             case 'LOGIN':
  453.                 $result $this->_authLogin($uid$pwd);
  454.                 break;
  455.             case 'PLAIN':
  456.                 $result $this->_authPlain($uid$pwd);
  457.                 break;
  458.             default:
  459.                 $result = PEAR::raiseError("$method is not a supported authentication method");
  460.                 break;
  461.         }
  462.  
  463.         /* If an error was encountered, return the PEAR_Error object. */
  464.         if (PEAR::isError($result)) {
  465.             return $result;
  466.         }
  467.  
  468.         return true;
  469.     }
  470.  
  471.     /**
  472.      * Authenticates the user using the DIGEST-MD5 method.
  473.      *
  474.      * @param string The userid to authenticate as.
  475.      * @param string The password to authenticate with.
  476.      *
  477.      * @return mixed Returns a PEAR_Error with an error message on any
  478.      *                kind of failure, or true on success.
  479.      * @access private
  480.      * @since  1.1.0
  481.      */
  482.     function _authDigest_MD5($uid$pwd)
  483.     {
  484.         if (PEAR::isError($error $this->_put('AUTH''DIGEST-MD5'))) {
  485.             return $error;
  486.         }
  487.         /* 334: Continue authentication request */
  488.         if (PEAR::isError($error $this->_parseResponse(334))) {
  489.             /* 503: Error: already authenticated */
  490.             if ($this->_code === 503{
  491.                 return true;
  492.             }
  493.             return $error;
  494.         }
  495.  
  496.         $challenge base64_decode($this->_arguments[0]);
  497.         $digest &Auth_SASL::factory('digestmd5');
  498.         $auth_str base64_encode($digest->getResponse($uid$pwd$challenge,
  499.                                                        $this->host"smtp"));
  500.  
  501.         if (PEAR::isError($error $this->_put($auth_str))) {
  502.             return $error;
  503.         }
  504.         /* 334: Continue authentication request */
  505.         if (PEAR::isError($error $this->_parseResponse(334))) {
  506.             return $error;
  507.         }
  508.  
  509.         /* We don't use the protocol's third step because SMTP doesn't
  510.          * allow subsequent authentication, so we just silently ignore
  511.          * it. */
  512.         if (PEAR::isError($error $this->_put(' '))) {
  513.             return $error;
  514.         }
  515.         /* 235: Authentication successful */
  516.         if (PEAR::isError($error $this->_parseResponse(235))) {
  517.             return $error;
  518.         }
  519.     }
  520.  
  521.     /**
  522.      * Authenticates the user using the CRAM-MD5 method.
  523.      *
  524.      * @param string The userid to authenticate as.
  525.      * @param string The password to authenticate with.
  526.      *
  527.      * @return mixed Returns a PEAR_Error with an error message on any
  528.      *                kind of failure, or true on success.
  529.      * @access private
  530.      * @since  1.1.0
  531.      */
  532.     function _authCRAM_MD5($uid$pwd)
  533.     {
  534.         if (PEAR::isError($error $this->_put('AUTH''CRAM-MD5'))) {
  535.             return $error;
  536.         }
  537.         /* 334: Continue authentication request */
  538.         if (PEAR::isError($error $this->_parseResponse(334))) {
  539.             /* 503: Error: already authenticated */
  540.             if ($this->_code === 503{
  541.                 return true;
  542.             }
  543.             return $error;
  544.         }
  545.  
  546.         $challenge base64_decode($this->_arguments[0]);
  547.         $cram &Auth_SASL::factory('crammd5');
  548.         $auth_str base64_encode($cram->getResponse($uid$pwd$challenge));
  549.  
  550.         if (PEAR::isError($error $this->_put($auth_str))) {
  551.             return $error;
  552.         }
  553.  
  554.         /* 235: Authentication successful */
  555.         if (PEAR::isError($error $this->_parseResponse(235))) {
  556.             return $error;
  557.         }
  558.     }
  559.  
  560.     /**
  561.      * Authenticates the user using the LOGIN method.
  562.      *
  563.      * @param string The userid to authenticate as.
  564.      * @param string The password to authenticate with.
  565.      *
  566.      * @return mixed Returns a PEAR_Error with an error message on any
  567.      *                kind of failure, or true on success.
  568.      * @access private
  569.      * @since  1.1.0
  570.      */
  571.     function _authLogin($uid$pwd)
  572.     {
  573.         if (PEAR::isError($error $this->_put('AUTH''LOGIN'))) {
  574.             return $error;
  575.         }
  576.         /* 334: Continue authentication request */
  577.         if (PEAR::isError($error $this->_parseResponse(334))) {
  578.             /* 503: Error: already authenticated */
  579.             if ($this->_code === 503{
  580.                 return true;
  581.             }
  582.             return $error;
  583.         }
  584.  
  585.         if (PEAR::isError($error $this->_put(base64_encode($uid)))) {
  586.             return $error;
  587.         }
  588.         /* 334: Continue authentication request */
  589.         if (PEAR::isError($error $this->_parseResponse(334))) {
  590.             return $error;
  591.         }
  592.  
  593.         if (PEAR::isError($error $this->_put(base64_encode($pwd)))) {
  594.             return $error;
  595.         }
  596.  
  597.         /* 235: Authentication successful */
  598.         if (PEAR::isError($error $this->_parseResponse(235))) {
  599.             return $error;
  600.         }
  601.  
  602.         return true;
  603.     }
  604.  
  605.     /**
  606.      * Authenticates the user using the PLAIN method.
  607.      *
  608.      * @param string The userid to authenticate as.
  609.      * @param string The password to authenticate with.
  610.      *
  611.      * @return mixed Returns a PEAR_Error with an error message on any
  612.      *                kind of failure, or true on success.
  613.      * @access private
  614.      * @since  1.1.0
  615.      */
  616.     function _authPlain($uid$pwd)
  617.     {
  618.         if (PEAR::isError($error $this->_put('AUTH''PLAIN'))) {
  619.             return $error;
  620.         }
  621.         /* 334: Continue authentication request */
  622.         if (PEAR::isError($error $this->_parseResponse(334))) {
  623.             /* 503: Error: already authenticated */
  624.             if ($this->_code === 503{
  625.                 return true;
  626.             }
  627.             return $error;
  628.         }
  629.  
  630.         $auth_str base64_encode(chr(0$uid chr(0$pwd);
  631.  
  632.         if (PEAR::isError($error $this->_put($auth_str))) {
  633.             return $error;
  634.         }
  635.  
  636.         /* 235: Authentication successful */
  637.         if (PEAR::isError($error $this->_parseResponse(235))) {
  638.             return $error;
  639.         }
  640.  
  641.         return true;
  642.     }
  643.  
  644.     /**
  645.      * Send the HELO command.
  646.      *
  647.      * @param string The domain name to say we are.
  648.      *
  649.      * @return mixed Returns a PEAR_Error with an error message on any
  650.      *                kind of failure, or true on success.
  651.      * @access public
  652.      * @since  1.0
  653.      */
  654.     function helo($domain)
  655.     {
  656.         if (PEAR::isError($error $this->_put('HELO'$domain))) {
  657.             return $error;
  658.         }
  659.         if (PEAR::isError($error $this->_parseResponse(250))) {
  660.             return $error;
  661.         }
  662.  
  663.         return true;
  664.     }
  665.  
  666.     /**
  667.      * Send the MAIL FROM: command.
  668.      *
  669.      * @param string The sender (reverse path) to set.
  670.      *
  671.      * @param array optional arguments. Currently supported:
  672.      *         verp   boolean or string. If true or string
  673.      *                verp is enabled. If string the characters
  674.      *                are considered verp separators.
  675.      *
  676.      * @return mixed Returns a PEAR_Error with an error message on any
  677.      *                kind of failure, or true on success.
  678.      * @access public
  679.      * @since  1.0
  680.      */
  681.     function mailFrom($sender$args = array())
  682.     {
  683.         $argstr '';
  684.  
  685.         if (isset($args['verp'])) {
  686.             /* XVERP */
  687.             if ($args['verp'=== true{
  688.                 $argstr .= ' XVERP';
  689.  
  690.             /* XVERP=something */
  691.             elseif (trim($args['verp'])) {
  692.                 $argstr .= ' XVERP=' $args['verp'];
  693.             }
  694.         }
  695.  
  696.         if (PEAR::isError($error $this->_put('MAIL'"FROM:<$sender>$argstr"))) {
  697.             return $error;
  698.         }
  699.         if (PEAR::isError($error $this->_parseResponse(250))) {
  700.             return $error;
  701.         }
  702.  
  703.         return true;
  704.     }
  705.  
  706.     /**
  707.      * Send the RCPT TO: command.
  708.      *
  709.      * @param string The recipient (forward path) to add.
  710.      *
  711.      * @return mixed Returns a PEAR_Error with an error message on any
  712.      *                kind of failure, or true on success.
  713.      * @access public
  714.      * @since  1.0
  715.      */
  716.     function rcptTo($recipient)
  717.     {
  718.         if (PEAR::isError($error $this->_put('RCPT'"TO:<$recipient>"))) {
  719.             return $error;
  720.         }
  721.         if (PEAR::isError($error $this->_parseResponse(array(250251)))) {
  722.             return $error;
  723.         }
  724.  
  725.         return true;
  726.     }
  727.  
  728.     /**
  729.      * Quote the data so that it meets SMTP standards.
  730.      *
  731.      * This is provided as a separate public function to facilitate
  732.      * easier overloading for the cases where it is desirable to
  733.      * customize the quoting behavior.
  734.      *
  735.      * @param string $data  The message text to quote. The string must be passed
  736.      *                       by reference, and the text will be modified in place.
  737.      *
  738.      * @access public
  739.      * @since  1.2
  740.      */
  741.     function quotedata(&$data)
  742.     {
  743.         /* Change Unix (\n) and Mac (\r) linefeeds into
  744.          * Internet-standard CRLF (\r\n) linefeeds. */
  745.         $data preg_replace(array('/(?<!\r)\n/','/\r(?!\n)/')"\r\n"$data);
  746.  
  747.         /* Because a single leading period (.) signifies an end to the
  748.          * data, legitimate leading periods need to be "doubled"
  749.          * (e.g. '..'). */
  750.         $data str_replace("\n.""\n.."$data);
  751.     }
  752.  
  753.     /**
  754.      * Send the DATA command.
  755.      *
  756.      * @param string $data  The message body to send.
  757.      *
  758.      * @return mixed Returns a PEAR_Error with an error message on any
  759.      *                kind of failure, or true on success.
  760.      * @access public
  761.      * @since  1.0
  762.      */
  763.     function data($data)
  764.     {
  765.         /* RFC 1870, section 3, subsection 3 states "a value of zero
  766.          * indicates that no fixed maximum message size is in force".
  767.          * Furthermore, it says that if "the parameter is omitted no
  768.          * information is conveyed about the server's fixed maximum
  769.          * message size". */
  770.         if (isset($this->_esmtp['SIZE']&& ($this->_esmtp['SIZE'> 0)) {
  771.             if (strlen($data>= $this->_esmtp['SIZE']{
  772.                 $this->disconnect();
  773.                 return PEAR::raiseError('Message size excedes the server limit');
  774.             }
  775.         }
  776.  
  777.         /* Quote the data based on the SMTP standards. */
  778.         $this->quotedata($data);
  779.  
  780.         if (PEAR::isError($error $this->_put('DATA'))) {
  781.             return $error;
  782.         }
  783.         if (PEAR::isError($error $this->_parseResponse(354))) {
  784.             return $error;
  785.         }
  786.  
  787.         if (PEAR::isError($result $this->_send($data "\r\n.\r\n"))) {
  788.             return $result;
  789.         }
  790.         if (PEAR::isError($error $this->_parseResponse(250))) {
  791.             return $error;
  792.         }
  793.  
  794.         return true;
  795.     }
  796.  
  797.     /**
  798.      * Send the SEND FROM: command.
  799.      *
  800.      * @param string The reverse path to send.
  801.      *
  802.      * @return mixed Returns a PEAR_Error with an error message on any
  803.      *                kind of failure, or true on success.
  804.      * @access public
  805.      * @since  1.2.6
  806.      */
  807.     function sendFrom($path)
  808.     {
  809.         if (PEAR::isError($error $this->_put('SEND'"FROM:<$path>"))) {
  810.             return $error;
  811.         }
  812.         if (PEAR::isError($error $this->_parseResponse(250))) {
  813.             return $error;
  814.         }
  815.  
  816.         return true;
  817.     }
  818.  
  819.     /**
  820.      * Backwards-compatibility wrapper for sendFrom().
  821.      *
  822.      * @param string The reverse path to send.
  823.      *
  824.      * @return mixed Returns a PEAR_Error with an error message on any
  825.      *                kind of failure, or true on success.
  826.      *
  827.      * @access      public
  828.      * @since       1.0
  829.      * @deprecated  1.2.6
  830.      */
  831.     function send_from($path)
  832.     {
  833.         return sendFrom($path);
  834.     }
  835.  
  836.     /**
  837.      * Send the SOML FROM: command.
  838.      *
  839.      * @param string The reverse path to send.
  840.      *
  841.      * @return mixed Returns a PEAR_Error with an error message on any
  842.      *                kind of failure, or true on success.
  843.      * @access public
  844.      * @since  1.2.6
  845.      */
  846.     function somlFrom($path)
  847.     {
  848.         if (PEAR::isError($error $this->_put('SOML'"FROM:<$path>"))) {
  849.             return $error;
  850.         }
  851.         if (PEAR::isError($error $this->_parseResponse(250))) {
  852.             return $error;
  853.         }
  854.  
  855.         return true;
  856.     }
  857.  
  858.     /**
  859.      * Backwards-compatibility wrapper for somlFrom().
  860.      *
  861.      * @param string The reverse path to send.
  862.      *
  863.      * @return mixed Returns a PEAR_Error with an error message on any
  864.      *                kind of failure, or true on success.
  865.      *
  866.      * @access      public
  867.      * @since       1.0
  868.      * @deprecated  1.2.6
  869.      */
  870.     function soml_from($path)
  871.     {
  872.         return somlFrom($path);
  873.     }
  874.  
  875.     /**
  876.      * Send the SAML FROM: command.
  877.      *
  878.      * @param string The reverse path to send.
  879.      *
  880.      * @return mixed Returns a PEAR_Error with an error message on any
  881.      *                kind of failure, or true on success.
  882.      * @access public
  883.      * @since  1.2.6
  884.      */
  885.     function samlFrom($path)
  886.     {
  887.         if (PEAR::isError($error $this->_put('SAML'"FROM:<$path>"))) {
  888.             return $error;
  889.         }
  890.         if (PEAR::isError($error $this->_parseResponse(250))) {
  891.             return $error;
  892.         }
  893.  
  894.         return true;
  895.     }
  896.  
  897.     /**
  898.      * Backwards-compatibility wrapper for samlFrom().
  899.      *
  900.      * @param string The reverse path to send.
  901.      *
  902.      * @return mixed Returns a PEAR_Error with an error message on any
  903.      *                kind of failure, or true on success.
  904.      *
  905.      * @access      public
  906.      * @since       1.0
  907.      * @deprecated  1.2.6
  908.      */
  909.     function saml_from($path)
  910.     {
  911.         return samlFrom($path);
  912.     }
  913.  
  914.     /**
  915.      * Send the RSET command.
  916.      *
  917.      * @return mixed Returns a PEAR_Error with an error message on any
  918.      *                kind of failure, or true on success.
  919.      * @access public
  920.      * @since  1.0
  921.      */
  922.     function rset()
  923.     {
  924.         if (PEAR::isError($error $this->_put('RSET'))) {
  925.             return $error;
  926.         }
  927.         if (PEAR::isError($error $this->_parseResponse(250))) {
  928.             return $error;
  929.         }
  930.  
  931.         return true;
  932.     }
  933.  
  934.     /**
  935.      * Send the VRFY command.
  936.      *
  937.      * @param string The string to verify
  938.      *
  939.      * @return mixed Returns a PEAR_Error with an error message on any
  940.      *                kind of failure, or true on success.
  941.      * @access public
  942.      * @since  1.0
  943.      */
  944.     function vrfy($string)
  945.     {
  946.         /* Note: 251 is also a valid response code */
  947.         if (PEAR::isError($error $this->_put('VRFY'$string))) {
  948.             return $error;
  949.         }
  950.         if (PEAR::isError($error $this->_parseResponse(array(250252)))) {
  951.             return $error;
  952.         }
  953.  
  954.         return true;
  955.     }
  956.  
  957.     /**
  958.      * Send the NOOP command.
  959.      *
  960.      * @return mixed Returns a PEAR_Error with an error message on any
  961.      *                kind of failure, or true on success.
  962.      * @access public
  963.      * @since  1.0
  964.      */
  965.     function noop()
  966.     {
  967.         if (PEAR::isError($error $this->_put('NOOP'))) {
  968.             return $error;
  969.         }
  970.         if (PEAR::isError($error $this->_parseResponse(250))) {
  971.             return $error;
  972.         }
  973.  
  974.         return true;
  975.     }
  976.  
  977.     /**
  978.      * Backwards-compatibility method.  identifySender()'s functionality is
  979.      * now handled internally.
  980.      *
  981.      * @return  boolean     This method always return true.
  982.      *
  983.      * @access  public
  984.      * @since   1.0
  985.      */
  986.     function identifySender()
  987.     {
  988.         return true;
  989.     }
  990.  
  991. }

Documentation generated on Mon, 11 Mar 2019 14:16:58 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.