lmtp.php

来自「PHP 知识管理系统(基于树结构的知识管理系统), 英文原版的PHP源码。」· PHP 代码 · 共 730 行 · 第 1/2 页

PHP
730
字号
<?php
//
// +----------------------------------------------------------------------+
// | PHP Version 4                                                        |
// +----------------------------------------------------------------------+
// | Copyright (c) 1997-2003 The PHP Group                                |
// +----------------------------------------------------------------------+
// | This source file is subject to version 2.02 of the PHP license,      |
// | that is bundled with this package in the file LICENSE, and is        |
// | available at through the world-wide-web at                           |
// | http://www.php.net/license/2_02.txt.                                 |
// | If you did not receive a copy of the PHP license and are unable to   |
// | obtain it through the world-wide-web, please send a note to          |
// | license@php.net so we can mail you a copy immediately.               |
// +----------------------------------------------------------------------+
// | Authors: Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>      |
// |          Chuck Hagenbuch <chuck@horde.org>                           |
// |          Jon Parise <jon@php.net>                                    |
// |                                                                      |
// +----------------------------------------------------------------------+

require_once 'Net/Socket.php';

/**
 * Provides an implementation of the LMTP protocol using PEAR's
 * Net_Socket:: class.
 *
 * @package Net_LMTP
 * @author  Chuck Hagenbuch <chuck@horde.org>
 * @author  Jon Parise <jon@php.net>
 * @author  Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>
 */
class Net_LMTP {


    /**
     * The server to connect to.
     * @var string
     */
    var $_host;

    /**
     * The port to connect to.
     * @var int
     */
    var $_port;

    /**
     * The value to give when sending LHLO.
     * @var string
     */
    var $_localhost;

    /**
     * Should debugging output be enabled?
     * @var boolean
     * @access private
     */
    var $_debug = false;

    /**
     * The socket resource being used to connect to the LMTP server.
     * @var resource
     * @access private
     */
    var $_socket = null;

    /**
     * The most recent server response code.
     * @var int
     * @access private
     */
    var $_code = -1;

    /**
     * The most recent server response arguments.
     * @var array
     * @access private
     */
    var $_arguments = array();

    /**
     * Stores detected features of the LMTP server.
     * @var array
     * @access private
     */
    var $_esmtp = array();


