Net_IMAP-Protocol
[ class tree: Net_IMAP-Protocol ] [ index: Net_IMAP-Protocol ] [ all elements ]

Source for file IMAPProtocol.php

Documentation is available at IMAPProtocol.php

  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4                                                        |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group                                |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license,      |
  9. // | that is bundled with this package in the file LICENSE, and is        |
  10. // | available at through the world-wide-web at                           |
  11. // | http://www.php.net/license/2_02.txt.                                 |
  12. // | If you did not receive a copy of the PHP license and are unable to   |
  13. // | obtain it through the world-wide-web, please send a note to          |
  14. // | license@php.net so we can mail you a copy immediately.               |
  15. // +----------------------------------------------------------------------+
  16. // | Author: Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>       |
  17. // +----------------------------------------------------------------------+
  18. require_once 'Net/Socket.php';
  19.  
  20.  
  21.  
  22. /**
  23.  * Provides an implementation of the IMAP protocol using PEAR's
  24.  * Net_Socket:: class.
  25.  *
  26.  * @package Net_IMAP/Protocol
  27.  * @author  Damian Alejandro Fernandez Sosa <damlists@cnba.uba.ar>
  28.  */
  29.  
  30.  
  31.     /**
  32.     * The auth methods this class support
  33.     * @var array 
  34.     */
  35.     var $supportedAuthMethods=array('DIGEST-MD5''CRAM-MD5''LOGIN');
  36.  
  37.  
  38.     /**
  39.     * The auth methods this class support
  40.     * @var array 
  41.     */
  42.     var $supportedSASLAuthMethods=array('DIGEST-MD5''CRAM-MD5');
  43.  
  44.      /**
  45.      * _serverAuthMethods
  46.      * @var boolean 
  47.      */
  48.     var $_serverAuthMethods = null;
  49.  
  50.  
  51.     /**
  52.      * The the current mailbox
  53.      * @var string 
  54.      */
  55.     var $currentMailbox = "INBOX" ;
  56.  
  57.  
  58.     /**
  59.      * The socket resource being used to connect to the IMAP server.
  60.      * @var resource 
  61.      */
  62.     var $_socket = null;
  63.  
  64.      /**
  65.      * To allow class debuging
  66.      * @var boolean 
  67.      */
  68.     var $_debug = false;
  69.  
  70.     var $dbgDialog = '';
  71.  
  72.      /**
  73.      * Command Number
  74.      * @var int 
  75.      */
  76.     var $_cmd_counter = 1;
  77.  
  78.  
  79.      /**
  80.      * Command Number for IMAP commands
  81.      * @var int 
  82.      */
  83.     var $_lastCmdID = 1;
  84.  
  85.      /**
  86.      * Command Number
  87.      * @var boolean 
  88.      */
  89.     var $_unParsedReturn = false;
  90.  
  91.  
  92.  
  93.      /**
  94.      * _connected: checks if there is a connection made to a imap server or not
  95.      * @var boolean 
  96.      */
  97.     var $_connected = false;
  98.      /**
  99.      * Capabilities
  100.      * @var boolean 
  101.      */
  102.     var $_serverSupportedCapabilities = null;
  103.  
  104.  
  105.  
  106.      /**
  107.      * Use UTF-7 funcionallity
  108.      * @var boolean 
  109.      */
  110.     //var $_useUTF_7 = false;
  111.     var $_useUTF_7 = true;
  112.  
  113.  
  114.  
  115.     /**
  116.      * Constructor
  117.      *
  118.      * Instantiates a new Net_IMAP object.
  119.      *
  120.      * @since  1.0
  121.      */
  122.     function Net_IMAPProtocol()
  123.     {
  124.         $this->_socket = new Net_Socket();
  125.  
  126.         /*
  127.          * Include the Auth_SASL package.  If the package is not available,
  128.          * we disable the authentication methods that depend upon it.
  129.          */
  130.  
  131.  
  132.         if ((@include_once 'Auth/SASL.php'== false{
  133.             foreach($this->supportedSASLAuthMethods as $SASLMethod){
  134.                 $pos array_search$SASLMethod $this->supportedAuthMethods);
  135.                 unset($this->supportedAuthMethods[$pos]);
  136.             }
  137.         }
  138.  
  139.     }
  140.  
  141.  
  142.     /**
  143.      * Attempt to connect to the IMAP server.
  144.      *
  145.      * @return mixed Returns a PEAR_Error with an error message on any
  146.      *                kind of failure, or true on success.
  147.      * @access public
  148.      * @since  1.0
  149.      */
  150.     function cmdConnect($host"localhost"  $port = 143)
  151.     {
  152.         if$this->_connected ){
  153.             return new PEAR_Error'already connected, logout first!' );
  154.         }
  155.         if PEAR::isError$this->_socket->connect$host $port ) ) ) {
  156.             return new PEAR_Error'unable to open socket' );
  157.         }
  158.         if PEAR::isError$this->_getRawResponse() ) ) {
  159.             return new PEAR_Error'unable to open socket' );
  160.         }
  161.         $this->_connected = true;
  162.         return true;
  163.     }
  164.  
  165.  
  166.     /**
  167.      * get the cmd ID
  168.      *
  169.      * @return string Returns the CmdID and increment the counter
  170.      *
  171.      * @access private
  172.      * @since  1.0
  173.      */
  174.     function _getCmdId()
  175.     {
  176.         $this->_lastCmdID "A000" $this->_cmd_counter ;
  177.         $this->_cmd_counter++;
  178.         return $this->_lastCmdID;
  179.     }
  180.  
  181.  
  182.     /**
  183.      * get the last cmd ID
  184.      *
  185.      * @return string Returns the last cmdId
  186.      *
  187.      * @access public
  188.      * @since  1.0
  189.      */
  190.     function getLastCmdId()
  191.     {
  192.         return $this->_lastCmdID;
  193.     }
  194.  
  195.  
  196.  
  197.  
  198.     /**
  199.      * get current mailbox name
  200.      *
  201.      * @return string Returns the current mailbox
  202.      *
  203.      * @access public
  204.      * @since  1.0
  205.      */
  206.     function getCurrentMailbox()
  207.     {
  208.         return $this->currentMailbox;
  209.     }
  210.  
  211.  
  212.  
  213.  
  214.     /**
  215.      * Sets the debuging information on or off
  216.      *
  217.      * @param boolean True or false
  218.      *
  219.      * @return nothing 
  220.      * @access public
  221.      * @since  1.0
  222.      */
  223.     function setDebug($debug = true)
  224.     {
  225.         $this->_debug $debug;
  226.     }
  227.  
  228.  
  229.     function getDebugDialog()
  230.     {
  231.         return $this->dbgDialog;
  232.     }
  233.  
  234.  
  235.  
  236.     /**
  237.      * Send the given string of data to the server.
  238.      *
  239.      * @param   string  $data    The string of data to send.
  240.      *
  241.      * @return  mixed   True on success or a PEAR_Error object on failure.
  242.      *
  243.      * @access  private
  244.      * @since  1.0
  245.      */
  246.     function _send($data)
  247.     {
  248.         if($this->_socket->eof() ){
  249.             return new PEAR_Error'Failed to write to socket: (connection lost!) ' );
  250.         }
  251.         if PEAR::isError$error $this->_socket->write$data ) ) ) {
  252.  
  253.             return new PEAR_Error'Failed to write to socket: ' .
  254.                                   $error->getMessage() );
  255.         }
  256.  
  257.         if$this->_debug ){
  258.             // C: means this data was sent by  the client (this class)
  259.             echo "C: $data";
  260.             $this->dbgDialog.="C: $data";
  261.         }
  262.         return true;
  263.     }
  264.  
  265.     /**
  266.      * Receive the given string of data from the server.
  267.      *
  268.      * @return  mixed   a line of response on success or a PEAR_Error object on failure.
  269.      *
  270.      * @access  private
  271.      * @since  1.0
  272.      */
  273.     function _recvLn()
  274.     {
  275.  
  276.         if (PEAR::isError$this->lastline $this->_socket->gets8192 ) ) ) {
  277.             return new PEAR_Error('Failed to write to socket: ' .
  278.                                               $this->lastline->getMessage() );
  279.         }
  280.         if($this->_debug){
  281.             // S: means this data was sent by  the IMAP Server
  282.             echo "S: " $this->lastline "" ;
  283.             $this->dbgDialog.="S: " $this->lastline "" ;
  284.         }
  285.         if$this->lastline == '' ){
  286.             return new PEAR_Error('Failed to receive from the  socket: '  );
  287.         }
  288.         return $this->lastline;
  289.     }
  290.  
  291.  
  292.  
  293.  
  294.  
  295.     /**
  296.      * Send a command to the server with an optional string of arguments.
  297.      * A carriage return / linefeed (CRLF) sequence will be appended to each
  298.      * command string before it is sent to the IMAP server.
  299.      *
  300.      * @param   string  $commandId  The IMAP cmdID to send to the server.
  301.      * @param   string  $command    The IMAP command to send to the server.
  302.      * @param   string  $args       A string of optional arguments to append
  303.      *                               to the command.
  304.      *
  305.      * @return  mixed   The result of the _send() call.
  306.      *
  307.      * @access  private
  308.      * @since  1.0
  309.      */
  310.     function _putCMD($commandId $command$args '')
  311.     {
  312.         if !empty$args ) ) {
  313.             return $this->_send$commandId " " $command ' ' $args "\r\n" );
  314.         }
  315.         return $this->_send$commandId " " $command "\r\n" );
  316.     }
  317.  
  318.  
  319.  
  320.  
  321.  
  322.  
  323.     /**
  324.      * Get a response from the server with an optional string of commandID.
  325.      * A carriage return / linefeed (CRLF) sequence will be appended to each
  326.      * command string before it is sent to the IMAP server.
  327.      *
  328.      * @param   string  $commandid    The IMAP commandid retrive from the server.
  329.      *
  330.      * @return  string   The result response.
  331.      *
  332.      * @access  private
  333.      */
  334.     function _getRawResponse($commandId '*')
  335.     {
  336.        $arguments '';
  337.        while !PEAR::isError$this->_recvLn() ) ) {
  338.            $reply_code strtok$this->lastline ' ' );
  339.            $arguments.= $this->lastline;
  340.            if !(strcmp$commandId $reply_code ) ) ) {
  341.            return $arguments;
  342.            }
  343.        }
  344.        return $arguments;
  345.      }
  346.  
  347.  
  348.  
  349.  
  350.  
  351.      /**
  352.      * get the "returning of the unparsed response" feature status
  353.      *
  354.      * @return boolean return if the unparsed response is returned or not
  355.      *
  356.      * @access public
  357.      * @since  1.0
  358.      *
  359.      */
  360.     function getUnparsedResponse()
  361.     {
  362.         return $this->_unParsedReturn;
  363.     }
  364.  
  365.  
  366.  
  367.  
  368.  
  369.  
  370.      /**
  371.      * set the "returning of the unparsed response" feature on or off
  372.      *
  373.      * @param  boolean  $status: true: feature is on
  374.      * @return nothing 
  375.      *
  376.      * @access public
  377.      * @since  1.0
  378.      */
  379.     function setUnparsedResponse($status)
  380.     {
  381.         $this->_unParsedReturn $status;
  382.     }
  383.  
  384.  
  385.  
  386.  
  387.  
  388.  
  389.     /**
  390.      * Attempt to login to the iMAP server.
  391.      *
  392.      * @param string The userid to authenticate as.
  393.      * @param string The password to authenticate with.
  394.      *
  395.      * @return array Returns an array containing the response
  396.      *
  397.      * @access public
  398.      * @since  1.0
  399.      */
  400.     function cmdLogin($uid $pwd)
  401.     {
  402.         $param="\"$uid\" \"$pwd\"";
  403.         return $this->_genericCommand('LOGIN'$param);
  404.     }
  405.  
  406.  
  407.  
  408.  
  409.  
  410.  
  411.     /**
  412.      * Attempt to authenticate to the iMAP server.
  413.      * @param string The userid to authenticate as.
  414.      * @param string The password to authenticate with.
  415.      * @param string The cmdID.
  416.      *
  417.      * @return array Returns an array containing the response
  418.      *
  419.      * @access public
  420.      * @since  1.0
  421.      */
  422.     function cmdAuthenticate($uid $pwd $userMethod = null)
  423.     {
  424.  
  425.         if!$this->_connected ){
  426.             return new PEAR_Error('not connected!');
  427.         }
  428.  
  429.         $cmdid $this->_getCmdId();
  430.  
  431.  
  432.         if PEAR::isError$method $this->_getBestAuthMethod($userMethod) ) ) {
  433.             return $method;
  434.         }
  435.  
  436.  
  437.         switch ($method{
  438.             case 'DIGEST-MD5':
  439.                 $result $this->_authDigest_MD5$uid $pwd $cmdid );
  440.                 break;
  441.             case 'CRAM-MD5':
  442.                 $result $this->_authCRAM_MD5$uid $pwd ,$cmdid );
  443.                 break;
  444.             case 'LOGIN':
  445.                 $result $this->_authLOGIN$uid $pwd $cmdid );
  446.                 break;
  447.  
  448.             default :
  449.                 $result = new PEAR_Error"$method is not a supported authentication method);
  450.                 break;
  451.         }
  452.  
  453.         $args $this->_getRawResponse$cmdid );
  454.         return $this->_genericImapResponseParser$args $cmdid );
  455.  
  456.     }
  457.  
  458.  
  459.  
  460.  
  461.  
  462.  
  463.  
  464.  
  465.      /* Authenticates the user using the DIGEST-MD5 method.
  466.      *
  467.      * @param string The userid to authenticate as.
  468.      * @param string The password to authenticate with.
  469.      * @param string The cmdID.
  470.      *
  471.      * @return array Returns an array containing the response
  472.      *
  473.      * @access private
  474.      * @since  1.0
  475.      */
  476.     function _authDigest_MD5($uid $pwd $cmdid)
  477.     {
  478.  
  479.         if PEAR::isError($error $this->_putCMD$cmdid ,"AUTHENTICATE" "DIGEST-MD5") ) ) {
  480.             return $error;
  481.         }
  482.  
  483.         if (PEAR::isError$args $this->_recvLn() ) ) {
  484.             return $args;
  485.         }
  486.  
  487.         $this->_getNextToken$args $plus );
  488.  
  489.         $this->_getNextToken$args $space );
  490.  
  491.         $this->_getNextToken$args $challenge );
  492.  
  493.         $challenge base64_decode$challenge );
  494.  
  495.         $digest &Auth_SASL::factory('digestmd5');
  496.  
  497.         $auth_str base64_encode($digest->getResponse($uid$pwd$challenge,"localhost""imap"));
  498.  
  499.         if PEAR::isError$error $this->_send("$auth_str\r\n"))) {
  500.             return $error;
  501.         }
  502.  
  503.         if PEAR::isError$args $this->_recvLn() )) {
  504.             return $args;
  505.         }
  506.         /*
  507.          * We don't use the protocol's third step because IMAP doesn't allow
  508.          * subsequent authentication, so we just silently ignore it.
  509.          */
  510.         if PEAR::isError$error $this->_send"\r\n" ) ) ) {
  511.             return $error;
  512.         }
  513.     }
  514.  
  515.  
  516.  
  517.  
  518.  
  519.  
  520.  
  521.  
  522.      /* Authenticates the user using the CRAM-MD5 method.
  523.      *
  524.      * @param string The userid to authenticate as.
  525.      * @param string The password to authenticate with.
  526.      * @param string The cmdID.
  527.      *
  528.      * @return array Returns an array containing the response
  529.      *
  530.      * @access private
  531.      * @since  1.0
  532.      */
  533.     function _authCRAM_MD5($uid$pwd$cmdid)
  534.     {
  535.  
  536.  
  537.  
  538.         if PEAR::isError($error $this->_putCMD$cmdid ,"AUTHENTICATE" "CRAM-MD5") ) ) {
  539.             return $error;
  540.         }
  541.  
  542.         if PEAR::isError$args $this->_recvLn() ) ) {
  543.             return $args;
  544.         }
  545.  
  546.         $this->_getNextToken$args $plus );
  547.  
  548.         $this->_getNextToken$args $space );
  549.  
  550.         $this->_getNextToken$args $challenge );
  551.  
  552.         $challenge base64_decode$challenge );
  553.  
  554.         $cram &Auth_SASL::factory('crammd5');
  555.  
  556.         $auth_str base64_encode$cram->getResponse$uid $pwd $challenge ) );
  557.  
  558.         if PEAR::isError$error $this->_send$auth_str."\r\n" ) ) ) {
  559.             return $error;
  560.         }
  561.  
  562.     }
  563.  
  564.  
  565.  
  566.  
  567.  
  568.  
  569.  
  570.  
  571.  
  572.      /* Authenticates the user using the LOGIN method.
  573.      *
  574.      * @param string The userid to authenticate as.
  575.      * @param string The password to authenticate with.
  576.      * @param string The cmdID.
  577.      *
  578.      * @return array Returns an array containing the response
  579.      *
  580.      * @access private
  581.      * @since  1.0
  582.      */
  583.     function _authLOGIN($uid$pwd$cmdid)
  584.     {
  585.  
  586.         if (PEAR::isError($error $this->_putCMD($cmdid,"AUTHENTICATE""LOGIN"))) {
  587.             return $error;
  588.         }
  589.  
  590.         if (PEAR::isError($args $this->_recvLn() )) {
  591.             return $args;
  592.         }
  593.  
  594.         $this->_getNextToken$args $plus );
  595.  
  596.         $this->_getNextToken$args $space );
  597.  
  598.         $this->_getNextToken$args $challenge );
  599.  
  600.         $challenge base64_decode$challenge );
  601.  
  602.         $auth_str base64_encode"$uid);
  603.  
  604.         if PEAR::isError$error $this->_send$auth_str."\r\n" ) ) ) {
  605.             return $error;
  606.         }
  607.  
  608.         if (PEAR::isError$args $this->_recvLn() ) ) {
  609.             return $args;
  610.         }
  611.  
  612.         $auth_str base64_encode"$pwd);
  613.  
  614.         if PEAR::isError($error $this->_send$auth_str."\r\n" ) ) ) {
  615.             return $error;
  616.         }
  617.  
  618.     }
  619.  
  620.  
  621.  
  622.  
  623.  
  624.  
  625.  
  626.  
  627.     /**
  628.      * Returns the name of the best authentication method that the server
  629.      * has advertised.
  630.      *
  631.      * @param string if !=null,authenticate with this method ($userMethod).
  632.      *
  633.      * @return mixed    Returns a string containing the name of the best
  634.      *                   supported authentication method or a PEAR_Error object
  635.      *                   if a failure condition is encountered.
  636.      * @access private
  637.      * @since  1.0
  638.      */
  639.     function _getBestAuthMethod($userMethod = null)
  640.     {
  641.        $this->cmdCapability();
  642.  
  643.         if($userMethod != null ){
  644.  
  645.             $methods = array();
  646.  
  647.             $methods[$userMethod;
  648.  
  649.         }else{
  650.             $methods $this->supportedAuthMethods;
  651.         }
  652.  
  653.         if( ($methods != null&& ($this->_serverAuthMethods != null)){
  654.             foreach $methods as $method {
  655.                 if in_array$method $this->_serverAuthMethods ) ) {
  656.                     return $method;
  657.                 }
  658.             }
  659.             $serverMethods=implode(',' ,$this->_serverAuthMethods);
  660.             $myMethods=implode(',' ,$this->supportedAuthMethods);
  661.             return new PEAR_Error("$method NOT supported authentication method!. This IMAP server " .
  662.                 "supports these methods: $serverMethods, but I support $myMethods");
  663.         }else{
  664.             return new PEAR_Error("This IMAP server don't support any Auth methods");
  665.         }
  666.     }
  667.  
  668.  
  669.  
  670.  
  671.  
  672.  
  673.  
  674.  
  675.  
  676.     /**
  677.      * Attempt to disconnect from the iMAP server.
  678.      *
  679.      * @return array Returns an array containing the response
  680.      *
  681.      * @access public
  682.      * @since  1.0
  683.      */
  684.     function cmdLogout()
  685.     {
  686.         if!$this->_connected ){
  687.             return new PEAR_Error'not connected!' );
  688.         }
  689.  
  690.         $cmdid $this->_getCmdId();
  691.         if PEAR::isError$error $this->_putCMD$cmdid 'LOGOUT' ) ) ) {
  692.             return $error;
  693.         }
  694.         if PEAR::isError($args $this->_getRawResponse() ) ) {
  695.             return $args;
  696.         }
  697.         if (PEAR::isError$this->_socket->disconnect() ) ) {
  698.             return new PEAR_Error('socket disconnect failed');
  699.         }
  700.  
  701.         return $args;
  702.         // not for now
  703.         //return $this->_genericImapResponseParser($args,$cmdid);
  704.  
  705.     }
  706.  
  707.  
  708.  
  709.  
  710.  
  711.     /**
  712.      * Send the NOOP command.
  713.      *
  714.      * @return array Returns an array containing the response
  715.      *
  716.      * @access public
  717.      * @since  1.0
  718.      */
  719.     function cmdNoop()
  720.     {
  721.         return $this->_genericCommand('NOOP');
  722.     }
  723.  
  724.  
  725.  
  726.  
  727.  
  728.  
  729.  
  730.  
  731.  
  732.     /**
  733.      * Send the CHECK command.
  734.      *
  735.      * @return array Returns an array containing the response
  736.      *
  737.      * @access public
  738.      * @since  1.0
  739.      */
  740.     function cmdCheck()
  741.     {
  742.         return $this->_genericCommand('CHECK');
  743.     }
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.     /**
  755.      * Send the  Select Mailbox Command
  756.      *
  757.      * @param string The mailbox to select.
  758.      *
  759.      * @return array Returns an array containing the response
  760.      *
  761.      * @access public
  762.      * @since  1.0
  763.      */
  764.     function cmdSelect($mailbox)
  765.     {
  766.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  767.         if!PEAR::isError$ret$this->_genericCommand('SELECT'$mailbox_name) ) ){
  768.             $this->currentMailbox  = $mailbox;
  769.         }
  770.         return $ret;
  771.     }
  772.  
  773.  
  774.  
  775.  
  776.  
  777.  
  778.  
  779.  
  780.  
  781.  
  782.     /**
  783.      * Send the  EXAMINE  Mailbox Command
  784.      *
  785.      * @param string The mailbox to examine.
  786.      * @return array Returns an array containing the response
  787.      *
  788.      * @access public
  789.      * @since  1.0
  790.      */
  791.     function cmdExamine($mailbox)
  792.     {
  793.  
  794.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  795.         $ret=$this->_genericCommand('EXAMINE'$mailbox_name);
  796.         $parsed='';
  797.         if(isset$ret["PARSED") ){
  798.             for($i=0;$i<count($ret["PARSED"])$i++)$command=$ret["PARSED"][$i]["EXT"];
  799.                     $parsed[key($command)]=$command[key($command)];
  800.             }
  801.         }
  802.         return array("PARSED"=>$parsed,"RESPONSE"=>$ret["RESPONSE"]);
  803.     }
  804.  
  805.  
  806.  
  807.  
  808.  
  809.  
  810.  
  811.     /**
  812.      * Send the  CREATE Mailbox Command
  813.      *
  814.      * @param string The mailbox to create.
  815.      * @return array Returns an array containing the response
  816.      *
  817.      * @access public
  818.      * @since  1.0
  819.      */
  820.     function cmdCreate($mailbox)
  821.     {
  822.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  823.         return $this->_genericCommand('CREATE'$mailbox_name);
  824.     }
  825.  
  826.  
  827.  
  828.  
  829.  
  830.  
  831.  
  832.     /**
  833.      * Send the  RENAME Mailbox Command
  834.      *
  835.      * @param string The old mailbox name.
  836.      * @param string The new (renamed) mailbox name.
  837.      *
  838.      * @return array Returns an array containing the response
  839.      *
  840.      * @access public
  841.      * @since  1.0
  842.      */
  843.     function cmdRename($mailbox$new_mailbox)
  844.     {
  845.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  846.         $new_mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($new_mailbox) );
  847.         return $this->_genericCommand('RENAME'"$mailbox_name $new_mailbox_name);
  848.     }
  849.  
  850.  
  851.  
  852.  
  853.  
  854.  
  855.  
  856.  
  857.     /**
  858.      * Send the  DELETE Mailbox Command
  859.      *
  860.      * @param string The mailbox name to delete.
  861.      *
  862.      * @return array Returns an array containing the response
  863.      *
  864.      * @access public
  865.      * @since  1.0
  866.      */
  867.     function cmdDelete($mailbox)
  868.     {
  869.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  870.         return $this->_genericCommand('DELETE'$mailbox_name);
  871.     }
  872.  
  873.  
  874.  
  875.  
  876.  
  877.  
  878.  
  879.     /**
  880.      * Send the  SUSCRIBE  Mailbox Command
  881.      *
  882.      * @param string The mailbox name to suscribe.
  883.      *
  884.      * @return array Returns an array containing the response
  885.      *
  886.      * @access public
  887.      * @since  1.0
  888.      */
  889.     function cmdSubscribe($mailbox)
  890.     {
  891.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  892.         return $this->_genericCommand('SUBSCRIBE'$mailbox_name );
  893.     }
  894.  
  895.  
  896.  
  897.  
  898.  
  899.  
  900.  
  901.  
  902.     /**
  903.      * Send the  UNSUSCRIBE  Mailbox Command
  904.      *
  905.      * @return mixed Returns a PEAR_Error with an error message on any
  906.      *                kind of failure, or true on success.
  907.      * @access public
  908.      * @since  1.0
  909.      */
  910.     function cmdUnsubscribe($mailbox)
  911.     {
  912.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  913.         return $this->_genericCommand('UNSUBSCRIBE'$mailbox_name );
  914.     }
  915.  
  916.  
  917.  
  918.  
  919.  
  920.  
  921.  
  922.  
  923.     /**
  924.      * Send the  FETCH Command
  925.      *
  926.      * @return mixed Returns a PEAR_Error with an error message on any
  927.      *                kind of failure, or true on success.
  928.      * @access public
  929.      * @since  1.0
  930.      */
  931.     function cmdFetch($msgset$fetchparam)
  932.     {
  933.         return $this->_genericCommand('FETCH' "$msgset $fetchparam);
  934.     }
  935.  
  936.  
  937.  
  938.  
  939.  
  940.  
  941.  
  942.     /**
  943.      * Send the  CAPABILITY Command
  944.      *
  945.      * @return mixed Returns a PEAR_Error with an error message on any
  946.      *                kind of failure, or true on success.
  947.      * @access public
  948.      * @since  1.0
  949.      */
  950.     function cmdCapability()
  951.     {
  952.         $ret $this->_genericCommand'CAPABILITY' );
  953.  
  954.         if(isset$ret["PARSED") ){
  955.             $ret["PARSED"]=$ret["PARSED"][0]["EXT"]["CAPABILITY"];
  956.             //fill the $this->_serverAuthMethods and $this->_serverSupportedCapabilities arrays
  957.             foreach$ret["PARSED"]["CAPABILITIES"as $auth_method ){
  958.                 ifstrtouppersubstr$auth_method ,) ) == "AUTH=" )
  959.                     $this->_serverAuthMethods[substr$auth_method );
  960.             }
  961.             // Keep the capabilities response to use ir later
  962.             $this->_serverSupportedCapabilities $ret["PARSED"]["CAPABILITIES"];
  963.         }
  964.  
  965.         return $ret;
  966.     }
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.  
  977.     /**
  978.      * Send the  STATUS Mailbox Command
  979.      *
  980.      * @param string $mailbox the mailbox name
  981.      * @param string $request the request status it could be:
  982.      *               MESSAGES | RECENT | UIDNEXT
  983.      *               UIDVALIDITY | UNSEEN
  984.      * @return array Returns a Parsed Response
  985.      *
  986.      * @access public
  987.      * @since  1.0
  988.      */
  989.     function cmdStatus($mailbox$request)
  990.     {
  991.  
  992.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  993.  
  994.         if$request!="MESSAGES" && $request!="RECENT" && $request!="UIDNEXT" &&
  995.             $request!="UIDVALIDITY" && $request!="UNSEEN" ){
  996.             // TODO:  fix this error!
  997.             $this->_prot_error("request '$request' is invalid! see RFC2060!!!!__LINE__ __FILE__false );
  998.         }
  999.         $ret $this->_genericCommand('STATUS'"$mailbox_name ($request));
  1000.         if(isset$ret["PARSED") ){
  1001.             $ret['PARSED']=$ret["PARSED"][count($ret['PARSED'])-1]["EXT"];
  1002.         }
  1003.         return $ret;
  1004.     }
  1005.  
  1006.  
  1007.  
  1008.  
  1009.  
  1010.  
  1011.     /**
  1012.      * Send the  LIST  Command
  1013.      *
  1014.      * @return mixed Returns a PEAR_Error with an error message on any
  1015.      *                kind of failure, or true on success.
  1016.      * @access public
  1017.      * @since  1.0
  1018.      */
  1019.     function cmdList($mailbox_base$mailbox)
  1020.     {
  1021.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  1022.         $mailbox_base=sprintf("\"%s\"",$this->utf_7_encode($mailbox_base) );
  1023.         return $this->_genericCommand('LIST'"$mailbox_base $mailbox_name);
  1024.     }
  1025.  
  1026.  
  1027.  
  1028.  
  1029.  
  1030.  
  1031.     /**
  1032.      * Send the  LSUB  Command
  1033.      *
  1034.      * @return mixed Returns a PEAR_Error with an error message on any
  1035.      *                kind of failure, or true on success.
  1036.      * @access public
  1037.      * @since  1.0
  1038.      */
  1039.     function cmdLsub($mailbox_base$mailbox)
  1040.     {
  1041.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  1042.         $mailbox_base=sprintf("\"%s\"",$this->utf_7_encode($mailbox_base) );
  1043.         return $this->_genericCommand('LSUB'"$mailbox_base $mailbox_name);
  1044.     }
  1045.  
  1046.  
  1047.  
  1048.  
  1049.  
  1050.  
  1051.     /**
  1052.      * Send the  APPEND  Command
  1053.      *
  1054.      * @return mixed Returns a PEAR_Error with an error message on any
  1055.      *                kind of failure, or true on success.
  1056.      * @access public
  1057.      * @since  1.0
  1058.      */
  1059.     function cmdAppend($mailbox$msg $flags_list '' ,$time '')
  1060.     {
  1061.         if(!$this->_connected){
  1062.             return new PEAR_Error('not connected!');
  1063.         }
  1064.  
  1065.  
  1066.         $cmdid=$this->_getCmdId();
  1067.         $msg_size=strlen($msg);
  1068.  
  1069.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  1070.         // TODO:
  1071.         // Falta el codigo para que flags list y time hagan algo!!
  1072.         if$this->hasCapability"LITERAL+" == true ){
  1073.             $param=sprintf("%s %s%s{%s+}\r\n%s",$mailbox_name,$flags_list,$time,$msg_size,$msg);
  1074.             if (PEAR::isError($error $this->_putCMD($cmdid 'APPEND' $param ) ) ) {
  1075.                 return $error;
  1076.             }
  1077.         }else{
  1078.             $param=sprintf("%s %s%s{%s}\r\n",$mailbox_name,$flags_list,$time,$msg_size);
  1079.             if (PEAR::isError($error $this->_putCMD($cmdid 'APPEND' $param ) ) ) {
  1080.             return $error;
  1081.             }
  1082.             if (PEAR::isError($error $this->_recvLn() ) ) {
  1083.             return $error;
  1084.             }
  1085.  
  1086.             if (PEAR::isError($error $this->_send$msg ) ) ) {
  1087.             return $error;
  1088.             }
  1089.         }
  1090.  
  1091.  
  1092.         $args=$this->_getRawResponse($cmdid);
  1093.         $ret $this->_genericImapResponseParser($args,$cmdid);
  1094.         return $ret;
  1095.     }
  1096.  
  1097.  
  1098.  
  1099.     /**
  1100.      * Send the CLOSE command.
  1101.      *
  1102.      * @return mixed Returns a PEAR_Error with an error message on any
  1103.      *                kind of failure, or true on success.
  1104.      * @access public
  1105.      * @since  1.0
  1106.      */
  1107.     function cmdClose()
  1108.     {
  1109.         return $this->_genericCommand('CLOSE');
  1110.     }
  1111.  
  1112.  
  1113.  
  1114.  
  1115.  
  1116.  
  1117.     /**
  1118.      * Send the EXPUNGE command.
  1119.      *
  1120.      * @return mixed Returns a PEAR_Error with an error message on any
  1121.      *                kind of failure, or true on success.
  1122.      * @access public
  1123.      * @since  1.0
  1124.      */
  1125.     function cmdExpunge()
  1126.     {
  1127.         $ret=$this->_genericCommand('EXPUNGE');
  1128.  
  1129.         if(isset$ret["PARSED") ){
  1130.            $parsed=$ret["PARSED"];
  1131.             unset($ret["PARSED"]);
  1132.             foreach($parsed as $command){
  1133.                 ifstrtoupper($command["COMMAND"]== 'EXPUNGE' ){
  1134.                         $ret["PARSED"][$command["COMMAND"]][]=$command["NRO"];
  1135.                 }else{
  1136.                         $ret["PARSED"][$command["COMMAND"]]=$command["NRO"];
  1137.                 }
  1138.             }
  1139.         }
  1140.         return $ret;
  1141.     }
  1142.  
  1143.  
  1144.  
  1145.  
  1146.  
  1147.  
  1148.  
  1149.     /**
  1150.      * Send the SEARCH command.
  1151.      *
  1152.      * @return mixed Returns a PEAR_Error with an error message on any
  1153.      *                kind of failure, or true on success.
  1154.      * @access public
  1155.      * @since  1.0
  1156.      */
  1157.  
  1158.     function cmdSearch($search_cmd)
  1159.     {
  1160.         /*        if($_charset != '' )
  1161.                     $_charset = "[$_charset] ";
  1162.                 $param=sprintf("%s%s",$charset,$search_cmd);
  1163.         */
  1164.         $ret $this->_genericCommand('SEARCH'$search_cmd );
  1165.         if(isset$ret["PARSED") ){
  1166.             $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  1167.         }
  1168.         return $ret;
  1169.     }
  1170.  
  1171.  
  1172.  
  1173.  
  1174.  
  1175.  
  1176.     /**
  1177.      * Send the STORE command.
  1178.      *
  1179.      * @param string $message_set  the sessage_set
  1180.      * @param string $dataitem: the way we store the flags
  1181.      *           FLAGS: replace the flags whith $value
  1182.      *           FLAGS.SILENT: replace the flags whith $value but don't return untagged responses
  1183.      *
  1184.      *           +FLAGS: Add the flags whith $value
  1185.      *           +FLAGS.SILENT: Add the flags whith $value but don't return untagged responses
  1186.      *
  1187.      *           -FLAGS: Remove the flags whith $value
  1188.      *           -FLAGS.SILENT: Remove the flags whith $value but don't return untagged responses
  1189.      *
  1190.      * @param string $value 
  1191.      * @return mixed Returns a PEAR_Error with an error message on any
  1192.      *                kind of failure, or true on success.
  1193.      * @access public
  1194.      * @since  1.0
  1195.      */
  1196.  
  1197.     function cmdStore($message_set$dataitem$value)
  1198.     {
  1199.         /* As said in RFC2060...
  1200.         C: A003 STORE 2:4 +FLAGS (\Deleted)
  1201.         S: * 2 FETCH FLAGS (\Deleted \Seen)
  1202.         S: * 3 FETCH FLAGS (\Deleted)
  1203.         S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
  1204.         S: A003 OK STORE completed
  1205.         */
  1206.         if$dataitem!="FLAGS" && $dataitem!="FLAGS.SILENT" && $dataitem!="+FLAGS" &&
  1207.             $dataitem!="+FLAGS.SILENT" && $dataitem!="-FLAGS" && $dataitem!="-FLAGS.SILENT" ){
  1208.             $this->_prot_error("dataitem '$dataitem' is invalid! see RFC2060!!!!__LINE__ __FILE__ );
  1209.         }
  1210.         $param=sprintf("%s %s (%s)",$message_set,$dataitem,$value);
  1211.         return $this->_genericCommand('STORE'$param );
  1212.     }
  1213.  
  1214.  
  1215.  
  1216.  
  1217.  
  1218.  
  1219.  
  1220.     /**
  1221.      * Send the COPY command.
  1222.      *
  1223.      * @return mixed Returns a PEAR_Error with an error message on any
  1224.      *                kind of failure, or true on success.
  1225.      * @access public
  1226.      * @since  1.0
  1227.      */
  1228.  
  1229.     function cmdCopy($message_set$mailbox)
  1230.     {
  1231.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  1232.         return $this->_genericCommand('COPY'sprintf("%s %s",$message_set,$mailbox_name) );
  1233.     }
  1234.  
  1235.  
  1236.  
  1237.  
  1238.  
  1239.  
  1240.  
  1241.  
  1242.  
  1243.  
  1244.  
  1245.  
  1246.  
  1247.     function cmdUidFetch($msgset$fetchparam)
  1248.     {
  1249.         return $this->_genericCommand('UID FETCH'sprintf("%s %s",$msgset,$fetchparam) );
  1250.     }
  1251.  
  1252.  
  1253.  
  1254.  
  1255.  
  1256.  
  1257.  
  1258.  
  1259.     function cmdUidCopy($message_set$mailbox)
  1260.     {
  1261.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  1262.         return $this->_genericCommand('UID COPY'sprintf("%s %s",$message_set,$mailbox_name) );
  1263.     }
  1264.  
  1265.  
  1266.  
  1267.  
  1268.  
  1269.  
  1270.  
  1271.  
  1272.      /**
  1273.      * Send the UID STORE command.
  1274.      *
  1275.      * @param string $message_set  the sessage_set
  1276.      * @param string $dataitem: the way we store the flags
  1277.      *           FLAGS: replace the flags whith $value
  1278.      *           FLAGS.SILENT: replace the flags whith $value but don't return untagged responses
  1279.      *
  1280.      *           +FLAGS: Add the flags whith $value
  1281.      *           +FLAGS.SILENT: Add the flags whith $value but don't return untagged responses
  1282.      *
  1283.      *           -FLAGS: Remove the flags whith $value
  1284.      *           -FLAGS.SILENT: Remove the flags whith $value but don't return untagged responses
  1285.      *
  1286.      * @param string $value 
  1287.      * @return mixed Returns a PEAR_Error with an error message on any
  1288.      *                kind of failure, or true on success.
  1289.      * @access public
  1290.      * @since  1.0
  1291.      */
  1292.  
  1293.     function cmdUidStore($message_set$dataitem$value)
  1294.     {
  1295.         /* As said in RFC2060...
  1296.         C: A003 STORE 2:4 +FLAGS (\Deleted)
  1297.         S: * 2 FETCH FLAGS (\Deleted \Seen)
  1298.         S: * 3 FETCH FLAGS (\Deleted)
  1299.         S: * 4 FETCH FLAGS (\Deleted \Flagged \Seen)
  1300.         S: A003 OK STORE completed
  1301.         */
  1302.         if$dataitem!="FLAGS" && $dataitem!="FLAGS.SILENT" && $dataitem!="+FLAGS" &&
  1303.             $dataitem!="+FLAGS.SILENT" && $dataitem!="-FLAGS" && $dataitem!="-FLAGS.SILENT" ){
  1304.             $this->_prot_error("dataitem '$dataitem' is invalid! see RFC2060!!!!__LINE__ __FILE__ );
  1305.         }
  1306.         return $this->_genericCommand('UID STORE'sprintf("%s %s (%s)",$message_set,$dataitem,$value) );
  1307.     }
  1308.  
  1309.  
  1310.  
  1311.  
  1312.  
  1313.  
  1314.  
  1315.  
  1316.  
  1317.  
  1318.     /**
  1319.      * Send the SEARCH command.
  1320.      *
  1321.      * @return mixed Returns a PEAR_Error with an error message on any
  1322.      *                kind of failure, or true on success.
  1323.      * @access public
  1324.      * @since  1.0
  1325.      */
  1326.  
  1327.     function cmdUidSearch($search_cmd)
  1328.     {
  1329.         $ret=$this->_genericCommand('UID SEARCH'sprintf("%s",$search_cmd) );
  1330.         if(isset$ret["PARSED") ){
  1331.             $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  1332.         }
  1333.         return $ret;
  1334.     }
  1335.  
  1336.  
  1337.  
  1338.  
  1339.  
  1340.  
  1341.  
  1342.  
  1343.  
  1344.  
  1345.  
  1346.     /**
  1347.      * Send the X command.
  1348.      *
  1349.      * @return mixed Returns a PEAR_Error with an error message on any
  1350.      *                kind of failure, or true on success.
  1351.      * @access public
  1352.      * @since  1.0
  1353.      */
  1354.  
  1355.     function cmdX($atom$parameters)
  1356.     {
  1357.         return $this->_genericCommand("X$atom"$parameters );
  1358.     }
  1359.  
  1360.  
  1361.  
  1362.  
  1363.  
  1364.  
  1365.  
  1366.  
  1367. /********************************************************************
  1368. ***
  1369. ***             HERE ENDS the RFC2060 IMAPS FUNCTIONS
  1370. ***             AND BEGIN THE EXTENSIONS FUNCTIONS
  1371. ***
  1372. ********************************************************************/
  1373.  
  1374.  
  1375.  
  1376.  
  1377.  
  1378.  
  1379.  
  1380. /********************************************************************
  1381. ***             RFC2087 IMAP4 QUOTA extension BEGINS HERE
  1382. ********************************************************************/
  1383.  
  1384.  
  1385.  
  1386.  
  1387.     function cmdGetQuota($mailbox_name)
  1388.     {
  1389.  
  1390.  
  1391.         //Check if the IMAP server has QUOTA support
  1392.         if$this->hasQuotaSupport() ){
  1393.             return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1394.         }
  1395.         $mailbox_name=sprintf("%s",$this->utf_7_encode($mailbox_name) );
  1396.         $ret $this->_genericCommand('GETQUOTA'$mailbox_name );
  1397.         if(isset$ret["PARSED") ){
  1398.         // remove the array index because the quota response returns only 1 line of output
  1399.             $ret['PARSED']=$ret["PARSED"][0];
  1400.         }
  1401.         return $ret;
  1402.     }
  1403.  
  1404.  
  1405.  
  1406.  
  1407.     function cmdGetQuotaRoot($mailbox_name)
  1408.     {
  1409.         //Check if the IMAP server has QUOTA support
  1410.         if$this->hasQuotaSupport() ){
  1411.             return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1412.         }
  1413.         $mailbox_name=sprintf("%s",$this->utf_7_encode($mailbox_name) );
  1414.         $ret $this->_genericCommand('GETQUOTAROOT'$mailbox_name );
  1415.  
  1416.         if(isset$ret["PARSED") ){
  1417.         // remove the array index because the quota response returns only 1 line of output
  1418.             $ret['PARSED']=$ret["PARSED"][0];
  1419.         }
  1420.         return $ret;
  1421.     }
  1422.  
  1423.  
  1424.  
  1425.  
  1426.  
  1427. // TODO:  implement the quota by number of emails!!
  1428.     function cmdSetQuota($mailbox_name$storageQuota = null ,$messagesQuota = null )
  1429.     {
  1430.         //Check if the IMAP server has QUOTA support
  1431.         if$this->hasQuotaSupport() ){
  1432.             return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1433.         }
  1434.  
  1435.         if( ($messagesQuota == null&& $storageQuota == null) ){
  1436.             return new PEAR_Error('$storageQuota and $messagesQuota parameters can\'t be both null if you want to use quota');
  1437.         }
  1438.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1439.         //Make the command request
  1440.         $param=sprintf("%s (",$mailbox_name);
  1441.         if($storageQuota != null ){
  1442.             $param=sprintf("%sSTORAGE %s",$param,$storageQuota);
  1443.             if$messagesQuota != null ){
  1444.                 //if we have both types of quota on the same call we must append an space between
  1445.                 // those parameters
  1446.                 $param=sprintf("%s ",$param);
  1447.             }
  1448.         }
  1449.         if($messagesQuota != null ){
  1450.             $param=sprintf("%sMESSAGES %s",$param,$messagesQuota);
  1451.  
  1452.         }
  1453.         $param=sprintf("%s)",$param);
  1454.  
  1455.         return $this->_genericCommand('SETQUOTA'$param );
  1456.     }
  1457.  
  1458.  
  1459.  
  1460.  
  1461.  
  1462.  
  1463.     function cmdSetQuotaRoot($mailbox_name$storageQuota = null ,$messagesQuota = null)
  1464.     {
  1465.         //Check if the IMAP server has QUOTA support
  1466.         if$this->hasQuotaSupport() ){
  1467.             return new PEAR_Error("This IMAP server does not support QUOTA's! ");
  1468.         }
  1469.  
  1470.         if( ($messagesQuota == null&& $storageQuota == null) ){
  1471.             return new PEAR_Error('$storageQuota and $messagesQuota parameters can\'t be both null if you want to use quota');
  1472.         }
  1473.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1474.         //Make the command request
  1475.         $param=sprintf("%s (",$mailbox_name);
  1476.         if($storageQuota != null ){
  1477.             $param=sprintf("%sSTORAGE %s",$param,$storageQuota);
  1478.             if$messagesQuota != null ){
  1479.                 //if we have both types of quota on the same call we must append an space between
  1480.                 // those parameters
  1481.                 $param=sprintf("%s ",$param);
  1482.             }
  1483.         }
  1484.         if($messagesQuota != null ){
  1485.             $param=sprintf("%sMESSAGES %s",$param,$messagesQuota);
  1486.  
  1487.         }
  1488.         $param=sprintf("%s)",$param);
  1489.  
  1490.         return $this->_genericCommand('SETQUOTAROOT'$param );
  1491.     }
  1492.  
  1493.  
  1494.  
  1495. /********************************************************************
  1496. ***             RFC2087 IMAP4 QUOTA extension ENDS HERE
  1497. ********************************************************************/
  1498.  
  1499.  
  1500.  
  1501.  
  1502.  
  1503.  
  1504. /********************************************************************
  1505. ***             RFC2086 IMAP4 ACL extension BEGINS HERE
  1506. ********************************************************************/
  1507.  
  1508.  
  1509.  
  1510.     function cmdSetACL($mailbox_name$user$acl)
  1511.     {
  1512.  
  1513.         //Check if the IMAP server has ACL support
  1514.         if$this->hasAclSupport() ){
  1515.             return new PEAR_Error("This IMAP server does not support ACL's! ");
  1516.         }
  1517.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1518.         $user_name=sprintf("\"%s\"",$this->utf_7_encode($user) );
  1519.         if(is_array($acl)){
  1520.             $acl=implode('',$acl);
  1521.         }
  1522.         return $this->_genericCommand('SETACL'sprintf("%s %s \"%s\"",$mailbox_name,$user_name,$acl) );
  1523.     }
  1524.  
  1525.  
  1526.  
  1527.  
  1528.  
  1529.  
  1530.     function cmdDeleteACL($mailbox_name$user)
  1531.     {
  1532.         //Check if the IMAP server has ACL support
  1533.         if$this->hasAclSupport() ){
  1534.             return new PEAR_Error("This IMAP server does not support ACL's! ");
  1535.         }
  1536.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1537.         if(is_array($acl)){
  1538.             $acl=implode('',$acl);
  1539.         }
  1540.  
  1541.         return $this->_genericCommand('DELETEACL'sprintf("%s \"%s\"",$mailbox_name,$user) );
  1542.     }
  1543.  
  1544.  
  1545.  
  1546.  
  1547.  
  1548.  
  1549.  
  1550.  
  1551.  
  1552.  
  1553.  
  1554.  
  1555.  
  1556.     function cmdGetACL($mailbox_name)
  1557.     {
  1558.         //Check if the IMAP server has ACL support
  1559.         if$this->hasAclSupport() ){
  1560.             return new PEAR_Error("This IMAP server does not support ACL's! ");
  1561.         }
  1562.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1563.         $ret $this->_genericCommand('GETACL'sprintf("%s",$mailbox_name) );
  1564.         if(isset$ret["PARSED") ){
  1565.             $ret['PARSED']=$ret["PARSED"][0]["EXT"];
  1566.  
  1567.         }
  1568.         return $ret;
  1569.    }
  1570.  
  1571.  
  1572.  
  1573.  
  1574.  
  1575.  
  1576.  
  1577.     function cmdListRights($mailbox_name$user)
  1578.     {
  1579.         //Check if the IMAP server has ACL support
  1580.         if$this->hasAclSupport() ){
  1581.             return new PEAR_Error("This IMAP server does not support ACL's! ");
  1582.         }
  1583.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1584.         $ret $this->_genericCommand('LISTRIGHTS'sprintf("%s \"%s\"",$mailbox_name,$user) );
  1585.         if(isset$ret["PARSED") ){
  1586.             $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  1587.         }
  1588.         return $ret;
  1589.     }
  1590.  
  1591.  
  1592.  
  1593.  
  1594.  
  1595.  
  1596.  
  1597.  
  1598.  
  1599.  
  1600.  
  1601.  
  1602.  
  1603.     function cmdMyRights($mailbox_name)
  1604.     {
  1605.         //Check if the IMAP server has ACL support
  1606.         if$this->hasAclSupport() ){
  1607.             return new PEAR_Error("This IMAP server does not support ACL's! ");
  1608.         }
  1609.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox_name) );
  1610.         $ret $this->_genericCommand('MYRIGHTS'sprintf("%s",$mailbox_name) );
  1611.         if(isset$ret["PARSED") ){
  1612.             $ret["PARSED"]=$ret["PARSED"][0]["EXT"];
  1613.         }
  1614.         return $ret;
  1615.     }
  1616.  
  1617.  
  1618. /********************************************************************
  1619. ***             RFC2086 IMAP4 ACL extension ENDs HERE
  1620. ********************************************************************/
  1621.  
  1622.  
  1623.  
  1624.  
  1625.  
  1626.  
  1627.  
  1628.  
  1629.  
  1630.  
  1631.  
  1632.  
  1633. /*******************************************************************************
  1634. ***  draft-daboo-imap-annotatemore-05 IMAP4 ANNOTATEMORE extension BEGINS HERE
  1635. ********************************************************************************/
  1636.  
  1637.  
  1638.  
  1639.     function cmdSetAnnotation($mailbox_name$entry$values)
  1640.     {
  1641.         // Check if the IMAP server has ANNOTATEMORE support
  1642.         if(!$this->hasAnnotateMoreSupport()) {
  1643.             return new PEAR_Error('This IMAP server does not support the ANNOTATEMORE extension!');
  1644.         }
  1645.         if (!is_array($values)) {
  1646.             return new PEAR_Error('Invalid $values argument passed to cmdSetAnnotation');
  1647.         }
  1648.  
  1649.         $vallist '';
  1650.         foreach ($values as $name => $value{
  1651.             $vallist .= "\"$name\" \"$value\" ";
  1652.         }
  1653.         $vallist rtrim($vallist);
  1654.  
  1655.         return $this->_genericCommand('SETANNOTATION'sprintf('"%s" "%s" (%s)'$mailbox_name$entry$vallist));
  1656.     }
  1657.  
  1658.  
  1659.  
  1660.  
  1661.  
  1662.  
  1663.  
  1664.  
  1665.  
  1666.  
  1667.  
  1668.  
  1669.  
  1670.     function cmdDeleteAnnotation($mailbox_name$entry$values)
  1671.     {
  1672.         // Check if the IMAP server has ANNOTATEMORE support
  1673.         if(!$this->hasAnnotateMoreSupport()) {
  1674.             return new PEAR_Error('This IMAP server does not support the ANNOTATEMORE extension!');
  1675.         }
  1676.         if (!is_array($values)) {
  1677.             return new PEAR_Error('Invalid $values argument passed to cmdDeleteAnnotation');
  1678.         }
  1679.  
  1680.         $vallist '';
  1681.         foreach ($values as $name{
  1682.             $vallist .= "\"$name\" NIL ";
  1683.         }
  1684.         $vallist rtrim($vallist);
  1685.  
  1686.         return $this->_genericCommand('SETANNOTATION'sprintf('"%s" "%s" (%s)'$mailbox_name$entry$vallist));
  1687.     }
  1688.  
  1689.  
  1690.  
  1691.  
  1692.  
  1693.  
  1694.  
  1695.  
  1696.  
  1697.  
  1698.  
  1699.  
  1700.     function cmdGetAnnotation($mailbox_name$entries$values)
  1701.     {
  1702.         // Check if the IMAP server has ANNOTATEMORE support
  1703.         if(!$this->hasAnnotateMoreSupport()) {
  1704.             return new PEAR_Error('This IMAP server does not support the ANNOTATEMORE extension!');
  1705.         }
  1706.  
  1707.         $entlist '';
  1708.  
  1709.        if (!is_array($entries)) {
  1710.             $entries = array($entries);
  1711.        }
  1712.  
  1713.         foreach ($entries as $name{
  1714.             $entlist .= "\"$name\" ";
  1715.         }
  1716.         $entlist rtrim($entlist);
  1717.         if (count($entries> 1{
  1718.             $entlist = "($entlist)";
  1719.         }
  1720.  
  1721.  
  1722.  
  1723.         $vallist '';
  1724.         if (!is_array($values)) {
  1725.             $values = array($values);
  1726.         }
  1727.  
  1728.         foreach ($values as $name{
  1729.             $vallist .= "\"$name\" ";
  1730.         }
  1731.         $vallist rtrim($vallist);
  1732.         if (count($values> 1{
  1733.             $vallist = "($vallist)";
  1734.         }
  1735.  
  1736.         return $this->_genericCommand('GETANNOTATION'sprintf('"%s" %s %s'$mailbox_name$entlist$vallist));
  1737.    }
  1738.  
  1739.  
  1740. /*****************************************************************************
  1741. ***  draft-daboo-imap-annotatemore-05 IMAP4 ANNOTATEMORE extension ENDs HERE
  1742. ******************************************************************************/
  1743.  
  1744.  
  1745.  
  1746.  
  1747.  
  1748.  
  1749.  
  1750. /********************************************************************
  1751. ***
  1752. ***             HERE ENDS THE EXTENSIONS FUNCTIONS
  1753. ***             AND BEGIN THE AUXILIARY FUNCTIONS
  1754. ***
  1755. ********************************************************************/
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.     /**
  1762.     * tell if the server has capability $capability
  1763.     *
  1764.     * @return true or false
  1765.     *
  1766.     * @access public
  1767.     * @since  1.0
  1768.     */
  1769.     function getServerAuthMethods()
  1770.     {
  1771.         if$this->_serverAuthMethods == null ){
  1772.             $this->cmdCapability();
  1773.             return $this->_serverAuthMethods;
  1774.         }
  1775.         return false;
  1776.     }
  1777.  
  1778.  
  1779.  
  1780.  
  1781.  
  1782.  
  1783.  
  1784.     /**
  1785.     * tell if the server has capability $capability
  1786.     *
  1787.     * @return true or false
  1788.     *
  1789.     * @access public
  1790.     * @since  1.0
  1791.     */
  1792.     function hasCapability($capability)
  1793.     {
  1794.         if$this->_serverSupportedCapabilities == null ){
  1795.             $this->cmdCapability();
  1796.         }
  1797.         if($this->_serverSupportedCapabilities != null ){
  1798.             ifin_array$capability $this->_serverSupportedCapabilities ) ){
  1799.                 return true;
  1800.             }
  1801.         }
  1802.         return false;
  1803.     }
  1804.  
  1805.  
  1806.  
  1807.     /**
  1808.     * tell if the server has Quota support
  1809.     *
  1810.     * @return true or false
  1811.     *
  1812.     * @access public
  1813.     * @since  1.0
  1814.     */
  1815.     function hasQuotaSupport()
  1816.     {
  1817.         return $this->hasCapability('QUOTA');
  1818.     }
  1819.  
  1820.  
  1821.  
  1822.  
  1823.  
  1824.     /**
  1825.     * tell if the server has Quota support
  1826.     *
  1827.     * @return true or false
  1828.     *
  1829.     * @access public
  1830.     * @since  1.0
  1831.     */
  1832.     function hasAclSupport()
  1833.     {
  1834.         return $this->hasCapability('ACL');
  1835.     }
  1836.  
  1837.  
  1838.  
  1839.  
  1840.  
  1841.     /**
  1842.     * tell if the server has support for the ANNOTATEMORE extension
  1843.     *
  1844.     * @return true or false
  1845.     *
  1846.     * @access public
  1847.     * @since  1.0
  1848.     */
  1849.     function hasAnnotateMoreSupport()
  1850.     {
  1851.         return $this->hasCapability('ANNOTATEMORE');
  1852.     }
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.  
  1859.  
  1860.  
  1861.  
  1862.  
  1863.     /**
  1864.     * Parses the responses like RFC822.SIZE and INTERNALDATE
  1865.     *
  1866.     * @param string the IMAP's server response
  1867.     *
  1868.     * @return string containing  the parsed response
  1869.     * @access private
  1870.     * @since  1.0
  1871.     */
  1872.  
  1873.     function _parseOneStringResponse(&$str$line,$file)
  1874.     {
  1875.         $this->_parseSpace($str $line $file );
  1876.         $size $this->_getNextToken($str,$uid);
  1877.         return $uid;
  1878.     }
  1879.  
  1880.  
  1881.     /**
  1882.     * Parses the FLAG response
  1883.     *
  1884.     * @param string the IMAP's server response
  1885.     *
  1886.     * @return Array containing  the parsed  response
  1887.     * @access private
  1888.     * @since  1.0
  1889.     */
  1890.     function _parseFLAGSresponse(&$str)
  1891.     {
  1892.         $this->_parseSpace($str __LINE__ __FILE__ );
  1893.         $params_arr[$this->_arrayfy_content($str);
  1894.         $flags_arr=array();
  1895.         for$i = 0 ; $i count($params_arr[0]$i++ ){
  1896.             $flags_arr[$params_arr[0][$i];
  1897.         }
  1898.         return $flags_arr;
  1899.     }
  1900.  
  1901.  
  1902.  
  1903.  
  1904.  
  1905.     /**
  1906.     * Parses the BODY response
  1907.     *
  1908.     * @param string the IMAP's server response
  1909.     *
  1910.     * @return Array containing  the parsed  response
  1911.     * @access private
  1912.     * @since  1.0
  1913.     */
  1914.  
  1915.     function _parseBodyResponse(&$str$command){
  1916.  
  1917.             $this->_parseSpace($str __LINE__ __FILE__ );
  1918.             while($str[0!= ')' && $str!=''){
  1919.                 $params_arr[$this->_arrayfy_content($str);
  1920.             }
  1921.  
  1922.             return $params_arr;
  1923.     }
  1924.  
  1925.  
  1926.  
  1927.  
  1928.  
  1929.  
  1930.     /**
  1931.     * Makes the content an Array
  1932.     *
  1933.     * @param string the IMAP's server response
  1934.     *
  1935.     * @return Array containing  the parsed  response
  1936.     * @access private
  1937.     * @since  1.0
  1938.     */
  1939.     function _arrayfy_content(&$str)
  1940.     {
  1941.         $params_arr=array();
  1942.         $this->_getNextToken($str,$params);
  1943.         if($params != '(' ){
  1944.             return $params;
  1945.         }
  1946.         $this->_getNextToken($str,$params,false,false);
  1947.         while $str != '' && $params != ')'){
  1948.                 if($params != '' ){
  1949.                     if($params[0== '(' ){
  1950.                         $params=$this->_arrayfy_content$params );
  1951.                     }
  1952.                     if($params != ' ' ){
  1953.                         //I don't remove the colons (") to handle the case of retriving " "
  1954.                         // If I remove the colons the parser will interpret this field as an imap separator (space)
  1955.                         // instead of a valid field so I remove the colons here
  1956.                         if($params=='""'){
  1957.                             $params='';
  1958.                         }else{
  1959.                             if($params[0]=='"'){
  1960.                                 $params=substr($params,1,strlen($params)-2);
  1961.                             }
  1962.                         }
  1963.                         $params_arr[]=$params;
  1964.                     }
  1965.                 }else{
  1966.                     //if params if empty (for example i'm parsing 2 quotes ("")
  1967.                     // I'll append an array entry to mantain compatibility
  1968.                     $params_arr[]=$params;
  1969.                 }
  1970.                 $this->_getNextToken($str,$params,false,false);
  1971.         }
  1972.         return $params_arr;
  1973.     }
  1974.  
  1975.  
  1976.  
  1977.  
  1978.     /**
  1979.     * Parses the BODY[],BODY[TEXT],.... responses
  1980.     *
  1981.     * @param string the IMAP's server response
  1982.     *
  1983.     * @return Array containing  the parsed  response
  1984.     * @access private
  1985.     * @since  1.0
  1986.     */
  1987.     function _parseContentresponse(&$str$command)
  1988.     {
  1989.         $content '';
  1990.         $this->_parseSpace($str __LINE__ __FILE__ );
  1991.         $size  =$this->_getNextToken($str,$content);
  1992.         return array"CONTENT"=> $content "CONTENT_SIZE" =>$size );
  1993.     }
  1994.  
  1995.  
  1996.  
  1997.  
  1998.  
  1999.  
  2000.  
  2001.  
  2002.     /**
  2003.     * Parses the ENVELOPE response
  2004.     *
  2005.     * @param string the IMAP's server response
  2006.     *
  2007.     * @return Array containing  the parsed  response
  2008.     * @access private
  2009.     * @since  1.0
  2010.     */
  2011.     function _parseENVELOPEresponse(&$str)
  2012.     {
  2013.         $content '';
  2014.         $this->_parseSpace($str __LINE__ __FILE__ );
  2015.  
  2016.         $this->_getNextToken($str,$parenthesis);
  2017.         if$parenthesis != '(' ){
  2018.                 $this->_prot_error("must be a '(' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  2019.         }
  2020.         // Get the email's Date
  2021.         $this->_getNextToken($str,$date);
  2022.  
  2023.         $this->_parseSpace($str __LINE__ __FILE__ );
  2024.  
  2025.         // Get the email's Subject:
  2026.         $this->_getNextToken($str,$subject);
  2027.         //$subject=$this->decode($subject);
  2028.  
  2029.         $this->_parseSpace($str __LINE__ __FILE__ );
  2030.  
  2031.         //FROM LIST;
  2032.         $from_arr $this->_getAddressList($str);
  2033.  
  2034.         $this->_parseSpace($str __LINE__ __FILE__ );
  2035.  
  2036.         //"SENDER LIST\n";
  2037.         $sender_arr $this->_getAddressList($str);
  2038.  
  2039.         $this->_parseSpace($str __LINE__ __FILE__ );
  2040.  
  2041.         //"REPLY-TO LIST\n";
  2042.         $reply_to_arr=$this->_getAddressList($str);
  2043.  
  2044.         $this->_parseSpace($str __LINE__ __FILE__ );
  2045.  
  2046.         //"TO LIST\n";
  2047.         $to_arr $this->_getAddressList($str);
  2048.  
  2049.         $this->_parseSpace($str __LINE__ __FILE__ );
  2050.  
  2051.         //"CC LIST\n";
  2052.         $cc_arr $this->_getAddressList($str);
  2053.  
  2054.         $this->_parseSpace($str __LINE__ __FILE__ );
  2055.  
  2056.         //"BCC LIST|$str|\n";
  2057.         $bcc_arr $this->_getAddressList($str);
  2058.  
  2059.         $this->_parseSpace($str __LINE__ __FILE__ );
  2060.  
  2061.         $this->_getNextToken($str,$in_reply_to);
  2062.  
  2063.         $this->_parseSpace($str __LINE__ __FILE__ );
  2064.  
  2065.         $this->_getNextToken($str,$message_id);
  2066.  
  2067.         $this->_getNextToken($str,$parenthesis);
  2068.  
  2069.         if$parenthesis != ')' ){
  2070.             $this->_prot_error("must be a ')' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  2071.         }
  2072.  
  2073.         return array"DATE"=> $date "SUBJECT" => $subject,"FROM" => $from_arr,
  2074.             "SENDER" => $sender_arr "REPLY_TO" => $reply_to_arr"TO" => $to_arr,
  2075.             "CC" =>$cc_arr"BCC"=> $bcc_arr"IN_REPLY_TO" =>$in_reply_to"MESSAGE_ID"=>$message_id  );
  2076.     }
  2077.  
  2078.  
  2079.  
  2080.  
  2081.  
  2082.     /**
  2083.     * Parses the ARRDLIST as defined in RFC
  2084.     *
  2085.     * @param string the IMAP's server response
  2086.     *
  2087.     * @return Array containing  the parsed  response
  2088.     * @access private
  2089.     * @since  1.0
  2090.     */
  2091.     function _getAddressList(&$str)
  2092.     {
  2093.         $params_arr $this->_arrayfy_content($str);
  2094.         if!isset$params_arr ) ){
  2095.             return $params_arr;
  2096.         }
  2097.  
  2098.  
  2099.         ifis_array($params_arr) ){
  2100.             $personal_name  $params_arr[0][0];
  2101.             $at_domain_list $params_arr[0][1];
  2102.             $mailbox_name   $params_arr[0][2];
  2103.             $host_name      $params_arr[0][3];
  2104.             if$mailbox_name!='' && $host_name!='' ){
  2105.                 $email=$mailbox_name "@" $host_name;
  2106.             }else{
  2107.                 $email=false;
  2108.             }
  2109.             if($email==false){
  2110.                 $rfc822_email=false;
  2111.             }else{
  2112.                 if(!isset($personal_name)){
  2113.                     $rfc822_email"<"$email ">";
  2114.                 }else{
  2115.                     $rfc822_email"\""$personal_name ."\" <"$email ">";
  2116.                 }
  2117.             }
  2118.             $email_arr[= array "PERSONAL_NAME"=> $personal_name "AT_DOMAIN_LIST"=>$at_domain_list ,
  2119.                                    "MAILBOX_NAME"=> $this->utf_7_decode($mailbox_name)"HOST_NAME"=> $host_name,
  2120.                                    "EMAIL"=>$email "RFC822_EMAIL" => $rfc822_email );
  2121.             return $email_arr;
  2122.         }
  2123.  
  2124.         return array();
  2125.     }
  2126.  
  2127.  
  2128.  
  2129.  
  2130.  
  2131.  
  2132.  
  2133.     /**
  2134.     * Utility funcion to find the closing parenthesis ")" Position it takes care of quoted ones
  2135.     *
  2136.     * @param string the IMAP's server response
  2137.     *
  2138.     * @return int containing  the pos of the closing parenthesis ")"
  2139.     * @access private
  2140.     * @since  1.0
  2141.     */
  2142.     function _getClosingBracesPos($str_line$startDelim ='('$stopDelim ')' )
  2143.     {
  2144.         $len strlen$str_line );
  2145.         $pos = 0;
  2146.         // ignore all extra characters
  2147.         // If inside of a string, skip string -- Boundary IDs and other
  2148.         // things can have ) in them.
  2149.         if $str_line[$pos!= $startDelim {
  2150.             $this->_prot_error("_getClosingParenthesisPos: must start with a '(' but is a '"$str_line[$pos."'!!!!\n" .
  2151.                 "STR_LINE:$str_line|size:$len|POS: $pos\n__LINE__ __FILE__ );
  2152.             return$len );
  2153.         }
  2154.         for$pos = 1 ; $pos $len $pos++ ){
  2155.             if ($str_line[$pos== $stopDelim {
  2156.                 break;
  2157.             }
  2158.             if ($str_line[$pos== '"'{
  2159.                 $pos++;
  2160.                 while $str_line[$pos!= '"' && $pos $len {
  2161.                     if ($str_line[$pos== "\\" && $str_line[$pos + 1 == '"' )
  2162.                         $pos++;
  2163.                     if ($str_line[$pos== "\\" && $str_line[$pos + 1 == "\\" )
  2164.                         $pos++;
  2165.                     $pos++;
  2166.                 }
  2167.             }
  2168.             if $str_line[$pos== $startDelim {
  2169.                 $str_line_aux substr$str_line $pos );
  2170.                 $pos_aux $this->_getClosingBracesPos$str_line_aux );
  2171.                 $pos+=$pos_aux;
  2172.             }
  2173.         }
  2174.         if$str_line[$pos!= $stopDelim ){
  2175.             $this->_prot_error("_getClosingBracesPos: must be a $stopDelim but is a '". $str_line[$pos."'|POS:$pos|STR_LINE:$str_line!!!!__LINE__ __FILE__ );
  2176.         }
  2177.  
  2178.         if$pos >= $len )
  2179.             return false;
  2180.         return $pos;
  2181.     }
  2182.  
  2183.  
  2184.  
  2185.  
  2186.  
  2187.  
  2188.     /**
  2189.     * Utility funcion to get from here to the end of the line
  2190.     *
  2191.     * @param string the IMAP's server response
  2192.     *
  2193.     * @return string containing  the string to the end of the line
  2194.     * @access private
  2195.     * @since  1.0
  2196.     */
  2197.  
  2198.     function _getToEOL(&$str $including = true)
  2199.     {
  2200.         $len strlen$str );
  2201.         if$including ){
  2202.             for($i=0;$i<$len;$i++){
  2203.                 if$str[$i=="\n" )
  2204.                     break;
  2205.             }
  2206.             $content=substr($str,0,$i + 1);
  2207.             $str=substr($str,$i + 1);
  2208.             return $content;
  2209.  
  2210.         }else{
  2211.             for$i = 0 ; $i $len $i++ ){
  2212.                 if$str[$i=="\n" || $str[$i== "\r")
  2213.                     break;
  2214.             }
  2215.             $content substr$str ,$i );
  2216.             $str substr$str $i );
  2217.             return $content;
  2218.         }
  2219.     }
  2220.  
  2221.  
  2222.  
  2223.  
  2224.     /**
  2225.     * Fetches the next IMAP token or parenthesis
  2226.     *
  2227.     * @param string the IMAP's server response
  2228.     * @param string the next token
  2229.     * @param boolean true: the parenthesis IS a token, false: I consider
  2230.     *         all the response in parenthesis as a token
  2231.     *
  2232.     * @return int containing  the content size
  2233.     * @access private
  2234.     * @since  1.0
  2235.     */
  2236.  
  2237.  
  2238.     function _getNextToken(&$str&$content$parenthesisIsToken=true,$colonIsToken=true){
  2239.         $len strlen($str);
  2240.         $pos = 0;
  2241.         $content_size = false;
  2242.         $content = false;
  2243.         if($str == '' || $len < 2 ){
  2244.             $content=$str;
  2245.             return $len;
  2246.         }
  2247.         switch$str[0){
  2248.         case '{':
  2249.             if( ($posClosingBraces $this->_getClosingBracesPos($str'{' '}' )) == false ){
  2250.                 $this->_prot_error("_getClosingBracesPos() error!!!" __LINE__ __FILE__ );
  2251.             }
  2252.             if(is_numeric( ( $strBytes substr$str $posClosingBraces - 1) ) ) ){
  2253.                 $this->_prot_error("must be a number but is a '" $strBytes ."'!!!!" __LINE__ __FILE__ );
  2254.             }
  2255.             if$str[$posClosingBraces!= '}' ){
  2256.                 $this->_prot_error("must be a '}'  but is a '" $str[$posClosingBraces."'!!!!" __LINE__ __FILE__ );
  2257.             }
  2258.             if$str[$posClosingBraces + 1!= "\r" ){
  2259.                 $this->_prot_error("must be a '\\r'  but is a '" $str[$posClosingBraces + 1."'!!!!" __LINE__ __FILE__ );
  2260.             }
  2261.             if$str[$posClosingBraces + 2!= "\n" ){
  2262.                 $this->_prot_error("must be a '\\n'  but is a '" $str[$posClosingBraces + 2."'!!!!" __LINE__ __FILE__ );
  2263.             }
  2264.             $content substr$str $posClosingBraces + 3 $strBytes );
  2265.             ifstrlen$content != $strBytes ){
  2266.                 $this->_prot_error("content size is "strlen($content. " but the string reports a size of $strBytes!!!\n__LINE__ __FILE__ );
  2267.             }
  2268.             $content_size $strBytes;
  2269.             //Advance the string
  2270.             $str substr$str $posClosingBraces $strBytes + 3 );
  2271.             break;
  2272.         case '"':
  2273.             if($colonIsToken){
  2274.                 for($pos=1;$pos<$len;$pos++){
  2275.                     if $str[$pos== "\"" {
  2276.                         break;
  2277.                     }
  2278.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\"" )
  2279.                         $pos++;
  2280.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\\" )
  2281.                         $pos++;
  2282.                 }
  2283.                 if($str[$pos!= '"' ){
  2284.                     $this->_prot_error("must be a '\"'  but is a '" $str[$pos."'!!!!" __LINE__ __FILE__ );
  2285.                 }
  2286.                 $content_size $pos;
  2287.                 $content substr$str $pos - 1 );
  2288.                 //Advance the string
  2289.                 $str substr$str $pos + 1 );
  2290.             }else{
  2291.                 for($pos=1;$pos<$len;$pos++){
  2292.                     if $str[$pos== "\"" {
  2293.                         break;
  2294.                     }
  2295.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\"" )
  2296.                         $pos++;
  2297.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\\" )
  2298.                         $pos++;
  2299.                 }
  2300.                 if($str[$pos!= '"' ){
  2301.                     $this->_prot_error("must be a '\"'  but is a '" $str[$pos."'!!!!" __LINE__ __FILE__ );
  2302.                 }
  2303.                 $content_size $pos;
  2304.                 $content substr$str $pos + 1 );
  2305.                 //Advance the string
  2306.                 $str substr$str $pos + 1 );
  2307.  
  2308.             }
  2309.             break;
  2310.  
  2311.         case "\r":
  2312.             $pos = 1;
  2313.             if$str[1== "\n")
  2314.                 $pos++;
  2315.             $content_size $pos;
  2316.             $content substr$str $pos );
  2317.             $str substr$str $pos );
  2318.             break;
  2319.         case "\n":
  2320.             $pos = 1;
  2321.             $content_size $pos;
  2322.             $content substr$str $pos );
  2323.             $str substr$str $pos );
  2324.             break;
  2325.         case '(':
  2326.             if$parenthesisIsToken == false ){
  2327.                 $pos $this->_getClosingBracesPos$str );
  2328.                 $content_size $pos + 1;
  2329.                 $content substr$str $pos + 1 );
  2330.                 $str substr$str $pos + 1 );
  2331.             }else{
  2332.                 $pos = 1;
  2333.                 $content_size $pos;
  2334.                 $content substr$str $pos );
  2335.                 $str substr$str $pos );
  2336.             }
  2337.             break;
  2338.         case ')':
  2339.             $pos = 1;
  2340.             $content_size $pos;
  2341.             $content substr$str $pos );
  2342.             $str substr$str $pos );
  2343.             break;
  2344.         case ' ':
  2345.             $pos = 1;
  2346.             $content_size $pos;
  2347.             $content substr$str $pos );
  2348.             $str substr$str $pos );
  2349.             break;
  2350.         default:
  2351.             for$pos = 0 ; $pos $len $pos++ ){
  2352.                 if $str[$pos== ' ' || $str[$pos== "\r" || $str[$pos== ')' || $str[$pos== '(' || $str[$pos== "\n" {
  2353.                     break;
  2354.                 }
  2355.                 if $str[$pos== "\\" && $str[$pos + 1 == ' '  )
  2356.                     $pos++;
  2357.                 if $str[$pos== "\\" && $str[$pos + 1 == "\\" )
  2358.                     $pos++;
  2359.             }
  2360.             //Advance the string
  2361.             if$pos == 0 ){
  2362.                 $content_size = 1;
  2363.                 $content substr$str );
  2364.                 $str substr$str );
  2365.             }else{
  2366.                 $content_size $pos;
  2367.                 $content substr$str $pos );
  2368.                 if($pos $len){
  2369.                     $str substr$str $pos  );
  2370.                 }else{
  2371.                 //if this is the end of the string... exit the switch
  2372.                     break;
  2373.                 }
  2374.  
  2375.  
  2376.             }
  2377.             break;
  2378.         }
  2379.         return $content_size;
  2380.     }
  2381.  
  2382.  
  2383.  
  2384.  
  2385.  
  2386.  
  2387.     /**
  2388.     * Utility funcion to display to console the protocol errors
  2389.     *
  2390.     * @param string the error
  2391.     * @param int the line producing the error
  2392.     * @param string file where the error was produced
  2393.     *
  2394.     * @return string containing  the error
  2395.     * @access private
  2396.     * @since  1.0
  2397.     */
  2398.     function _prot_error($str $line $file,$printError=true)
  2399.     {
  2400.         if($printError){
  2401.             echo "$line,$file,PROTOCOL ERROR!:$str\n";
  2402.         }
  2403.     }
  2404.  
  2405.  
  2406.  
  2407.  
  2408.  
  2409.  
  2410.  
  2411.     function _getEXTarray(&$str $startDelim '(' $stopDelim ')'){
  2412.         /* I let choose the $startDelim  and $stopDelim to allow parsing
  2413.            the OK response  so I also can parse a response like this
  2414.            * OK [UIDNEXT 150] Predicted next UID
  2415.         */
  2416.         $this->_getNextToken$str $parenthesis );
  2417.         if$parenthesis != $startDelim ){
  2418.             $this->_prot_error("must be a '$startDelim' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  2419.         }
  2420.         $parenthesis '';
  2421.         $struct_arr = array();
  2422.         while$parenthesis != $stopDelim && $str != '' ){
  2423.             // The command
  2424.             $this->_getNextToken$str $token );
  2425.             $token strtoupper$token );
  2426.  
  2427.             if( ( $ret $this->_retrParsedResponse$str $token ) ) != false ){
  2428.                 //$struct_arr[$token] = $ret;
  2429.                 $struct_arr=array_merge($struct_arr$ret);
  2430.             }
  2431.  
  2432.             $parenthesis=$token;
  2433.  
  2434.         }//While
  2435.  
  2436.        if$parenthesis != $stopDelim  ){
  2437.             $this->_prot_error("1_must be a '$stopDelim' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  2438.        }
  2439.         return $struct_arr;
  2440.     }
  2441.  
  2442.  
  2443.  
  2444.  
  2445.  
  2446.     function _retrParsedResponse&$str $token$previousToken = null)
  2447.     {
  2448.  
  2449.     //echo "\n\nTOKEN:$token\r\n";
  2450.         switch$token ){
  2451.         case "RFC822.SIZE" :
  2452.             return array($token=>$this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2453.             break;
  2454. //        case "RFC822.TEXT" :
  2455.  
  2456. //        case "RFC822.HEADER" :
  2457.  
  2458.  
  2459.         case "RFC822" :
  2460.             return array($token=>$this->_parseContentresponse$str $token ));
  2461.             break;
  2462.         case "FLAGS" :
  2463.  
  2464.         case "PERMANENTFLAGS" :
  2465.             return array($token=>$this->_parseFLAGSresponse$str ));
  2466.             break;
  2467.  
  2468.         case "ENVELOPE" :
  2469.             return array($token=>$this->_parseENVELOPEresponse$str ));
  2470.             break;
  2471.         case "EXPUNGE" :
  2472.             return false;
  2473.             break;
  2474.  
  2475.         case "UID" :
  2476.  
  2477.         case "UIDNEXT" :
  2478.  
  2479.         case "UIDVALIDITY" :
  2480.  
  2481.         case "UNSEEN" :
  2482.  
  2483.         case "MESSAGES" :
  2484.  
  2485.         case "UIDNEXT" :
  2486.  
  2487.         case "UIDVALIDITY" :
  2488.  
  2489.         case "UNSEEN" :
  2490.  
  2491.         case "INTERNALDATE" :
  2492.             return array($token=>$this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2493.             break;
  2494.         case "BODY" :
  2495.  
  2496.         case "BODYSTRUCTURE" :
  2497.             return array($token=>$this->_parseBodyResponse$str $token ));
  2498.             break;
  2499.         case "RECENT" :
  2500.             if$previousToken != null ){
  2501.                 $aux["RECENT"]=$previousToken;
  2502.                 return $aux;
  2503.             }else{
  2504.                 return array($token=>$this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2505.             }
  2506.             break;
  2507.  
  2508.         case "EXISTS" :
  2509.             return array($token=>$previousToken);
  2510.             break;
  2511.         case "READ-WRITE" :
  2512.  
  2513.         case "READ-ONLY" :
  2514.             return array($token=>$token);
  2515.             break;
  2516.         case "QUOTA" :
  2517.             /*
  2518.             A tipical GETQUOTA DIALOG IS AS FOLLOWS
  2519.  
  2520.                 C: A0004 GETQUOTA user.damian
  2521.                 S: * QUOTA user.damian (STORAGE 1781460 4000000)
  2522.                 S: A0004 OK Completed
  2523.             */
  2524.  
  2525.             $mailbox $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2526.             $this->_parseSpace$str __LINE__ __FILE__ );
  2527.             $this->_parseString$str '(' __LINE__ __FILE__ );
  2528.  
  2529.             $ret_aux = array("MAILBOX"=>$this->utf_7_decode($mailbox) );
  2530.             $this->_getNextToken$str $quota_resp );
  2531.             if( ( $ext $this->_retrParsedResponse$str $quota_resp )) == false){
  2532.                     $this->_prot_error("bogus response!!!!" __LINE__ __FILE__ );
  2533.             }
  2534.             $ret_aux=array_merge($ret_aux,$ext);
  2535.  
  2536.             $this->_getNextToken$str $separator );
  2537.             if$separator == ')' ){
  2538.                 return array($token=>$ret_aux);
  2539.             }
  2540.  
  2541.  
  2542.             $this->_parseSpace$str __LINE__ __FILE__ );
  2543.  
  2544.             $this->_getNextToken$str $quota_resp );
  2545.             if( ( $ext $this->_retrParsedResponse$str $quota_resp )) == false){
  2546.                     $this->_prot_error("bogus response!!!!" __LINE__ __FILE__ );
  2547.             }
  2548.             $ret_aux=array_merge($ret_aux,$ext);
  2549.  
  2550.             $this->_parseString$str ')' __LINE__ __FILE__ );
  2551.             return array($token=>$ret_aux);
  2552.             break;
  2553.  
  2554.         case "QUOTAROOT" :
  2555.             /*
  2556.             A tipical GETQUOTA DIALOG IS AS FOLLOWS
  2557.  
  2558.                 C: A0004 GETQUOTA user.damian
  2559.                 S: * QUOTA user.damian (STORAGE 1781460 4000000)
  2560.                 S: A0004 OK Completed
  2561.             */
  2562.             $mailbox $this->utf_7_decode($this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2563.  
  2564.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2565.  
  2566.             $quotaroot $this->_parseOneStringResponse$str_line,__LINE__ __FILE__ );
  2567.             $ret @array"MAILBOX"=>$this->utf_7_decode($mailbox$token=>$quotaroot );
  2568.             return array($token=>$ret);
  2569.             break;
  2570.         case "STORAGE" :
  2571.                 $used $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2572.                 $qmax $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2573.                 return array($token=>array("USED"=> $used"QMAX" => $qmax));
  2574.         break;
  2575.         case "MESSAGE" :
  2576.                 $mused $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2577.                 $mmax $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2578.                 return array($token=>array("MUSED"=> $mused"MMAX" => $mmax));
  2579.         break;
  2580.         case "FETCH" :
  2581.                 $this->_parseSpace$str  ,__LINE__  ,__FILE__ );
  2582.                 // Get the parsed pathenthesis
  2583.                 $struct_arr $this->_getEXTarray$str );
  2584.                 return $struct_arr;
  2585.             break;
  2586.         case "CAPABILITY" :
  2587.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2588.                 $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2589.                 $struct_arr["CAPABILITIES"explode' ' $str_line );
  2590.                 return array($token=>$struct_arr);
  2591.             break;
  2592.         case "STATUS" :
  2593.                 $mailbox $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2594.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2595.                 $ext $this->_getEXTarray$str );
  2596.                 $struct_arr["MAILBOX"$this->utf_7_decode($mailbox);
  2597.                 $struct_arr["ATTRIBUTES"$ext;
  2598.                 return array($token=>$struct_arr);
  2599.             break;
  2600.         case "LIST" :
  2601.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2602.                 $params_arr $this->_arrayfy_content$str );
  2603.  
  2604.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2605.                 $this->_getNextToken$str $hierarchydelim );
  2606.  
  2607.                 $this->_parseSpace$str,__LINE__ __FILE__);
  2608.                 $this->_getNextToken$str $mailbox_name );
  2609.  
  2610.                 $result_array = array"NAME_ATTRIBUTES"=>$params_arr "HIERACHY_DELIMITER"=>$hierarchydelim "MAILBOX_NAME"=>  $this->utf_7_decode($mailbox_name) );
  2611.                 return array($token=>$result_array);
  2612.             break;
  2613.         case "LSUB" :
  2614.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2615.                 $params_arr $this->_arrayfy_content$str );
  2616.  
  2617.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2618.                 $this->_getNextToken$str $hierarchydelim );
  2619.  
  2620.                 $this->_parseSpace$str,__LINE__ __FILE__);
  2621.                 $this->_getNextToken$str $mailbox_name );
  2622.  
  2623.                 $result_array = array"NAME_ATTRIBUTES"=>$params_arr "HIERACHY_DELIMITER"=>$hierarchydelim "MAILBOX_NAME"=> $this->utf_7_decode($mailbox_name) );
  2624.                 return array($token=>$result_array);
  2625.             break;
  2626.  
  2627.             case "SEARCH" :
  2628.                 $str_line rtrimsubstr$this->_getToEOL$str false 1) );
  2629.                 $struct_arr["SEARCH_LIST"explode' ' $str_line );
  2630.                 if(count($struct_arr["SEARCH_LIST"]== 1 && $struct_arr["SEARCH_LIST"][0]==''){
  2631.                     $struct_arr["SEARCH_LIST"]=null;
  2632.                 }
  2633.                 return array($token=>$struct_arr);
  2634.             break;
  2635.             case "OK" :
  2636.                 /* TODO:
  2637.                     parse the [ .... ] part of the response, use the method
  2638.                     _getEXTarray(&$str,'[',$stopDelim=']')
  2639.  
  2640.                 */
  2641.                 $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2642.                 if($str_line[0== '[' ){
  2643.                     $braceLen=$this->_getClosingBracesPos($str_line'['']' );
  2644.                     $str_aux='('substr($str_line,1,$braceLen -1)')';
  2645.                     $ext_arr=$this->_getEXTarray($str_aux);
  2646.                     //$ext_arr=array($token=>$this->_getEXTarray($str_aux));
  2647.                 }else{
  2648.                     $ext_arr=$str_line;
  2649.                     //$ext_arr=array($token=>$str_line);
  2650.                 }
  2651.                 $result_array =  $ext_arr;
  2652.                 return $result_array;
  2653.                 break;
  2654.         case "NO" :
  2655.         /* TODO:
  2656.             parse the [ .... ] part of the response, use the method
  2657.             _getEXTarray(&$str,'[',$stopDelim=']')
  2658.  
  2659.         */
  2660.  
  2661.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2662.             $result_array[@array"COMMAND"=>$token "EXT"=>$str_line );
  2663.             return $result_array;
  2664.             break;
  2665.         case "BAD" :
  2666.         /* TODO:
  2667.             parse the [ .... ] part of the response, use the method
  2668.             _getEXTarray(&$str,'[',$stopDelim=']')
  2669.  
  2670.         */
  2671.  
  2672.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2673.             $result_array[= array"COMMAND"=>$token "EXT"=>$str_line );
  2674.             return $result_array;
  2675.             break;
  2676.         case "BYE" :
  2677.         /* TODO:
  2678.             parse the [ .... ] part of the response, use the method
  2679.             _getEXTarray(&$str,'[',$stopDelim=']')
  2680.  
  2681.         */
  2682.  
  2683.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2684.             $result_array[= array"COMMAND"=>$command "EXT"=> $str_line );
  2685.             return $result_array;
  2686.             break;
  2687.  
  2688.         case "LISTRIGHTS" :
  2689.                 $this->_parseSpace$str ,__LINE__ __FILE__ );
  2690.                 $this->_getNextToken$str $mailbox );
  2691.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2692.                 $this->_getNextToken$str $user );
  2693.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2694.                 $this->_getNextToken$str $granted );
  2695.  
  2696.                 $ungranted explode' ' rtrimsubstr$this->_getToEOL$str false ) ) );
  2697.  
  2698.                 $result_array @array"MAILBOX"=>$this->utf_7_decode($mailbox"USER"=>$user "GRANTED"=>$granted "UNGRANTED"=>$ungranted );
  2699.                 return $result_array;
  2700.             break;
  2701.  
  2702.         case "MYRIGHTS" :
  2703.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2704.                 $this->_getNextToken$str ,$mailbox );
  2705.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2706.                 $this->_getNextToken$str $granted );
  2707.  
  2708.                 $result_array = array"MAILBOX"=>$this->utf_7_decode($mailbox"GRANTED"=>$granted );
  2709.                 return $result_array;
  2710.             break;
  2711.  
  2712.         case "ACL" :
  2713.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2714.                 $this->_getNextToken$str $mailbox );
  2715.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2716.                 $acl_arr explode' ' rtrimsubstr$this->_getToEOL$str false ) ) );
  2717.  
  2718.                 for$i = 0 ; $i count$acl_arr $i += 2 ){
  2719.                     $arr[= array"USER"=>$acl_arr[$i"RIGHTS"=>$acl_arr$i + 1 );
  2720.                 }
  2721.  
  2722.                 $result_array = array"MAILBOX"=>$this->utf_7_decode($mailbox"USERS"=>$arr );
  2723.                 return $result_array;
  2724.             break;
  2725.  
  2726.         case "ANNOTATION" :
  2727.                 $this->_parseSpace($str__LINE____FILE__);
  2728.                 $this->_getNextToken($str$mailbox);
  2729.  
  2730.                 $this->_parseSpace($str__LINE____FILE__);
  2731.                 $this->_getNextToken($str$entry);
  2732.  
  2733.                 $this->_parseSpace($str__LINE____FILE__);
  2734.                 $attrs $this->_arrayfy_content($str);
  2735.  
  2736.                 $result_array = array('MAILBOX' => $mailbox'ENTRY' => $entry 'ATTRIBUTES' => $attrs);
  2737.                 return $result_array;
  2738.             break;
  2739.  
  2740.         case "":
  2741.             $this->_prot_error"PROTOCOL ERROR!:str empty!!" __LINE__ __FILE__ );
  2742.             break;
  2743.         case "(":
  2744.             $this->_prot_error("OPENING PARENTHESIS ERROR!!!!!!!!!!!!!!!!!" __LINE__ __FILE__ );
  2745.             break;
  2746.         case ")":
  2747.             //"CLOSING PARENTHESIS BREAK!!!!!!!"
  2748.             break;
  2749.         case "\r\n":
  2750.             $this->_prot_error("BREAK!!!!!!!!!!!!!!!!!" __LINE__ __FILE__ );
  2751.             break;
  2752.         case ' ':
  2753.             // this can happen and we just ignore it
  2754.             // This happens when - for example - fetch returns more than 1 parammeter
  2755.             // for example you ask to get RFC822.SIZE and UID
  2756.             //$this->_prot_error("SPACE BREAK!!!!!!!!!!!!!!!!!" , __LINE__ , __FILE__ );
  2757.             break;
  2758.         default:
  2759.             $body_token=strtoupper(substr($token,0,5));
  2760.             //echo "BODYYYYYYY: $body_token\n";
  2761.             $rfc822_token=strtoupper(substr($token,0,7));
  2762.             //echo "BODYYYYYYY: $rfc822_token|$token\n";
  2763.  
  2764.             if$body_token == 'BODY[' || $body_token == 'BODY.' || $rfc822_token == 'RFC822.' {
  2765.                 //echo "TOKEN:$token\n";
  2766.                 //$this->_getNextToken( $str , $mailbox );
  2767.                 return array($token=>$this->_parseContentresponse$str $token ));
  2768.             }else{
  2769.                 $this->_prot_error"UNIMPLEMMENTED! I don't know the parameter '$token' !!!__LINE__ __FILE__ );
  2770.             }
  2771.             break;
  2772.         }
  2773.         return false;
  2774. }
  2775.  
  2776.  
  2777.  
  2778.  
  2779.  
  2780.  
  2781.     /*
  2782.     * Verifies that the next character IS a space
  2783.     */
  2784.     function _parseSpace(&$str,$line,$file$printError = true)
  2785.     {
  2786.     /*
  2787.         This code repeats a lot in this class
  2788.         so i make it a function to make all the code shorter
  2789.     */
  2790.         $this->_getNextToken$str $space );
  2791.         if$space != ' ' ){
  2792.             $this->_prot_error("must be a ' ' but is a '$space' !!!!$line $file,$printError );
  2793.         }
  2794.         return $space;
  2795.     }
  2796.  
  2797.  
  2798.  
  2799.  
  2800.  
  2801.  
  2802.     function _parseString&$str $char $line $file )
  2803.     {
  2804.     /*
  2805.         This code repeats a lot in this class
  2806.         so i make it a function to make all the code shorter
  2807.     */
  2808.         $this->_getNextToken$str $char_aux );
  2809.         ifstrtoupper($char_aux!= strtoupper$char ) ){
  2810.             $this->_prot_error("must be a $char but is a '$char_aux' !!!!"$line $file );
  2811.         }
  2812.         return $char_aux;
  2813.     }
  2814.  
  2815.  
  2816.  
  2817.  
  2818.  
  2819.     function _genericImapResponseParser&$str $cmdid = null )
  2820.     {
  2821.  
  2822.         $result_array=array();
  2823.         if$this->_unParsedReturn ){
  2824.             $unparsed_str $str;
  2825.         }
  2826.  
  2827.         $this->_getNextToken$str $token );
  2828.  
  2829.         while$token != $cmdid && $str != '' ){
  2830.         if($token == "+" ){
  2831.         //if the token  is + ignore the line
  2832.         // TODO: verify that this is correct!!!
  2833.             $this->_getToEOL$str );
  2834.             $this->_getNextToken$str $token );
  2835.         }
  2836.  
  2837.             $this->_parseString$str ' ' __LINE__ __FILE__ );
  2838.  
  2839.             $this->_getNextToken$str $token );
  2840.         if$token == '+' ){
  2841.             $this->_getToEOL$str );
  2842.             $this->_getNextToken$str $token );
  2843.         }else
  2844.             ifis_numeric$token ) ){
  2845.                 // The token is a NUMBER so I store it
  2846.                 $msg_nro $token;
  2847.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2848.  
  2849.                 // I get the command
  2850.                 $this->_getNextToken$str $command );
  2851.  
  2852.                 if( ( $ext_arr $this->_retrParsedResponse$str $command$msg_nro ) ) == false ){
  2853.                 //  if this bogus response cis a FLAGS () or EXPUNGE response
  2854.                 // the ignore it
  2855.                     if$command != 'FLAGS' && $command != 'EXPUNGE' ){
  2856.                         $this->_prot_error("bogus response!!!!" __LINE__ __FILE__false);
  2857.                     }
  2858.                 }
  2859.                 $result_array[= array"COMMAND"=>$command "NRO"=>$msg_nro "EXT"=>$ext_arr );
  2860.             }else{
  2861.                 // OK the token is not a NUMBER so it MUST be a COMMAND
  2862.                 $command $token;
  2863.  
  2864.                 /* Call the parser return the array
  2865.                     take care of bogus responses!
  2866.                 */
  2867.  
  2868.                 if( ( $ext_arr $this->_retrParsedResponse$str $command ) ) == false ){
  2869.                     $this->_prot_error"bogus response!!!! (COMMAND:$command)__LINE__ __FILE__ );
  2870.                 }
  2871.                 $result_array[= array"COMMAND"=>$command "EXT"=>$ext_arr );
  2872.  
  2873.  
  2874.             }
  2875.  
  2876.  
  2877.             $this->_getNextToken$str $token );
  2878.  
  2879.             $token strtoupper$token );
  2880.             if$token != "\r\n" && $token != '' ){
  2881.                 $this->_prot_error("PARSE ERROR!!! must be a '\\r\\n' here  but is a '$token'!!!! (getting the next line)|STR:|$str|__LINE__ __FILE__ );
  2882.             }
  2883.             $this->_getNextToken$str $token );
  2884.  
  2885.             if($token == "+" ){
  2886.                 //if the token  is + ignore the line
  2887.                 // TODO: verify that this is correct!!!
  2888.                 $this->_getToEOL$str );
  2889.                 $this->_getNextToken$str $token );
  2890.             }
  2891.         }//While
  2892.         // OK we finish the UNTAGGED Response now we must parse the FINAL TAGGED RESPONSE
  2893.         //TODO: make this a litle more elegant!
  2894.  
  2895.         $this->_parseSpace$str __LINE__ __FILE__false );
  2896.  
  2897.         $this->_getNextToken$str $cmd_status );
  2898.  
  2899.         $str_line rtrim (substr$this->_getToEOL$str ) );
  2900.  
  2901.  
  2902.         $response["RESPONSE"]=array"CODE"=>$cmd_status "STR_CODE"=>$str_line "CMDID"=>$cmdid );
  2903.  
  2904.         $ret=$response;
  2905.         if!empty($result_array)){
  2906.             $ret=array_merge($ret,array("PARSED"=>$result_array) );
  2907.         }
  2908.  
  2909.         if$this->_unParsedReturn ){
  2910.             $unparsed["UNPARSED"]=$unparsed_str;
  2911.             $ret=array_merge($ret,$unparsed);
  2912.         }
  2913.  
  2914.  
  2915.         ifisset($status_arr) ){
  2916.             $status["STATUS"]=$status_arr;
  2917.             $ret=array_merge($ret,$status);
  2918.         }
  2919.         return $ret;
  2920.  
  2921. }
  2922.  
  2923.  
  2924.  
  2925.  
  2926.     function _genericCommand($command$params '')
  2927.     {
  2928.         if!$this->_connected ){
  2929.             return new PEAR_Error"not connected! (CMD:$command));
  2930.         }
  2931.         $cmdid $this->_getCmdId();
  2932.         $this->_putCMD$cmdid $command $params );
  2933.         $args=$this->_getRawResponse$cmdid );
  2934.         return $this->_genericImapResponseParser$args $cmdid );
  2935.     }
  2936.  
  2937.  
  2938.  
  2939.      function utf_7_encode($str)
  2940.     {
  2941.         if($this->_useUTF_7 == false ){
  2942.             return $str;
  2943.         }
  2944.         //return imap_utf7_encode($str);
  2945.  
  2946.         $encoded_utf7 '';
  2947.         $base64_part  '';
  2948.     if(is_array($str)){
  2949.         return new PEAR_Error('error');
  2950.     }
  2951.  
  2952.  
  2953.         for ($i = 0; $i strlen($str)$i++{
  2954.             //those chars should be base64 encoded
  2955.             if ( ((ord($str[$i]>= 39 and (ord($str[$i]<= 126 )) or ((ord($str[$i]>= 32 and (ord($str[$i]<= 37 )) ) {
  2956.                 if ($base64_part{
  2957.                     $encoded_utf7 sprintf("%s&%s-"$encoded_utf7str_replace('=''',base64_encode($base64_part))  );
  2958.                     $base64_part '';
  2959.                 }
  2960.                 $encoded_utf7 sprintf("%s%s",$encoded_utf7 $str[$i]);
  2961.             else {
  2962.                 //handle &
  2963.                 if (ord($str[$i]== 38 {
  2964.                     if ($base64_part{
  2965.                         $encoded_utf7 sprintf("%s&%s-"$encoded_utf7str_replace('=''',base64_encode($base64_part))  );
  2966.                         $base64_part '';
  2967.                     }
  2968.                     $encoded_utf7 sprintf("%s&-"$encoded_utf7 );
  2969.                 else {
  2970.                     $base64_part sprintf("%s%s",$base64_part  $str[$i]);
  2971.                     //$base64_part = sprintf("%s%s%s",$base64_part , chr(0) , $str[$i]);
  2972.                 }
  2973.             }
  2974.         }
  2975.         if ($base64_part{
  2976.             $encoded_utf7 sprintf("%s&%s-"$encoded_utf7str_replace('=''',base64_encode($base64_part))   );
  2977.             $base64_part '';
  2978.         }
  2979.         return $encoded_utf7;
  2980.     }
  2981.  
  2982.  
  2983.     function utf_7_decode($str)
  2984.     {
  2985.  
  2986.         if($this->_useUTF_7 == false ){
  2987.             return $str;
  2988.         }
  2989.  
  2990.         //return imap_utf7_decode($str);
  2991.  
  2992.         $base64_part '';
  2993.         $decoded_utf7 '';
  2994.  
  2995.         for ($i = 0; $i strlen($str)$i++{
  2996.             if strlen($base64_part> 0 {
  2997.                 if ($str[$i== '-'{
  2998.                     if ($base64_part == '&'{
  2999.                         $decoded_utf7 sprintf("%s&" $decoded_utf7 );
  3000.                     else {
  3001.                         $next_part_decodedbase64_decodesubstr$base64_part) ) ;
  3002.                         $decoded_utf7 sprintf("%s%s"$decoded_utf7 $next_part_decoded );
  3003.                     }
  3004.                     $base64_part '';
  3005.  
  3006.                 else {
  3007.                     $base64_part sprintf("%s%s"$base64_part $str[$i);
  3008.                 }
  3009.             else {
  3010.                 if ($str[$i== '&'{
  3011.                     $base64_part '&';
  3012.                 else {
  3013.                     $decoded_utf7 sprintf("%s%s"$decoded_utf7 $str[$i);
  3014.                 }
  3015.             }
  3016.         }
  3017.         return $decoded_utf7;
  3018.     }
  3019.  
  3020.  
  3021.  
  3022. }//Class
  3023. ?>

Documentation generated on Mon, 11 Mar 2019 13:54:09 -0400 by phpDocumentor 1.4.4. PEAR Logo Copyright © PHP Group 2004.