From: moodler <moodler>
Date: Fri, 22 Aug 2003 12:35:43 +0000 (+0000)
Subject: pclzip 2.0 RC2 - hopefully better!
X-Git-Url: http://git.mjollnir.org/gw?a=commitdiff_plain;h=0ddf039078a9f7fcbeec1d5dd7650a4b403cd12c;p=moodle.git

pclzip 2.0 RC2 - hopefully better!
---

diff --git a/lib/pclzip/pclzip.lib.php b/lib/pclzip/pclzip.lib.php
index 75d69929d6..c310856330 100644
--- a/lib/pclzip/pclzip.lib.php
+++ b/lib/pclzip/pclzip.lib.php
@@ -1,6 +1,6 @@
 <?php
 // --------------------------------------------------------------------------------
-// PhpConcept Library - Zip Module 2.0-rc1
+// PhpConcept Library - Zip Module 2.0-rc2
 // --------------------------------------------------------------------------------
 // License GNU/LGPL - Vincent Blavet - July 2003
 // http://www.phpconcept.net
@@ -63,7 +63,7 @@
 // --------------------------------------------------------------------------------
 
   // ----- Global variables
-  $g_pclzip_version = "2.0-rc1";
+  $g_pclzip_version = "2.0-rc2";
 
   // ----- Error codes
   //   -1 : Unable to open file in binary write mode
@@ -80,6 +80,7 @@
   //  -12 : Unable to rename file (rename)
   //  -13 : Invalid header checksum
   //  -14 : Invalid archive size
+  define( 'PCLZIP_ERR_NO_ERROR', 0 );
   define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
   define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
   define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
@@ -105,6 +106,10 @@
   define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
   define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
   define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
+  define( 'PCLZIP_OPT_BY_NAME', 77008 );
+  define( 'PCLZIP_OPT_BY_INDEX', 77009 );
+  define( 'PCLZIP_OPT_BY_EREG', 77010 );
+  define( 'PCLZIP_OPT_BY_PREG', 77011 );
 
   // ----- Call backs values
   define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
@@ -223,6 +228,7 @@
     $v_add_path = "";
     $v_remove_path = "";
     $v_remove_all_path = false;
+    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
 
     // ----- Look for variable options arguments
     $v_size = func_num_args();
@@ -264,13 +270,6 @@
         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
         }
-        if (!isset($v_options[PCLZIP_OPT_NO_COMPRESSION])) {
-          $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION not set.");
-        }
-        else {
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION set.");
-        }
       }
 
       // ----- Look for 2 args
@@ -385,6 +384,7 @@
     $v_add_path = "";
     $v_remove_path = "";
     $v_remove_all_path = false;
+    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
 
     // ----- Look for variable options arguments
     $v_size = func_num_args();
@@ -426,13 +426,6 @@
         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
         }
-        if (!isset($v_options[PCLZIP_OPT_NO_COMPRESSION])) {
-          $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION not set.");
-        }
-        else {
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_NO_COMPRESSION set.");
-        }
       }
 
       // ----- Look for 2 args
