OSDN Git Service

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