1227 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
			
		
		
	
	
			1227 lines
		
	
	
		
			33 KiB
		
	
	
	
		
			PHP
		
	
	
	
	
	
<?php
 | 
						|
// +-----------------------------------------------------------------------+
 | 
						|
// | Copyright (c) 2002, Richard Heyes                                     |
 | 
						|
// | All rights reserved.                                                  |
 | 
						|
// |                                                                       |
 | 
						|
// | Redistribution and use in source and binary forms, with or without    |
 | 
						|
// | modification, are permitted provided that the following conditions    |
 | 
						|
// | are met:                                                              |
 | 
						|
// |                                                                       |
 | 
						|
// | o Redistributions of source code must retain the above copyright      |
 | 
						|
// |   notice, this list of conditions and the following disclaimer.       |
 | 
						|
// | o Redistributions in binary form must reproduce the above copyright   |
 | 
						|
// |   notice, this list of conditions and the following disclaimer in the |
 | 
						|
// |   documentation and/or other materials provided with the distribution.|
 | 
						|
// | o The names of the authors may not be used to endorse or promote      |
 | 
						|
// |   products derived from this software without specific prior written  |
 | 
						|
// |   permission.                                                         |
 | 
						|
// |                                                                       |
 | 
						|
// | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS   |
 | 
						|
// | "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT     |
 | 
						|
// | LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR |
 | 
						|
// | A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT  |
 | 
						|
// | OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
 | 
						|
// | SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT      |
 | 
						|
// | LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
 | 
						|
// | DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
 | 
						|
// | THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT   |
 | 
						|
// | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
 | 
						|
// | OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  |
 | 
						|
// |                                                                       |
 | 
						|
// +-----------------------------------------------------------------------+
 | 
						|
// | Author: Richard Heyes <richard@phpguru.org>                           |
 | 
						|
// | Co-Author: Damian Fernandez Sosa <damlists@cnba.uba.ar>               |
 | 
						|
// +-----------------------------------------------------------------------+
 | 
						|
//
 | 
						|
// $Id: POP3.php,v 1.2 2004/12/05 16:34:39 damian Exp $
 | 
						|
 | 
						|
require_once('Net/Socket.php');
 | 
						|
 | 
						|
 | 
						|
 | 
						|
/**
 | 
						|
*  +----------------------------- IMPORTANT ------------------------------+
 | 
						|
*  | Usage of this class compared to native php extensions such as IMAP   |
 | 
						|
*  | is slow and may be feature deficient. If available you are STRONGLY  |
 | 
						|
*  | recommended to use the php extensions.                               |
 | 
						|
*  +----------------------------------------------------------------------+
 | 
						|
*
 | 
						|
* POP3 Access Class
 | 
						|
*
 | 
						|
* For usage see the example script
 | 
						|
*/
 | 
						|
 | 
						|
define('NET_POP3_STATE_DISCONNECTED',  1, true);
 | 
						|
define('NET_POP3_STATE_AUTHORISATION', 2, true);
 | 
						|
define('NET_POP3_STATE_TRANSACTION',   4, true);
 | 
						|
 | 
						|