@@ -606,7 +599,7 @@
   //function extract($p_path="./", $p_remove_path="")
   function extract(/* options */)
   {
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip:extract", "");
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
     $v_result=1;
 
     // ----- Reset the error handler
@@ -628,6 +621,9 @@
     $v_size = func_num_args();
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
 
+    // ----- Default values for option
+    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
+
     // ----- Look for arguments
     if ($v_size > 0) {
       // ----- Get the arguments
@@ -645,7 +641,12 @@
                                                    PCLZIP_OPT_ADD_PATH => 'optional',
                                                    PCLZIP_CB_PRE_EXTRACT => 'optional',
                                                    PCLZIP_CB_POST_EXTRACT => 'optional',
-                                                   PCLZIP_OPT_SET_CHMOD => 'optional' ));
+                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
+                                                   PCLZIP_OPT_BY_NAME => 'optional',
+                                                   PCLZIP_OPT_BY_EREG => 'optional',
+                                                   PCLZIP_OPT_BY_PREG => 'optional',
+                                                   PCLZIP_OPT_BY_INDEX => 'optional',
+                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional' ));
         if ($v_result != 1) {
           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
           return 0;
@@ -699,7 +700,7 @@
 
     // ----- Call the extracting fct
     $p_list = array();
-    if (($v_result = $this->privExtract($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)
+    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)
     {
       unset($p_list);
       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
@@ -712,6 +713,7 @@
   }
   // --------------------------------------------------------------------------------
 
+
   // --------------------------------------------------------------------------------
   // Function :
   //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
@@ -856,37 +858,23 @@
     // ----- Trace
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
 
-    // ----- Look if the $p_index is really an integer
-    if (is_integer($p_index))
-    {
-      // ----- Call the extracting fct
-      if (($v_result = $this->privExtractByIndex($p_list, "$p_index", $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)
-      {
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
-        return(0);
-      }
+    // ----- Trick
+    // Here I want to reuse extractByRule(), so I need to parse the $p_index
+    // with privParseOptions()
+    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
+    $v_options_trick = array();
+    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
+                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));
+    if ($v_result != 1) {
+        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+        return 0;
     }
+    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
 
-    // ----- Look if the index is a string
-    else if (is_string($p_index))
-    {
-      // ----- Call the extracting fct
-      if (($v_result = $this->privExtractByIndex($p_list, $p_index, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)
-      {
+    // ----- Call the extracting fct
+    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1) {
         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
         return(0);
-      }
-    }
-
-    // ----- Invalid variable
-    else
-    {
-      // ----- Error log
-      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type $p_index");
-
-      // ----- Return
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
-      return 0;
     }
 
     // ----- Return
@@ -896,26 +884,21 @@
   // --------------------------------------------------------------------------------
 
   // --------------------------------------------------------------------------------
-  // Function : deleteByIndex()
+  // Function :
+  //   delete([$p_option, $p_option_value, ...])
   // Description :
-  //   This method delete somes files or folder entries from the zip archive.
-  //   The entries (files or folders) are identified by their index in the
-  //   archive (0-n).
-  //   Note that if the index identify a folder entry, only the folder entry
-  //   is deleted, and not all the files included in the folder.
   // Parameters :
-  //   $p_index : A single index (integer) or a string of indexes of files to
-  //              delete. The form of the string is "0,4-6,8-12" with only numbers
-  //              and '-' for range or ',' to separate ranges. No spaces or ';'
-  //              are allowed.
+  //   None
+  // Options :
+  //   PCLZIP_OPT_BY_INDEX :
   // Return Values :
   //   0 on failure,
   //   The list of the files which are still present in the archive.
   //   (see PclZip::listContent() for list entry format)
   // --------------------------------------------------------------------------------
-  function deleteByIndex($p_index)
+  function delete(/* options */)
   {
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
     $v_result=1;
 
     // ----- Reset the error handler
@@ -927,39 +910,77 @@
       return(0);
     }
 
-    // ----- Look if the $p_index is really an integer
-    if (is_integer($p_index))
-    {
-      // ----- Call the delete fct
-      if (($v_result = $this->privDeleteByIndex("$p_index", $p_list)) != 1)
-      {
+    // ----- Set default values
+    $v_options = array();
+
+    // ----- Look for variable options arguments
+    $v_size = func_num_args();
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
+
+    // ----- Look for no arguments
+    if ($v_size <= 0) {
+        // ----- Error log
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing arguments");
+
+        // ----- Return
         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
-        return(0);
-      }
+        return 0;
     }
 
-    // ----- Look if the index is a string
-    else if (is_string($p_index))
-    {
-      // ----- Call the delete fct
-      if (($v_result = $this->privDeleteByIndex($p_index, $p_list)) != 1)
-      {
+    // ----- Get the arguments
+    $v_arg_list = &func_get_args();
+
+    // ----- Parse the options
+    $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
+                                        array (PCLZIP_OPT_BY_NAME => 'optional',
+                                               PCLZIP_OPT_BY_EREG => 'optional',
+                                               PCLZIP_OPT_BY_PREG => 'optional',
+                                               PCLZIP_OPT_BY_INDEX => 'optional' ));
+    if ($v_result != 1) {
+        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
+        return 0;
+    }
+
+    // ----- Check that at least one rule is set
+    if (   (!isset($v_options[PCLZIP_OPT_BY_NAME]))
+        && (!isset($v_options[PCLZIP_OPT_BY_EREG]))
+        && (!isset($v_options[PCLZIP_OPT_BY_PREG]))
+        && (!isset($v_options[PCLZIP_OPT_BY_INDEX]))) {
+        // ----- Error log
+        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "At least one filtering rule must be set");
+
+        // ----- Return
         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
-        return(0);
-      }
+        return 0;
     }
 
-    // ----- Invalid variable
-    else
+    // ----- Call the delete fct
+    $v_list = array();
+    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1)
     {
-      // ----- Error log
-      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type $p_index");
-
-      // ----- Return
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
-      return 0;
+      unset($v_list);
+      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
+      return(0);
     }
 
+    // ----- Return
+    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
+    return $v_list;
+  }
+  // --------------------------------------------------------------------------------
+
+  // --------------------------------------------------------------------------------
+  // Function : deleteByIndex()
+  // Description :
+  //   ***** Deprecated *****
+  //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
+  // --------------------------------------------------------------------------------
+  function deleteByIndex($p_index)
+  {
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
+    
+    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
+
     // ----- Return
     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
     return $p_list;
@@ -1360,6 +1381,168 @@
           $i++;
         break;
 
+        // ----- Look for options that request an array of string for value
+        case PCLZIP_OPT_BY_NAME :
+          // ----- Check the number of parameters
+          if (($i+1) >= $p_size) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+            return PclZip::errorCode();
+          }
+
+          // ----- Get the value
+          if (is_string($p_options_list[$i+1])) {
+              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
+          }
+          else if (is_array($p_options_list[$i+1])) {
+              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+          }
+          else {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+            return PclZip::errorCode();
+          }
+          ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+          $i++;
+        break;
+
+        // ----- Look for options that request an EREG or PREG expression
+        case PCLZIP_OPT_BY_EREG :
+        case PCLZIP_OPT_BY_PREG :
+          // ----- Check the number of parameters
+          if (($i+1) >= $p_size) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+            return PclZip::errorCode();
+          }
+
+          // ----- Get the value
+          if (is_string($p_options_list[$i+1])) {
+              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
+          }
+          else {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+            return PclZip::errorCode();
+          }
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
+          $i++;
+        break;
+
+        // ----- Look for options that request an array of index
+        case PCLZIP_OPT_BY_INDEX :
+          // ----- Check the number of parameters
+          if (($i+1) >= $p_size) {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+            return PclZip::errorCode();
+          }
+
+          // ----- Get the value
+          $v_work_list = array();
+          if (is_string($p_options_list[$i+1])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
+
+              // ----- Remove spaces
+              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
+
+              // ----- Parse items
+              $v_work_list = explode(",", $p_options_list[$i+1]);
+          }
+          else if (is_integer($p_options_list[$i+1])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
+              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
+          }
+          else if (is_array($p_options_list[$i+1])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
+              $v_work_list = $p_options_list[$i+1];
+          }
+          else {
+            // ----- Error log
+            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+            return PclZip::errorCode();
+          }
+          
+          // ----- Reduce the index list
+          // each index item in the list must be a couple with a start and
+          // an end value : [0,3], [5-5], [8-10], ...
+          // ----- Check the format of each item
+          $v_sort_flag=false;
+          $v_sort_value=0;
+          for ($j=0; $j<sizeof($v_work_list); $j++) {
+              // ----- Explode the item
+              $v_item_list = explode("-", $v_work_list[$j]);
+              $v_size_item_list = sizeof($v_item_list);
+              
+              // ----- TBC : Here we might check that each item is a
+              // real integer ...
+              
+              // ----- Look for single value
+              if ($v_size_item_list == 1) {
+                  // ----- Set the option value
+                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
+              }
+              elseif ($v_size_item_list == 2) {
+                  // ----- Set the option value
+                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
+                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
+              }
+              else {
+                  // ----- Error log
+                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+                  // ----- Return
+                  //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+                  return PclZip::errorCode();
+              }
+
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");
+
+              // ----- Look for list sort
+              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
+                  $v_sort_flag=true;
+
+                  // ----- TBC : An automatic sort should be writen ...
+                  // ----- Error log
+                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
+
+                  // ----- Return
+                  //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+                  return PclZip::errorCode();
+              }
+              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
+          }
+          
+          // ----- Sort the items
+          if ($v_sort_flag) {
+              // TBC : To Be Completed
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
+          }
+
+          // ----- Next option
+          $i++;
+        break;
+
         // ----- Look for options that request no value
         case PCLZIP_OPT_REMOVE_ALL_PATH :
         case PCLZIP_OPT_EXTRACT_AS_STRING :
@@ -1506,10 +1689,10 @@
     $v_result=1;
     $v_list_detail = array();
 
-    // ----- Look if the archive exists
-    if (!is_file($this->zipname))
+    // ----- Look if the archive exists or is empty
+    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
     {
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, create it.");
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
 
       // ----- Do a create
       $v_result = $this->privCreate($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);
@@ -2414,7 +2597,7 @@
     $p_info['compressed_size'] = $p_header['compressed_size'];
     $p_info['mtime'] = $p_header['mtime'];
     $p_info['comment'] = $p_header['comment'];
-    $p_info['folder'] = ($p_header['external']==0x41FF0010);
+    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
     $p_info['index'] = $p_header['index'];
     $p_info['status'] = $p_header['status'];
 
@@ -2425,8 +2608,9 @@
   // --------------------------------------------------------------------------------
 
   // --------------------------------------------------------------------------------
-  // Function : privExtract()
+  // Function : privExtractByRule()
   // Description :
+  //   Extract a file or directory depending of rules (by index, by name, ...)
   // Parameters :
   //   $p_file_list : An array where will be placed the properties of each
   //                  extracted file
@@ -2439,13 +2623,13 @@
   // Return Values :
   //   1 on success,0 or less on error (see error code list)
   // --------------------------------------------------------------------------------
-  function privExtract(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
+  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
   {
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtract", "list, path=$p_path, remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
     $v_result=1;
 
     // ----- Check the path
-    if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")&& (substr($p_path,1,2)!= ":/")))
+    if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/")))
       $p_path = "./".$p_path;
 
     // ----- Reduce the path last (and duplicated) '/'
@@ -2490,14 +2674,15 @@
     $v_pos_entry = $v_central_dir['offset'];
 
     // ----- Read each entry
-    for ($i=0; $i<$v_central_dir['entries']; $i++)
+    $j_start = 0;
+    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
     {
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file entry : $i'");
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
 
       // ----- Read next Central dir entry
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
       @rewind($this->zip_fd);
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
       if (@fseek($this->zip_fd, $v_pos_entry))
       {
         // ----- Close the zip file
@@ -2529,210 +2714,90 @@
       // ----- Store the file position
       $v_pos_entry = ftell($this->zip_fd);
 
-      // ----- Go to the file position
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");
-      @rewind($this->zip_fd);
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");
-      if (@fseek($this->zip_fd, $v_header['offset']))
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-
-        // ----- Error log
-        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
-
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
-        return PclZip::errorCode();
-      }
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
-
-      // ----- Extracting the file
-      if (($v_result = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options)) != 1)
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
-      }
-
-      // ----- Get the only interesting attributes
-      if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$i])) != 1)
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
+      // ----- Look for the specific extract rules
+      $v_extract = false;
 
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
+      // ----- Look for extract by name rule
+      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
+          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
+
+          // ----- Look if the filename is in the list
+          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
+
+              // ----- Look for a directory
+              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
+
+                  // ----- Look if the directory is in the filename path
+                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
+                      $v_extract = true;
+                  }
+              }
+              // ----- Look for a filename
+              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
+                  $v_extract = true;
+              }
+          }
       }
