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.         }
  962.         // Keep the capabilities response to use ir later
  963.         $this->_serverSupportedCapabilities $ret["PARSED"]["CAPABILITIES"];
  964.         return $ret;
  965.     }
  966.  
  967.  
  968.  
  969.  
  970.  
  971.  
  972.  
  973.  
  974.  
  975.  
  976.     /**
  977.      * Send the  STATUS Mailbox Command
  978.      *
  979.      * @param string $mailbox the mailbox name
  980.      * @param string $request the request status it could be:
  981.      *               MESSAGES | RECENT | UIDNEXT
  982.      *               UIDVALIDITY | UNSEEN
  983.      * @return array Returns a Parsed Response
  984.      *
  985.      * @access public
  986.      * @since  1.0
  987.      */
  988.     function cmdStatus($mailbox$request)
  989.     {
  990.  
  991.         $mailbox_name=sprintf("\"%s\"",$this->utf_7_encode($mailbox) );
  992.  
  993.         if$request!="MESSAGES" && $request!="RECENT" && $request!="UIDNEXT" &&
  994.             $request!="UIDVALIDITY" && $request!="UNSEEN" ){
  995.             // TODO:  fix this error!
  996.             $this->_prot_error("request '$request' is invalid! see RFC2060!!!!__LINE__ __FILE__false );
  997.         }
  998.         $ret $this->_genericCommand('STATUS'"$mailbox_name ($request));
  999.         if(isset$ret["PARSED") ){
  1000.             $ret['PARSED']=$ret["PARSED"][0]["EXT"];
  1001.  
  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. ***             HERE ENDS THE EXTENSIONS FUNCTIONS
  1630. ***             AND BEGIN THE AUXILIARY FUNCTIONS
  1631. ***
  1632. ********************************************************************/
  1633.  
  1634.  
  1635.  
  1636.  
  1637.  
  1638.     /**
  1639.     * tell if the server has capability $capability
  1640.     *
  1641.     * @return true or false
  1642.     *
  1643.     * @access public
  1644.     * @since  1.0
  1645.     */
  1646.     function getServerAuthMethods()
  1647.     {
  1648.         if$this->_serverAuthMethods == null ){
  1649.             $this->cmdCapability();
  1650.             return $this->_serverAuthMethods;
  1651.         }
  1652.         return false;
  1653.     }
  1654.  
  1655.  
  1656.  
  1657.  
  1658.  
  1659.  
  1660.  
  1661.     /**
  1662.     * tell if the server has capability $capability
  1663.     *
  1664.     * @return true or false
  1665.     *
  1666.     * @access public
  1667.     * @since  1.0
  1668.     */
  1669.     function hasCapability($capability)
  1670.     {
  1671.         if$this->_serverSupportedCapabilities == null ){
  1672.             $this->cmdCapability();
  1673.         }
  1674.         if($this->_serverSupportedCapabilities != null ){
  1675.             ifin_array$capability $this->_serverSupportedCapabilities ) ){
  1676.                 return true;
  1677.             }
  1678.         }
  1679.         return false;
  1680.     }
  1681.  
  1682.  
  1683.  
  1684.     /**
  1685.     * tell if the server has Quota support
  1686.     *
  1687.     * @return true or false
  1688.     *
  1689.     * @access public
  1690.     * @since  1.0
  1691.     */
  1692.     function hasQuotaSupport()
  1693.     {
  1694.         return $this->hasCapability('QUOTA');
  1695.     }
  1696.  
  1697.  
  1698.  
  1699.  
  1700.  
  1701.     /**
  1702.     * tell if the server has Quota support
  1703.     *
  1704.     * @return true or false
  1705.     *
  1706.     * @access public
  1707.     * @since  1.0
  1708.     */
  1709.     function hasAclSupport()
  1710.     {
  1711.         return $this->hasCapability('ACL');
  1712.     }
  1713.  
  1714.  
  1715.  
  1716.  
  1717.  
  1718.  
  1719.     /**
  1720.     * Parses the responses like RFC822.SIZE and INTERNALDATE
  1721.     *
  1722.     * @param string the IMAP's server response
  1723.     *
  1724.     * @return string containing  the parsed response
  1725.     * @access private
  1726.     * @since  1.0
  1727.     */
  1728.  
  1729.     function _parseOneStringResponse(&$str$line,$file)
  1730.     {
  1731.         $this->_parseSpace($str $line $file );
  1732.         $size $this->_getNextToken($str,$uid);
  1733.         return $uid;
  1734.     }
  1735.  
  1736.  
  1737.     /**
  1738.     * Parses the FLAG response
  1739.     *
  1740.     * @param string the IMAP's server response
  1741.     *
  1742.     * @return Array containing  the parsed  response
  1743.     * @access private
  1744.     * @since  1.0
  1745.     */
  1746.     function _parseFLAGSresponse(&$str)
  1747.     {
  1748.         $this->_parseSpace($str __LINE__ __FILE__ );
  1749.         $params_arr[$this->_arrayfy_content($str);
  1750.         $flags_arr=array();
  1751.         for$i = 0 ; $i count($params_arr[0]$i++ ){
  1752.             $flags_arr[$params_arr[0][$i];
  1753.         }
  1754.         return $flags_arr;
  1755.     }
  1756.  
  1757.  
  1758.  
  1759.  
  1760.  
  1761.     /**
  1762.     * Parses the BODY response
  1763.     *
  1764.     * @param string the IMAP's server response
  1765.     *
  1766.     * @return Array containing  the parsed  response
  1767.     * @access private
  1768.     * @since  1.0
  1769.     */
  1770.  
  1771.     function _parseBodyResponse(&$str$command){
  1772.  
  1773.             $this->_parseSpace($str __LINE__ __FILE__ );
  1774.             while($str[0!= ')' && $str!=''){
  1775.                 $params_arr[$this->_arrayfy_content($str);
  1776.             }
  1777.  
  1778.             return $params_arr;
  1779.     }
  1780.  
  1781.  
  1782.  
  1783.  
  1784.  
  1785.  
  1786.     /**
  1787.     * Makes the content an Array
  1788.     *
  1789.     * @param string the IMAP's server response
  1790.     *
  1791.     * @return Array containing  the parsed  response
  1792.     * @access private
  1793.     * @since  1.0
  1794.     */
  1795.     function _arrayfy_content(&$str)
  1796.     {
  1797.         $params_arr=array();
  1798.         $this->_getNextToken($str,$params);
  1799.         if($params != '(' ){
  1800.             return $params;
  1801.         }
  1802.         $this->_getNextToken($str,$params,false,false);
  1803.         while $str != '' && $params != ')'){
  1804.                 if($params != '' ){
  1805.                     if($params[0== '(' ){
  1806.                         $params=$this->_arrayfy_content$params );
  1807.                     }
  1808.                     if($params != ' ' ){
  1809.                         //I don't remove the colons (") to handle the case of retriving " "
  1810.                         // If I remove the colons the parser will interpret this field as an imap separator (space)
  1811.                         // instead of a valid field so I remove the colons here
  1812.                         if($params=='""'){
  1813.                             $params='';
  1814.                         }else{
  1815.                             if($params[0]=='"'){
  1816.                                 $params=substr($params,1,strlen($params)-2);
  1817.                             }
  1818.                         }
  1819.                         $params_arr[]=$params;
  1820.                     }
  1821.                 }else{
  1822.                     //if params if empty (for example i'm parsing 2 quotes ("")
  1823.                     // I'll append an array entry to mantain compatibility
  1824.                     $params_arr[]=$params;
  1825.                 }
  1826.                 $this->_getNextToken($str,$params,false,false);
  1827.         }
  1828.         return $params_arr;
  1829.     }
  1830.  
  1831.  
  1832.  
  1833.  
  1834.     /**
  1835.     * Parses the BODY[],BODY[TEXT],.... responses
  1836.     *
  1837.     * @param string the IMAP's server response
  1838.     *
  1839.     * @return Array containing  the parsed  response
  1840.     * @access private
  1841.     * @since  1.0
  1842.     */
  1843.     function _parseContentresponse(&$str$command)
  1844.     {
  1845.         $content '';
  1846.         $this->_parseSpace($str __LINE__ __FILE__ );
  1847.         $size  =$this->_getNextToken($str,$content);
  1848.         return array"CONTENT"=> $content "CONTENT_SIZE" =>$size );
  1849.     }
  1850.  
  1851.  
  1852.  
  1853.  
  1854.  
  1855.  
  1856.  
  1857.  
  1858.     /**
  1859.     * Parses the ENVELOPE response
  1860.     *
  1861.     * @param string the IMAP's server response
  1862.     *
  1863.     * @return Array containing  the parsed  response
  1864.     * @access private
  1865.     * @since  1.0
  1866.     */
  1867.     function _parseENVELOPEresponse(&$str)
  1868.     {
  1869.         $content '';
  1870.         $this->_parseSpace($str __LINE__ __FILE__ );
  1871.  
  1872.         $this->_getNextToken($str,$parenthesis);
  1873.         if$parenthesis != '(' ){
  1874.                 $this->_prot_error("must be a '(' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  1875.         }
  1876.         // Get the email's Date
  1877.         $this->_getNextToken($str,$date);
  1878.  
  1879.         $this->_parseSpace($str __LINE__ __FILE__ );
  1880.  
  1881.         // Get the email's Subject:
  1882.         $this->_getNextToken($str,$subject);
  1883.         //$subject=$this->decode($subject);
  1884.  
  1885.         $this->_parseSpace($str __LINE__ __FILE__ );
  1886.  
  1887.         //FROM LIST;
  1888.         $from_arr $this->_getAddressList($str);
  1889.  
  1890.         $this->_parseSpace($str __LINE__ __FILE__ );
  1891.  
  1892.         //"SENDER LIST\n";
  1893.         $sender_arr $this->_getAddressList($str);
  1894.  
  1895.         $this->_parseSpace($str __LINE__ __FILE__ );
  1896.  
  1897.         //"REPLY-TO LIST\n";
  1898.         $reply_to_arr=$this->_getAddressList($str);
  1899.  
  1900.         $this->_parseSpace($str __LINE__ __FILE__ );
  1901.  
  1902.         //"TO LIST\n";
  1903.         $to_arr $this->_getAddressList($str);
  1904.  
  1905.         $this->_parseSpace($str __LINE__ __FILE__ );
  1906.  
  1907.         //"CC LIST\n";
  1908.         $cc_arr $this->_getAddressList($str);
  1909.  
  1910.         $this->_parseSpace($str __LINE__ __FILE__ );
  1911.  
  1912.         //"BCC LIST|$str|\n";
  1913.         $bcc_arr $this->_getAddressList($str);
  1914.  
  1915.         $this->_parseSpace($str __LINE__ __FILE__ );
  1916.  
  1917.         $this->_getNextToken($str,$in_reply_to);
  1918.  
  1919.         $this->_parseSpace($str __LINE__ __FILE__ );
  1920.  
  1921.         $this->_getNextToken($str,$message_id);
  1922.  
  1923.         $this->_getNextToken($str,$parenthesis);
  1924.  
  1925.         if$parenthesis != ')' ){
  1926.             $this->_prot_error("must be a ')' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  1927.         }
  1928.  
  1929.         return array"DATE"=> $date "SUBJECT" => $subject,"FROM" => $from_arr,
  1930.             "SENDER" => $sender_arr "REPLY_TO" => $reply_to_arr"TO" => $to_arr,
  1931.             "CC" =>$cc_arr"BCC"=> $bcc_arr"IN_REPLY_TO" =>$in_reply_to"MESSAGE_ID"=>$message_id  );
  1932.     }
  1933.  
  1934.  
  1935.  
  1936.  
  1937.  
  1938.     /**
  1939.     * Parses the ARRDLIST as defined in RFC
  1940.     *
  1941.     * @param string the IMAP's server response
  1942.     *
  1943.     * @return Array containing  the parsed  response
  1944.     * @access private
  1945.     * @since  1.0
  1946.     */
  1947.     function _getAddressList(&$str)
  1948.     {
  1949.         $params_arr $this->_arrayfy_content($str);
  1950.         if!isset$params_arr ) ){
  1951.             return $params_arr;
  1952.         }
  1953.  
  1954.  
  1955.         ifis_array($params_arr) ){
  1956.             $personal_name  $params_arr[0][0];
  1957.             $at_domain_list $params_arr[0][1];
  1958.             $mailbox_name   $params_arr[0][2];
  1959.             $host_name      $params_arr[0][3];
  1960.             if$mailbox_name!='' && $host_name!='' ){
  1961.                 $email=$mailbox_name "@" $host_name;
  1962.             }else{
  1963.                 $email=false;
  1964.             }
  1965.             if($email==false){
  1966.                 $rfc822_email=false;
  1967.             }else{
  1968.                 if(!isset($personal_name)){
  1969.                     $rfc822_email"<"$email ">";
  1970.                 }else{
  1971.                     $rfc822_email"\""$personal_name ."\" <"$email ">";
  1972.                 }
  1973.             }
  1974.             $email_arr[= array "PERSONAL_NAME"=> $personal_name "AT_DOMAIN_LIST"=>$at_domain_list ,
  1975.                                    "MAILBOX_NAME"=> $this->utf_7_decode($mailbox_name)"HOST_NAME"=> $host_name,
  1976.                                    "EMAIL"=>$email "RFC822_EMAIL" => $rfc822_email );
  1977.             return $email_arr;
  1978.         }
  1979.  
  1980.         return array();
  1981.     }
  1982.  
  1983.  
  1984.  
  1985.  
  1986.  
  1987.  
  1988.  
  1989.     /**
  1990.     * Utility funcion to find the closing parenthesis ")" Position it takes care of quoted ones
  1991.     *
  1992.     * @param string the IMAP's server response
  1993.     *
  1994.     * @return int containing  the pos of the closing parenthesis ")"
  1995.     * @access private
  1996.     * @since  1.0
  1997.     */
  1998.     function _getClosingBracesPos($str_line$startDelim ='('$stopDelim ')' )
  1999.     {
  2000.         $len strlen$str_line );
  2001.         $pos = 0;
  2002.         // ignore all extra characters
  2003.         // If inside of a string, skip string -- Boundary IDs and other
  2004.         // things can have ) in them.
  2005.         if $str_line[$pos!= $startDelim {
  2006.             $this->_prot_error("_getClosingParenthesisPos: must start with a '(' but is a '"$str_line[$pos."'!!!!\n" .
  2007.                 "STR_LINE:$str_line|size:$len|POS: $pos\n__LINE__ __FILE__ );
  2008.             return$len );
  2009.         }
  2010.         for$pos = 1 ; $pos $len $pos++ ){
  2011.             if ($str_line[$pos== $stopDelim {
  2012.                 break;
  2013.             }
  2014.             if ($str_line[$pos== '"'{
  2015.                 $pos++;
  2016.                 while $str_line[$pos!= '"' && $pos $len {
  2017.                     if ($str_line[$pos== "\\" && $str_line[$pos + 1 == '"' )
  2018.                         $pos++;
  2019.                     if ($str_line[$pos== "\\" && $str_line[$pos + 1 == "\\" )
  2020.                         $pos++;
  2021.                     $pos++;
  2022.                 }
  2023.             }
  2024.             if $str_line[$pos== $startDelim {
  2025.                 $str_line_aux substr$str_line $pos );
  2026.                 $pos_aux $this->_getClosingBracesPos$str_line_aux );
  2027.                 $pos+=$pos_aux;
  2028.             }
  2029.         }
  2030.         if$str_line[$pos!= $stopDelim ){
  2031.             $this->_prot_error("_getClosingBracesPos: must be a $stopDelim but is a '". $str_line[$pos."'|POS:$pos|STR_LINE:$str_line!!!!__LINE__ __FILE__ );
  2032.         }
  2033.  
  2034.         if$pos >= $len )
  2035.             return false;
  2036.         return $pos;
  2037.     }
  2038.  
  2039.  
  2040.  
  2041.  
  2042.  
  2043.  
  2044.     /**
  2045.     * Utility funcion to get from here to the end of the line
  2046.     *
  2047.     * @param string the IMAP's server response
  2048.     *
  2049.     * @return string containing  the string to the end of the line
  2050.     * @access private
  2051.     * @since  1.0
  2052.     */
  2053.  
  2054.     function _getToEOL(&$str $including = true)
  2055.     {
  2056.         $len strlen$str );
  2057.         if$including ){
  2058.             for($i=0;$i<$len;$i++){
  2059.                 if$str[$i=="\n" )
  2060.                     break;
  2061.             }
  2062.             $content=substr($str,0,$i + 1);
  2063.             $str=substr($str,$i + 1);
  2064.             return $content;
  2065.  
  2066.         }else{
  2067.             for$i = 0 ; $i $len $i++ ){
  2068.                 if$str[$i=="\n" || $str[$i== "\r")
  2069.                     break;
  2070.             }
  2071.             $content substr$str ,$i );
  2072.             $str substr$str $i );
  2073.             return $content;
  2074.         }
  2075.     }
  2076.  
  2077.  
  2078.  
  2079.  
  2080.     /**
  2081.     * Fetches the next IMAP token or parenthesis
  2082.     *
  2083.     * @param string the IMAP's server response
  2084.     * @param string the next token
  2085.     * @param boolean true: the parenthesis IS a token, false: I consider
  2086.     *         all the response in parenthesis as a token
  2087.     *
  2088.     * @return int containing  the content size
  2089.     * @access private
  2090.     * @since  1.0
  2091.     */
  2092.  
  2093.  
  2094.     function _getNextToken(&$str&$content$parenthesisIsToken=true,$colonIsToken=true){
  2095.         $len strlen($str);
  2096.         $pos = 0;
  2097.         $content_size = false;
  2098.         $content = false;
  2099.         if($str == '' || $len < 2 ){
  2100.             $content=$str;
  2101.             return $len;
  2102.         }
  2103.         switch$str[0){
  2104.         case '{':
  2105.             if( ($posClosingBraces $this->_getClosingBracesPos($str'{' '}' )) == false ){
  2106.                 $this->_prot_error("_getClosingBracesPos() error!!!" __LINE__ __FILE__ );
  2107.             }
  2108.             if(is_numeric( ( $strBytes substr$str $posClosingBraces - 1) ) ) ){
  2109.                 $this->_prot_error("must be a number but is a '" $strBytes ."'!!!!" __LINE__ __FILE__ );
  2110.             }
  2111.             if$str[$posClosingBraces!= '}' ){
  2112.                 $this->_prot_error("must be a '}'  but is a '" $str[$posClosingBraces."'!!!!" __LINE__ __FILE__ );
  2113.             }
  2114.             if$str[$posClosingBraces + 1!= "\r" ){
  2115.                 $this->_prot_error("must be a '\\r'  but is a '" $str[$posClosingBraces + 1."'!!!!" __LINE__ __FILE__ );
  2116.             }
  2117.             if$str[$posClosingBraces + 2!= "\n" ){
  2118.                 $this->_prot_error("must be a '\\n'  but is a '" $str[$posClosingBraces + 2."'!!!!" __LINE__ __FILE__ );
  2119.             }
  2120.             $content substr$str $posClosingBraces + 3 $strBytes );
  2121.             ifstrlen$content != $strBytes ){
  2122.                 $this->_prot_error("content size is "strlen($content. " but the string reports a size of $strBytes!!!\n__LINE__ __FILE__ );
  2123.             }
  2124.             $content_size $strBytes;
  2125.             //Advance the string
  2126.             $str substr$str $posClosingBraces $strBytes + 3 );
  2127.             break;
  2128.         case '"':
  2129.             if($colonIsToken){
  2130.                 for($pos=1;$pos<$len;$pos++){
  2131.                     if $str[$pos== "\"" {
  2132.                         break;
  2133.                     }
  2134.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\"" )
  2135.                         $pos++;
  2136.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\\" )
  2137.                         $pos++;
  2138.                 }
  2139.                 if($str[$pos!= '"' ){
  2140.                     $this->_prot_error("must be a '\"'  but is a '" $str[$pos."'!!!!" __LINE__ __FILE__ );
  2141.                 }
  2142.                 $content_size $pos;
  2143.                 $content substr$str $pos - 1 );
  2144.                 //Advance the string
  2145.                 $str substr$str $pos + 1 );
  2146.             }else{
  2147.                 for($pos=1;$pos<$len;$pos++){
  2148.                     if $str[$pos== "\"" {
  2149.                         break;
  2150.                     }
  2151.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\"" )
  2152.                         $pos++;
  2153.                     if ($str[$pos== "\\" && $str[$pos + 1 == "\\" )
  2154.                         $pos++;
  2155.                 }
  2156.                 if($str[$pos!= '"' ){
  2157.                     $this->_prot_error("must be a '\"'  but is a '" $str[$pos."'!!!!" __LINE__ __FILE__ );
  2158.                 }
  2159.                 $content_size $pos;
  2160.                 $content substr$str $pos + 1 );
  2161.                 //Advance the string
  2162.                 $str substr$str $pos + 1 );
  2163.  
  2164.             }
  2165.             break;
  2166.  
  2167.         case "\r":
  2168.             $pos = 1;
  2169.             if$str[1== "\n")
  2170.                 $pos++;
  2171.             $content_size $pos;
  2172.             $content substr$str $pos );
  2173.             $str substr$str $pos );
  2174.             break;
  2175.         case "\n":
  2176.             $pos = 1;
  2177.             $content_size $pos;
  2178.             $content substr$str $pos );
  2179.             $str substr$str $pos );
  2180.             break;
  2181.         case '(':
  2182.             if$parenthesisIsToken == false ){
  2183.                 $pos $this->_getClosingBracesPos$str );
  2184.                 $content_size $pos + 1;
  2185.                 $content substr$str $pos + 1 );
  2186.                 $str substr$str $pos + 1 );
  2187.             }else{
  2188.                 $pos = 1;
  2189.                 $content_size $pos;
  2190.                 $content substr$str $pos );
  2191.                 $str substr$str $pos );
  2192.             }
  2193.             break;
  2194.         case ')':
  2195.             $pos = 1;
  2196.             $content_size $pos;
  2197.             $content substr$str $pos );
  2198.             $str substr$str $pos );
  2199.             break;
  2200.         case ' ':
  2201.             $pos = 1;
  2202.             $content_size $pos;
  2203.             $content substr$str $pos );
  2204.             $str substr$str $pos );
  2205.             break;
  2206.         default:
  2207.             for$pos = 0 ; $pos $len $pos++ ){
  2208.                 if $str[$pos== ' ' || $str[$pos== "\r" || $str[$pos== ')' || $str[$pos== '(' || $str[$pos== "\n" {
  2209.                     break;
  2210.                 }
  2211.                 if $str[$pos== "\\" && $str[$pos + 1 == ' '  )
  2212.                     $pos++;
  2213.                 if $str[$pos== "\\" && $str[$pos + 1 == "\\" )
  2214.                     $pos++;
  2215.             }
  2216.             //Advance the string
  2217.             if$pos == 0 ){
  2218.                 $content_size = 1;
  2219.                 $content substr$str );
  2220.                 $str substr$str );
  2221.             }else{
  2222.                 $content_size $pos;
  2223.                 $content substr$str $pos );
  2224.                 if($pos $len){
  2225.                     $str substr$str $pos  );
  2226.                 }else{
  2227.                 //if this is the end of the string... exit the switch
  2228.                     break;
  2229.                 }
  2230.  
  2231.  
  2232.             }
  2233.             break;
  2234.         }
  2235.         return $content_size;
  2236.     }
  2237.  
  2238.  
  2239.  
  2240.  
  2241.  
  2242.  
  2243.     /**
  2244.     * Utility funcion to display to console the protocol errors
  2245.     *
  2246.     * @param string the error
  2247.     * @param int the line producing the error
  2248.     * @param string file where the error was produced
  2249.     *
  2250.     * @return string containing  the error
  2251.     * @access private
  2252.     * @since  1.0
  2253.     */
  2254.     function _prot_error($str $line $file,$printError=true)
  2255.     {
  2256.         if($printError){
  2257.             echo "$line,$file,PROTOCOL ERROR!:$str\n";
  2258.         }
  2259.     }
  2260.  
  2261.  
  2262.  
  2263.  
  2264.  
  2265.  
  2266.  
  2267.     function _getEXTarray(&$str $startDelim '(' $stopDelim ')'){
  2268.         /* I let choose the $startDelim  and $stopDelim to allow parsing
  2269.            the OK response  so I also can parse a response like this
  2270.            * OK [UIDNEXT 150] Predicted next UID
  2271.         */
  2272.         $this->_getNextToken$str $parenthesis );
  2273.         if$parenthesis != $startDelim ){
  2274.             $this->_prot_error("must be a '$startDelim' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  2275.         }
  2276.         $parenthesis '';
  2277.         $struct_arr = array();
  2278.         while$parenthesis != $stopDelim && $str != '' ){
  2279.             // The command
  2280.             $this->_getNextToken$str $token );
  2281.             $token strtoupper$token );
  2282.  
  2283.             if( ( $ret $this->_retrParsedResponse$str $token ) ) != false ){
  2284.                 //$struct_arr[$token] = $ret;
  2285.                 $struct_arr=array_merge($struct_arr$ret);
  2286.             }
  2287.  
  2288.             $parenthesis=$token;
  2289.  
  2290.         }//While
  2291.  
  2292.        if$parenthesis != $stopDelim  ){
  2293.             $this->_prot_error("1_must be a '$stopDelim' but is a '$parenthesis' !!!!__LINE__ __FILE__ );
  2294.        }
  2295.         return $struct_arr;
  2296.     }
  2297.  
  2298.  
  2299.  
  2300.  
  2301.  
  2302.     function _retrParsedResponse&$str $token$previousToken = null)
  2303.     {
  2304.  
  2305.     //echo "\n\nTOKEN:$token\r\n";
  2306.         switch$token ){
  2307.         case "RFC822.SIZE" :
  2308.             return array($token=>$this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2309.             break;
  2310. //        case "RFC822.TEXT" :
  2311.  
  2312. //        case "RFC822.HEADER" :
  2313.  
  2314.  
  2315.         case "RFC822" :
  2316.             return array($token=>$this->_parseContentresponse$str $token ));
  2317.             break;
  2318.         case "FLAGS" :
  2319.  
  2320.         case "PERMANENTFLAGS" :
  2321.             return array($token=>$this->_parseFLAGSresponse$str ));
  2322.             break;
  2323.  
  2324.         case "ENVELOPE" :
  2325.             return array($token=>$this->_parseENVELOPEresponse$str ));
  2326.             break;
  2327.         case "EXPUNGE" :
  2328.             return false;
  2329.             break;
  2330.  
  2331.         case "UID" :
  2332.  
  2333.         case "UIDNEXT" :
  2334.  
  2335.         case "UIDVALIDITY" :
  2336.  
  2337.         case "UNSEEN" :
  2338.  
  2339.         case "MESSAGES" :
  2340.  
  2341.         case "UIDNEXT" :
  2342.  
  2343.         case "UIDVALIDITY" :
  2344.  
  2345.         case "UNSEEN" :
  2346.  
  2347.         case "INTERNALDATE" :
  2348.             return array($token=>$this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2349.             break;
  2350.         case "BODY" :
  2351.  
  2352.         case "BODYSTRUCTURE" :
  2353.             return array($token=>$this->_parseBodyResponse$str $token ));
  2354.             break;
  2355.         case "RECENT" :
  2356.             if$previousToken != null ){
  2357.                 $aux["RECENT"]=$previousToken;
  2358.                 return $aux;
  2359.             }else{
  2360.                 return array($token=>$this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2361.             }
  2362.             break;
  2363.  
  2364.         case "EXISTS" :
  2365.             return array($token=>$previousToken);
  2366.             break;
  2367.         case "READ-WRITE" :
  2368.  
  2369.         case "READ-ONLY" :
  2370.             return array($token=>$token);
  2371.             break;
  2372.         case "QUOTA" :
  2373.             /*
  2374.             A tipical GETQUOTA DIALOG IS AS FOLLOWS
  2375.  
  2376.                 C: A0004 GETQUOTA user.damian
  2377.                 S: * QUOTA user.damian (STORAGE 1781460 4000000)
  2378.                 S: A0004 OK Completed
  2379.             */
  2380.  
  2381.             $mailbox $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2382.             $this->_parseSpace$str __LINE__ __FILE__ );
  2383.             $this->_parseString$str '(' __LINE__ __FILE__ );
  2384.  
  2385.             $ret_aux = array("MAILBOX"=>$this->utf_7_decode($mailbox) );
  2386.             $this->_getNextToken$str $quota_resp );
  2387.             if( ( $ext $this->_retrParsedResponse$str $quota_resp )) == false){
  2388.                     $this->_prot_error("bogus response!!!!" __LINE__ __FILE__ );
  2389.             }
  2390.             $ret_aux=array_merge($ret_aux,$ext);
  2391.  
  2392.             $this->_getNextToken$str $separator );
  2393.             if$separator == ')' ){
  2394.                 return array($token=>$ret_aux);
  2395.             }
  2396.  
  2397.  
  2398.             $this->_parseSpace$str __LINE__ __FILE__ );
  2399.  
  2400.             $this->_getNextToken$str $quota_resp );
  2401.             if( ( $ext $this->_retrParsedResponse$str $quota_resp )) == false){
  2402.                     $this->_prot_error("bogus response!!!!" __LINE__ __FILE__ );
  2403.             }
  2404.             $ret_aux=array_merge($ret_aux,$ext);
  2405.  
  2406.             $this->_parseString$str ')' __LINE__ __FILE__ );
  2407.             return array($token=>$ret_aux);
  2408.             break;
  2409.  
  2410.         case "QUOTAROOT" :
  2411.             /*
  2412.             A tipical GETQUOTA DIALOG IS AS FOLLOWS
  2413.  
  2414.                 C: A0004 GETQUOTA user.damian
  2415.                 S: * QUOTA user.damian (STORAGE 1781460 4000000)
  2416.                 S: A0004 OK Completed
  2417.             */
  2418.             $mailbox $this->utf_7_decode($this->_parseOneStringResponse$str,__LINE__ __FILE__ ));
  2419.  
  2420.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2421.  
  2422.             $quotaroot $this->_parseOneStringResponse$str_line,__LINE__ __FILE__ );
  2423.             $ret @array"MAILBOX"=>$this->utf_7_decode($mailbox$token=>$quotaroot );
  2424.             return array($token=>$ret);
  2425.             break;
  2426.         case "STORAGE" :
  2427.                 $used $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2428.                 $qmax $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2429.                 return array($token=>array("USED"=> $used"QMAX" => $qmax));
  2430.         break;
  2431.         case "MESSAGE" :
  2432.                 $mused $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2433.                 $mmax $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2434.                 return array($token=>array("MUSED"=> $mused"MMAX" => $mmax));
  2435.         break;
  2436.         case "FETCH" :
  2437.                 $this->_parseSpace$str  ,__LINE__  ,__FILE__ );
  2438.                 // Get the parsed pathenthesis
  2439.                 $struct_arr $this->_getEXTarray$str );
  2440.                 return $struct_arr;
  2441.             break;
  2442.         case "CAPABILITY" :
  2443.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2444.                 $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2445.                 $struct_arr["CAPABILITIES"explode' ' $str_line );
  2446.                 return array($token=>$struct_arr);
  2447.             break;
  2448.         case "STATUS" :
  2449.                 $mailbox $this->_parseOneStringResponse$str,__LINE__ __FILE__ );
  2450.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2451.                 $ext $this->_getEXTarray$str );
  2452.                 $struct_arr["MAILBOX"$this->utf_7_decode($mailbox);
  2453.                 $struct_arr["ATTRIBUTES"$ext;
  2454.                 return array($token=>$struct_arr);
  2455.             break;
  2456.         case "LIST" :
  2457.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2458.                 $params_arr $this->_arrayfy_content$str );
  2459.  
  2460.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2461.                 $this->_getNextToken$str $hierarchydelim );
  2462.  
  2463.                 $this->_parseSpace$str,__LINE__ __FILE__);
  2464.                 $this->_getNextToken$str $mailbox_name );
  2465.  
  2466.                 $result_array = array"NAME_ATTRIBUTES"=>$params_arr "HIERACHY_DELIMITER"=>$hierarchydelim "MAILBOX_NAME"=>  $this->utf_7_decode($mailbox_name) );
  2467.                 return array($token=>$result_array);
  2468.             break;
  2469.         case "LSUB" :
  2470.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2471.                 $params_arr $this->_arrayfy_content$str );
  2472.  
  2473.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2474.                 $this->_getNextToken$str $hierarchydelim );
  2475.  
  2476.                 $this->_parseSpace$str,__LINE__ __FILE__);
  2477.                 $this->_getNextToken$str $mailbox_name );
  2478.  
  2479.                 $result_array = array"NAME_ATTRIBUTES"=>$params_arr "HIERACHY_DELIMITER"=>$hierarchydelim "MAILBOX_NAME"=> $this->utf_7_decode($mailbox_name) );
  2480.                 return array($token=>$result_array);
  2481.             break;
  2482.  
  2483.             case "SEARCH" :
  2484.                 $str_line rtrimsubstr$this->_getToEOL$str false 1) );
  2485.                 $struct_arr["SEARCH_LIST"explode' ' $str_line );
  2486.                 if(count($struct_arr["SEARCH_LIST"]== 1 && $struct_arr["SEARCH_LIST"][0]==''){
  2487.                     $struct_arr["SEARCH_LIST"]=null;
  2488.                 }
  2489.                 return array($token=>$struct_arr);
  2490.             break;
  2491.             case "OK" :
  2492.                 /* TODO:
  2493.                     parse the [ .... ] part of the response, use the method
  2494.                     _getEXTarray(&$str,'[',$stopDelim=']')
  2495.  
  2496.                 */
  2497.                 $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2498.                 if($str_line[0== '[' ){
  2499.                     $braceLen=$this->_getClosingBracesPos($str_line'['']' );
  2500.                     $str_aux='('substr($str_line,1,$braceLen -1)')';
  2501.                     $ext_arr=$this->_getEXTarray($str_aux);
  2502.                     //$ext_arr=array($token=>$this->_getEXTarray($str_aux));
  2503.                 }else{
  2504.                     $ext_arr=$str_line;
  2505.                     //$ext_arr=array($token=>$str_line);
  2506.                 }
  2507.                 $result_array =  $ext_arr;
  2508.                 return $result_array;
  2509.                 break;
  2510.         case "NO" :
  2511.         /* TODO:
  2512.             parse the [ .... ] part of the response, use the method
  2513.             _getEXTarray(&$str,'[',$stopDelim=']')
  2514.  
  2515.         */
  2516.  
  2517.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2518.             $result_array[@array"COMMAND"=>$token "EXT"=>$str_line );
  2519.             return $result_array;
  2520.             break;
  2521.         case "BAD" :
  2522.         /* TODO:
  2523.             parse the [ .... ] part of the response, use the method
  2524.             _getEXTarray(&$str,'[',$stopDelim=']')
  2525.  
  2526.         */
  2527.  
  2528.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2529.             $result_array[= array"COMMAND"=>$token "EXT"=>$str_line );
  2530.             return $result_array;
  2531.             break;
  2532.         case "BYE" :
  2533.         /* TODO:
  2534.             parse the [ .... ] part of the response, use the method
  2535.             _getEXTarray(&$str,'[',$stopDelim=']')
  2536.  
  2537.         */
  2538.  
  2539.             $str_line rtrimsubstr$this->_getToEOL$str false ) );
  2540.             $result_array[= array"COMMAND"=>$command "EXT"=> $str_line );
  2541.             return $result_array;
  2542.             break;
  2543.  
  2544.         case "LISTRIGHTS" :
  2545.                 $this->_parseSpace$str ,__LINE__ __FILE__ );
  2546.                 $this->_getNextToken$str $mailbox );
  2547.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2548.                 $this->_getNextToken$str $user );
  2549.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2550.                 $this->_getNextToken$str $granted );
  2551.  
  2552.                 $ungranted explode' ' rtrimsubstr$this->_getToEOL$str false ) ) );
  2553.  
  2554.                 $result_array @array"MAILBOX"=>$this->utf_7_decode($mailbox"USER"=>$user "GRANTED"=>$granted "UNGRANTED"=>$ungranted );
  2555.                 return $result_array;
  2556.             break;
  2557.  
  2558.         case "MYRIGHTS" :
  2559.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2560.                 $this->_getNextToken$str ,$mailbox );
  2561.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2562.                 $this->_getNextToken$str $granted );
  2563.  
  2564.                 $result_array = array"MAILBOX"=>$this->utf_7_decode($mailbox"GRANTED"=>$granted );
  2565.                 return $result_array;
  2566.             break;
  2567.  
  2568.         case "ACL" :
  2569.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2570.                 $this->_getNextToken$str $mailbox );
  2571.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2572.                 $acl_arr explode' ' rtrimsubstr$this->_getToEOL$str false ) ) );
  2573.  
  2574.                 for$i = 0 ; $i count$acl_arr $i += 2 ){
  2575.                     $arr[= array"USER"=>$acl_arr[$i"RIGHTS"=>$acl_arr$i + 1 );
  2576.                 }
  2577.  
  2578.                 $result_array = array"MAILBOX"=>$this->utf_7_decode($mailbox"USERS"=>$arr );
  2579.                 return $result_array;
  2580.             break;
  2581.  
  2582.  
  2583.         case "":
  2584.             $this->_prot_error"PROTOCOL ERROR!:str empty!!" __LINE__ __FILE__ );
  2585.             break;
  2586.         case "(":
  2587.             $this->_prot_error("OPENING PARENTHESIS ERROR!!!!!!!!!!!!!!!!!" __LINE__ __FILE__ );
  2588.             break;
  2589.         case ")":
  2590.             //"CLOSING PARENTHESIS BREAK!!!!!!!"
  2591.             break;
  2592.         case "\r\n":
  2593.             $this->_prot_error("BREAK!!!!!!!!!!!!!!!!!" __LINE__ __FILE__ );
  2594.             break;
  2595.         case ' ':
  2596.             // this can happen and we just ignore it
  2597.             // This happens when - for example - fetch returns more than 1 parammeter
  2598.             // for example you ask to get RFC822.SIZE and UID
  2599.             //$this->_prot_error("SPACE BREAK!!!!!!!!!!!!!!!!!" , __LINE__ , __FILE__ );
  2600.             break;
  2601.         default:
  2602.             $body_token=strtoupper(substr($token,0,5));
  2603.             //echo "BODYYYYYYY: $body_token\n";
  2604.             $rfc822_token=strtoupper(substr($token,0,7));
  2605.             //echo "BODYYYYYYY: $rfc822_token|$token\n";
  2606.  
  2607.             if$body_token == 'BODY[' || $body_token == 'BODY.' || $rfc822_token == 'RFC822.' {
  2608.                 //echo "TOKEN:$token\n";
  2609.                 //$this->_getNextToken( $str , $mailbox );
  2610.                 return array($token=>$this->_parseContentresponse$str $token ));
  2611.             }else{
  2612.                 $this->_prot_error"UNIMPLEMMENTED! I don't know the parameter '$token' !!!__LINE__ __FILE__ );
  2613.             }
  2614.             break;
  2615.         }
  2616.         return false;
  2617. }
  2618.  
  2619.  
  2620.  
  2621.  
  2622.  
  2623.  
  2624.     /*
  2625.     * Verifies that the next character IS a space
  2626.     */
  2627.     function _parseSpace(&$str,$line,$file$printError = true)
  2628.     {
  2629.     /*
  2630.         This code repeats a lot in this class
  2631.         so i make it a function to make all the code shorter
  2632.     */
  2633.         $this->_getNextToken$str $space );
  2634.         if$space != ' ' ){
  2635.             $this->_prot_error("must be a ' ' but is a '$space' !!!!$line $file,$printError );
  2636.         }
  2637.         return $space;
  2638.     }
  2639.  
  2640.  
  2641.  
  2642.  
  2643.  
  2644.  
  2645.     function _parseString&$str $char $line $file )
  2646.     {
  2647.     /*
  2648.         This code repeats a lot in this class
  2649.         so i make it a function to make all the code shorter
  2650.     */
  2651.         $this->_getNextToken$str $char_aux );
  2652.         ifstrtoupper($char_aux!= strtoupper$char ) ){
  2653.             $this->_prot_error("must be a $char but is a '$char_aux' !!!!"$line $file );
  2654.         }
  2655.         return $char_aux;
  2656.     }
  2657.  
  2658.  
  2659.  
  2660.  
  2661.  
  2662.     function _genericImapResponseParser&$str $cmdid = null )
  2663.     {
  2664.  
  2665.         $result_array=array();
  2666.         if$this->_unParsedReturn ){
  2667.             $unparsed_str $str;
  2668.         }
  2669.  
  2670.         $this->_getNextToken$str $token );
  2671.  
  2672.         while$token != $cmdid && $str != '' ){
  2673.         if($token == "+" ){
  2674.         //if the token  is + ignore the line
  2675.         // TODO: verify that this is correct!!!
  2676.             $this->_getToEOL$str );
  2677.             $this->_getNextToken$str $token );
  2678.         }
  2679.  
  2680.             $this->_parseString$str ' ' __LINE__ __FILE__ );
  2681.  
  2682.             $this->_getNextToken$str $token );
  2683.         if$token == '+' ){
  2684.             $this->_getToEOL$str );
  2685.             $this->_getNextToken$str $token );
  2686.         }else
  2687.             ifis_numeric$token ) ){
  2688.                 // The token is a NUMBER so I store it
  2689.                 $msg_nro $token;
  2690.                 $this->_parseSpace$str __LINE__ __FILE__ );
  2691.  
  2692.                 // I get the command
  2693.                 $this->_getNextToken$str $command );
  2694.  
  2695.                 if( ( $ext_arr $this->_retrParsedResponse$str $command$msg_nro ) ) == false ){
  2696.                 //  if this bogus response cis a FLAGS () or EXPUNGE response
  2697.                 // the ignore it
  2698.                     if$command != 'FLAGS' && $command != 'EXPUNGE' ){
  2699.                         $this->_prot_error("bogus response!!!!" __LINE__ __FILE__false);
  2700.                     }
  2701.                 }
  2702.                 $result_array[= array"COMMAND"=>$command "NRO"=>$msg_nro "EXT"=>$ext_arr );
  2703.             }else{
  2704.                 // OK the token is not a NUMBER so it MUST be a COMMAND
  2705.                 $command $token;
  2706.  
  2707.                 /* Call the parser return the array
  2708.                     take care of bogus responses!
  2709.                 */
  2710.  
  2711.                 if( ( $ext_arr $this->_retrParsedResponse$str $command ) ) == false ){
  2712.                     $this->_prot_error"bogus response!!!! (COMMAND:$command)__LINE__ __FILE__ );
  2713.                 }
  2714.                 $result_array[= array"COMMAND"=>$command "EXT"=>$ext_arr );
  2715.  
  2716.  
  2717.             }
  2718.  
  2719.  
  2720.             $this->_getNextToken$str $token );
  2721.  
  2722.             $token strtoupper$token );
  2723.             if$token != "\r\n" && $token != '' ){
  2724.                 $this->_prot_error("PARSE ERROR!!! must be a '\\r\\n' here  but is a '$token'!!!! (getting the next line)|STR:|$str|__LINE__ __FILE__ );
  2725.             }
  2726.             $this->_getNextToken$str $token );
  2727.  
  2728.             if($token == "+" ){
  2729.                 //if the token  is + ignore the line
  2730.                 // TODO: verify that this is correct!!!
  2731.                 $this->_getToEOL$str );
  2732.                 $this->_getNextToken$str $token );
  2733.             }
  2734.         }//While
  2735.         // OK we finish the UNTAGGED Response now we must parse the FINAL TAGGED RESPONSE
  2736.         //TODO: make this a litle more elegant!
  2737.  
  2738.         $this->_parseSpace$str __LINE__ __FILE__false );
  2739.  
  2740.         $this->_getNextToken$str $cmd_status );
  2741.  
  2742.         $str_line rtrim (substr$this->_getToEOL$str ) );
  2743.  
  2744.  
  2745.         $response["RESPONSE"]=array"CODE"=>$cmd_status "STR_CODE"=>$str_line "CMDID"=>$cmdid );
  2746.  
  2747.         $ret=$response;
  2748.         if!empty($result_array)){
  2749.             $ret=array_merge($ret,array("PARSED"=>$result_array) );
  2750.         }
  2751.  
  2752.         if$this->_unParsedReturn ){
  2753.             $unparsed["UNPARSED"]=$unparsed_str;
  2754.             $ret=array_merge($ret,$unparsed);
  2755.         }
  2756.  
  2757.  
  2758.         ifisset($status_arr) ){
  2759.             $status["STATUS"]=$status_arr;
  2760.             $ret=array_merge($ret,$status);
  2761.         }
  2762.         return $ret;
  2763.  
  2764. }
  2765.  
  2766.  
  2767.  
  2768.  
  2769.     function _genericCommand($command$params '')
  2770.     {
  2771.         if!$this->_connected ){
  2772.             return new PEAR_Error"not connected! (CMD:$command));
  2773.         }
  2774.         $cmdid $this->_getCmdId();
  2775.         $this->_putCMD$cmdid $command $params );
  2776.         $args=$this->_getRawResponse$cmdid );
  2777.         return $this->_genericImapResponseParser$args $cmdid );
  2778.     }
  2779.  
  2780.  
  2781.  
  2782.      function utf_7_encode($str)
  2783.     {
  2784.         if($this->_useUTF_7 == false ){
  2785.             return $str;
  2786.         }
  2787.         //return imap_utf7_encode($str);
  2788.  
  2789.         $encoded_utf7 '';
  2790.         $base64_part  '';
  2791.     if(is_array($str)){
  2792.         return new PEAR_Error('error');
  2793.     }
  2794.  
  2795.  
  2796.         for ($i = 0; $i strlen($str)$i++{
  2797.             //those chars should be base64 encoded
  2798.             if ( ((ord($str[$i]>= 39 and (ord($str[$i]<= 126 )) or ((ord($str[$i]>= 32 and (ord($str[$i]<= 37 )) ) {
  2799.                 if ($base64_part{
  2800.                     $encoded_utf7 sprintf("%s&%s-"$encoded_utf7str_replace('=''',base64_encode($base64_part))  );
  2801.                     $base64_part '';
  2802.                 }
  2803.                 $encoded_utf7 sprintf("%s%s",$encoded_utf7 $str[$i]);
  2804.             else {
  2805.                 //handle &
  2806.                 if (ord($str[$i]== 38 {
  2807.                     if ($base64_part{
  2808.                         $encoded_utf7 sprintf("%s&%s-"$encoded_utf7str_replace('=''',base64_encode($base64_part))  );
  2809.                         $base64_part '';
  2810.                     }
  2811.                     $encoded_utf7 sprintf("%s&-"$encoded_utf7 );
  2812.                 else {
  2813.                     $base64_part sprintf("%s%s",$base64_part  $str[$i]);
  2814.                     //$base64_part = sprintf("%s%s%s",$base64_part , chr(0) , $str[$i]);
  2815.                 }
  2816.             }
  2817.         }
  2818.         if ($base64_part{
  2819.             $encoded_utf7 sprintf("%s&%s-"$encoded_utf7str_replace('=''',base64_encode($base64_part))   );
  2820.             $base64_part '';
  2821.         }
  2822.         return $encoded_utf7;
  2823.     }
  2824.  
  2825.  
  2826.     function utf_7_decode($str)
  2827.     {
  2828.  
  2829.         if($this->_useUTF_7 == false ){
  2830.             return $str;
  2831.         }
  2832.  
  2833.         //return imap_utf7_decode($str);
  2834.  
  2835.         $base64_part '';
  2836.         $decoded_utf7 '';
  2837.  
  2838.         for ($i = 0; $i strlen($str)$i++{
  2839.             if strlen($base64_part> 0 {
  2840.                 if ($str[$i== '-'{
  2841.                     if ($base64_part == '&'{
  2842.                         $decoded_utf7 sprintf("%s&" $decoded_utf7 );
  2843.                     else {
  2844.                         $next_part_decodedbase64_decodesubstr$base64_part) ) ;
  2845.                         $decoded_utf7 sprintf("%s%s"$decoded_utf7 $next_part_decoded );
  2846.                     }
  2847.                     $base64_part '';
  2848.  
  2849.                 else {
  2850.                     $base64_part sprintf("%s%s"$base64_part $str[$i);
  2851.                 }
  2852.             else {
  2853.                 if ($str[$i== '&'{
  2854.                     $base64_part '&';
  2855.                 else {
  2856.                     $decoded_utf7 sprintf("%s%s"$decoded_utf7 $str[$i);
  2857.                 }
  2858.             }
  2859.         }
  2860.         return $decoded_utf7;
  2861.     }
  2862.  
  2863.  
  2864.  
  2865. }//Class
  2866. ?>

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