   /**
    * The auth methods this class support
    * @var array
    */
    var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'LOGIN');


    /**
    * The auth methods this class support
    * @var array
    */
    var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5');




    /**
     * Instantiates a new Net_LMTP object, overriding any defaults
     * with parameters that are passed in.
     *
     * @param string The server to connect to.
     * @param int The port to connect to.
     * @param string The value to give when sending LHLO.
     *
     * @access  public
     * @since   1.0
     */
    function Net_LMTP($host = 'localhost', $port = 2003, $localhost = 'localhost')
    {
        $this->_host = $host;
        $this->_port = $port;
        $this->_localhost = $localhost;
        $this->_socket = new Net_Socket();

       if ((@include_once 'Auth/SASL.php') == false) {
            foreach($this->supportedSASLAuthMethods as $SASLMethod){
                $pos = array_search( $SASLMethod , $this->supportedAuthMethods);
                unset($this->supportedAuthMethods[$pos]);
            }
        }


    }

    /**
     * Set the value of the debugging flag.
     *
     * @param   boolean $debug      New value for the debugging flag.
     *
     * @access  public
     * @since   1.0
     */
    function setDebug($debug)
    {
        $this->_debug = $debug;
    }

    /**
     * Send the given string of data to the server.
     *
     * @param   string  $data       The string of data to send.
     *
     * @return  mixed   True on success or a PEAR_Error object on failure.
     *
     * @access  private
     * @since   1.0
     */
    function _send($data)
    {
        if ($this->_debug) {
            echo "DEBUG: Send: $data\n";
        }

        if (PEAR::isError($error = $this->_socket->write($data))) {
            return new PEAR_Error('Failed to write to socket: ' .
                                  $error->getMessage());
        }

        return true;
    }

    /**
     * Send a command to the server with an optional string of arguments.
     * A carriage return / linefeed (CRLF) sequence will be appended to each
     * command string before it is sent to the LMTP server.
     *
     * @param   string  $command    The LMTP command to send to the server.
     * @param   string  $args       A string of optional arguments to append
     *                              to the command.
     *
     * @return  mixed   The result of the _send() call.
     *
     * @access  private
     * @since   1.0
     */
    function _put($command, $args = '')
    {
        if (!empty($args)) {
            return $this->_send($command . ' ' . $args . "\r\n");
        }

        return $this->_send($command . "\r\n");
    }

    /**
     * Read a reply from the LMTP server.  The reply consists of a response
     * code and a response message.
     *
     * @param   mixed   $valid      The set of valid response codes.  These
     *                              may be specified as an array of integer
     *                              values or as a single integer value.
     *
     * @return  mixed   True if the server returned a valid response code or
     *                  a PEAR_Error object is an error condition is reached.
     *
     * @access  private
     * @since   1.0
     *
     * @see     getResponse
     */
    function _parseResponse($valid)
    {
        $this->_code = -1;
        $this->_arguments = array();

        while ($line = $this->_socket->readLine()) {
            if ($this->_debug) {
                echo "DEBUG: Recv: $line\n";
            }

            /* If we receive an empty line, the connection has been closed. */
            if (empty($line)) {
                $this->disconnect();
                return new PEAR_Error("Connection was unexpectedly closed");
            }

            /* Read the code and store the rest in the arguments array. */
            $code = substr($line, 0, 3);
            $this->_arguments[] = trim(substr($line, 4));

            /* Check the syntax of the response code. */
            if (is_numeric($code)) {
                $this->_code = (int)$code;
            } else {
                $this->_code = -1;
                break;
            }

            /* If this is not a multiline response, we're done. */
            if (substr($line, 3, 1) != '-') {
                break;
            }
        }

        /* Compare the server's response code with the valid code. */
        if (is_int($valid) && ($this->_code === $valid)) {
            return true;
        }

        /* If we were given an array of valid response codes, check each one. */
        if (is_array($valid)) {
            foreach ($valid as $valid_code) {
                if ($this->_code === $valid_code) {
                    return true;
                }
            }
        }

        return new PEAR_Error("Invalid response code received from server");
    }

    /**
     * Return a 2-tuple containing the last response from the LMTP server.
     *
     * @return  array   A two-element array: the first element contains the
     *                  response code as an integer and the second element
     *                  contains the response's arguments as a string.
     *
     * @access  public
     * @since   1.0
     */
    function getResponse()
    {
        return array($this->_code, join("\n", $this->_arguments));
    }

    /**
     * Attempt to connect to the LMTP server.
     *
     * @param   int     $timeout    The timeout value (in seconds) for the
     *                              socket connection.
     *
     * @return mixed Returns a PEAR_Error with an error message on any
     *               kind of failure, or true on success.
     * @access public
     * @since  1.0
     */
    function connect($timeout = null)
    {
        $result = $this->_socket->connect($this->_host, $this->_port,
                                          false, $timeout);
        if (PEAR::isError($result)) {
            return new PEAR_Error('Failed to connect socket: ' .
                                  $result->getMessage());
        }

        if (PEAR::isError($error = $this->_parseResponse(220))) {
            return $error;
        }
        if (PEAR::isError($error = $this->_negotiate())) {
            return $error;
        }

        return true;
    }

    /**
     * Attempt to disconnect from the LMTP server.
     *
     * @return mixed Returns a PEAR_Error with an error message on any
     *               kind of failure, or true on success.
     * @access public
     * @since  1.0
     */
    function disconnect()
    {
        if (PEAR::isError($error = $this->_put('QUIT'))) {
            return $error;
        }
        if (PEAR::isError($error = $this->_parseResponse(221))) {
            return $error;
        }
        if (PEAR::isError($error = $this->_socket->disconnect())) {
            return new PEAR_Error('Failed to disconnect socket: ' .
                                  $error->getMessage());
        }

        return true;
    }

    /**
     * Attempt to send the LHLO command and obtain a list of ESMTP
     * extensions available
     *
     * @return mixed Returns a PEAR_Error with an error message on any
     *               kind of failure, or true on success.
     *
     * @access private
     * @since  1.0
     */
    function _negotiate()
    {
        if (PEAR::isError($error = $this->_put('LHLO', $this->_localhost))) {
            return $error;
        }

        if (PEAR::isError($this->_parseResponse(250))) {
            return new PEAR_Error('LHLO was not accepted: ', $this->_code);
            return true;
        }

        foreach ($this->_arguments as $argument) {
            $verb = strtok($argument, ' ');
            $arguments = substr($argument, strlen($verb) + 1,
                                strlen($argument) - strlen($verb) - 1);
            $this->_esmtp[$verb] = $arguments;
        }

        return true;
    }

    /**
     * Returns the name of the best authentication method that the server
     * has advertised.
     *
     * @return mixed    Returns a string containing the name of the best

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?