-    }
 
-    // ----- Close the zip file
-    $this->privCloseFd();
+      // ----- Look for extract by ereg rule
+      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
+               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
 
-    // ----- Return
-    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-    return $v_result;
-  }
-  // --------------------------------------------------------------------------------
-
-  // --------------------------------------------------------------------------------
-  // Function : privExtractByIndex()
-  // Description :
-  // Parameters :
-  //   $p_file_list : An array where will be placed the properties of each
-  //                  extracted file
-  //   $p_index : A single index (integer) or a string of indexes of files to
-  //              extract. The form of the string is "0,4-6,8-12" with only numbers
-  //              and '-' for range or ',' to separate ranges. No spaces or ';'
-  //              are allowed.
-  //   $p_path : Path to add while writing the extracted files
-  //   $p_remove_path : Path to remove (from the file memorized path) while writing the
-  //                    extracted files. If the path does not match the file path,
-  //                    the file is extracted with its memorized path.
-  //                    $p_remove_path does not apply to 'list' mode.
-  //                    $p_path and $p_remove_path are commulative.
-  // Return Values :
-  //   1 on success,0 or less on error (see error code list)
-  // --------------------------------------------------------------------------------
-  function privExtractByIndex(&$p_file_list, $p_index, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
-  {
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByIndex", "list, index='$p_index', path=$p_path, remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
-    $v_result=1;
-
-    // ----- Check the path
-    if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../")&& (substr($p_path,1,2)!=":/")))
-      $p_path = "./".$p_path;
-
-    // ----- Reduce the path last (and duplicated) '/'
-    if (($p_path != "./") && ($p_path != "/"))
-    {
-      // ----- Look for the path end '/'
-      while (substr($p_path, -1) == "/")
-      {
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
-        $p_path = substr($p_path, 0, strlen($p_path)-1);
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
+          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+              $v_extract = true;
+          }
       }
-    }
-
-    // ----- Look for path to remove format (should end by /)
-    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
-    {
-      $p_remove_path .= '/';
-    }
-    $p_remove_path_size = strlen($p_remove_path);
-
-    // ----- Open the zip file
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
-    if (($v_result = $this->privOpenFd('rb')) != 1)
-    {
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-      return $v_result;
-    }
 
-    // ----- Read the central directory informations
-    $v_central_dir = array();
-    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
-    {
-      // ----- Close the zip file
-      $this->privCloseFd();
-
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-      return $v_result;
-    }
+      // ----- Look for extract by preg rule
+      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
+               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
 
-    // ----- Manipulate the index list
-    $p_index = strtr($p_index, ' ', '');
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Reduced index : '$p_index'");
-    $v_index_list = explode(",", $p_index);
-    // TBC : Here I should sort the index. However a simple sort is not enought.
-    // look for the use of usort()
-    //sort($v_index_list);
-
-    // ----- Start at beginning of Central Dir
-    $v_pos_entry = $v_central_dir['offset'];
-
-    // ----- Read each entry
-    for ($i=0, $j_start=0, $v_nb_extracted=0; ($i<$v_central_dir['entries']) && ($j_start<sizeof($v_index_list)); $i++)
-    {
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : $i'");
-
-      // ----- Read next Central dir entry
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");
-      @rewind($this->zip_fd);
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");
-      if (@fseek($this->zip_fd, $v_pos_entry))
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-
-        // ----- Error log
-        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
-
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
-        return PclZip::errorCode();
+          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+              $v_extract = true;
+          }
       }
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
-
-      // ----- Read the file header
-      $v_header = array();
-      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
 
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
+      // ----- Look for extract by index rule
+      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
+          
+          // ----- Look if the index is in the list
+          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
+
+              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
+                  $v_extract = true;
+              }
+              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
+                  $j_start = $j+1;
+              }
+
+              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
+                  break;
+              }
+          }
       }
 