class Net_POP3 {
 | 
						|
 | 
						|
    /*
 | 
						|
    * Some basic information about the mail drop
 | 
						|
    * garnered from the STAT command
 | 
						|
    *
 | 
						|
    * @var array
 | 
						|
    */
 | 
						|
    var $_maildrop;
 | 
						|
 | 
						|
    /*
 | 
						|
    * Used for APOP to store the timestamp
 | 
						|
    *
 | 
						|
    * @var string
 | 
						|
    */
 | 
						|
    var $_timestamp;
 | 
						|
 | 
						|
    /*
 | 
						|
    * Timeout that is passed to the socket object
 | 
						|
    *
 | 
						|
    * @var integer
 | 
						|
    */
 | 
						|
    var $_timeout;
 | 
						|
 | 
						|
    /*
 | 
						|
    * Socket object
 | 
						|
    *
 | 
						|
    * @var object
 | 
						|
    */
 | 
						|
    var $_socket;
 | 
						|
 | 
						|
    /*
 | 
						|
    * Current state of the connection. Used with the
 | 
						|
    * constants defined above.
 | 
						|
    *
 | 
						|
    * @var integer
 | 
						|
    */
 | 
						|
    var $_state;
 | 
						|
 | 
						|
    /*
 | 
						|
    * Hostname to connect to
 | 
						|
    *
 | 
						|
    * @var string
 | 
						|
    */
 | 
						|
    var $_host;
 | 
						|
 | 
						|
    /*
 | 
						|
    * Port to connect to
 | 
						|
    *
 | 
						|
    * @var integer
 | 
						|
    */
 | 
						|
    var $_port;
 | 
						|
 | 
						|
    /**
 | 
						|
    * To allow class debuging
 | 
						|
    * @var boolean
 | 
						|
    */
 | 
						|
    var $_debug = false;
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
    * The auth methods this class support
 | 
						|
    * @var array
 | 
						|
    */
 | 
						|
    //var $supportedAuthMethods=array('DIGEST-MD5', 'CRAM-MD5', 'APOP' , 'PLAIN' , 'LOGIN', 'USER');
 | 
						|
    //Disabling DIGEST-MD5 for now
 | 
						|
    var $supportedAuthMethods=array( 'CRAM-MD5', 'APOP' , 'PLAIN' , 'LOGIN', 'USER');
 | 
						|
    //var $supportedAuthMethods=array( 'CRAM-MD5', 'PLAIN' , 'LOGIN');
 | 
						|
    //var $supportedAuthMethods=array( 'PLAIN' , 'LOGIN');
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
    * The auth methods this class support
 | 
						|
    * @var array
 | 
						|
    */
 | 
						|
    var $supportedSASLAuthMethods=array('DIGEST-MD5', 'CRAM-MD5');
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
    * The capability response
 | 
						|
    * @var array
 | 
						|
    */
 | 
						|
    var $_capability;
 | 
						|
 | 
						|
   /*
 | 
						|
    * Constructor. Sets up the object variables, and instantiates
 | 
						|
    * the socket object.
 | 
						|
    *
 | 
						|
    */
 | 
						|
 | 
						|
 | 
						|
    function __construct()
 | 
						|
    {
 | 
						|
        $this->_timestamp =  ''; // Used for APOP
 | 
						|
        $this->_maildrop  =  array();
 | 
						|
        $this->_timeout   =  3;
 | 
						|
        $this->_state     =  NET_POP3_STATE_DISCONNECTED;
 | 
						|
        $this->_socket    = new Net_Socket();
 | 
						|
        /*
 | 
						|
        * Include the Auth_SASL package.  If the package is not available,
 | 
						|
        * we disable the authentication methods that depend upon it.
 | 
						|
        */
 | 
						|
        if ((@include_once 'Auth/SASL.php') == false) {
 | 
						|
            if($this->_debug){
 | 
						|
                echo "AUTH_SASL NOT PRESENT!\n";
 | 
						|
            }
 | 
						|
            foreach($this->supportedSASLAuthMethods as $SASLMethod){
 | 
						|
                $pos = array_search( $SASLMethod, $this->supportedAuthMethods );
 | 
						|
                if($this->_debug){
 | 
						|
                    echo "DISABLING METHOD $SASLMethod\n";
 | 
						|
                }
 | 
						|
                unset($this->supportedAuthMethods[$pos]);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
    * Handles the errors the class can find
 | 
						|
    * on the server
 | 
						|
    *
 | 
						|
    * @access private
 | 
						|
    * @return PEAR_Error
 | 
						|
    */
 | 
						|
 | 
						|
    function _raiseError($msg, $code =-1)
 | 
						|
    {
 | 
						|
    include_once 'PEAR.php';
 | 
						|
    return PEAR::raiseError($msg, $code);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    
 | 
						|
    /*
 | 
						|
    * Connects to the given host on the given port.
 | 
						|
    * Also looks for the timestamp in the greeting
 | 
						|
    * needed for APOP authentication
 | 
						|
    *
 | 
						|
    * @param  string $host Hostname/IP address to connect to
 | 
						|
    * @param  string $port Port to use to connect to on host
 | 
						|
    * @return bool  Success/Failure
 | 
						|
    */
 | 
						|
    function connect($host = 'localhost', $port = 110)
 | 
						|
    {
 | 
						|
        $this->_host = $host;
 | 
						|
        $this->_port = $port;
 | 
						|
 | 
						|
        $result = $this->_socket->connect($host, $port, false, $this->_timeout);
 | 
						|
        if ($result === true) {
 | 
						|
            $data = $this->_recvLn();
 | 
						|
 | 
						|
            if( $this->_checkResponse($data) ){
 | 
						|
            // if the response begins with '+OK' ...
 | 
						|
//            if (@substr(strtoupper($data), 0, 3) == '+OK') {
 | 
						|
                // Check for string matching apop timestamp
 | 
						|
                if (preg_match('/<.+@.+>/U', $data, $matches)) {
 | 
						|
                    $this->_timestamp = $matches[0];
 | 
						|
                }
 | 
						|
                $this->_maildrop = array();
 | 
						|
                $this->_state    = NET_POP3_STATE_AUTHORISATION;
 | 
						|
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        $this->_socket->disconnect();
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Disconnect function. Sends the QUIT command
 | 
						|
    * and closes the socket.
 | 
						|
    *
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function disconnect()
 | 
						|
    {
 | 
						|
        return $this->_cmdQuit();
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Performs the login procedure. If there is a timestamp
 | 
						|
    * stored, APOP will be tried first, then basic USER/PASS.
 | 
						|
    *
 | 
						|
    * @param  string $user Username to use
 | 
						|
    * @param  string $pass Password to use
 | 
						|
    * @param  mixed $apop Whether to try APOP first, if used as string you can select the auth methd to use ( $pop3->login('validlogin', 'validpass', "CRAM-MD5");
 | 
						|
    *          Valid methods are: 'DIGEST-MD5','CRAM-MD5','LOGIN','PLAIN','APOP','USER' 
 | 
						|
    * @return mixed  true on Success/ PEAR_ERROR on error
 | 
						|
    */
 | 
						|
    function login($user, $pass, $apop = true)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_AUTHORISATION) {
 | 
						|
 | 
						|
            if(PEAR::isError($ret= $this->_cmdAuthenticate($user , $pass , $apop ) ) ){
 | 
						|
                return $ret;
 | 
						|
            }
 | 
						|
            if( ! PEAR::isError($ret)){
 | 
						|
                $this->_state = NET_POP3_STATE_TRANSACTION;
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
 | 
						|
        }
 | 
						|
        return $this->_raiseError('Generic login error' , 1);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
    * Parses the response from the capability command. Stores
 | 
						|
    * the result in $this->_capability
 | 
						|
    *
 | 
						|
    * @access private
 | 
						|
    */
 | 
						|
    function _parseCapability()
 | 
						|
    {
 | 
						|
 | 
						|
        if(!PEAR::isError($data = $this->_sendCmd('CAPA'))){
 | 
						|
            $data = $this->_getMultiline();
 | 
						|
        }else {
 | 
						|
            // CAPA command not supported, reset data var
 | 
						|
            //  to avoid Notice errors of preg_split on an object
 | 
						|
            $data = '';
 | 
						|
        }
 | 
						|
        $data = preg_split('/\r?\n/', $data, -1, PREG_SPLIT_NO_EMPTY);
 | 
						|
 | 
						|
        for ($i = 0; $i < count($data); $i++) {
 | 
						|
 | 
						|
            $capa='';
 | 
						|
            if (preg_match('/^([a-z,\-]+)( ((.*))|$)$/i', $data[$i], $matches)) {
 | 
						|
 | 
						|
                $capa=strtolower($matches[1]);
 | 
						|
                switch ($capa) {
 | 
						|
                    case 'implementation':
 | 
						|
                        $this->_capability['implementation'] = $matches[3];
 | 
						|
                        break;
 | 
						|
                    case 'sasl':
 | 
						|
                        $this->_capability['sasl'] = preg_split('/\s+/', $matches[3]);
 | 
						|
                        break;
 | 
						|
                    default :
 | 
						|
                        $this->_capability[$capa] = $matches[2];
 | 
						|
                        break;
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /**
 | 
						|
     * Returns the name of the best authentication method that the server
 | 
						|
     * has advertised.
 | 
						|
     *
 | 
						|
     * @param string if !=null,authenticate with this method ($userMethod).
 | 
						|
     *
 | 
						|
     * @return mixed    Returns a string containing the name of the best
 | 
						|
     *                  supported authentication method or a PEAR_Error object
 | 
						|
     *                  if a failure condition is encountered.
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _getBestAuthMethod($userMethod = null)
 | 
						|
    {
 | 
						|
 | 
						|
/*
 | 
						|
       return 'USER';
 | 
						|
       return 'APOP';
 | 
						|
       return 'DIGEST-MD5';
 | 
						|
       return 'CRAM-MD5';
 | 
						|
*/
 | 
						|
 | 
						|
 | 
						|
        $this->_parseCapability();
 | 
						|
 | 
						|
        //unset($this->_capability['sasl']);
 | 
						|
 | 
						|
       if( isset($this->_capability['sasl']) ){
 | 
						|
           $serverMethods=$this->_capability['sasl'];
 | 
						|
       }else{
 | 
						|
            $serverMethods=array('USER');
 | 
						|
            // Check for timestamp before attempting APOP
 | 
						|
            if ($this->_timestamp != null)
 | 
						|
            {
 | 
						|
                $serverMethods[] = 'APOP';
 | 
						|
            }
 | 
						|
       }
 | 
						|
 | 
						|
        if($userMethod !== null && $userMethod !== true ){
 | 
						|
            $methods = array();
 | 
						|
            $methods[] = $userMethod;
 | 
						|
            return $userMethod;
 | 
						|
        }else{
 | 
						|
            $methods = $this->supportedAuthMethods;
 | 
						|
        }
 | 
						|
 | 
						|
        if( ($methods != null) && ($serverMethods != null)){
 | 
						|
 | 
						|
            foreach ( $methods as $method ) {
 | 
						|
 | 
						|
                if ( in_array( $method , $serverMethods ) ) {
 | 
						|
                    return $method;
 | 
						|
                }
 | 
						|
            }
 | 
						|
            $serverMethods=implode(',' , $serverMethods );
 | 
						|
            $myMethods=implode(',' ,$this->supportedAuthMethods);
 | 
						|
            return $this->_raiseError("$method NOT supported authentication method!. This server " .
 | 
						|
                "supports these methods: $serverMethods, but I support $myMethods");
 | 
						|
        }else{
 | 
						|
            return $this->_raiseError("This server don't support any Auth methods");
 | 
						|
        }
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /* Handles the authentication using any known method
 | 
						|
     *
 | 
						|
     * @param string The userid to authenticate as.
 | 
						|
     * @param string The password to authenticate with.
 | 
						|
     * @param string The method to use ( if $usermethod == '' then the class chooses the best method (the stronger is the best ) )
 | 
						|
     *
 | 
						|
     * @return mixed  string or PEAR_Error
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _cmdAuthenticate($uid , $pwd , $userMethod = null )
 | 
						|
    {
 | 
						|
 | 
						|
 | 
						|
        if ( PEAR::isError( $method = $this->_getBestAuthMethod($userMethod) ) ) {
 | 
						|
            return $method;
 | 
						|
        }
 | 
						|
 | 
						|
        switch ($method) {
 | 
						|
            case 'DIGEST-MD5':
 | 
						|
                $result = $this->_authDigest_MD5( $uid , $pwd );
 | 
						|
                break;
 | 
						|
            case 'CRAM-MD5':
 | 
						|
                $result = $this->_authCRAM_MD5( $uid , $pwd );
 | 
						|
                break;
 | 
						|
            case 'LOGIN':
 | 
						|
                $result = $this->_authLOGIN( $uid , $pwd );
 | 
						|
                break;
 | 
						|
            case 'PLAIN':
 | 
						|
                $result = $this->_authPLAIN( $uid , $pwd );
 | 
						|
                break;
 | 
						|
            case 'APOP':
 | 
						|
                $result = $this->_cmdApop( $uid , $pwd );
 | 
						|
                // if APOP fails fallback to USER auth
 | 
						|
                if( PEAR::isError( $result ) ){
 | 
						|
                    //echo "APOP FAILED!!!\n";
 | 
						|
                    $result=$this->_authUSER( $uid , $pwd );
 | 
						|
                }
 | 
						|
                break;
 | 
						|
            case 'USER':
 | 
						|
                $result = $this->_authUSER( $uid , $pwd );
 | 
						|
            break;
 | 
						|
 | 
						|
 | 
						|
            default :
 | 
						|
                $result = $this->_raiseError( "$method is not a supported authentication method" );
 | 
						|
                break;
 | 
						|
        }
 | 
						|
        return $result;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
     /* Authenticates the user using the USER-PASS method.
 | 
						|
     *
 | 
						|
     * @param string The userid to authenticate as.
 | 
						|
     * @param string The password to authenticate with.
 | 
						|
     *
 | 
						|
     * @return mixed    true on success or PEAR_Error on failure
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _authUSER($user, $pass  )
 | 
						|
    {
 | 
						|
        if ( PEAR::isError($ret=$this->_cmdUser($user) ) ){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
        if ( PEAR::isError($ret=$this->_cmdPass($pass) ) ){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
     /* Authenticates the user using the PLAIN method.
 | 
						|
     *
 | 
						|
     * @param string The userid to authenticate as.
 | 
						|
     * @param string The password to authenticate with.
 | 
						|
     *
 | 
						|
     * @return array Returns an array containing the response
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _authPLAIN($user, $pass  )
 | 
						|
    {
 | 
						|
        $cmd=sprintf('AUTH PLAIN %s', base64_encode( chr(0) . $user . chr(0) . $pass ) );
 | 
						|
 | 
						|
        if ( PEAR::isError( $ret = $this->_send($cmd) ) ) {
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ){
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        if( PEAR::isError($ret=$this->_checkResponse($challenge) )){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
        
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
     /* Authenticates the user using the PLAIN method.
 | 
						|
     *
 | 
						|
     * @param string The userid to authenticate as.
 | 
						|
     * @param string The password to authenticate with.
 | 
						|
     *
 | 
						|
     * @return array Returns an array containing the response
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _authLOGIN($user, $pass  )
 | 
						|
    {
 | 
						|
        $this->_send('AUTH LOGIN');
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        if( PEAR::isError($ret=$this->_checkResponse($challenge) )){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
 | 
						|
        if ( PEAR::isError( $ret = $this->_send(sprintf('%s', base64_encode($user))) ) ) {
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        if( PEAR::isError($ret=$this->_checkResponse($challenge) )){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( PEAR::isError( $ret = $this->_send(sprintf('%s', base64_encode($pass))) ) ) {
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        return $this->_checkResponse($challenge);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
     /* Authenticates the user using the CRAM-MD5 method.
 | 
						|
     *
 | 
						|
     * @param string The userid to authenticate as.
 | 
						|
     * @param string The password to authenticate with.
 | 
						|
     *
 | 
						|
     * @return array Returns an array containing the response
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _authCRAM_MD5($uid, $pwd )
 | 
						|
    {
 | 
						|
        if ( PEAR::isError( $ret = $this->_send( 'AUTH CRAM-MD5' ) ) ) {
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        if( PEAR::isError($ret=$this->_checkResponse($challenge) )){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        // remove '+ '
 | 
						|
        
 | 
						|
        $challenge=substr($challenge,2);
 | 
						|
        
 | 
						|
        $challenge = base64_decode( $challenge );
 | 
						|
 | 
						|
        $cram = &Auth_SASL::factory('crammd5');
 | 
						|
        $auth_str = base64_encode( $cram->getResponse( $uid , $pwd , $challenge ) );
 | 
						|
 | 
						|
 | 
						|
        if ( PEAR::isError($error = $this->_send( $auth_str ) ) ) {
 | 
						|
            return $error;
 | 
						|
        }
 | 
						|
        if ( PEAR::isError( $ret = $this->_recvLn() ) ) {
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
        //echo "RET:$ret\n";
 | 
						|
        return $this->_checkResponse($ret);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
     /* Authenticates the user using the DIGEST-MD5 method.
 | 
						|
     *
 | 
						|
     * @param string The userid to authenticate as.
 | 
						|
     * @param string The password to authenticate with.
 | 
						|
     * @param string The efective user
 | 
						|
     *
 | 
						|
     * @return array Returns an array containing the response
 | 
						|
     *
 | 
						|
     * @access private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _authDigest_MD5($uid, $pwd)
 | 
						|
    {
 | 
						|
        if ( PEAR::isError( $ret = $this->_send( 'AUTH DIGEST-MD5' ) ) ) {
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        if( PEAR::isError($ret=$this->_checkResponse($challenge) )){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
 | 
						|
        // remove '+ '
 | 
						|
        $challenge=substr($challenge,2);
 | 
						|
 | 
						|
        $challenge = base64_decode( $challenge );
 | 
						|
        $digest = &Auth_SASL::factory('digestmd5');
 | 
						|
        $auth_str = base64_encode($digest->getResponse($uid, $pwd, $challenge, "localhost", "pop3" ));
 | 
						|
 | 
						|
        if ( PEAR::isError($error = $this->_send( $auth_str ) ) ) {
 | 
						|
            return $error;
 | 
						|
        }
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        if( PEAR::isError($ret=$this->_checkResponse($challenge) )){
 | 
						|
            return $ret;
 | 
						|
        }
 | 
						|
         /*
 | 
						|
         * We don't use the protocol's third step because POP3 doesn't allow
 | 
						|
         * subsequent authentication, so we just silently ignore it.
 | 
						|
         */
 | 
						|
 | 
						|
        if ( PEAR::isError( $challenge = $this->_send("\r\n") ) ) {
 | 
						|
            return $challenge ;
 | 
						|
        }
 | 
						|
        
 | 
						|
        if ( PEAR::isError( $challenge = $this->_recvLn() ) ) {
 | 
						|
            return $challenge;
 | 
						|
        }
 | 
						|
        
 | 
						|
        return $this->_checkResponse($challenge);
 | 
						|
        
 | 
						|
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the APOP command
 | 
						|
    *
 | 
						|
    * @param  $user Username to send
 | 
						|
    * @param  $pass Password to send
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdApop($user, $pass)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_AUTHORISATION) {
 | 
						|
 | 
						|
            if (!empty($this->_timestamp)) {
 | 
						|
                if(PEAR::isError($data = $this->_sendCmd('APOP ' . $user . ' ' . md5($this->_timestamp . $pass)) ) ){
 | 
						|
                    return $data;
 | 
						|
                }
 | 
						|
                $this->_state = NET_POP3_STATE_TRANSACTION;
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return $this->_raiseError('Not In NET_POP3_STATE_AUTHORISATION State1');
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Returns the raw headers of the specified message.
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message number
 | 
						|
    * @return mixed   Either raw headers or false on error
 | 
						|
    */
 | 
						|
    function getRawHeaders($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            return $this->_cmdTop($msg_id, 0);
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Returns the  headers of the specified message in an
 | 
						|
    * associative array. Array keys are the header names, array
 | 
						|
    * values are the header values. In the case of multiple headers
 | 
						|
    * having the same names, eg Received:, the array value will be
 | 
						|
    * an indexed array of all the header values.
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message number
 | 
						|
    * @return mixed   Either array of headers or false on error
 | 
						|
    */
 | 
						|
    function getParsedHeaders($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
 | 
						|
            $raw_headers = rtrim($this->getRawHeaders($msg_id));
 | 
						|
 | 
						|
            $raw_headers = preg_replace("/\r\n[ \t]+/", ' ', $raw_headers); // Unfold headers
 | 
						|
            $raw_headers = explode("\r\n", $raw_headers);
 | 
						|
            foreach ($raw_headers as $value) {
 | 
						|
                $name  = substr($value, 0, $pos = strpos($value, ':'));
 | 
						|
                $value = ltrim(substr($value, $pos + 1));
 | 
						|
                if (isset($headers[$name]) AND is_array($headers[$name])) {
 | 
						|
                    $headers[$name][] = $value;
 | 
						|
                } elseif (isset($headers[$name])) {
 | 
						|
                    $headers[$name] = array($headers[$name], $value);
 | 
						|
                } else {
 | 
						|
                    $headers[$name] = $value;
 | 
						|
                }
 | 
						|
            }
 | 
						|
 | 
						|
            return $headers;
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Returns the body of the message with given message number.
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message number
 | 
						|
    * @return mixed   Either message body or false on error
 | 
						|
    */
 | 
						|
    function getBody($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            $msg = $this->_cmdRetr($msg_id);
 | 
						|
            return substr($msg, strpos($msg, "\r\n\r\n")+4);
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Returns the entire message with given message number.
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message number
 | 
						|
    * @return mixed   Either entire message or false on error
 | 
						|
    */
 | 
						|
    function getMsg($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            return $this->_cmdRetr($msg_id);
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Returns the size of the maildrop
 | 
						|
    *
 | 
						|
    * @return mixed Either size of maildrop or false on error
 | 
						|
    */
 | 
						|
    function getSize()
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if (isset($this->_maildrop['size'])) {
 | 
						|
                return $this->_maildrop['size'];
 | 
						|
            } else {
 | 
						|
                list(, $size) = $this->_cmdStat();
 | 
						|
                return $size;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Returns number of messages in this maildrop
 | 
						|
    *
 | 
						|
    * @return mixed Either number of messages or false on error
 | 
						|
    */
 | 
						|
    function numMsg()
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if (isset($this->_maildrop['num_msg'])) {
 | 
						|
                return $this->_maildrop['num_msg'];
 | 
						|
            } else {
 | 
						|
                list($num_msg, ) = $this->_cmdStat();
 | 
						|
                return $num_msg;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Marks a message for deletion. Only will be deleted if the
 | 
						|
    * disconnect() method is called.
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message to delete
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function deleteMsg($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            return $this->_cmdDele($msg_id);
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Combination of LIST/UIDL commands, returns an array
 | 
						|
    * of data
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Optional message number
 | 
						|
    * @return mixed Array of data or false on error
 | 
						|
    */
 | 
						|
    function getListing($msg_id = null)
 | 
						|
    {
 | 
						|
    
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if (!isset($msg_id)){
 | 
						|
            
 | 
						|
                $list=array();
 | 
						|
                if ($list = $this->_cmdList()) {
 | 
						|
                    if ($uidl = $this->_cmdUidl()) {
 | 
						|
                        foreach ($uidl as $i => $value) {
 | 
						|
                            $list[$i]['uidl'] = $value['uidl'];
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    return $list;
 | 
						|
                }else{
 | 
						|
                    return array();
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                if ($list = $this->_cmdList($msg_id) AND $uidl = $this->_cmdUidl($msg_id)) {
 | 
						|
                    return array_merge($list, $uidl);
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the USER command
 | 
						|
    *
 | 
						|
    * @param  string $user Username to send
 | 
						|
    * @return bool  Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdUser($user)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_AUTHORISATION) {
 | 
						|
            return $this->_sendCmd('USER ' . $user);
 | 
						|
        }
 | 
						|
        return $this->_raiseError('Not In NET_POP3_STATE_AUTHORISATION State');
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the PASS command
 | 
						|
    *
 | 
						|
    * @param  string $pass Password to send
 | 
						|
    * @return bool  Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdPass($pass)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_AUTHORISATION) {
 | 
						|
            return $this->_sendCmd('PASS ' . $pass);
 | 
						|
        }
 | 
						|
        return $this->_raiseError('Not In NET_POP3_STATE_AUTHORISATION State');
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the STAT command
 | 
						|
    *
 | 
						|
    * @return mixed Indexed array of number of messages and
 | 
						|
    *               maildrop size, or false on error.
 | 
						|
    */
 | 
						|
    function _cmdStat()
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if(!PEAR::isError($data = $this->_sendCmd('STAT'))){
 | 
						|
                sscanf($data, '+OK %d %d', $msg_num, $size);
 | 
						|
                $this->_maildrop['num_msg'] = $msg_num;
 | 
						|
                $this->_maildrop['size']    = $size;
 | 
						|
 | 
						|
                return array($msg_num, $size);
 | 
						|
            }
 | 
						|
        }
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the LIST command
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Optional message number
 | 
						|
    * @return mixed   Indexed array of msg_id/msg size or
 | 
						|
    *                 false on error
 | 
						|
    */
 | 
						|
    function _cmdList($msg_id = null)
 | 
						|
    {
 | 
						|
        $return=array();
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if (!isset($msg_id)) {
 | 
						|
                if(!PEAR::isError($data = $this->_sendCmd('LIST') )){
 | 
						|
                    $data = $this->_getMultiline();
 | 
						|
                    $data = explode("\r\n", $data);                    
 | 
						|
                    foreach ($data as $line) {
 | 
						|
                        if($line !=''){
 | 
						|
                            sscanf($line, '%s %s', $msg_id, $size);
 | 
						|
                            $return[] = array('msg_id' => $msg_id, 'size' => $size);
 | 
						|
                        }
 | 
						|
                    }
 | 
						|
                    return $return;
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
                if(!PEAR::isError($data = $this->_sendCmd('LIST ' . $msg_id))){
 | 
						|
                    if($data!=''){
 | 
						|
                        sscanf($data, '+OK %d %d', $msg_id, $size);
 | 
						|
                        return array('msg_id' => $msg_id, 'size' => $size);
 | 
						|
                    }
 | 
						|
                    return array();
 | 
						|
                }
 | 
						|
            }
 | 
						|
        }
 | 
						|
        
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the RETR command
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id The message number to retrieve
 | 
						|
    * @return mixed   The message or false on error
 | 
						|
    */
 | 
						|
    function _cmdRetr($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if(!PEAR::isError($data = $this->_sendCmd('RETR ' . $msg_id) )){
 | 
						|
                $data = $this->_getMultiline();
 | 
						|
                return $data;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the DELE command
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message number to mark as deleted
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdDele($msg_id)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            return $this->_sendCmd('DELE ' . $msg_id);
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the NOOP command
 | 
						|
    *
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdNoop()
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if(!PEAR::isError($data = $this->_sendCmd('NOOP'))){
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the RSET command
 | 
						|
    *
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdRset()
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
            if(!PEAR::isError($data = $this->_sendCmd('RSET'))){
 | 
						|
                return true;
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the QUIT command
 | 
						|
    *
 | 
						|
    * @return bool Success/Failure
 | 
						|
    */
 | 
						|
    function _cmdQuit()
 | 
						|
    {
 | 
						|
        $data = $this->_sendCmd('QUIT');
 | 
						|
        $this->_state = NET_POP3_STATE_DISCONNECTED;
 | 
						|
        $this->_socket->disconnect();
 | 
						|
 | 
						|
        return (bool)$data;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the TOP command
 | 
						|
    *
 | 
						|
    * @param  integer  $msg_id    Message number
 | 
						|
    * @param  integer  $num_lines Number of lines to retrieve
 | 
						|
    * @return mixed Message data or false on error
 | 
						|
    */
 | 
						|
    function _cmdTop($msg_id, $num_lines)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
 | 
						|
            if(!PEAR::isError($data = $this->_sendCmd('TOP ' . $msg_id . ' ' . $num_lines))){
 | 
						|
                return $this->_getMultiline();
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends the UIDL command
 | 
						|
    *
 | 
						|
    * @param  integer $msg_id Message number
 | 
						|
    * @return mixed indexed array of msg_id/uidl or false on error
 | 
						|
    */
 | 
						|
    function _cmdUidl($msg_id = null)
 | 
						|
    {
 | 
						|
        if ($this->_state == NET_POP3_STATE_TRANSACTION) {
 | 
						|
 | 
						|
            if (!isset($msg_id)) {
 | 
						|
                if(!PEAR::isError($data = $this->_sendCmd('UIDL') )){
 | 
						|
                    $data = $this->_getMultiline();
 | 
						|
                    $data = explode("\r\n", $data);
 | 
						|
                    foreach ($data as $line) {
 | 
						|
                        sscanf($line, '%d %s', $msg_id, $uidl);
 | 
						|
                        $return[] = array('msg_id' => $msg_id, 'uidl' => $uidl);
 | 
						|
                    }
 | 
						|
 | 
						|
                    return $return;
 | 
						|
                }
 | 
						|
            } else {
 | 
						|
 | 
						|
                $data = $this->_sendCmd('UIDL ' . $msg_id);
 | 
						|
                sscanf($data, '+OK %d %s', $msg_id, $uidl);
 | 
						|
                return array('msg_id' => $msg_id, 'uidl' => $uidl);
 | 
						|
            }
 | 
						|
        }
 | 
						|
 | 
						|
        return false;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
 | 
						|
    /*
 | 
						|
    * Sends a command, checks the reponse, and
 | 
						|
    * if good returns the reponse, other wise
 | 
						|
    * returns false.
 | 
						|
    *
 | 
						|
    * @param  string $cmd  Command to send (\r\n will be appended)
 | 
						|
    * @return mixed First line of response if successful, otherwise false
 | 
						|
    */
 | 
						|
    function _sendCmd($cmd)
 | 
						|
    {
 | 
						|
        if (PEAR::isError($result = $this->_send($cmd) )){
 | 
						|
            return $result ;
 | 
						|
        }
 | 
						|
 | 
						|
        if (PEAR::isError($data = $this->_recvLn() )){
 | 
						|
            return $data;
 | 
						|
        }
 | 
						|
        
 | 
						|
        if ( strtoupper(substr($data, 0, 3)) == '+OK') {
 | 
						|
            return $data;
 | 
						|
        }
 | 
						|
        
 | 
						|
        
 | 
						|
        return $this->_raiseError($data);
 | 
						|
    }
 | 
						|
 | 
						|
    /*
 | 
						|
    * Reads a multiline reponse and returns the data
 | 
						|
    *
 | 
						|
    * @return string The reponse.
 | 
						|
    */
 | 
						|
    function _getMultiline()
 | 
						|
    {
 | 
						|
        $data = '';
 | 
						|
        while(!PEAR::isError($tmp = $this->_recvLn() ) ) {
 | 
						|
            if($tmp == '.'){
 | 
						|
                return substr($data, 0, -2);
 | 
						|
            }
 | 
						|
            if (substr($tmp, 0, 2) == '..') {
 | 
						|
                $tmp = substr($tmp, 1);
 | 
						|
            }
 | 
						|
            $data .= $tmp . "\r\n";
 | 
						|
        }
 | 
						|
        return substr($data, 0, -2);
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
   /**
 | 
						|
    * Sets the bebug state
 | 
						|
    *
 | 
						|
    * @param  bool $debug 
 | 
						|
    * @access public
 | 
						|
    * @return void
 | 
						|
    */
 | 
						|
    function setDebug($debug=true)
 | 
						|
    {
 | 
						|
        $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 "C: $data\n";
 | 
						|
        }
 | 
						|
 | 
						|
        if (PEAR::isError($error = $this->_socket->writeLine($data))) {
 | 
						|
            return $this->_raiseError('Failed to write to socket: ' . $error->getMessage());
 | 
						|
        }
 | 
						|
        return true;
 | 
						|
    }
 | 
						|
 | 
						|
 | 
						|
 | 
						|
     /**
 | 
						|
     * Receive the given string of data from the server.
 | 
						|
     *
 | 
						|
     * @return  mixed   a line of response on success or a PEAR_Error object on failure.
 | 
						|
     *
 | 
						|
     * @access  private
 | 
						|
     * @since  1.0
 | 
						|
     */
 | 
						|
    function _recvLn()
 | 
						|
    {
 | 
						|
        if (PEAR::isError( $lastline = $this->_socket->readLine( 8192 ) ) ) {
 | 
						|
            return $this->_raiseError('Failed to write to socket: ' . $this->lastline->getMessage() );
 | 
						|
        }
 | 
						|
        if($this->_debug){
 | 
						|
            // S: means this data was sent by  the POP3 Server
 | 
						|
            echo "S:$lastline\n" ;
 | 
						|
        }
 | 
						|
        return $lastline;
 | 
						|
    }
 | 
						|
 | 
						|
     /**
 | 
						|
     * Checks de server Response
 | 
						|
     *
 | 
						|
     * @param  string $response the response
 | 
						|
     * @return  mixed   true on success or a PEAR_Error object on failure.
 | 
						|
     *
 | 
						|
     * @access  private
 | 
						|
     * @since  1.3.3
 | 
						|
     */
 | 
						|
 | 
						|
    function _checkResponse($response)
 | 
						|
    {
 | 
						|
        if (@substr(strtoupper($response), 0, 3) == '+OK') {
 | 
						|
            return true;
 | 
						|
        }else{
 | 
						|
            if (@substr(strtoupper($response), 0, 4) == '-ERR') {
 | 
						|
                return $this->_raiseError($response);
 | 
						|
            }else{
 | 
						|
                if (@substr(strtoupper($response), 0, 2) == '+ ') {
 | 
						|
                    return true;
 | 
						|
                }
 | 
						|
            }
 | 
						|
    
 | 
						|
        }
 | 
						|
        return $this->_raiseError("Unknown Response ($response)");
 | 
						|
    }
 | 
						|
    
 | 
						|
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
?>
 |