-      // ----- Store the index
-      $v_header['index'] = $i;
-
-      // ----- Store the file position
-      $v_pos_entry = ftell($this->zip_fd);
-
-      // ----- Look if the index is in the list
-      $v_extract = false;
-      for ($j=$j_start; ($j<sizeof($v_index_list)) && (!$v_extract); $j++)
-      {
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in '".$v_index_list[$j]."'");
-
-        // ----- Extract range
-        $v_item_list = explode("-", $v_index_list[$j]);
-        $v_size_item_list = sizeof($v_item_list);
-        if ($v_size_item_list == 1)
-        {
-          if ($i==$v_item_list[0])
-          {
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as a single index");
-            $v_extract = true;
-          }
-          if ($i>=$v_item_list[0])
-          {
-            $j_start = $j+1;
-          }
-        }
-        else if ($v_size_item_list == 2)
-        {
-          if (($i>=$v_item_list[0]) && ($i<=$v_item_list[1]))
-          {
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
-            $v_extract = true;
-          }
-          if ($i>=$v_item_list[1])
-          {
-            $j_start = $j+1;
-          }
-        }
-        if ($v_item_list[0]>$i)
-        {
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Range is greater than index, stop loop");
-          break;
-        }
+      // ----- Look for no rule, which means extract all the archive
+      else {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
+          $v_extract = true;
       }
+      
 
       // ----- Look for real extraction
       if ($v_extract)
@@ -2740,9 +2805,9 @@
         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
 
         // ----- Go to the file position
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
         @rewind($this->zip_fd);
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
         if (@fseek($this->zip_fd, $v_header['offset']))
         {
           // ----- Close the zip file
@@ -2755,7 +2820,7 @@
           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
           return PclZip::errorCode();
         }
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
 
         // ----- Look for extraction as string
         if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
@@ -2779,10 +2844,10 @@
             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
             return $v_result;
           }
-          
+
           // ----- Set the file content
           $p_file_list[$v_nb_extracted]['content'] = $v_string;
-          
+
           // ----- Next extracted file
           $v_nb_extracted++;
         }
@@ -2959,14 +3024,14 @@
 
     // ----- Check the directory availability and create it if necessary
     else {
-      if (($p_entry['external']==0x41FF0010) || (substr($p_entry['filename'], -1) == '/'))
+      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
         $v_dir_to_check = $p_entry['filename'];
       else if (!strstr($p_entry['filename'], "/"))
         $v_dir_to_check = "";
       else
         $v_dir_to_check = dirname($p_entry['filename']);
 
-      if (($v_result = $this->privDirCheck($v_dir_to_check, ($p_entry['external']==0x41FF0010))) != 1) {
+      if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
 
         // ----- Change the file status
@@ -2984,7 +3049,7 @@
     if ($p_entry['status'] == 'ok') {
 
       // ----- Do the extraction (if not a folder)
-      if (!($p_entry['external']==0x41FF0010))
+      if (!(($p_entry['external']&0x00000010)==0x00000010))
       {
 
         // ----- Look for not compressed file
@@ -3122,7 +3187,7 @@
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
 
     // ----- Do the extraction (if not a folder)
-    if (!($p_entry['external']==0x41FF0010))
+    if (!(($p_entry['external']&0x00000010)==0x00000010))
     {
       // ----- Look for not compressed file
       if ($p_entry['compressed_size'] == $p_entry['size'])
@@ -3335,44 +3400,42 @@
     }
 
     // ----- Extract the values
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
     $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
 
     // ----- Get filename
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$p_header['filename_len']);
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
     if ($p_header['filename_len'] != 0)
       $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
     else
       $p_header['filename'] = '';
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');
 
     // ----- Get extra
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra length : ".$p_header['extra_len']);
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
     if ($p_header['extra_len'] != 0)
       $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
     else
       $p_header['extra'] = '';
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra : \''.$p_header['extra'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');
 
     // ----- Get comment
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$p_header['comment_len']);
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
     if ($p_header['comment_len'] != 0)
       $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
     else
       $p_header['comment'] = '';
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_header['comment'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');
 
     // ----- Extract properties
-    //$p_header['size'] = $v_data['size'];
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');
-    //$p_header['compressed_size'] = $v_data['compressed_size'];
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
-    //$p_header['crc'] = $v_data['crc'];
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.$p_header['crc'].'\'');
-    //$p_header['flag'] = $v_data['flag'];
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset : \''.$p_header['offset'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.$p_header['crc'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');
 
     // ----- Recuperate date in UNIX format
     if ($p_header['mdate'] && $p_header['mtime'])
@@ -3390,12 +3453,12 @@
       // ----- Get UNIX date format
       $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
 
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
     }
     else
     {
       $p_header['mtime'] = time();
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
     }
 
     // ----- Set the stored filename
@@ -3405,18 +3468,15 @@
     $p_header['status'] = 'ok';
 
     // ----- Look if it is a directory
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "external (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".($p_header['external']==0x41FF0010?'is a folder':'is a file').')');
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "External (Hex) : '".sprintf("Ox%04X", $p_header['external'])."' (".(($p_header['external']&0x00000010)==0x00000010?'is a folder':'is a file').')');
     if (substr($p_header['filename'], -1) == '/')
     {
       $p_header['external'] = 0x41FF0010;
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Force folder external : \''.$p_header['external'].'\'');
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.$p_header['external'].'\'');
     }
 
-
-    // TBC
-    //for(reset($p_header); $key = key($p_header); next($p_header)) {
-    // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
-    //}
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');
 
     // ----- Return
     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
@@ -3603,14 +3663,14 @@
   // --------------------------------------------------------------------------------
 
   // --------------------------------------------------------------------------------
-  // Function : privDeleteByIndex()
+  // Function : privDeleteByRule()
   // Description :
   // Parameters :
   // Return Values :
   // --------------------------------------------------------------------------------
-  function privDeleteByIndex($p_index, &$p_result_list)
+  function privDeleteByRule(&$p_result_list, &$p_options)
   {
-    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByIndex", "index='$p_index'");
+    //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
     $v_result=1;
     $v_list_detail = array();
 
@@ -3638,19 +3698,11 @@
     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
 
     // ----- Scan all the files
-    // ----- Manipulate the index list
-    $p_index = strtr($p_index, ' ', '');
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Reduced index : '$p_index'");
-    $v_index_list = explode(",", $p_index);
-    // TBC : Here I should sort the index. However a simple sort is not enought.
-    // look for the use of usort()
-    //sort($v_index_list);
-
     // ----- Start at beginning of Central Dir
     $v_pos_entry = $v_central_dir['offset'];
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position before rewind : ".ftell($this->zip_fd)."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
     @rewind($this->zip_fd);
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after rewind : ".ftell($this->zip_fd)."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
     if (@fseek($this->zip_fd, $v_pos_entry))
     {
       // ----- Close the zip file
@@ -3663,13 +3715,14 @@
       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
       return PclZip::errorCode();
     }
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
+    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
 
     // ----- Read each entry
     $v_header_list = array();
-    for ($i=0, $j_start=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
+    $j_start = 0;
+    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
     {
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : $i'");
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
 
       // ----- Read the file header
       $v_header_list[$v_nb_extracted] = array();
@@ -3682,209 +3735,255 @@
         return $v_result;
       }
 
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
+
       // ----- Store the index
       $v_header_list[$v_nb_extracted]['index'] = $i;
 
-      // ----- Look if the index is in the list
-      for ($j=$j_start, $v_found = false; ($j<sizeof($v_index_list)) && (!$v_found); $j++)
-      {
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in '".$v_index_list[$j]."'");
-
-        // ----- Extract range
-        $v_item_list = explode("-", $v_index_list[$j]);
-        $v_size_item_list = sizeof($v_item_list);
-        if ($v_size_item_list == 1)
-        {
-          if ($i==$v_item_list[0])
-          {
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as a single index");
-            $v_found = true;
+      // ----- Look for the specific extract rules
+      $v_found = false;
+
+      // ----- Look for extract by name rule
+      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
+          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
+
+          // ----- Look if the filename is in the list
+          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
+
+              // ----- Look for a directory
+              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
+
+                  // ----- Look if the directory is in the filename path
+                  if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
+                      && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
+                      $v_found = true;
+                  }
+                  elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
+                          && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
+                      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
+                      $v_found = true;
+                  }
+              }
+              // ----- Look for a filename
+              elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
+                  $v_found = true;
+              }
           }
-          if ($i>=$v_item_list[0])
-          {
-            $j_start = $j+1;
+      }
+
+      // ----- Look for extract by ereg rule
+      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
+               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
+
+          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+              $v_found = true;
           }
-        }
-        else if ($v_size_item_list == 2)
-        {
-          if (($i>=$v_item_list[0]) && ($i<=$v_item_list[1]))
-          {
-            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
-            $v_found = true;
+      }
+
+      // ----- Look for extract by preg rule
+      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
+               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
+
+          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
+              $v_found = true;
           }
-          if ($i>=$v_item_list[1])
-          {
-            $j_start = $j+1;
+      }
+
+      // ----- Look for extract by index rule
+      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
+               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
+          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
+
+          // ----- Look if the index is in the list
+          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
+              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look if index '$i' is in [".$p_options[PCLZIP_OPT_BY_INDEX][$j]['start'].",".$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']."]");
+
+              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
+                  $v_found = true;
+              }
+              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
+                  $j_start = $j+1;
+              }
+
+              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
+                  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
+                  break;
+              }
           }
-        }
-        if ($v_item_list[0]>$i)
-        {
-          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Range is greater than index, stop loop");
-          break;
-        }
       }
 
       // ----- Look for deletion
       if ($v_found)
       {
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header['filename']."', index '$i' need to be deleted");
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
         unset($v_header_list[$v_nb_extracted]);
       }
       else
       {
-        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header['filename']."', index '$i' will not be deleted");
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
         $v_nb_extracted++;
       }
     }
 
-    // ----- Creates a temporay file
-    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
+    // ----- Look if something need to be deleted
+    if ($v_nb_extracted > 0) {
 
-    // ----- Creates a temporary zip archive
-    $v_temp_zip = new PclZip($v_zip_temp_name);
+        // ----- Creates a temporay file
+        $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
 
-    // ----- Open the temporary zip file in write mode
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
-    if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1)
-    {
-      $this->privCloseFd();
+        // ----- Creates a temporary zip archive
+        $v_temp_zip = new PclZip($v_zip_temp_name);
 
-      // ----- Return
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-      return $v_result;
-    }
+        // ----- Open the temporary zip file in write mode
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
+        if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
+            $this->privCloseFd();
 
-    // ----- Look which file need to be kept
-    for ($i=0; $i<sizeof($v_header_list); $i++)
-    {
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry : $i'");
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+            return $v_result;
+        }
 
-      // ----- Calculate the position of the header
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Offset='". $v_header_list[$i]['offset']."'");
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
-      @rewind($this->zip_fd);
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
-      if (@fseek($this->zip_fd,  $v_header_list[$i]['offset']))
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-        $v_temp_zip->privCloseFd();
-        @unlink($v_zip_temp_name);
+        // ----- Look which file need to be kept
+        for ($i=0; $i<sizeof($v_header_list); $i++) {
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
+
+            // ----- Calculate the position of the header
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
+            @rewind($this->zip_fd);
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
+            if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+                $v_temp_zip->privCloseFd();
+                @unlink($v_zip_temp_name);
+
+                // ----- Error log
+                PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+
+                // ----- Return
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
+                return PclZip::errorCode();
+            }
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
+
+            // ----- Read the file header
+            if (($v_result = $this->privReadFileHeader($v_header_list[$i])) != 1) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+                $v_temp_zip->privCloseFd();
+                @unlink($v_zip_temp_name);
+
+                // ----- Return
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+                return $v_result;
+            }
 
-        // ----- Error log
-        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
+            // ----- Write the file header
+            if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+                $v_temp_zip->privCloseFd();
+                @unlink($v_zip_temp_name);
 
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
-        return PclZip::errorCode();
-      }
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
+                // ----- Return
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+                return $v_result;
+            }
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
+
+            // ----- Read/write the data block
+            if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
+                // ----- Close the zip file
+                $this->privCloseFd();
+                $v_temp_zip->privCloseFd();
+                @unlink($v_zip_temp_name);
+
+                // ----- Return
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+                return $v_result;
+            }
+        }
 
-      // ----- Read the file header
-      if (($v_result = $this->privReadFileHeader($v_header_list[$i])) != 1)
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-        $v_temp_zip->privCloseFd();
-        @unlink($v_zip_temp_name);
+        // ----- Store the offset of the central dir
+        $v_offset = @ftell($v_temp_zip->zip_fd);
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
+
+        // ----- Re-Create the Central Dir files header
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
+        for ($i=0; $i<sizeof($v_header_list); $i++) {
+            // ----- Create the file header
+            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
+            if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
+                $v_temp_zip->privCloseFd();
+                $this->privCloseFd();
+                @unlink($v_zip_temp_name);
+
+                // ----- Return
+                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+                return $v_result;
+            }
 
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
-      }
+            // ----- Transform the header to a 'usable' info
+            $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
+        }
 
-      // ----- Write the file header
-      if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1)
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-        $v_temp_zip->privCloseFd();
-        @unlink($v_zip_temp_name);
+        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
 
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
-      }
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset for this file is '".$v_header_list[$i]['offset']."'");
+        // ----- Zip file comment
+        $v_comment = '';
 
-      // ----- Read/write the data block
-      if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1)
-      {
-        // ----- Close the zip file
-        $this->privCloseFd();
-        $v_temp_zip->privCloseFd();
-        @unlink($v_zip_temp_name);
+        // ----- Calculate the size of the central header
+        $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
 
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
-      }
-    }
+        // ----- Create the central dir footer
+        if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
+            // ----- Reset the file list
+            unset($v_header_list);
+            $v_temp_zip->privCloseFd();
+            $this->privCloseFd();
+            @unlink($v_zip_temp_name);
 
-    // ----- Store the offset of the central dir
-    $v_offset = @ftell($v_temp_zip->zip_fd);
-    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
+            // ----- Return
+            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
+            return $v_result;
+        }
 
-    // ----- Re-Create the Central Dir files header
-    for ($i=0; $i<sizeof($v_header_list); $i++)
-    {
-      // ----- Create the file header
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Offset of file : ".$v_header_list[$i]['offset']);
-      if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1)
-      {
+        // ----- Close
         $v_temp_zip->privCloseFd();
         $this->privCloseFd();
-        @unlink($v_zip_temp_name);
 
-        // ----- Return
-        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-        return $v_result;
-      }
+        // ----- Delete the zip file
+        // TBC : I should test the result ...
+        @unlink($this->zipname);
 
-      // ----- Transform the header to a 'usable' info
-      $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
-    }
-
-    // ----- Zip file comment
-    $v_comment = '';
-
-    // ----- Calculate the size of the central header
-    $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
-
-    // ----- Create the central dir footer
-    if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1)
-    {
-      // ----- Reset the file list
-      unset($v_header_list);
-      $v_temp_zip->privCloseFd();
-      $this->privCloseFd();
-      @unlink($v_zip_temp_name);
-
-      // ----- Return
-      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
-      return $v_result;
+        // ----- Rename the temporary file
+        // TBC : I should test the result ...
+        //@rename($v_zip_temp_name, $this->zipname);
+        PclZipUtilRename($v_zip_temp_name, $this->zipname);
+    
+        // ----- Destroy the temporary archive
+        unset($v_temp_zip);
     }
 
-    // ----- Close
-    $v_temp_zip->privCloseFd();
-    $this->privCloseFd();
-
-    // ----- Delete the zip file
-    // TBC : I should test the result ...
-    @unlink($this->zipname);
-
-    // ----- Rename the temporary file
-    // TBC : I should test the result ...
-    //@rename($v_zip_temp_name, $this->zipname);
-    PclZipUtilRename($v_zip_temp_name, $this->zipname);
-
     // ----- Return
     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
     return $v_result;
   }
   // --------------------------------------------------------------------------------
 
-
   // --------------------------------------------------------------------------------
   // Function : privDirCheck()
   // Description :
@@ -4377,9 +4476,9 @@
     if ($v_result) {
       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
       // ----- Skip all the empty items
-      while (($v_list_path[$j] == '') && ($j < $v_list_path_size)) $j++;
-      while (($v_list_dir[$i] == '') && ($i < $v_list_dir_size)) $i++;
-      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
+      while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
+      while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
+      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Looking on dir($i)='".($i < $v_list_dir_size?$v_list_dir[$i]:'')."' and path($j)='".($j < $v_list_path_size?$v_list_path[$j]:'')."'");
 
       if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
         // ----- There are exactly the same
@@ -4538,6 +4637,18 @@
       case PCLZIP_OPT_SET_CHMOD :
         $v_result = 'PCLZIP_OPT_SET_CHMOD';
       break;
+      case PCLZIP_OPT_BY_NAME :
+        $v_result = 'PCLZIP_OPT_BY_NAME';
+      break;
+      case PCLZIP_OPT_BY_INDEX :
+        $v_result = 'PCLZIP_OPT_BY_INDEX';
+      break;
+      case PCLZIP_OPT_BY_EREG :
+        $v_result = 'PCLZIP_OPT_BY_EREG';
+      break;
+      case PCLZIP_OPT_BY_PREG :
+        $v_result = 'PCLZIP_OPT_BY_PREG';
+      break;
 
 
       case PCLZIP_CB_PRE_EXTRACT :
@@ -4576,7 +4687,7 @@
   // --------------------------------------------------------------------------------
   function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
   {
-    if (OS_WINDOWS) {
+    if (stristr(php_uname(), 'windows')) {
       // ----- Look for potential disk letter
       if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
           $p_path = substr($p_path, $v_position+1);
diff --git a/lib/pclzip/readme.txt b/lib/pclzip/readme.txt
index e53dfaf7bd..4574840d87 100644
--- a/lib/pclzip/readme.txt
+++ b/lib/pclzip/readme.txt
@@ -1,5 +1,5 @@
 // --------------------------------------------------------------------------------
-// PclZip 2.0-rc1 - readme.txt
+// PclZip 2.0-rc2 - readme.txt
 // --------------------------------------------------------------------------------
 // License GNU/GPL - january 2003
 // Vincent Blavet - vincent@phpconcept.net
@@ -31,9 +31,22 @@
 2 - What's new
 ==============
 
-  Version 2.0-rc1 :
+  Version 2.0-rc2 :
     ***** Warning : Some new features may break the backward compatibility for your scripts.
                     Please carefully read the readme file.
+    - Add the ability to delete by Index, name and regular expression. This feature is 
+      performed by the method delete(), which uses the optional parameters
+      PCLZIP_OPT_BY_INDEX, PCLZIP_OPT_BY_NAME, PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG.
+    - Add the ability to extract by regular expression. To extract by regexp you must use the method
+      extract(), with the option PCLZIP_OPT_BY_EREG or PCLZIP_OPT_BY_PREG 
+      (depending if you want to use ereg() or preg_match() syntax) followed by the 
+      regular expression pattern.
+    - Add the ability to extract by index, directly with the extract() method. This is a
+      code improvment of the extractByIndex() method.
+    - Add the ability to extract by name. To extract by name you must use the method
+      extract(), with the option PCLZIP_OPT_BY_NAME followed by the filename to
+      extract or an array of filenames to extract. To extract all a folder, use the folder
+      name rather than the filename with a '/' at the end.
     - Add the ability to add files without compression. This is done with a new attribute
       which is PCLZIP_OPT_NO_COMPRESSION.
     - Add the attribute PCLZIP_OPT_EXTRACT_AS_STRING, which allow to extract a file directly
@@ -48,6 +61,11 @@
       path is the same
       as a zipped dir. The dir is not zipped (['status'] = filtered), only its content.
     - Add better support for windows paths (thanks for help from manus@manusfreedom.com).
+    - Corrected bug : When the archive file already exists with size=0, the add() method
+      fails. Corrected in 2.0.
+    - Remove the use of OS_WINDOWS constant. Use php_uname() function rather.
+    - Control the order of index ranges in extract by index feature.
+    - Change the internal management of folders (better handling of internal flag).
 
 
   Version 1.3 :