home *** CD-ROM | disk | FTP | other *** search
/ Chip 2004 April / CMCD0404.ISO / Software / Freeware / Programare / groupoffice-com-2.01 / classes / pclzip.class.inc < prev    next >
Text File  |  2004-03-08  |  200KB  |  4,705 lines

  1. <?php
  2. // --------------------------------------------------------------------------------
  3. // PhpConcept Library - Zip Module 2.0
  4. // --------------------------------------------------------------------------------
  5. // License GNU/LGPL - Vincent Blavet - September 2003
  6. // http://www.phpconcept.net
  7. // --------------------------------------------------------------------------------
  8. //
  9. // Presentation :
  10. //   PclZip is a PHP library that manage ZIP archives.
  11. //   So far tests show that archives generated by PclZip are readable by
  12. //   WinZip application and other tools.
  13. //
  14. // Description :
  15. //   See readme.txt and http://www.phpconcept.net
  16. //
  17. // Warning :
  18. //   This library and the associated files are non commercial, non professional
  19. //   work.
  20. //   It should not have unexpected results. However if any damage is caused by
  21. //   this software the author can not be responsible.
  22. //   The use of this software is at the risk of the user.
  23. //
  24. // --------------------------------------------------------------------------------
  25. // $Id: pclzip.class.inc,v 1.1 2003/12/03 19:46:47 mschering Exp $
  26. // --------------------------------------------------------------------------------
  27.  
  28.   // ----- Constants
  29.   define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
  30.   
  31.   // ----- File list separator
  32.   // In version 1.x of PclZip, the separator for file list is a space
  33.   // (which is not a very smart choice, specifically for windows paths !).
  34.   // A better separator should be a comma (,). This constant gives you the
  35.   // abilty to change that.
  36.   // However notice that changing this value, may have impact on existing
  37.   // scripts, using space separated filenames.
  38.   // Recommanded values for compatibility with older versions :
  39.   //define( 'PCLZIP_SEPARATOR', ' ' );
  40.   // Recommanded values for smart separation of filenames.
  41.   define( 'PCLZIP_SEPARATOR', ',' );
  42.  
  43.   // ----- Error configuration
  44.   // 0 : PclZip Class integrated error handling
  45.   // 1 : PclError external library error handling. By enabling this
  46.   //     you must ensure that you have included PclError library.
  47.   // [2,...] : reserved for futur use
  48.   define( 'PCLZIP_ERROR_EXTERNAL', 0 );
  49.  
  50.   // ----- Optional static temporary directory
  51.   //       By default temporary files are generated in the script current
  52.   //       path.
  53.   //       If defined :
  54.   //       - MUST BE terminated by a '/'.
  55.   //       - MUST be a valid, already created directory
  56.   //       Samples :
  57.   // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
  58.   // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
  59.   define( 'PCLZIP_TEMPORARY_DIR', '' );
  60.  
  61. // --------------------------------------------------------------------------------
  62. // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
  63. // --------------------------------------------------------------------------------
  64.  
  65.   // ----- Global variables
  66.   $g_pclzip_version = "2.0";
  67.  
  68.   // ----- Error codes
  69.   //   -1 : Unable to open file in binary write mode
  70.   //   -2 : Unable to open file in binary read mode
  71.   //   -3 : Invalid parameters
  72.   //   -4 : File does not exist
  73.   //   -5 : Filename is too long (max. 255)
  74.   //   -6 : Not a valid zip file
  75.   //   -7 : Invalid extracted file size
  76.   //   -8 : Unable to create directory
  77.   //   -9 : Invalid archive extension
  78.   //  -10 : Invalid archive format
  79.   //  -11 : Unable to delete file (unlink)
  80.   //  -12 : Unable to rename file (rename)
  81.   //  -13 : Invalid header checksum
  82.   //  -14 : Invalid archive size
  83.   define( 'PCLZIP_ERR_NO_ERROR', 0 );
  84.   define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
  85.   define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
  86.   define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
  87.   define( 'PCLZIP_ERR_MISSING_FILE', -4 );
  88.   define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
  89.   define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
  90.   define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
  91.   define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
  92.   define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
  93.   define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
  94.   define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
  95.   define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
  96.   define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
  97.   define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
  98.   define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
  99.   define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
  100.  
  101.   // ----- Options values
  102.   define( 'PCLZIP_OPT_PATH', 77001 );
  103.   define( 'PCLZIP_OPT_ADD_PATH', 77002 );
  104.   define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
  105.   define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
  106.   define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
  107.   define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
  108.   define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
  109.   define( 'PCLZIP_OPT_BY_NAME', 77008 );
  110.   define( 'PCLZIP_OPT_BY_INDEX', 77009 );
  111.   define( 'PCLZIP_OPT_BY_EREG', 77010 );
  112.   define( 'PCLZIP_OPT_BY_PREG', 77011 );
  113.  
  114.   // ----- Call backs values
  115.   define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
  116.   define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
  117.   define( 'PCLZIP_CB_PRE_ADD', 78003 );
  118.   define( 'PCLZIP_CB_POST_ADD', 78004 );
  119.   /* For futur use
  120.   define( 'PCLZIP_CB_PRE_LIST', 78005 );
  121.   define( 'PCLZIP_CB_POST_LIST', 78006 );
  122.   define( 'PCLZIP_CB_PRE_DELETE', 78007 );
  123.   define( 'PCLZIP_CB_POST_DELETE', 78008 );
  124.   */
  125.  
  126.   // --------------------------------------------------------------------------------
  127.   // Class : PclZip
  128.   // Description :
  129.   //   PclZip is the class that represent a Zip archive.
  130.   //   The public methods allow the manipulation of the archive.
  131.   // Attributes :
  132.   //   Attributes must not be accessed directly.
  133.   // Methods :
  134.   //   PclZip() : Object creator
  135.   //   create() : Creates the Zip archive
  136.   //   listContent() : List the content of the Zip archive
  137.   //   extract() : Extract the content of the archive
  138.   //   properties() : List the properties of the archive
  139.   // --------------------------------------------------------------------------------
  140.   class PclZip
  141.   {
  142.     // ----- Filename of the zip file
  143.     var $zipname = '';
  144.  
  145.     // ----- File descriptor of the zip file
  146.     var $zip_fd = 0;
  147.  
  148.     // ----- Internal error handling
  149.     var $error_code = 1;
  150.     var $error_string = '';
  151.  
  152.   // --------------------------------------------------------------------------------
  153.   // Function : PclZip()
  154.   // Description :
  155.   //   Creates a PclZip object and set the name of the associated Zip archive
  156.   //   filename.
  157.   //   Note that no real action is taken, if the archive does not exist it is not
  158.   //   created. Use create() for that.
  159.   // --------------------------------------------------------------------------------
  160.   function PclZip($p_zipname)
  161.   {
  162.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");
  163.  
  164.     // ----- Tests the zlib
  165.     if (!function_exists('gzopen'))
  166.     {
  167.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");
  168.       die('Abort '.basename(__FILE__).' : Missing zlib extensions');
  169.     }
  170.  
  171.     // ----- Set the attributes
  172.     $this->zipname = $p_zipname;
  173.     $this->zip_fd = 0;
  174.  
  175.     // ----- Return
  176.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);
  177.     return;
  178.   }
  179.   // --------------------------------------------------------------------------------
  180.  
  181.   // --------------------------------------------------------------------------------
  182.   // Function :
  183.   //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
  184.   //   create($p_filelist, $p_option, $p_option_value, ...)
  185.   // Description :
  186.   //   This method supports two different synopsis. The first one is historical.
  187.   //   This method creates a Zip Archive. The Zip file is created in the
  188.   //   filesystem. The files and directories indicated in $p_filelist
  189.   //   are added in the archive. See the parameters description for the
  190.   //   supported format of $p_filelist.
  191.   //   When a directory is in the list, the directory and its content is added
  192.   //   in the archive.
  193.   //   In this synopsis, the function takes an optional variable list of
  194.   //   options. See bellow the supported options.
  195.   // Parameters :
  196.   //   $p_filelist : An array containing file or directory names, or
  197.   //                 a string containing one filename or one directory name, or
  198.   //                 a string containing a list of filenames and/or directory
  199.   //                 names separated by spaces.
  200.   //   $p_add_dir : A path to add before the real path of the archived file,
  201.   //                in order to have it memorized in the archive.
  202.   //   $p_remove_dir : A path to remove from the real path of the file to archive,
  203.   //                   in order to have a shorter path memorized in the archive.
  204.   //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  205.   //                   is removed first, before $p_add_dir is added.
  206.   // Options :
  207.   //   PCLZIP_OPT_ADD_PATH :
  208.   //   PCLZIP_OPT_REMOVE_PATH :
  209.   //   PCLZIP_OPT_REMOVE_ALL_PATH :
  210.   //   PCLZIP_CB_PRE_ADD :
  211.   //   PCLZIP_CB_POST_ADD :
  212.   // Return Values :
  213.   //   0 on failure,
  214.   //   The list of the added files, with a status of the add action.
  215.   //   (see PclZip::listContent() for list entry format)
  216.   // --------------------------------------------------------------------------------
  217. //  function create($p_filelist, $p_add_dir="", $p_remove_dir="")
  218.   function create($p_filelist /*, options */)
  219.   {
  220.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");
  221.     $v_result=1;
  222.  
  223.     // ----- Reset the error handler
  224.     $this->privErrorReset();
  225.  
  226.     // ----- Set default values
  227.     $v_options = array();
  228.     $v_add_path = "";
  229.     $v_remove_path = "";
  230.     $v_remove_all_path = false;
  231.     $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  232.  
  233.     // ----- Look for variable options arguments
  234.     $v_size = func_num_args();
  235.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  236.  
  237.     // ----- Look for arguments
  238.     if ($v_size > 1) {
  239.       // ----- Get the arguments
  240.       $v_arg_list = &func_get_args();
  241.  
  242.       // ----- Remove form the options list the first argument
  243.       array_shift($v_arg_list);
  244.       $v_size--;
  245.  
  246.       // ----- Look for first arg
  247.       if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  248.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
  249.  
  250.         // ----- Parse the options
  251.         $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  252.                                             array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  253.                                                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  254.                                                    PCLZIP_OPT_ADD_PATH => 'optional',
  255.                                                    PCLZIP_CB_PRE_ADD => 'optional',
  256.                                                    PCLZIP_CB_POST_ADD => 'optional',
  257.                                                    PCLZIP_OPT_NO_COMPRESSION => 'optional' ));
  258.         if ($v_result != 1) {
  259.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  260.           return 0;
  261.         }
  262.  
  263.         // ----- Set the arguments
  264.         if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  265.           $v_add_path = $v_options[PCLZIP_OPT_ADD_PATH];
  266.         }
  267.         if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  268.           $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  269.         }
  270.         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  271.           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  272.         }
  273.       }
  274.  
  275.       // ----- Look for 2 args
  276.       // Here we need to support the first historic synopsis of the
  277.       // method.
  278.       else {
  279.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  280.  
  281.         // ----- Get the first argument
  282.         $v_add_path = $v_arg_list[0];
  283.  
  284.         // ----- Look for the optional second argument
  285.         if ($v_size == 2) {
  286.           $v_remove_path = $v_arg_list[1];
  287.         }
  288.         else if ($v_size > 2) {
  289.           // ----- Error log
  290.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  291.  
  292.           // ----- Return
  293.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  294.           return 0;
  295.         }
  296.       }
  297.     }
  298.  
  299.     // ----- Trace
  300.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "add_path='$v_add_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_all_path?'true':'false')."'");
  301.  
  302.     // ----- Look if the $p_filelist is really an array
  303.     $p_result_list = array();
  304.     if (is_array($p_filelist))
  305.     {
  306.       // ----- Call the create fct
  307.       $v_result = $this->privCreate($p_filelist, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
  308.     }
  309.  
  310.     // ----- Look if the $p_filelist is a string
  311.     else if (is_string($p_filelist))
  312.     {
  313.       // ----- Create a list with the elements from the string
  314.       $v_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  315.  
  316.       // ----- Call the create fct
  317.       $v_result = $this->privCreate($v_list, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
  318.     }
  319.  
  320.     // ----- Invalid variable
  321.     else
  322.     {
  323.       // ----- Error log
  324.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
  325.       $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  326.     }
  327.  
  328.     if ($v_result != 1)
  329.     {
  330.       // ----- Return
  331.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  332.       return 0;
  333.     }
  334.  
  335.     // ----- Return
  336.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
  337.     return $p_result_list;
  338.   }
  339.   // --------------------------------------------------------------------------------
  340.  
  341.   // --------------------------------------------------------------------------------
  342.   // Function :
  343.   //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
  344.   //   add($p_filelist, $p_option, $p_option_value, ...)
  345.   // Description :
  346.   //   This method supports two synopsis. The first one is historical.
  347.   //   This methods add the list of files in an existing archive.
  348.   //   If a file with the same name already exists, it is added at the end of the
  349.   //   archive, the first one is still present.
  350.   //   If the archive does not exist, it is created.
  351.   // Parameters :
  352.   //   $p_filelist : An array containing file or directory names, or
  353.   //                 a string containing one filename or one directory name, or
  354.   //                 a string containing a list of filenames and/or directory
  355.   //                 names separated by spaces.
  356.   //   $p_add_dir : A path to add before the real path of the archived file,
  357.   //                in order to have it memorized in the archive.
  358.   //   $p_remove_dir : A path to remove from the real path of the file to archive,
  359.   //                   in order to have a shorter path memorized in the archive.
  360.   //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  361.   //                   is removed first, before $p_add_dir is added.
  362.   // Options :
  363.   //   PCLZIP_OPT_ADD_PATH :
  364.   //   PCLZIP_OPT_REMOVE_PATH :
  365.   //   PCLZIP_OPT_REMOVE_ALL_PATH :
  366.   //   PCLZIP_CB_PRE_ADD :
  367.   //   PCLZIP_CB_POST_ADD :
  368.   // Return Values :
  369.   //   0 on failure,
  370.   //   The list of the added files, with a status of the add action.
  371.   //   (see PclZip::listContent() for list entry format)
  372.   // --------------------------------------------------------------------------------
  373. //  function add($p_filelist, $p_add_dir="", $p_remove_dir="")
  374.   function add($p_filelist /* options */)
  375.   {
  376.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");
  377.     $v_result=1;
  378.  
  379.     // ----- Reset the error handler
  380.     $this->privErrorReset();
  381.  
  382.     // ----- Set default values
  383.     $v_options = array();
  384.     $v_add_path = "";
  385.     $v_remove_path = "";
  386.     $v_remove_all_path = false;
  387.     $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  388.  
  389.     // ----- Look for variable options arguments
  390.     $v_size = func_num_args();
  391.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  392.  
  393.     // ----- Look for arguments
  394.     if ($v_size > 1) {
  395.       // ----- Get the arguments
  396.       $v_arg_list = &func_get_args();
  397.  
  398.       // ----- Remove form the options list the first argument
  399.       array_shift($v_arg_list);
  400.       $v_size--;
  401.  
  402.       // ----- Look for first arg
  403.       if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  404.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
  405.  
  406.         // ----- Parse the options
  407.         $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  408.                                             array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  409.                                                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  410.                                                    PCLZIP_OPT_ADD_PATH => 'optional',
  411.                                                    PCLZIP_CB_PRE_ADD => 'optional',
  412.                                                    PCLZIP_CB_POST_ADD => 'optional',
  413.                                                    PCLZIP_OPT_NO_COMPRESSION => 'optional' ));
  414.         if ($v_result != 1) {
  415.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  416.           return 0;
  417.         }
  418.  
  419.         // ----- Set the arguments
  420.         if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  421.           $v_add_path = $v_options[PCLZIP_OPT_ADD_PATH];
  422.         }
  423.         if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  424.           $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  425.         }
  426.         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  427.           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  428.         }
  429.       }
  430.  
  431.       // ----- Look for 2 args
  432.       // Here we need to support the first historic synopsis of the
  433.       // method.
  434.       else {
  435.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  436.  
  437.         // ----- Get the first argument
  438.         $v_add_path = $v_arg_list[0];
  439.  
  440.         // ----- Look for the optional second argument
  441.         if ($v_size == 2) {
  442.           $v_remove_path = $v_arg_list[1];
  443.         }
  444.         else if ($v_size > 2) {
  445.           // ----- Error log
  446.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  447.  
  448.           // ----- Return
  449.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  450.           return 0;
  451.         }
  452.       }
  453.     }
  454.  
  455.     // ----- Trace
  456.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "add_path='$v_add_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_all_path?'true':'false')."'");
  457.  
  458.     // ----- Look if the $p_filelist is really an array
  459.     $p_result_list = array();
  460.     if (is_array($p_filelist))
  461.     {
  462.       // ----- Call the create fct
  463.       $v_result = $this->privAdd($p_filelist, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
  464.     }
  465.  
  466.     // ----- Look if the $p_filelist is a string
  467.     else if (is_string($p_filelist))
  468.     {
  469.       // ----- Create a list with the elements from the string
  470.       $v_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  471.  
  472.       // ----- Call the create fct
  473.       $v_result = $this->privAdd($v_list, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
  474.     }
  475.  
  476.     // ----- Invalid variable
  477.     else
  478.     {
  479.       // ----- Error log
  480.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
  481.       $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  482.     }
  483.  
  484.     if ($v_result != 1)
  485.     {
  486.       // ----- Return
  487.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  488.       return 0;
  489.     }
  490.  
  491.     // ----- Return
  492.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
  493.     return $p_result_list;
  494.   }
  495.   // --------------------------------------------------------------------------------
  496.  
  497.   // --------------------------------------------------------------------------------
  498.   // Function : listContent()
  499.   // Description :
  500.   //   This public method, gives the list of the files and directories, with their
  501.   //   properties.
  502.   //   The properties of each entries in the list are (used also in other functions) :
  503.   //     filename : Name of the file. For a create or add action it is the filename
  504.   //                given by the user. For an extract function it is the filename
  505.   //                of the extracted file.
  506.   //     stored_filename : Name of the file / directory stored in the archive.
  507.   //     size : Size of the stored file.
  508.   //     compressed_size : Size of the file's data compressed in the archive
  509.   //                       (without the headers overhead)
  510.   //     mtime : Last known modification date of the file (UNIX timestamp)
  511.   //     comment : Comment associated with the file
  512.   //     folder : true | false
  513.   //     index : index of the file in the archive
  514.   //     status : status of the action (depending of the action) :
  515.   //              Values are :
  516.   //                ok : OK !
  517.   //                filtered : the file / dir is not extracted (filtered by user)
  518.   //                already_a_directory : the file can not be extracted because a
  519.   //                                      directory with the same name already exists
  520.   //                write_protected : the file can not be extracted because a file
  521.   //                                  with the same name already exists and is
  522.   //                                  write protected
  523.   //                newer_exist : the file was not extracted because a newer file exists
  524.   //                path_creation_fail : the file is not extracted because the folder
  525.   //                                     does not exists and can not be created
  526.   //                write_error : the file was not extracted because there was a
  527.   //                              error while writing the file
  528.   //                read_error : the file was not extracted because there was a error
  529.   //                             while reading the file
  530.   //                invalid_header : the file was not extracted because of an archive
  531.   //                                 format error (bad file header)
  532.   //   Note that each time a method can continue operating when there
  533.   //   is an action error on a file, the error is only logged in the file status.
  534.   // Return Values :
  535.   //   0 on an unrecoverable failure,
  536.   //   The list of the files in the archive.
  537.   // --------------------------------------------------------------------------------
  538.   function listContent()
  539.   {
  540.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");
  541.     $v_result=1;
  542.  
  543.     // ----- Reset the error handler
  544.     $this->privErrorReset();
  545.  
  546.     // ----- Check archive
  547.     if (!$this->privCheckFormat()) {
  548.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  549.       return(0);
  550.     }
  551.  
  552.     // ----- Call the extracting fct
  553.     $p_list = array();
  554.     if (($v_result = $this->privList($p_list)) != 1)
  555.     {
  556.       unset($p_list);
  557.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  558.       return(0);
  559.     }
  560.  
  561.     // ----- Return
  562.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  563.     return $p_list;
  564.   }
  565.   // --------------------------------------------------------------------------------
  566.  
  567.   // --------------------------------------------------------------------------------
  568.   // Function :
  569.   //   extract($p_path="./", $p_remove_path="")
  570.   //   extract([$p_option, $p_option_value, ...])
  571.   // Description :
  572.   //   This method supports two synopsis. The first one is historical.
  573.   //   This method extract all the files / directories from the archive to the
  574.   //   folder indicated in $p_path.
  575.   //   If you want to ignore the 'root' part of path of the memorized files
  576.   //   you can indicate this in the optional $p_remove_path parameter.
  577.   //   By default, if a newer file with the same name already exists, the
  578.   //   file is not extracted.
  579.   //
  580.   //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
  581.   //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
  582.   //   at the end of the path value of PCLZIP_OPT_PATH.
  583.   // Parameters :
  584.   //   $p_path : Path where the files and directories are to be extracted
  585.   //   $p_remove_path : First part ('root' part) of the memorized path
  586.   //                    (if any similar) to remove while extracting.
  587.   // Options :
  588.   //   PCLZIP_OPT_PATH :
  589.   //   PCLZIP_OPT_ADD_PATH :
  590.   //   PCLZIP_OPT_REMOVE_PATH :
  591.   //   PCLZIP_OPT_REMOVE_ALL_PATH :
  592.   //   PCLZIP_CB_PRE_EXTRACT :
  593.   //   PCLZIP_CB_POST_EXTRACT :
  594.   // Return Values :
  595.   //   0 or a negative value on failure,
  596.   //   The list of the extracted files, with a status of the action.
  597.   //   (see PclZip::listContent() for list entry format)
  598.   // --------------------------------------------------------------------------------
  599.   //function extract($p_path="./", $p_remove_path="")
  600.   function extract(/* options */)
  601.   {
  602.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
  603.     $v_result=1;
  604.  
  605.     // ----- Reset the error handler
  606.     $this->privErrorReset();
  607.  
  608.     // ----- Check archive
  609.     if (!$this->privCheckFormat()) {
  610.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  611.       return(0);
  612.     }
  613.  
  614.     // ----- Set default values
  615.     $v_options = array();
  616.     $v_path = "./";
  617.     $v_remove_path = "";
  618.     $v_remove_all_path = false;
  619.  
  620.     // ----- Look for variable options arguments
  621.     $v_size = func_num_args();
  622.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  623.  
  624.     // ----- Default values for option
  625.     $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  626.  
  627.     // ----- Look for arguments
  628.     if ($v_size > 0) {
  629.       // ----- Get the arguments
  630.       $v_arg_list = &func_get_args();
  631.  
  632.       // ----- Look for first arg
  633.       if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  634.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
  635.  
  636.         // ----- Parse the options
  637.         $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  638.                                             array (PCLZIP_OPT_PATH => 'optional',
  639.                                                    PCLZIP_OPT_REMOVE_PATH => 'optional',
  640.                                                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  641.                                                    PCLZIP_OPT_ADD_PATH => 'optional',
  642.                                                    PCLZIP_CB_PRE_EXTRACT => 'optional',
  643.                                                    PCLZIP_CB_POST_EXTRACT => 'optional',
  644.                                                    PCLZIP_OPT_SET_CHMOD => 'optional',
  645.                                                    PCLZIP_OPT_BY_NAME => 'optional',
  646.                                                    PCLZIP_OPT_BY_EREG => 'optional',
  647.                                                    PCLZIP_OPT_BY_PREG => 'optional',
  648.                                                    PCLZIP_OPT_BY_INDEX => 'optional',
  649.                                                    PCLZIP_OPT_EXTRACT_AS_STRING => 'optional' ));
  650.         if ($v_result != 1) {
  651.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  652.           return 0;
  653.         }
  654.  
  655.         // ----- Set the arguments
  656.         if (isset($v_options[PCLZIP_OPT_PATH])) {
  657.           $v_path = $v_options[PCLZIP_OPT_PATH];
  658.         }
  659.         if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  660.           $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  661.         }
  662.         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  663.           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  664.         }
  665.         if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  666.           // ----- Check for '/' in last path char
  667.           if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  668.             $v_path .= '/';
  669.           }
  670.           $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  671.         }
  672.       }
  673.  
  674.       // ----- Look for 2 args
  675.       // Here we need to support the first historic synopsis of the
  676.       // method.
  677.       else {
  678.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  679.  
  680.         // ----- Get the first argument
  681.         $v_path = $v_arg_list[0];
  682.  
  683.         // ----- Look for the optional second argument
  684.         if ($v_size == 2) {
  685.           $v_remove_path = $v_arg_list[1];
  686.         }
  687.         else if ($v_size > 2) {
  688.           // ----- Error log
  689.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  690.  
  691.           // ----- Return
  692.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  693.           return 0;
  694.         }
  695.       }
  696.     }
  697.  
  698.     // ----- Trace
  699.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
  700.  
  701.     // ----- Call the extracting fct
  702.     $p_list = array();
  703.     if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1)
  704.     {
  705.       unset($p_list);
  706.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  707.       return(0);
  708.     }
  709.  
  710.     // ----- Return
  711.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  712.     return $p_list;
  713.   }
  714.   // --------------------------------------------------------------------------------
  715.  
  716.  
  717.   // --------------------------------------------------------------------------------
  718.   // Function :
  719.   //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
  720.   //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
  721.   // Description :
  722.   //   This method supports two synopsis. The first one is historical.
  723.   //   This method is doing a partial extract of the archive.
  724.   //   The extracted files or folders are identified by their index in the
  725.   //   archive (from 0 to n).
  726.   //   Note that if the index identify a folder, only the folder entry is
  727.   //   extracted, not all the files included in the archive.
  728.   // Parameters :
  729.   //   $p_index : A single index (integer) or a string of indexes of files to
  730.   //              extract. The form of the string is "0,4-6,8-12" with only numbers
  731.   //              and '-' for range or ',' to separate ranges. No spaces or ';'
  732.   //              are allowed.
  733.   //   $p_path : Path where the files and directories are to be extracted
  734.   //   $p_remove_path : First part ('root' part) of the memorized path
  735.   //                    (if any similar) to remove while extracting.
  736.   // Options :
  737.   //   PCLZIP_OPT_PATH :
  738.   //   PCLZIP_OPT_ADD_PATH :
  739.   //   PCLZIP_OPT_REMOVE_PATH :
  740.   //   PCLZIP_OPT_REMOVE_ALL_PATH :
  741.   //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
  742.   //     not as files.
  743.   //     The resulting content is in a new field 'content' in the file
  744.   //     structure.
  745.   //     This option must be used alone (any other options are ignored).
  746.   //   PCLZIP_CB_PRE_EXTRACT :
  747.   //   PCLZIP_CB_POST_EXTRACT :
  748.   // Return Values :
  749.   //   0 on failure,
  750.   //   The list of the extracted files, with a status of the action.
  751.   //   (see PclZip::listContent() for list entry format)
  752.   // --------------------------------------------------------------------------------
  753.   function extractByIndex($p_index /* $options */)
  754.   {
  755.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");
  756.     $v_result=1;
  757.  
  758.     // ----- Reset the error handler
  759.     $this->privErrorReset();
  760.  
  761.     // ----- Check archive
  762.     if (!$this->privCheckFormat()) {
  763.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  764.       return(0);
  765.     }
  766.  
  767.     // ----- Set default values
  768.     $v_options = array();
  769.     $v_path = "./";
  770.     $v_remove_path = "";
  771.     $v_remove_all_path = false;
  772.  
  773.     // ----- Look for variable options arguments
  774.     $v_size = func_num_args();
  775.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  776.  
  777.     // ----- Default values for option
  778.     $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  779.  
  780.     // ----- Look for arguments
  781.     if ($v_size > 1) {
  782.       // ----- Get the arguments
  783.       $v_arg_list = &func_get_args();
  784.  
  785.       // ----- Remove form the options list the first argument
  786.       array_shift($v_arg_list);
  787.       $v_size--;
  788.  
  789.       // ----- Look for first arg
  790.       if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  791.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
  792.  
  793.         // ----- Parse the options
  794.         $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  795.                                             array (PCLZIP_OPT_PATH => 'optional',
  796.                                                    PCLZIP_OPT_REMOVE_PATH => 'optional',
  797.                                                    PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  798.                                                    PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  799.                                                    PCLZIP_OPT_ADD_PATH => 'optional',
  800.                                                    PCLZIP_CB_PRE_EXTRACT => 'optional',
  801.                                                    PCLZIP_CB_POST_EXTRACT => 'optional',
  802.                                                    PCLZIP_OPT_SET_CHMOD => 'optional' ));
  803.         if ($v_result != 1) {
  804.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  805.           return 0;
  806.         }
  807.  
  808.         // ----- Set the arguments
  809.         if (isset($v_options[PCLZIP_OPT_PATH])) {
  810.           $v_path = $v_options[PCLZIP_OPT_PATH];
  811.         }
  812.         if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  813.           $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  814.         }
  815.         if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  816.           $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  817.         }
  818.         if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  819.           // ----- Check for '/' in last path char
  820.           if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  821.             $v_path .= '/';
  822.           }
  823.           $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  824.         }
  825.         if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
  826.           $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  827.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");
  828.         }
  829.         else {
  830.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");
  831.         }
  832.       }
  833.  
  834.       // ----- Look for 2 args
  835.       // Here we need to support the first historic synopsis of the
  836.       // method.
  837.       else {
  838.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
  839.  
  840.         // ----- Get the first argument
  841.         $v_path = $v_arg_list[0];
  842.  
  843.         // ----- Look for the optional second argument
  844.         if ($v_size == 2) {
  845.           $v_remove_path = $v_arg_list[1];
  846.         }
  847.         else if ($v_size > 2) {
  848.           // ----- Error log
  849.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  850.  
  851.           // ----- Return
  852.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  853.           return 0;
  854.         }
  855.       }
  856.     }
  857.  
  858.     // ----- Trace
  859.     //--(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')."'");
  860.  
  861.     // ----- Trick
  862.     // Here I want to reuse extractByRule(), so I need to parse the $p_index
  863.     // with privParseOptions()
  864.     $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
  865.     $v_options_trick = array();
  866.     $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
  867.                                         array (PCLZIP_OPT_BY_INDEX => 'optional' ));
  868.     if ($v_result != 1) {
  869.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  870.         return 0;
  871.     }
  872.     $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
  873.  
  874.     // ----- Call the extracting fct
  875.     if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) != 1) {
  876.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  877.         return(0);
  878.     }
  879.  
  880.     // ----- Return
  881.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  882.     return $p_list;
  883.   }
  884.   // --------------------------------------------------------------------------------
  885.  
  886.   // --------------------------------------------------------------------------------
  887.   // Function :
  888.   //   delete([$p_option, $p_option_value, ...])
  889.   // Description :
  890.   // Parameters :
  891.   //   None
  892.   // Options :
  893.   //   PCLZIP_OPT_BY_INDEX :
  894.   // Return Values :
  895.   //   0 on failure,
  896.   //   The list of the files which are still present in the archive.
  897.   //   (see PclZip::listContent() for list entry format)
  898.   // --------------------------------------------------------------------------------
  899.   function delete(/* options */)
  900.   {
  901.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
  902.     $v_result=1;
  903.  
  904.     // ----- Reset the error handler
  905.     $this->privErrorReset();
  906.  
  907.     // ----- Check archive
  908.     if (!$this->privCheckFormat()) {
  909.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  910.       return(0);
  911.     }
  912.  
  913.     // ----- Set default values
  914.     $v_options = array();
  915.  
  916.     // ----- Look for variable options arguments
  917.     $v_size = func_num_args();
  918.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
  919.  
  920.     // ----- Look for no arguments
  921.     if ($v_size <= 0) {
  922.         // ----- Error log
  923.         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing arguments");
  924.  
  925.         // ----- Return
  926.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  927.         return 0;
  928.     }
  929.  
  930.     // ----- Get the arguments
  931.     $v_arg_list = &func_get_args();
  932.  
  933.     // ----- Parse the options
  934.     $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  935.                                         array (PCLZIP_OPT_BY_NAME => 'optional',
  936.                                                PCLZIP_OPT_BY_EREG => 'optional',
  937.                                                PCLZIP_OPT_BY_PREG => 'optional',
  938.                                                PCLZIP_OPT_BY_INDEX => 'optional' ));
  939.     if ($v_result != 1) {
  940.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  941.         return 0;
  942.     }
  943.  
  944.     // ----- Check that at least one rule is set
  945.     if (   (!isset($v_options[PCLZIP_OPT_BY_NAME]))
  946.         && (!isset($v_options[PCLZIP_OPT_BY_EREG]))
  947.         && (!isset($v_options[PCLZIP_OPT_BY_PREG]))
  948.         && (!isset($v_options[PCLZIP_OPT_BY_INDEX]))) {
  949.         // ----- Error log
  950.         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "At least one filtering rule must be set");
  951.  
  952.         // ----- Return
  953.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  954.         return 0;
  955.     }
  956.  
  957.     // ----- Call the delete fct
  958.     $v_list = array();
  959.     if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1)
  960.     {
  961.       unset($v_list);
  962.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
  963.       return(0);
  964.     }
  965.  
  966.     // ----- Return
  967.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
  968.     return $v_list;
  969.   }
  970.   // --------------------------------------------------------------------------------
  971.  
  972.   // --------------------------------------------------------------------------------
  973.   // Function : deleteByIndex()
  974.   // Description :
  975.   //   ***** Deprecated *****
  976.   //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
  977.   // --------------------------------------------------------------------------------
  978.   function deleteByIndex($p_index)
  979.   {
  980.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
  981.     
  982.     $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
  983.  
  984.     // ----- Return
  985.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
  986.     return $p_list;
  987.   }
  988.   // --------------------------------------------------------------------------------
  989.  
  990.   // --------------------------------------------------------------------------------
  991.   // Function : properties()
  992.   // Description :
  993.   //   This method gives the properties of the archive.
  994.   //   The properties are :
  995.   //     nb : Number of files in the archive
  996.   //     comment : Comment associated with the archive file
  997.   //     status : not_exist, ok
  998.   // Parameters :
  999.   //   None
  1000.   // Return Values :
  1001.   //   0 on failure,
  1002.   //   An array with the archive properties.
  1003.   // --------------------------------------------------------------------------------
  1004.   function properties()
  1005.   {
  1006.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");
  1007.  
  1008.     // ----- Reset the error handler
  1009.     $this->privErrorReset();
  1010.  
  1011.     // ----- Check archive
  1012.     if (!$this->privCheckFormat()) {
  1013.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1014.       return(0);
  1015.     }
  1016.  
  1017.     // ----- Default properties
  1018.     $v_prop = array();
  1019.     $v_prop['comment'] = '';
  1020.     $v_prop['nb'] = 0;
  1021.     $v_prop['status'] = 'not_exist';
  1022.  
  1023.     // ----- Look if file exists
  1024.     if (@is_file($this->zipname))
  1025.     {
  1026.       // ----- Open the zip file
  1027.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1028.       if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  1029.       {
  1030.         // ----- Error log
  1031.         PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  1032.  
  1033.         // ----- Return
  1034.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);
  1035.         return 0;
  1036.       }
  1037.  
  1038.       // ----- Read the central directory informations
  1039.       $v_central_dir = array();
  1040.       if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1041.       {
  1042.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1043.         return 0;
  1044.       }
  1045.  
  1046.       // ----- Close the zip file
  1047.       $this->privCloseFd();
  1048.  
  1049.       // ----- Set the user attributes
  1050.       $v_prop['comment'] = $v_central_dir['comment'];
  1051.       $v_prop['nb'] = $v_central_dir['entries'];
  1052.       $v_prop['status'] = 'ok';
  1053.     }
  1054.  
  1055.     // ----- Return
  1056.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);
  1057.     return $v_prop;
  1058.   }
  1059.   // --------------------------------------------------------------------------------
  1060.  
  1061.   // --------------------------------------------------------------------------------
  1062.   // Function : duplicate()
  1063.   // Description :
  1064.   //   This method creates an archive by copying the content of an other one. If
  1065.   //   the archive already exist, it is replaced by the new one without any warning.
  1066.   // Parameters :
  1067.   //   $p_archive : The filename of a valid archive, or
  1068.   //                a valid PclZip object.
  1069.   // Return Values :
  1070.   //   1 on success.
  1071.   //   0 or a negative value on error (error code).
  1072.   // --------------------------------------------------------------------------------
  1073.   function duplicate($p_archive)
  1074.   {
  1075.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");
  1076.     $v_result = 1;
  1077.  
  1078.     // ----- Reset the error handler
  1079.     $this->privErrorReset();
  1080.  
  1081.     // ----- Look if the $p_archive is a PclZip object
  1082.     if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
  1083.     {
  1084.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");
  1085.  
  1086.       // ----- Duplicate the archive
  1087.       $v_result = $this->privDuplicate($p_archive->zipname);
  1088.     }
  1089.  
  1090.     // ----- Look if the $p_archive is a string (so a filename)
  1091.     else if (is_string($p_archive))
  1092.     {
  1093.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");
  1094.  
  1095.       // ----- Check that $p_archive is a valid zip file
  1096.       // TBC : Should also check the archive format
  1097.       if (!is_file($p_archive)) {
  1098.         // ----- Error log
  1099.         PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
  1100.         $v_result = PCLZIP_ERR_MISSING_FILE;
  1101.       }
  1102.       else {
  1103.         // ----- Duplicate the archive
  1104.         $v_result = $this->privDuplicate($p_archive);
  1105.       }
  1106.     }
  1107.  
  1108.     // ----- Invalid variable
  1109.     else
  1110.     {
  1111.       // ----- Error log
  1112.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1113.       $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1114.     }
  1115.  
  1116.     // ----- Return
  1117.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1118.     return $v_result;
  1119.   }
  1120.   // --------------------------------------------------------------------------------
  1121.  
  1122.   // --------------------------------------------------------------------------------
  1123.   // Function : merge()
  1124.   // Description :
  1125.   //   This method merge the $p_archive_to_add archive at the end of the current
  1126.   //   one ($this).
  1127.   //   If the archive ($this) does not exist, the merge becomes a duplicate.
  1128.   //   If the $p_archive_to_add archive does not exist, the merge is a success.
  1129.   // Parameters :
  1130.   //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
  1131.   //                       or a PclZip object archive.
  1132.   // Return Values :
  1133.   //   1 on success,
  1134.   //   0 or negative values on error (see below).
  1135.   // --------------------------------------------------------------------------------
  1136.   function merge($p_archive_to_add)
  1137.   {
  1138.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");
  1139.     $v_result = 1;
  1140.  
  1141.     // ----- Reset the error handler
  1142.     $this->privErrorReset();
  1143.  
  1144.     // ----- Check archive
  1145.     if (!$this->privCheckFormat()) {
  1146.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
  1147.       return(0);
  1148.     }
  1149.  
  1150.     // ----- Look if the $p_archive_to_add is a PclZip object
  1151.     if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
  1152.     {
  1153.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");
  1154.  
  1155.       // ----- Merge the archive
  1156.       $v_result = $this->privMerge($p_archive_to_add);
  1157.     }
  1158.  
  1159.     // ----- Look if the $p_archive_to_add is a string (so a filename)
  1160.     else if (is_string($p_archive_to_add))
  1161.     {
  1162.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");
  1163.  
  1164.       // ----- Create a temporary archive
  1165.       $v_object_archive = new PclZip($p_archive_to_add);
  1166.  
  1167.       // ----- Merge the archive
  1168.       $v_result = $this->privMerge($v_object_archive);
  1169.     }
  1170.  
  1171.     // ----- Invalid variable
  1172.     else
  1173.     {
  1174.       // ----- Error log
  1175.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1176.       $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1177.     }
  1178.  
  1179.     // ----- Return
  1180.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1181.     return $v_result;
  1182.   }
  1183.   // --------------------------------------------------------------------------------
  1184.  
  1185.  
  1186.  
  1187.   // --------------------------------------------------------------------------------
  1188.   // Function : errorCode()
  1189.   // Description :
  1190.   // Parameters :
  1191.   // --------------------------------------------------------------------------------
  1192.   function errorCode()
  1193.   {
  1194.     if (PCLZIP_ERROR_EXTERNAL == 1) {
  1195.       return(PclErrorCode());
  1196.     }
  1197.     else {
  1198.       return($this->error_code);
  1199.     }
  1200.   }
  1201.   // --------------------------------------------------------------------------------
  1202.  
  1203.   // --------------------------------------------------------------------------------
  1204.   // Function : errorName()
  1205.   // Description :
  1206.   // Parameters :
  1207.   // --------------------------------------------------------------------------------
  1208.   function errorName($p_with_code=false)
  1209.   {
  1210.     $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
  1211.                       PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
  1212.                       PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
  1213.                       PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
  1214.                       PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
  1215.                       PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
  1216.                       PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
  1217.                       PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
  1218.                       PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
  1219.                       PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
  1220.                       PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
  1221.                       PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
  1222.                       PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
  1223.                       PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
  1224.                       PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
  1225.                       PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
  1226.                       PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE' );
  1227.  
  1228.     if (isset($v_name[$this->error_code])) {
  1229.       $v_value = $v_name[$this->error_code];
  1230.     }
  1231.     else {
  1232.       $v_value = 'NoName';
  1233.     }
  1234.  
  1235.     if ($p_with_code) {
  1236.       return($v_value.' ('.$this->error_code.')');
  1237.     }
  1238.     else {
  1239.       return($v_value);
  1240.     }
  1241.   }
  1242.   // --------------------------------------------------------------------------------
  1243.  
  1244.   // --------------------------------------------------------------------------------
  1245.   // Function : errorInfo()
  1246.   // Description :
  1247.   // Parameters :
  1248.   // --------------------------------------------------------------------------------
  1249.   function errorInfo($p_full=false)
  1250.   {
  1251.     if (PCLZIP_ERROR_EXTERNAL == 1) {
  1252.       return(PclErrorString());
  1253.     }
  1254.     else {
  1255.       if ($p_full) {
  1256.         return($this->errorName(true)." : ".$this->error_string);
  1257.       }
  1258.       else {
  1259.         return($this->error_string." [code ".$this->error_code."]");
  1260.       }
  1261.     }
  1262.   }
  1263.   // --------------------------------------------------------------------------------
  1264.  
  1265.  
  1266. // --------------------------------------------------------------------------------
  1267. // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
  1268. // *****                                                        *****
  1269. // *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
  1270. // --------------------------------------------------------------------------------
  1271.  
  1272.  
  1273.  
  1274.   // --------------------------------------------------------------------------------
  1275.   // Function : privCheckFormat()
  1276.   // Description :
  1277.   //   This method check that the archive exists and is a valid zip archive.
  1278.   //   Several level of check exists. (futur)
  1279.   // Parameters :
  1280.   //   $p_level : Level of check. Default 0.
  1281.   //              0 : Check the first bytes (magic codes) (default value))
  1282.   //              1 : 0 + Check the central directory (futur)
  1283.   //              2 : 1 + Check each file header (futur)
  1284.   // Return Values :
  1285.   //   true on success,
  1286.   //   false on error, the error code is set.
  1287.   // --------------------------------------------------------------------------------
  1288.   function privCheckFormat($p_level=0)
  1289.   {
  1290.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");
  1291.     $v_result = true;
  1292.  
  1293.     // ----- Reset the error handler
  1294.     $this->privErrorReset();
  1295.  
  1296.     // ----- Look if the file exits
  1297.     if (!is_file($this->zipname)) {
  1298.       // ----- Error log
  1299.       PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
  1300.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
  1301.       return(false);
  1302.     }
  1303.  
  1304.     // ----- Check that the file is readeable
  1305.     if (!is_readable($this->zipname)) {
  1306.       // ----- Error log
  1307.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
  1308.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
  1309.       return(false);
  1310.     }
  1311.  
  1312.     // ----- Check the magic code
  1313.     // TBC
  1314.  
  1315.     // ----- Check the central header
  1316.     // TBC
  1317.  
  1318.     // ----- Check each file header
  1319.     // TBC
  1320.  
  1321.     // ----- Return
  1322.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1323.     return $v_result;
  1324.   }
  1325.   // --------------------------------------------------------------------------------
  1326.  
  1327.   // --------------------------------------------------------------------------------
  1328.   // Function : privParseOptions()
  1329.   // Description :
  1330.   //   This internal methods reads the variable list of arguments ($p_options_list,
  1331.   //   $p_size) and generate an array with the options and values ($v_result_list).
  1332.   //   $v_requested_options contains the options that can be present and those that
  1333.   //   must be present.
  1334.   //   $v_requested_options is an array, with the option value as key, and 'optional',
  1335.   //   or 'mandatory' as value.
  1336.   // Parameters :
  1337.   //   See above.
  1338.   // Return Values :
  1339.   //   1 on success.
  1340.   //   0 on failure.
  1341.   // --------------------------------------------------------------------------------
  1342.   function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options)
  1343.   {
  1344.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");
  1345.     $v_result=1;
  1346.  
  1347.     // ----- Read the options
  1348.     $i=0;
  1349.     while ($i<$p_size) {
  1350.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");
  1351.  
  1352.       // ----- Check if the option is requested
  1353.       if (!isset($v_requested_options[$p_options_list[$i]])) {
  1354.         // ----- Error log
  1355.         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
  1356.  
  1357.         // ----- Return
  1358.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1359.         return PclZip::errorCode();
  1360.       }
  1361.  
  1362.       // ----- Look for next option
  1363.       switch ($p_options_list[$i]) {
  1364.         // ----- Look for options that request a path value
  1365.         case PCLZIP_OPT_PATH :
  1366.         case PCLZIP_OPT_REMOVE_PATH :
  1367.         case PCLZIP_OPT_ADD_PATH :
  1368.           // ----- Check the number of parameters
  1369.           if (($i+1) >= $p_size) {
  1370.             // ----- Error log
  1371.             PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1372.  
  1373.             // ----- Return
  1374.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1375.             return PclZip::errorCode();
  1376.           }
  1377.  
  1378.           // ----- Get the value
  1379.           $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
  1380.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1381.           $i++;
  1382.         break;
  1383.  
  1384.         // ----- Look for options that request an array of string for value
  1385.         case PCLZIP_OPT_BY_NAME :
  1386.           // ----- Check the number of parameters
  1387.           if (($i+1) >= $p_size) {
  1388.             // ----- Error log
  1389.             PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1390.  
  1391.             // ----- Return
  1392.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1393.             return PclZip::errorCode();
  1394.           }
  1395.  
  1396.           // ----- Get the value
  1397.           if (is_string($p_options_list[$i+1])) {
  1398.               $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
  1399.           }
  1400.           else if (is_array($p_options_list[$i+1])) {
  1401.               $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1402.           }
  1403.           else {
  1404.             // ----- Error log
  1405.             PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1406.  
  1407.             // ----- Return
  1408.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1409.             return PclZip::errorCode();
  1410.           }
  1411.           ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1412.           $i++;
  1413.         break;
  1414.  
  1415.         // ----- Look for options that request an EREG or PREG expression
  1416.         case PCLZIP_OPT_BY_EREG :
  1417.         case PCLZIP_OPT_BY_PREG :
  1418.           // ----- Check the number of parameters
  1419.           if (($i+1) >= $p_size) {
  1420.             // ----- Error log
  1421.             PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1422.  
  1423.             // ----- Return
  1424.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1425.             return PclZip::errorCode();
  1426.           }
  1427.  
  1428.           // ----- Get the value
  1429.           if (is_string($p_options_list[$i+1])) {
  1430.               $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1431.           }
  1432.           else {
  1433.             // ----- Error log
  1434.             PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1435.  
  1436.             // ----- Return
  1437.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1438.             return PclZip::errorCode();
  1439.           }
  1440.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1441.           $i++;
  1442.         break;
  1443.  
  1444.         // ----- Look for options that request an array of index
  1445.         case PCLZIP_OPT_BY_INDEX :
  1446.           // ----- Check the number of parameters
  1447.           if (($i+1) >= $p_size) {
  1448.             // ----- Error log
  1449.             PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1450.  
  1451.             // ----- Return
  1452.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1453.             return PclZip::errorCode();
  1454.           }
  1455.  
  1456.           // ----- Get the value
  1457.           $v_work_list = array();
  1458.           if (is_string($p_options_list[$i+1])) {
  1459.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
  1460.  
  1461.               // ----- Remove spaces
  1462.               $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
  1463.  
  1464.               // ----- Parse items
  1465.               $v_work_list = explode(",", $p_options_list[$i+1]);
  1466.           }
  1467.           else if (is_integer($p_options_list[$i+1])) {
  1468.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
  1469.               $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
  1470.           }
  1471.           else if (is_array($p_options_list[$i+1])) {
  1472.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
  1473.               $v_work_list = $p_options_list[$i+1];
  1474.           }
  1475.           else {
  1476.             // ----- Error log
  1477.             PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1478.  
  1479.             // ----- Return
  1480.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1481.             return PclZip::errorCode();
  1482.           }
  1483.           
  1484.           // ----- Reduce the index list
  1485.           // each index item in the list must be a couple with a start and
  1486.           // an end value : [0,3], [5-5], [8-10], ...
  1487.           // ----- Check the format of each item
  1488.           $v_sort_flag=false;
  1489.           $v_sort_value=0;
  1490.           for ($j=0; $j<sizeof($v_work_list); $j++) {
  1491.               // ----- Explode the item
  1492.               $v_item_list = explode("-", $v_work_list[$j]);
  1493.               $v_size_item_list = sizeof($v_item_list);
  1494.               
  1495.               // ----- TBC : Here we might check that each item is a
  1496.               // real integer ...
  1497.               
  1498.               // ----- Look for single value
  1499.               if ($v_size_item_list == 1) {
  1500.                   // ----- Set the option value
  1501.                   $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1502.                   $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
  1503.               }
  1504.               elseif ($v_size_item_list == 2) {
  1505.                   // ----- Set the option value
  1506.                   $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1507.                   $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
  1508.               }
  1509.               else {
  1510.                   // ----- Error log
  1511.                   PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1512.  
  1513.                   // ----- Return
  1514.                   //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1515.                   return PclZip::errorCode();
  1516.               }
  1517.  
  1518.               //--(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']."]");
  1519.  
  1520.               // ----- Look for list sort
  1521.               if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
  1522.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
  1523.                   $v_sort_flag=true;
  1524.  
  1525.                   // ----- TBC : An automatic sort should be writen ...
  1526.                   // ----- Error log
  1527.                   PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1528.  
  1529.                   // ----- Return
  1530.                   //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1531.                   return PclZip::errorCode();
  1532.               }
  1533.               $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
  1534.           }
  1535.           
  1536.           // ----- Sort the items
  1537.           if ($v_sort_flag) {
  1538.               // TBC : To Be Completed
  1539.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
  1540.           }
  1541.  
  1542.           // ----- Next option
  1543.           $i++;
  1544.         break;
  1545.  
  1546.         // ----- Look for options that request no value
  1547.         case PCLZIP_OPT_REMOVE_ALL_PATH :
  1548.         case PCLZIP_OPT_EXTRACT_AS_STRING :
  1549.         case PCLZIP_OPT_NO_COMPRESSION :
  1550.           $v_result_list[$p_options_list[$i]] = true;
  1551.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1552.         break;
  1553.  
  1554.         // ----- Look for options that request an octal value
  1555.         case PCLZIP_OPT_SET_CHMOD :
  1556.           // ----- Check the number of parameters
  1557.           if (($i+1) >= $p_size) {
  1558.             // ----- Error log
  1559.             PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1560.  
  1561.             // ----- Return
  1562.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1563.             return PclZip::errorCode();
  1564.           }
  1565.  
  1566.           // ----- Get the value
  1567.           $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1568.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
  1569.           $i++;
  1570.         break;
  1571.  
  1572.         // ----- Look for options that request a call-back
  1573.         case PCLZIP_CB_PRE_EXTRACT :
  1574.         case PCLZIP_CB_POST_EXTRACT :
  1575.         case PCLZIP_CB_PRE_ADD :
  1576.         case PCLZIP_CB_POST_ADD :
  1577.         /* for futur use
  1578.         case PCLZIP_CB_PRE_DELETE :
  1579.         case PCLZIP_CB_POST_DELETE :
  1580.         case PCLZIP_CB_PRE_LIST :
  1581.         case PCLZIP_CB_POST_LIST :
  1582.         */
  1583.           // ----- Check the number of parameters
  1584.           if (($i+1) >= $p_size) {
  1585.             // ----- Error log
  1586.             PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1587.  
  1588.             // ----- Return
  1589.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1590.             return PclZip::errorCode();
  1591.           }
  1592.  
  1593.           // ----- Get the value
  1594.           $v_function_name = $p_options_list[$i+1];
  1595.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");
  1596.  
  1597.           // ----- Check that the value is a valid existing function
  1598.           if (!function_exists($v_function_name)) {
  1599.             // ----- Error log
  1600.             PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1601.  
  1602.             // ----- Return
  1603.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1604.             return PclZip::errorCode();
  1605.           }
  1606.  
  1607.           // ----- Set the attribute
  1608.           $v_result_list[$p_options_list[$i]] = $v_function_name;
  1609.           $i++;
  1610.         break;
  1611.  
  1612.         default :
  1613.           // ----- Error log
  1614.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Unknown optional parameter '".$p_options_list[$i]."'");
  1615.  
  1616.           // ----- Return
  1617.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1618.           return PclZip::errorCode();
  1619.       }
  1620.  
  1621.       // ----- Next options
  1622.       $i++;
  1623.     }
  1624.  
  1625.     // ----- Look for mandatory options
  1626.     for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1627.       // ----- Look for mandatory option
  1628.       if ($v_requested_options[$key] == 'mandatory') {
  1629.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
  1630.         // ----- Look if present
  1631.         if (!isset($v_result_list[$key])) {
  1632.           // ----- Error log
  1633.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1634.  
  1635.           // ----- Return
  1636.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1637.           return PclZip::errorCode();
  1638.         }
  1639.       }
  1640.     }
  1641.  
  1642.     // ----- Return
  1643.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1644.     return $v_result;
  1645.   }
  1646.   // --------------------------------------------------------------------------------
  1647.  
  1648.   // --------------------------------------------------------------------------------
  1649.   // Function : privCreate()
  1650.   // Description :
  1651.   // Parameters :
  1652.   // Return Values :
  1653.   // --------------------------------------------------------------------------------
  1654.   function privCreate($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  1655.   {
  1656.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list, result_list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  1657.     $v_result=1;
  1658.     $v_list_detail = array();
  1659.  
  1660.     // ----- Open the file in write mode
  1661.     if (($v_result = $this->privOpenFd('wb')) != 1)
  1662.     {
  1663.       // ----- Return
  1664.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1665.       return $v_result;
  1666.     }
  1667.  
  1668.     // ----- Add the list of files
  1669.     $v_result = $this->privAddList($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);
  1670.  
  1671.     // ----- Close
  1672.     $this->privCloseFd();
  1673.  
  1674.     // ----- Return
  1675.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1676.     return $v_result;
  1677.   }
  1678.   // --------------------------------------------------------------------------------
  1679.  
  1680.   // --------------------------------------------------------------------------------
  1681.   // Function : privAdd()
  1682.   // Description :
  1683.   // Parameters :
  1684.   // Return Values :
  1685.   // --------------------------------------------------------------------------------
  1686.   function privAdd($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  1687.   {
  1688.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list, result_list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  1689.     $v_result=1;
  1690.     $v_list_detail = array();
  1691.  
  1692.     // ----- Look if the archive exists or is empty
  1693.     if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
  1694.     {
  1695.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
  1696.  
  1697.       // ----- Do a create
  1698.       $v_result = $this->privCreate($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);
  1699.  
  1700.       // ----- Return
  1701.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1702.       return $v_result;
  1703.     }
  1704.  
  1705.     // ----- Open the zip file
  1706.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1707.     if (($v_result=$this->privOpenFd('rb')) != 1)
  1708.     {
  1709.       // ----- Return
  1710.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1711.       return $v_result;
  1712.     }
  1713.  
  1714.     // ----- Read the central directory informations
  1715.     $v_central_dir = array();
  1716.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1717.     {
  1718.       $this->privCloseFd();
  1719.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1720.       return $v_result;
  1721.     }
  1722.  
  1723.     // ----- Go to beginning of File
  1724.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  1725.     @rewind($this->zip_fd);
  1726.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  1727.  
  1728.     // ----- Creates a temporay file
  1729.     $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  1730.  
  1731.     // ----- Open the temporary file in write mode
  1732.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  1733.     if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  1734.     {
  1735.       $this->privCloseFd();
  1736.  
  1737.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  1738.  
  1739.       // ----- Return
  1740.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1741.       return PclZip::errorCode();
  1742.     }
  1743.  
  1744.     // ----- Copy the files from the archive to the temporary file
  1745.     // TBC : Here I should better append the file and go back to erase the central dir
  1746.     $v_size = $v_central_dir['offset'];
  1747.     while ($v_size != 0)
  1748.     {
  1749.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  1750.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  1751.       $v_buffer = fread($this->zip_fd, $v_read_size);
  1752.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  1753.       $v_size -= $v_read_size;
  1754.     }
  1755.  
  1756.     // ----- Swap the file descriptor
  1757.     // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  1758.     // the following methods on the temporary fil and not the real archive
  1759.     $v_swap = $this->zip_fd;
  1760.     $this->zip_fd = $v_zip_temp_fd;
  1761.     $v_zip_temp_fd = $v_swap;
  1762.  
  1763.     // ----- Add the files
  1764.     $v_header_list = array();
  1765.     if (($v_result = $this->privAddFileList($p_list, $v_header_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
  1766.     {
  1767.       fclose($v_zip_temp_fd);
  1768.       $this->privCloseFd();
  1769.       @unlink($v_zip_temp_name);
  1770.  
  1771.       // ----- Return
  1772.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1773.       return $v_result;
  1774.     }
  1775.  
  1776.     // ----- Store the offset of the central dir
  1777.     $v_offset = @ftell($this->zip_fd);
  1778.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
  1779.  
  1780.     // ----- Copy the block of file headers from the old archive
  1781.     $v_size = $v_central_dir['size'];
  1782.     while ($v_size != 0)
  1783.     {
  1784.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  1785.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  1786.       $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
  1787.       @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  1788.       $v_size -= $v_read_size;
  1789.     }
  1790.  
  1791.     // ----- Create the Central Dir files header
  1792.     for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
  1793.     {
  1794.       // ----- Create the file header
  1795.       if ($v_header_list[$i]['status'] == 'ok') {
  1796.         if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  1797.           fclose($v_zip_temp_fd);
  1798.           $this->privCloseFd();
  1799.           @unlink($v_zip_temp_name);
  1800.  
  1801.           // ----- Return
  1802.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1803.           return $v_result;
  1804.         }
  1805.         $v_count++;
  1806.       }
  1807.  
  1808.       // ----- Transform the header to a 'usable' info
  1809.       $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  1810.     }
  1811.  
  1812.     // ----- Zip file comment
  1813.     $v_comment = '';
  1814.  
  1815.     // ----- Calculate the size of the central header
  1816.     $v_size = @ftell($this->zip_fd)-$v_offset;
  1817.  
  1818.     // ----- Create the central dir footer
  1819.     if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
  1820.     {
  1821.       // ----- Reset the file list
  1822.       unset($v_header_list);
  1823.  
  1824.       // ----- Return
  1825.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1826.       return $v_result;
  1827.     }
  1828.  
  1829.     // ----- Swap back the file descriptor
  1830.     $v_swap = $this->zip_fd;
  1831.     $this->zip_fd = $v_zip_temp_fd;
  1832.     $v_zip_temp_fd = $v_swap;
  1833.  
  1834.     // ----- Close
  1835.     $this->privCloseFd();
  1836.  
  1837.     // ----- Close the temporary file
  1838.     @fclose($v_zip_temp_fd);
  1839.  
  1840.     // ----- Delete the zip file
  1841.     // TBC : I should test the result ...
  1842.     @unlink($this->zipname);
  1843.  
  1844.     // ----- Rename the temporary file
  1845.     // TBC : I should test the result ...
  1846.     //@rename($v_zip_temp_name, $this->zipname);
  1847.     PclZipUtilRename($v_zip_temp_name, $this->zipname);
  1848.  
  1849.     // ----- Return
  1850.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1851.     return $v_result;
  1852.   }
  1853.   // --------------------------------------------------------------------------------
  1854.  
  1855.   // --------------------------------------------------------------------------------
  1856.   // Function : privOpenFd()
  1857.   // Description :
  1858.   // Parameters :
  1859.   // --------------------------------------------------------------------------------
  1860.   function privOpenFd($p_mode)
  1861.   {
  1862.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);
  1863.     $v_result=1;
  1864.  
  1865.     // ----- Look if already open
  1866.     if ($this->zip_fd != 0)
  1867.     {
  1868.       // ----- Error log
  1869.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
  1870.  
  1871.       // ----- Return
  1872.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1873.       return PclZip::errorCode();
  1874.     }
  1875.  
  1876.     // ----- Open the zip file
  1877.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');
  1878.     if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
  1879.     {
  1880.       // ----- Error log
  1881.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
  1882.  
  1883.       // ----- Return
  1884.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  1885.       return PclZip::errorCode();
  1886.     }
  1887.  
  1888.     // ----- Return
  1889.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1890.     return $v_result;
  1891.   }
  1892.   // --------------------------------------------------------------------------------
  1893.  
  1894.   // --------------------------------------------------------------------------------
  1895.   // Function : privCloseFd()
  1896.   // Description :
  1897.   // Parameters :
  1898.   // --------------------------------------------------------------------------------
  1899.   function privCloseFd()
  1900.   {
  1901.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");
  1902.     $v_result=1;
  1903.  
  1904.     if ($this->zip_fd != 0)
  1905.       @fclose($this->zip_fd);
  1906.     $this->zip_fd = 0;
  1907.  
  1908.     // ----- Return
  1909.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1910.     return $v_result;
  1911.   }
  1912.   // --------------------------------------------------------------------------------
  1913.  
  1914.   // --------------------------------------------------------------------------------
  1915.   // Function : privAddList()
  1916.   // Description :
  1917.   //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  1918.   //   different from the real path of the file. This is usefull if you want to have PclTar
  1919.   //   running in any directory, and memorize relative path from an other directory.
  1920.   // Parameters :
  1921.   //   $p_list : An array containing the file or directory names to add in the tar
  1922.   //   $p_result_list : list of added files with their properties (specially the status field)
  1923.   //   $p_add_dir : Path to add in the filename path archived
  1924.   //   $p_remove_dir : Path to remove in the filename path archived
  1925.   // Return Values :
  1926.   // --------------------------------------------------------------------------------
  1927.   function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  1928.   {
  1929.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  1930.     $v_result=1;
  1931.  
  1932.     // ----- Add the files
  1933.     $v_header_list = array();
  1934.     if (($v_result = $this->privAddFileList($p_list, $v_header_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
  1935.     {
  1936.       // ----- Return
  1937.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1938.       return $v_result;
  1939.     }
  1940.  
  1941.     // ----- Store the offset of the central dir
  1942.     $v_offset = @ftell($this->zip_fd);
  1943.  
  1944.     // ----- Create the Central Dir files header
  1945.     for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
  1946.     {
  1947.       // ----- Create the file header
  1948.       if ($v_header_list[$i]['status'] == 'ok') {
  1949.         if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  1950.           // ----- Return
  1951.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1952.           return $v_result;
  1953.         }
  1954.         $v_count++;
  1955.       }
  1956.  
  1957.       // ----- Transform the header to a 'usable' info
  1958.       $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  1959.     }
  1960.  
  1961.     // ----- Zip file comment
  1962.     $v_comment = '';
  1963.  
  1964.     // ----- Calculate the size of the central header
  1965.     $v_size = @ftell($this->zip_fd)-$v_offset;
  1966.  
  1967.     // ----- Create the central dir footer
  1968.     if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
  1969.     {
  1970.       // ----- Reset the file list
  1971.       unset($v_header_list);
  1972.  
  1973.       // ----- Return
  1974.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1975.       return $v_result;
  1976.     }
  1977.  
  1978.     // ----- Return
  1979.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  1980.     return $v_result;
  1981.   }
  1982.   // --------------------------------------------------------------------------------
  1983.  
  1984.   // --------------------------------------------------------------------------------
  1985.   // Function : privAddFileList()
  1986.   // Description :
  1987.   //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  1988.   //   different from the real path of the file. This is usefull if you want to
  1989.   //   run the lib in any directory, and memorize relative path from an other directory.
  1990.   // Parameters :
  1991.   //   $p_list : An array containing the file or directory names to add in the tar
  1992.   //   $p_result_list : list of added files with their properties (specially the status field)
  1993.   //   $p_add_dir : Path to add in the filename path archived
  1994.   //   $p_remove_dir : Path to remove in the filename path archived
  1995.   // Return Values :
  1996.   // --------------------------------------------------------------------------------
  1997.   function privAddFileList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  1998.   {
  1999.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  2000.     $v_result=1;
  2001.     $v_header = array();
  2002.  
  2003.     // ----- Recuperate the current number of elt in list
  2004.     $v_nb = sizeof($p_result_list);
  2005.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have $v_nb elements");
  2006.  
  2007.     // ----- Loop on the files
  2008.     for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++)
  2009.     {
  2010.       // ----- Recuperate the filename
  2011.       $p_filename = PclZipUtilTranslateWinPath($p_list[$j], false);
  2012.  
  2013.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file [$p_filename]");
  2014.  
  2015.       // ----- Skip empty file names
  2016.       if ($p_filename == "")
  2017.       {
  2018.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
  2019.         continue;
  2020.       }
  2021.  
  2022.       // ----- Check the filename
  2023.       if (!file_exists($p_filename))
  2024.       {
  2025.         // ----- Error log
  2026.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '$p_filename' does not exists");
  2027.         PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '$p_filename' does not exists");
  2028.  
  2029.         // ----- Return
  2030.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2031.         return PclZip::errorCode();
  2032.       }
  2033.  
  2034.       /* This test is done later
  2035.       // ----- Check the path length
  2036.       if (strlen($p_filename) > 0xFF)
  2037.       {
  2038.         // ----- Error log
  2039.         PclZip::privErrorLog(-5, "File name is too long (max. 255) : '$p_filename'");
  2040.  
  2041.         // ----- Return
  2042.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2043.         return PclZip::errorCode();
  2044.       }
  2045.       */
  2046.  
  2047.       // ----- Look if it is a file or a dir with no all pathnre move
  2048.       if ((is_file($p_filename)) || ((is_dir($p_filename)) && !$p_remove_all_dir)) {
  2049.         // ----- Add the file
  2050.         if (($v_result = $this->privAddFile($p_filename, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
  2051.         {
  2052.           // ----- Return status
  2053.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2054.           return $v_result;
  2055.         }
  2056.  
  2057.         // ----- Store the file infos
  2058.         $p_result_list[$v_nb++] = $v_header;
  2059.       }
  2060.  
  2061.       // ----- Look for directory
  2062.       if (is_dir($p_filename))
  2063.       {
  2064.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "$p_filename is a directory");
  2065.  
  2066.         // ----- Look for path
  2067.         if ($p_filename != ".")
  2068.           $v_path = $p_filename."/";
  2069.         else
  2070.           $v_path = "";
  2071.  
  2072.         // ----- Read the directory for files and sub-directories
  2073.         $p_hdir = opendir($p_filename);
  2074.         $p_hitem = readdir($p_hdir); // '.' directory
  2075.         $p_hitem = readdir($p_hdir); // '..' directory
  2076.         while ($p_hitem = readdir($p_hdir))
  2077.         {
  2078.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for $p_hitem in the directory");
  2079.  
  2080.           // ----- Look for a file
  2081.           if (is_file($v_path.$p_hitem))
  2082.           {
  2083.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Add the file '".$v_path.$p_hitem."'");
  2084.  
  2085.             // ----- Add the file
  2086.             if (($v_result = $this->privAddFile($v_path.$p_hitem, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
  2087.             {
  2088.               // ----- Return status
  2089.               //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2090.               return $v_result;
  2091.             }
  2092.  
  2093.             // ----- Store the file infos
  2094.             $p_result_list[$v_nb++] = $v_header;
  2095.           }
  2096.  
  2097.           // ----- Recursive call to privAddFileList()
  2098.           else
  2099.           {
  2100.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Add the directory '".$v_path.$p_hitem."'");
  2101.  
  2102.             // ----- Need an array as parameter
  2103.             $p_temp_list[0] = $v_path.$p_hitem;
  2104.             $v_result = $this->privAddFileList($p_temp_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);
  2105.  
  2106.             // ----- Update the number of elements of the list
  2107.             $v_nb = sizeof($p_result_list);
  2108.           }
  2109.         }
  2110.  
  2111.         // ----- Free memory for the recursive loop
  2112.         unset($p_temp_list);
  2113.         unset($p_hdir);
  2114.         unset($p_hitem);
  2115.       }
  2116.     }
  2117.  
  2118.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have $v_nb elements");
  2119.  
  2120.     // ----- Return
  2121.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2122.     return $v_result;
  2123.   }
  2124.   // --------------------------------------------------------------------------------
  2125.  
  2126.   // --------------------------------------------------------------------------------
  2127.   // Function : privAddFile()
  2128.   // Description :
  2129.   // Parameters :
  2130.   // Return Values :
  2131.   // --------------------------------------------------------------------------------
  2132.   function privAddFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  2133.   {
  2134.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='$p_filename', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
  2135.     $v_result=1;
  2136.  
  2137.     if ($p_filename == "")
  2138.     {
  2139.       // ----- Error log
  2140.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
  2141.  
  2142.       // ----- Return
  2143.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2144.       return PclZip::errorCode();
  2145.     }
  2146.  
  2147.     // ----- Calculate the stored filename
  2148.     $v_stored_filename = $p_filename;
  2149.  
  2150.     // ----- Look for all path to remove
  2151.     if ($p_remove_all_dir) {
  2152.       $v_stored_filename = basename($p_filename);
  2153.     }
  2154.     // ----- Look for partial path remove
  2155.     else if ($p_remove_dir != "")
  2156.     {
  2157.       if (substr($p_remove_dir, -1) != '/')
  2158.         $p_remove_dir .= "/";
  2159.  
  2160.       if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./"))
  2161.       {
  2162.         if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
  2163.           $p_remove_dir = "./".$p_remove_dir;
  2164.         if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
  2165.           $p_remove_dir = substr($p_remove_dir, 2);
  2166.       }
  2167.  
  2168.       $v_compare = PclZipUtilPathInclusion($p_remove_dir, $p_filename);
  2169.       if ($v_compare > 0)
  2170. //      if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
  2171.       {
  2172.  
  2173.         if ($v_compare == 2) {
  2174.           $v_stored_filename = "";
  2175.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder");
  2176.         }
  2177.         else {
  2178.           $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
  2179.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'");
  2180.         }
  2181.       }
  2182.     }
  2183.     // ----- Look for path to add
  2184.     if ($p_add_dir != "")
  2185.     {
  2186.       if (substr($p_add_dir, -1) == "/")
  2187.         $v_stored_filename = $p_add_dir.$v_stored_filename;
  2188.       else
  2189.         $v_stored_filename = $p_add_dir."/".$v_stored_filename;
  2190.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
  2191.     }
  2192.  
  2193.     // ----- Filename (reduce the path of stored name)
  2194.     $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
  2195.  
  2196.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Filename (reduced) '$v_stored_filename', strlen ".strlen($v_stored_filename));
  2197.  
  2198.     /* filename length moved after call-back in release 1.3
  2199.     // ----- Check the path length
  2200.     if (strlen($v_stored_filename) > 0xFF)
  2201.     {
  2202.       // ----- Error log
  2203.       PclZip::privErrorLog(-5, "Stored file name is too long (max. 255) : '$v_stored_filename'");
  2204.  
  2205.       // ----- Return
  2206.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2207.       return PclZip::errorCode();
  2208.     }
  2209.     */
  2210.  
  2211.     // ----- Set the file properties
  2212.     clearstatcache();
  2213.     $p_header['version'] = 20;
  2214.     $p_header['version_extracted'] = 10;
  2215.     $p_header['flag'] = 0;
  2216.     $p_header['compression'] = 0;
  2217.     $p_header['mtime'] = filemtime($p_filename);
  2218.     $p_header['crc'] = 0;
  2219.     $p_header['compressed_size'] = 0;
  2220.     $p_header['size'] = filesize($p_filename);
  2221.     $p_header['filename_len'] = strlen($p_filename);
  2222.     $p_header['extra_len'] = 0;
  2223.     $p_header['comment_len'] = 0;
  2224.     $p_header['disk'] = 0;
  2225.     $p_header['internal'] = 0;
  2226.     $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
  2227.     $p_header['offset'] = 0;
  2228.     $p_header['filename'] = $p_filename;
  2229.     $p_header['stored_filename'] = $v_stored_filename;
  2230.     $p_header['extra'] = '';
  2231.     $p_header['comment'] = '';
  2232.     $p_header['status'] = 'ok';
  2233.     $p_header['index'] = -1;
  2234.  
  2235.     // ----- Look for pre-add callback
  2236.     if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
  2237.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");
  2238.  
  2239.       // ----- Generate a local information
  2240.       $v_local_header = array();
  2241.       $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2242.  
  2243.       // ----- Call the callback
  2244.       // Here I do not use call_user_func() because I need to send a reference to the
  2245.       // header.
  2246.       eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
  2247.       if ($v_result == 0) {
  2248.         // ----- Change the file status
  2249.         $p_header['status'] = "skipped";
  2250.         $v_result = 1;
  2251.       }
  2252.  
  2253.       // ----- Update the informations
  2254.       // Only some fields can be modified
  2255.       if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
  2256.         $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
  2257.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
  2258.       }
  2259.     }
  2260.  
  2261.     // ----- Look for empty stored filename
  2262.     if ($p_header['stored_filename'] == "") {
  2263.       $p_header['status'] = "filtered";
  2264.     }
  2265.     
  2266.     // ----- Check the path length
  2267.     if (strlen($p_header['stored_filename']) > 0xFF) {
  2268.       $p_header['status'] = 'filename_too_long';
  2269.     }
  2270.  
  2271.     // ----- Look if no error, or file not skipped
  2272.     if ($p_header['status'] == 'ok') {
  2273.  
  2274.       // ----- Look for a file
  2275.       if (is_file($p_filename))
  2276.       {
  2277.         // ----- Open the source file
  2278.         if (($v_file = @fopen($p_filename, "rb")) == 0) {
  2279.           PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
  2280.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2281.           return PclZip::errorCode();
  2282.         }
  2283.  
  2284.         if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
  2285.           // ----- Read the file content
  2286.           $v_content_compressed = @fread($v_file, $p_header['size']);
  2287.  
  2288.           // ----- Calculate the CRC
  2289.           $p_header['crc'] = crc32($v_content_compressed);
  2290.         }
  2291.         else {
  2292.           // ----- Read the file content
  2293.           $v_content = @fread($v_file, $p_header['size']);
  2294.  
  2295.           // ----- Calculate the CRC
  2296.           $p_header['crc'] = crc32($v_content);
  2297.  
  2298.           // ----- Compress the file
  2299.           $v_content_compressed = gzdeflate($v_content);
  2300.         }
  2301.  
  2302.         // ----- Set header parameters
  2303.         $p_header['compressed_size'] = strlen($v_content_compressed);
  2304.         $p_header['compression'] = 8;
  2305.  
  2306.         // ----- Call the header generation
  2307.         if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2308.           @fclose($v_file);
  2309.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2310.           return $v_result;
  2311.         }
  2312.  
  2313.         // ----- Write the compressed content
  2314.         $v_binary_data = pack('a'.$p_header['compressed_size'], $v_content_compressed);
  2315.         @fwrite($this->zip_fd, $v_binary_data, $p_header['compressed_size']);
  2316.         
  2317.         // ----- Close the file
  2318.         @fclose($v_file);
  2319.       }
  2320.  
  2321.       // ----- Look for a directory
  2322.       else
  2323.       {
  2324.         // ----- Set the file properties
  2325.         $p_header['filename'] .= '/';
  2326.         $p_header['filename_len']++;
  2327.         $p_header['size'] = 0;
  2328.         $p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
  2329.  
  2330.         // ----- Call the header generation
  2331.         if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
  2332.         {
  2333.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2334.           return $v_result;
  2335.         }
  2336.       }
  2337.     }
  2338.  
  2339.     // ----- Look for pre-add callback
  2340.     if (isset($p_options[PCLZIP_CB_POST_ADD])) {
  2341.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");
  2342.  
  2343.       // ----- Generate a local information
  2344.       $v_local_header = array();
  2345.       $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2346.  
  2347.       // ----- Call the callback
  2348.       // Here I do not use call_user_func() because I need to send a reference to the
  2349.       // header.
  2350.       eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
  2351.       if ($v_result == 0) {
  2352.         // ----- Ignored
  2353.         $v_result = 1;
  2354.       }
  2355.  
  2356.       // ----- Update the informations
  2357.       // Nothing can be modified
  2358.     }
  2359.  
  2360.     // ----- Return
  2361.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2362.     return $v_result;
  2363.   }
  2364.   // --------------------------------------------------------------------------------
  2365.  
  2366.   // --------------------------------------------------------------------------------
  2367.   // Function : privWriteFileHeader()
  2368.   // Description :
  2369.   // Parameters :
  2370.   // Return Values :
  2371.   // --------------------------------------------------------------------------------
  2372.   function privWriteFileHeader(&$p_header)
  2373.   {
  2374.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
  2375.     $v_result=1;
  2376.  
  2377.     // TBC
  2378.     //for(reset($p_header); $key = key($p_header); next($p_header)) {
  2379.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
  2380.     //}
  2381.  
  2382.     // ----- Store the offset position of the file
  2383.     $p_header['offset'] = ftell($this->zip_fd);
  2384.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
  2385.  
  2386.     // ----- Transform UNIX mtime to DOS format mdate/mtime
  2387.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  2388.     $v_date = getdate($p_header['mtime']);
  2389.     $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  2390.     $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  2391.  
  2392.     // ----- Packed data
  2393.     $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, $p_header['version'], $p_header['flag'],
  2394.                           $p_header['compression'], $v_mtime, $v_mdate,
  2395.                           $p_header['crc'], $p_header['compressed_size'], $p_header['size'],
  2396.                           strlen($p_header['stored_filename']), $p_header['extra_len']);
  2397.  
  2398.     // ----- Write the first 148 bytes of the header in the archive
  2399.     fputs($this->zip_fd, $v_binary_data, 30);
  2400.  
  2401.     // ----- Write the variable fields
  2402.     if (strlen($p_header['stored_filename']) != 0)
  2403.     {
  2404.       fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  2405.     }
  2406.     if ($p_header['extra_len'] != 0)
  2407.     {
  2408.       fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  2409.     }
  2410.  
  2411.     // ----- Return
  2412.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2413.     return $v_result;
  2414.   }
  2415.   // --------------------------------------------------------------------------------
  2416.  
  2417.   // --------------------------------------------------------------------------------
  2418.   // Function : privWriteCentralFileHeader()
  2419.   // Description :
  2420.   // Parameters :
  2421.   // Return Values :
  2422.   // --------------------------------------------------------------------------------
  2423.   function privWriteCentralFileHeader(&$p_header)
  2424.   {
  2425.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
  2426.     $v_result=1;
  2427.  
  2428.     // TBC
  2429.     //for(reset($p_header); $key = key($p_header); next($p_header)) {
  2430.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
  2431.     //}
  2432.  
  2433.     // ----- Transform UNIX mtime to DOS format mdate/mtime
  2434.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  2435.     $v_date = getdate($p_header['mtime']);
  2436.     $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  2437.     $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  2438.  
  2439.     // ----- Packed data
  2440.     $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, $p_header['version'], $p_header['version_extracted'],
  2441.                           $p_header['flag'], $p_header['compression'], $v_mtime, $v_mdate, $p_header['crc'],
  2442.                           $p_header['compressed_size'], $p_header['size'],
  2443.                           strlen($p_header['stored_filename']), $p_header['extra_len'], $p_header['comment_len'],
  2444.                           $p_header['disk'], $p_header['internal'], $p_header['external'], $p_header['offset']);
  2445.  
  2446.     // ----- Write the 42 bytes of the header in the zip file
  2447.     fputs($this->zip_fd, $v_binary_data, 46);
  2448.  
  2449.     // ----- Write the variable fields
  2450.     if (strlen($p_header['stored_filename']) != 0)
  2451.     {
  2452.       fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  2453.     }
  2454.     if ($p_header['extra_len'] != 0)
  2455.     {
  2456.       fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  2457.     }
  2458.     if ($p_header['comment_len'] != 0)
  2459.     {
  2460.       fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
  2461.     }
  2462.  
  2463.     // ----- Return
  2464.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2465.     return $v_result;
  2466.   }
  2467.   // --------------------------------------------------------------------------------
  2468.  
  2469.   // --------------------------------------------------------------------------------
  2470.   // Function : privWriteCentralHeader()
  2471.   // Description :
  2472.   // Parameters :
  2473.   // Return Values :
  2474.   // --------------------------------------------------------------------------------
  2475.   function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
  2476.   {
  2477.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
  2478.     $v_result=1;
  2479.  
  2480.     // ----- Packed data
  2481.     $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, $p_nb_entries, $p_size, $p_offset, strlen($p_comment));
  2482.  
  2483.     // ----- Write the 22 bytes of the header in the zip file
  2484.     fputs($this->zip_fd, $v_binary_data, 22);
  2485.  
  2486.     // ----- Write the variable fields
  2487.     if (strlen($p_comment) != 0)
  2488.     {
  2489.       fputs($this->zip_fd, $p_comment, strlen($p_comment));
  2490.     }
  2491.  
  2492.     // ----- Return
  2493.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2494.     return $v_result;
  2495.   }
  2496.   // --------------------------------------------------------------------------------
  2497.  
  2498.   // --------------------------------------------------------------------------------
  2499.   // Function : privList()
  2500.   // Description :
  2501.   // Parameters :
  2502.   // Return Values :
  2503.   // --------------------------------------------------------------------------------
  2504.   function privList(&$p_list)
  2505.   {
  2506.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
  2507.     $v_result=1;
  2508.  
  2509.     // ----- Open the zip file
  2510.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2511.     if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  2512.     {
  2513.       // ----- Error log
  2514.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  2515.  
  2516.       // ----- Return
  2517.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2518.       return PclZip::errorCode();
  2519.     }
  2520.  
  2521.     // ----- Read the central directory informations
  2522.     $v_central_dir = array();
  2523.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  2524.     {
  2525.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2526.       return $v_result;
  2527.     }
  2528.  
  2529.     // ----- Go to beginning of Central Dir
  2530.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'");
  2531.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  2532.     @rewind($this->zip_fd);
  2533.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  2534.     if (@fseek($this->zip_fd, $v_central_dir['offset']))
  2535.     {
  2536.       // ----- Error log
  2537.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  2538.  
  2539.       // ----- Return
  2540.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2541.       return PclZip::errorCode();
  2542.     }
  2543.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
  2544.  
  2545.     // ----- Read each entry
  2546.     for ($i=0; $i<$v_central_dir['entries']; $i++)
  2547.     {
  2548.       // ----- Read the file header
  2549.       if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  2550.       {
  2551.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2552.         return $v_result;
  2553.       }
  2554.       $v_header['index'] = $i;
  2555.  
  2556.       // ----- Get the only interesting attributes
  2557.       $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
  2558.       unset($v_header);
  2559.     }
  2560.  
  2561.     // ----- Close the zip file
  2562.     $this->privCloseFd();
  2563.  
  2564.     // ----- Return
  2565.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2566.     return $v_result;
  2567.   }
  2568.   // --------------------------------------------------------------------------------
  2569.  
  2570.   // --------------------------------------------------------------------------------
  2571.   // Function : privConvertHeader2FileInfo()
  2572.   // Description :
  2573.   //   This function takes the file informations from the central directory
  2574.   //   entries and extract the interesting parameters that will be given back.
  2575.   //   The resulting file infos are set in the array $p_info
  2576.   //     $p_info['filename'] : Filename with full path. Given by user (add),
  2577.   //                           extracted in the filesystem (extract).
  2578.   //     $p_info['stored_filename'] : Stored filename in the archive.
  2579.   //     $p_info['size'] = Size of the file.
  2580.   //     $p_info['compressed_size'] = Compressed size of the file.
  2581.   //     $p_info['mtime'] = Last modification date of the file.
  2582.   //     $p_info['comment'] = Comment associated with the file.
  2583.   //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
  2584.   //     $p_info['status'] = status of the action on the file.
  2585.   // Parameters :
  2586.   // Return Values :
  2587.   // --------------------------------------------------------------------------------
  2588.   function privConvertHeader2FileInfo($p_header, &$p_info)
  2589.   {
  2590.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'");
  2591.     $v_result=1;
  2592.  
  2593.     // ----- Get the interesting attributes
  2594.     $p_info['filename'] = $p_header['filename'];
  2595.     $p_info['stored_filename'] = $p_header['stored_filename'];
  2596.     $p_info['size'] = $p_header['size'];
  2597.     $p_info['compressed_size'] = $p_header['compressed_size'];
  2598.     $p_info['mtime'] = $p_header['mtime'];
  2599.     $p_info['comment'] = $p_header['comment'];
  2600.     $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
  2601.     $p_info['index'] = $p_header['index'];
  2602.     $p_info['status'] = $p_header['status'];
  2603.  
  2604.     // ----- Return
  2605.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2606.     return $v_result;
  2607.   }
  2608.   // --------------------------------------------------------------------------------
  2609.  
  2610.   // --------------------------------------------------------------------------------
  2611.   // Function : privExtractByRule()
  2612.   // Description :
  2613.   //   Extract a file or directory depending of rules (by index, by name, ...)
  2614.   // Parameters :
  2615.   //   $p_file_list : An array where will be placed the properties of each
  2616.   //                  extracted file
  2617.   //   $p_path : Path to add while writing the extracted files
  2618.   //   $p_remove_path : Path to remove (from the file memorized path) while writing the
  2619.   //                    extracted files. If the path does not match the file path,
  2620.   //                    the file is extracted with its memorized path.
  2621.   //                    $p_remove_path does not apply to 'list' mode.
  2622.   //                    $p_path and $p_remove_path are commulative.
  2623.   // Return Values :
  2624.   //   1 on success,0 or less on error (see error code list)
  2625.   // --------------------------------------------------------------------------------
  2626.   function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  2627.   {
  2628.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  2629.     $v_result=1;
  2630.  
  2631.     // ----- Check the path
  2632.     if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path,1,2)!=":/")))
  2633.       $p_path = "./".$p_path;
  2634.  
  2635.     // ----- Reduce the path last (and duplicated) '/'
  2636.     if (($p_path != "./") && ($p_path != "/"))
  2637.     {
  2638.       // ----- Look for the path end '/'
  2639.       while (substr($p_path, -1) == "/")
  2640.       {
  2641.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
  2642.         $p_path = substr($p_path, 0, strlen($p_path)-1);
  2643.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
  2644.       }
  2645.     }
  2646.  
  2647.     // ----- Look for path to remove format (should end by /)
  2648.     if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  2649.     {
  2650.       $p_remove_path .= '/';
  2651.     }
  2652.     $p_remove_path_size = strlen($p_remove_path);
  2653.  
  2654.     // ----- Open the zip file
  2655.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  2656.     if (($v_result = $this->privOpenFd('rb')) != 1)
  2657.     {
  2658.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2659.       return $v_result;
  2660.     }
  2661.  
  2662.     // ----- Read the central directory informations
  2663.     $v_central_dir = array();
  2664.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  2665.     {
  2666.       // ----- Close the zip file
  2667.       $this->privCloseFd();
  2668.  
  2669.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2670.       return $v_result;
  2671.     }
  2672.  
  2673.     // ----- Start at beginning of Central Dir
  2674.     $v_pos_entry = $v_central_dir['offset'];
  2675.  
  2676.     // ----- Read each entry
  2677.     $j_start = 0;
  2678.     for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  2679.     {
  2680.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
  2681.  
  2682.       // ----- Read next Central dir entry
  2683.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
  2684.       @rewind($this->zip_fd);
  2685.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
  2686.       if (@fseek($this->zip_fd, $v_pos_entry))
  2687.       {
  2688.         // ----- Close the zip file
  2689.         $this->privCloseFd();
  2690.  
  2691.         // ----- Error log
  2692.         PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  2693.  
  2694.         // ----- Return
  2695.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2696.         return PclZip::errorCode();
  2697.       }
  2698.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
  2699.  
  2700.       // ----- Read the file header
  2701.       $v_header = array();
  2702.       if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  2703.       {
  2704.         // ----- Close the zip file
  2705.         $this->privCloseFd();
  2706.  
  2707.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2708.         return $v_result;
  2709.       }
  2710.  
  2711.       // ----- Store the index
  2712.       $v_header['index'] = $i;
  2713.  
  2714.       // ----- Store the file position
  2715.       $v_pos_entry = ftell($this->zip_fd);
  2716.  
  2717.       // ----- Look for the specific extract rules
  2718.       $v_extract = false;
  2719.  
  2720.       // ----- Look for extract by name rule
  2721.       if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
  2722.           && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  2723.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
  2724.  
  2725.           // ----- Look if the filename is in the list
  2726.           for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
  2727.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
  2728.  
  2729.               // ----- Look for a directory
  2730.               if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  2731.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
  2732.  
  2733.                   // ----- Look if the directory is in the filename path
  2734.                   if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  2735.                       && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  2736.                       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
  2737.                       $v_extract = true;
  2738.                   }
  2739.               }
  2740.               // ----- Look for a filename
  2741.               elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  2742.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
  2743.                   $v_extract = true;
  2744.               }
  2745.           }
  2746.       }
  2747.  
  2748.       // ----- Look for extract by ereg rule
  2749.       else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
  2750.                && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  2751.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
  2752.  
  2753.           if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
  2754.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  2755.               $v_extract = true;
  2756.           }
  2757.       }
  2758.  
  2759.       // ----- Look for extract by preg rule
  2760.       else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
  2761.                && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  2762.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
  2763.  
  2764.           if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
  2765.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  2766.               $v_extract = true;
  2767.           }
  2768.       }
  2769.  
  2770.       // ----- Look for extract by index rule
  2771.       else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  2772.                && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  2773.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
  2774.           
  2775.           // ----- Look if the index is in the list
  2776.           for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
  2777.               //--(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']."]");
  2778.  
  2779.               if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  2780.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
  2781.                   $v_extract = true;
  2782.               }
  2783.               if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  2784.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
  2785.                   $j_start = $j+1;
  2786.               }
  2787.  
  2788.               if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  2789.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
  2790.                   break;
  2791.               }
  2792.           }
  2793.       }
  2794.  
  2795.       // ----- Look for no rule, which means extract all the archive
  2796.       else {
  2797.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
  2798.           $v_extract = true;
  2799.       }
  2800.       
  2801.  
  2802.       // ----- Look for real extraction
  2803.       if ($v_extract)
  2804.       {
  2805.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
  2806.  
  2807.         // ----- Go to the file position
  2808.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  2809.         @rewind($this->zip_fd);
  2810.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  2811.         if (@fseek($this->zip_fd, $v_header['offset']))
  2812.         {
  2813.           // ----- Close the zip file
  2814.           $this->privCloseFd();
  2815.  
  2816.           // ----- Error log
  2817.           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  2818.  
  2819.           // ----- Return
  2820.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  2821.           return PclZip::errorCode();
  2822.         }
  2823.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  2824.  
  2825.         // ----- Look for extraction as string
  2826.         if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
  2827.  
  2828.           // ----- Extracting the file
  2829.           if (($v_result = $this->privExtractFileAsString($v_header, $v_string)) != 1)
  2830.           {
  2831.             // ----- Close the zip file
  2832.             $this->privCloseFd();
  2833.  
  2834.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2835.             return $v_result;
  2836.           }
  2837.  
  2838.           // ----- Get the only interesting attributes
  2839.           if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
  2840.           {
  2841.             // ----- Close the zip file
  2842.             $this->privCloseFd();
  2843.  
  2844.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2845.             return $v_result;
  2846.           }
  2847.  
  2848.           // ----- Set the file content
  2849.           $p_file_list[$v_nb_extracted]['content'] = $v_string;
  2850.  
  2851.           // ----- Next extracted file
  2852.           $v_nb_extracted++;
  2853.         }
  2854.         else {
  2855.           // ----- Extracting the file
  2856.           if (($v_result = $this->privExtractFile($v_header, $p_path, $p_remove_path, $p_remove_all_path, $p_options)) != 1)
  2857.           {
  2858.             // ----- Close the zip file
  2859.             $this->privCloseFd();
  2860.  
  2861.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2862.             return $v_result;
  2863.           }
  2864.  
  2865.           // ----- Get the only interesting attributes
  2866.           if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
  2867.           {
  2868.             // ----- Close the zip file
  2869.             $this->privCloseFd();
  2870.  
  2871.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2872.             return $v_result;
  2873.           }
  2874.         }
  2875.       }
  2876.     }
  2877.  
  2878.     // ----- Close the zip file
  2879.     $this->privCloseFd();
  2880.  
  2881.     // ----- Return
  2882.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2883.     return $v_result;
  2884.   }
  2885.   // --------------------------------------------------------------------------------
  2886.  
  2887.   // --------------------------------------------------------------------------------
  2888.   // Function : privExtractFile()
  2889.   // Description :
  2890.   // Parameters :
  2891.   // Return Values :
  2892.   // --------------------------------------------------------------------------------
  2893.   function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  2894.   {
  2895.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
  2896.     $v_result=1;
  2897.  
  2898.     // ----- Read the file header
  2899.     if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  2900.     {
  2901.       // ----- Return
  2902.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2903.       return $v_result;
  2904.     }
  2905.  
  2906.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  2907.  
  2908.     // ----- Check that the file header is coherent with $p_entry info
  2909.     // TBC
  2910.  
  2911.     // ----- Look for all path to remove
  2912.     if ($p_remove_all_path == true) {
  2913.         // ----- Get the basename of the path
  2914.         $p_entry['filename'] = basename($p_entry['filename']);
  2915.     }
  2916.  
  2917.     // ----- Look for path to remove
  2918.     else if ($p_remove_path != "")
  2919.     {
  2920.       //if (strcmp($p_remove_path, $p_entry['filename'])==0)
  2921.       if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
  2922.       {
  2923.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'");
  2924.  
  2925.         // ----- Change the file status
  2926.         $p_entry['status'] = "filtered";
  2927.  
  2928.         // ----- Return
  2929.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2930.         return $v_result;
  2931.       }
  2932.  
  2933.       $p_remove_path_size = strlen($p_remove_path);
  2934.       if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
  2935.       {
  2936.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'");
  2937.  
  2938.         // ----- Remove the path
  2939.         $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
  2940.  
  2941.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'");
  2942.       }
  2943.     }
  2944.  
  2945.     // ----- Add the path
  2946.     if ($p_path != '')
  2947.     {
  2948.       $p_entry['filename'] = $p_path."/".$p_entry['filename'];
  2949.     }
  2950.  
  2951.     // ----- Look for pre-extract callback
  2952.     if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  2953.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
  2954.  
  2955.       // ----- Generate a local information
  2956.       $v_local_header = array();
  2957.       $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  2958.  
  2959.       // ----- Call the callback
  2960.       // Here I do not use call_user_func() because I need to send a reference to the
  2961.       // header.
  2962.       eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  2963.       if ($v_result == 0) {
  2964.         // ----- Change the file status
  2965.         $p_entry['status'] = "skipped";
  2966.         $v_result = 1;
  2967.       }
  2968.  
  2969.       // ----- Update the informations
  2970.       // Only some fields can be modified
  2971.       $p_entry['filename'] = $v_local_header['filename'];
  2972.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
  2973.     }
  2974.  
  2975.     // ----- Trace
  2976.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  2977.  
  2978.     // ----- Look if extraction should be done
  2979.     if ($p_entry['status'] == 'ok') {
  2980.  
  2981.     // ----- Look for specific actions while the file exist
  2982.     if (file_exists($p_entry['filename']))
  2983.     {
  2984.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists");
  2985.  
  2986.       // ----- Look if file is a directory
  2987.       if (is_dir($p_entry['filename']))
  2988.       {
  2989.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory");
  2990.  
  2991.         // ----- Change the file status
  2992.         $p_entry['status'] = "already_a_directory";
  2993.  
  2994.         // ----- Return
  2995.         ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  2996.         //return $v_result;
  2997.       }
  2998.       // ----- Look if file is write protected
  2999.       else if (!is_writeable($p_entry['filename']))
  3000.       {
  3001.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected");
  3002.  
  3003.         // ----- Change the file status
  3004.         $p_entry['status'] = "write_protected";
  3005.  
  3006.         // ----- Return
  3007.         ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3008.         //return $v_result;
  3009.       }
  3010.  
  3011.       // ----- Look if the extracted file is older
  3012.       else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
  3013.       {
  3014.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is newer (".date("l dS of F Y h:i:s A", filemtime($p_entry['filename'])).") than the extracted file (".date("l dS of F Y h:i:s A", $p_entry['mtime']).")");
  3015.  
  3016.         // ----- Change the file status
  3017.         $p_entry['status'] = "newer_exist";
  3018.  
  3019.         // ----- Return
  3020.         ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3021.         //return $v_result;
  3022.       }
  3023.     }
  3024.  
  3025.     // ----- Check the directory availability and create it if necessary
  3026.     else {
  3027.       if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
  3028.         $v_dir_to_check = $p_entry['filename'];
  3029.       else if (!strstr($p_entry['filename'], "/"))
  3030.         $v_dir_to_check = "";
  3031.       else
  3032.         $v_dir_to_check = dirname($p_entry['filename']);
  3033.  
  3034.       if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
  3035.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
  3036.  
  3037.         // ----- Change the file status
  3038.         $p_entry['status'] = "path_creation_fail";
  3039.  
  3040.         // ----- Return
  3041.         ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3042.         //return $v_result;
  3043.         $v_result = 1;
  3044.       }
  3045.     }
  3046.     }
  3047.  
  3048.     // ----- Look if extraction should be done
  3049.     if ($p_entry['status'] == 'ok') {
  3050.  
  3051.       // ----- Do the extraction (if not a folder)
  3052.       if (!(($p_entry['external']&0x00000010)==0x00000010))
  3053.       {
  3054.  
  3055.         // ----- Look for not compressed file
  3056.         if ($p_entry['compressed_size'] == $p_entry['size'])
  3057.         {
  3058.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  3059.  
  3060.           // ----- Opening destination file
  3061.           if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
  3062.           {
  3063.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
  3064.  
  3065.             // ----- Change the file status
  3066.             $p_entry['status'] = "write_error";
  3067.  
  3068.             // ----- Return
  3069.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3070.             return $v_result;
  3071.           }
  3072.  
  3073.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
  3074.  
  3075.           // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  3076.           $v_size = $p_entry['compressed_size'];
  3077.           while ($v_size != 0)
  3078.           {
  3079.             $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  3080.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes");
  3081.             $v_buffer = fread($this->zip_fd, $v_read_size);
  3082.             $v_binary_data = pack('a'.$v_read_size, $v_buffer);
  3083.             @fwrite($v_dest_file, $v_binary_data, $v_read_size);
  3084.             $v_size -= $v_read_size;
  3085.           }
  3086.  
  3087.           // ----- Closing the destination file
  3088.           fclose($v_dest_file);
  3089.  
  3090.           // ----- Change the file mtime
  3091.           touch($p_entry['filename'], $p_entry['mtime']);
  3092.         }
  3093.         else
  3094.         {
  3095.           // ----- Trace
  3096.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
  3097.  
  3098.           // ----- Opening destination file
  3099.           if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  3100.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
  3101.  
  3102.             // ----- Change the file status
  3103.             $p_entry['status'] = "write_error";
  3104.  
  3105.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3106.             return $v_result;
  3107.           }
  3108.  
  3109.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes");
  3110.  
  3111.           // ----- Read the compressed file in a buffer (one shot)
  3112.           $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  3113.           
  3114.           // ----- Decompress the file
  3115.           $v_file_content = gzinflate($v_buffer);
  3116.           unset($v_buffer);
  3117.  
  3118.           // ----- Write the uncompressed data
  3119.           @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
  3120.           unset($v_file_content);
  3121.  
  3122.           // ----- Closing the destination file
  3123.           @fclose($v_dest_file);
  3124.  
  3125.           // ----- Change the file mtime
  3126.           touch($p_entry['filename'], $p_entry['mtime']);
  3127.         }
  3128.  
  3129.         // ----- Look for chmod option
  3130.         if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
  3131.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'");
  3132.  
  3133.           // ----- Change the mode of the file
  3134.           chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
  3135.         }
  3136.  
  3137.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  3138.       }
  3139.     }
  3140.  
  3141.     // ----- Look for post-extract callback
  3142.     if (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  3143.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
  3144.  
  3145.       // ----- Generate a local information
  3146.       $v_local_header = array();
  3147.       $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3148.  
  3149.       // ----- Call the callback
  3150.       // Here I do not use call_user_func() because I need to send a reference to the
  3151.       // header.
  3152.       eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  3153.     }
  3154.  
  3155.     // ----- Return
  3156.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3157.     return $v_result;
  3158.   }
  3159.   // --------------------------------------------------------------------------------
  3160.  
  3161.   // --------------------------------------------------------------------------------
  3162.   // Function : privExtractFileAsString()
  3163.   // Description :
  3164.   // Parameters :
  3165.   // Return Values :
  3166.   // --------------------------------------------------------------------------------
  3167.   function privExtractFileAsString(&$p_entry, &$p_string)
  3168.   {
  3169.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'");
  3170.     $v_result=1;
  3171.  
  3172.     // ----- Read the file header
  3173.     $v_header = array();
  3174.     if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  3175.     {
  3176.       // ----- Return
  3177.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3178.       return $v_result;
  3179.     }
  3180.  
  3181.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
  3182.  
  3183.     // ----- Check that the file header is coherent with $p_entry info
  3184.     // TBC
  3185.  
  3186.     // ----- Trace
  3187.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
  3188.  
  3189.     // ----- Do the extraction (if not a folder)
  3190.     if (!(($p_entry['external']&0x00000010)==0x00000010))
  3191.     {
  3192.       // ----- Look for not compressed file
  3193.       if ($p_entry['compressed_size'] == $p_entry['size'])
  3194.       {
  3195.         // ----- Trace
  3196.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
  3197.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
  3198.  
  3199.         // ----- Reading the file
  3200.         $p_string = fread($this->zip_fd, $p_entry['compressed_size']);
  3201.       }
  3202.       else
  3203.       {
  3204.         // ----- Trace
  3205.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
  3206.  
  3207.         // ----- Reading the file
  3208.         $v_data = fread($this->zip_fd, $p_entry['compressed_size']);
  3209.         
  3210.         // ----- Decompress the file
  3211.         $p_string = gzinflate($v_data);
  3212.       }
  3213.  
  3214.       // ----- Trace
  3215.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
  3216.     }
  3217.     else {
  3218.         // TBC : error : can not extract a folder in a string
  3219.     }
  3220.  
  3221.     // ----- Return
  3222.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3223.     return $v_result;
  3224.   }
  3225.   // --------------------------------------------------------------------------------
  3226.  
  3227.   // --------------------------------------------------------------------------------
  3228.   // Function : privReadFileHeader()
  3229.   // Description :
  3230.   // Parameters :
  3231.   // Return Values :
  3232.   // --------------------------------------------------------------------------------
  3233.   function privReadFileHeader(&$p_header)
  3234.   {
  3235.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", "");
  3236.     $v_result=1;
  3237.  
  3238.     // ----- Read the 4 bytes signature
  3239.     $v_binary_data = @fread($this->zip_fd, 4);
  3240.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  3241.     $v_data = unpack('Vid', $v_binary_data);
  3242.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  3243.  
  3244.     // ----- Check signature
  3245.     if ($v_data['id'] != 0x04034b50)
  3246.     {
  3247.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header");
  3248.  
  3249.       // ----- Error log
  3250.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  3251.  
  3252.       // ----- Return
  3253.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3254.       return PclZip::errorCode();
  3255.     }
  3256.  
  3257.     // ----- Read the first 42 bytes of the header
  3258.     $v_binary_data = fread($this->zip_fd, 26);
  3259.  
  3260.     // ----- Look for invalid block size
  3261.     if (strlen($v_binary_data) != 26)
  3262.     {
  3263.       $p_header['filename'] = "";
  3264.       $p_header['status'] = "invalid_header";
  3265.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  3266.  
  3267.       // ----- Error log
  3268.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  3269.  
  3270.       // ----- Return
  3271.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3272.       return PclZip::errorCode();
  3273.     }
  3274.  
  3275.     // ----- Extract the values
  3276.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
  3277.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
  3278.     $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
  3279.  
  3280.     // ----- Get filename
  3281.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']);
  3282.     $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
  3283.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');
  3284.  
  3285.     // ----- Get extra_fields
  3286.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']);
  3287.     if ($v_data['extra_len'] != 0) {
  3288.       $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
  3289.     }
  3290.     else {
  3291.       $p_header['extra'] = '';
  3292.     }
  3293.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\'');
  3294.  
  3295.     // ----- Extract properties
  3296.     $p_header['compression'] = $v_data['compression'];
  3297.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.bin2hex($p_header['compression']).'\'');
  3298.     $p_header['size'] = $v_data['size'];
  3299.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');
  3300.     $p_header['compressed_size'] = $v_data['compressed_size'];
  3301.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
  3302.     $p_header['crc'] = $v_data['crc'];
  3303.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.$p_header['crc'].'\'');
  3304.     $p_header['flag'] = $v_data['flag'];
  3305.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');
  3306.  
  3307.     // ----- Recuperate date in UNIX format
  3308.     $p_header['mdate'] = $v_data['mdate'];
  3309.     $p_header['mtime'] = $v_data['mtime'];
  3310.     if ($p_header['mdate'] && $p_header['mtime'])
  3311.     {
  3312.       // ----- Extract time
  3313.       $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  3314.       $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  3315.       $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  3316.  
  3317.       // ----- Extract date
  3318.       $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  3319.       $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  3320.       $v_day = $p_header['mdate'] & 0x001F;
  3321.  
  3322.       // ----- Get UNIX date format
  3323.       $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  3324.  
  3325.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  3326.     }
  3327.     else
  3328.     {
  3329.       $p_header['mtime'] = time();
  3330.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  3331.     }
  3332.  
  3333.     // ----- Other informations
  3334.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compression type : ".$v_data['compression']);
  3335.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Version : ".$v_data['version']);
  3336.  
  3337.     // TBC
  3338.     //for(reset($v_data); $key = key($v_data); next($v_data)) {
  3339.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]);
  3340.     //}
  3341.  
  3342.     // ----- Set the stored filename
  3343.     $p_header['stored_filename'] = $p_header['filename'];
  3344.  
  3345.     // ----- Set the status field
  3346.     $p_header['status'] = "ok";
  3347.  
  3348.     // ----- Return
  3349.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3350.     return $v_result;
  3351.   }
  3352.   // --------------------------------------------------------------------------------
  3353.  
  3354.   // --------------------------------------------------------------------------------
  3355.   // Function : privReadCentralFileHeader()
  3356.   // Description :
  3357.   // Parameters :
  3358.   // Return Values :
  3359.   // --------------------------------------------------------------------------------
  3360.   function privReadCentralFileHeader(&$p_header)
  3361.   {
  3362.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", "");
  3363.     $v_result=1;
  3364.  
  3365.     // ----- Read the 4 bytes signature
  3366.     $v_binary_data = @fread($this->zip_fd, 4);
  3367.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  3368.     $v_data = unpack('Vid', $v_binary_data);
  3369.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  3370.  
  3371.     // ----- Check signature
  3372.     if ($v_data['id'] != 0x02014b50)
  3373.     {
  3374.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature");
  3375.  
  3376.       // ----- Error log
  3377.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  3378.  
  3379.       // ----- Return
  3380.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3381.       return PclZip::errorCode();
  3382.     }
  3383.  
  3384.     // ----- Read the first 42 bytes of the header
  3385.     $v_binary_data = fread($this->zip_fd, 42);
  3386.  
  3387.     // ----- Look for invalid block size
  3388.     if (strlen($v_binary_data) != 42)
  3389.     {
  3390.       $p_header['filename'] = "";
  3391.       $p_header['status'] = "invalid_header";
  3392.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
  3393.  
  3394.       // ----- Error log
  3395.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  3396.  
  3397.       // ----- Return
  3398.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3399.       return PclZip::errorCode();
  3400.     }
  3401.  
  3402.     // ----- Extract the values
  3403.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
  3404.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
  3405.     $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);
  3406.  
  3407.     // ----- Get filename
  3408.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
  3409.     if ($p_header['filename_len'] != 0)
  3410.       $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
  3411.     else
  3412.       $p_header['filename'] = '';
  3413.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');
  3414.  
  3415.     // ----- Get extra
  3416.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
  3417.     if ($p_header['extra_len'] != 0)
  3418.       $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
  3419.     else
  3420.       $p_header['extra'] = '';
  3421.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');
  3422.  
  3423.     // ----- Get comment
  3424.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
  3425.     if ($p_header['comment_len'] != 0)
  3426.       $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
  3427.     else
  3428.       $p_header['comment'] = '';
  3429.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');
  3430.  
  3431.     // ----- Extract properties
  3432.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');
  3433.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
  3434.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');
  3435.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
  3436.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.$p_header['crc'].'\'');
  3437.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');
  3438.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');
  3439.  
  3440.     // ----- Recuperate date in UNIX format
  3441.     if ($p_header['mdate'] && $p_header['mtime'])
  3442.     {
  3443.       // ----- Extract time
  3444.       $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  3445.       $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  3446.       $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  3447.  
  3448.       // ----- Extract date
  3449.       $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  3450.       $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  3451.       $v_day = $p_header['mdate'] & 0x001F;
  3452.  
  3453.       // ----- Get UNIX date format
  3454.       $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  3455.  
  3456.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  3457.     }
  3458.     else
  3459.     {
  3460.       $p_header['mtime'] = time();
  3461.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
  3462.     }
  3463.  
  3464.     // ----- Set the stored filename
  3465.     $p_header['stored_filename'] = $p_header['filename'];
  3466.  
  3467.     // ----- Set default status to ok
  3468.     $p_header['status'] = 'ok';
  3469.  
  3470.     // ----- Look if it is a directory
  3471.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
  3472.     //--(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').')');
  3473.     if (substr($p_header['filename'], -1) == '/')
  3474.     {
  3475.       $p_header['external'] = 0x41FF0010;
  3476.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.$p_header['external'].'\'');
  3477.     }
  3478.  
  3479.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');
  3480.  
  3481.     // ----- Return
  3482.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3483.     return $v_result;
  3484.   }
  3485.   // --------------------------------------------------------------------------------
  3486.  
  3487.   // --------------------------------------------------------------------------------
  3488.   // Function : privReadEndCentralDir()
  3489.   // Description :
  3490.   // Parameters :
  3491.   // Return Values :
  3492.   // --------------------------------------------------------------------------------
  3493.   function privReadEndCentralDir(&$p_central_dir)
  3494.   {
  3495.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
  3496.     $v_result=1;
  3497.  
  3498.     // ----- Go to the end of the zip file
  3499.     $v_size = filesize($this->zipname);
  3500.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
  3501.     @fseek($this->zip_fd, $v_size);
  3502.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\'');
  3503.     if (@ftell($this->zip_fd) != $v_size)
  3504.     {
  3505.       // ----- Error log
  3506.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
  3507.  
  3508.       // ----- Return
  3509.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3510.       return PclZip::errorCode();
  3511.     }
  3512.  
  3513.     // ----- First try : look if this is an archive with no commentaries (most of the time)
  3514.     // in this case the end of central dir is at 22 bytes of the file end
  3515.     $v_found = 0;
  3516.     if ($v_size > 26) {
  3517.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
  3518.       @fseek($this->zip_fd, $v_size-22);
  3519.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\'');
  3520.       if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
  3521.       {
  3522.         // ----- Error log
  3523.         PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  3524.  
  3525.         // ----- Return
  3526.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3527.         return PclZip::errorCode();
  3528.       }
  3529.  
  3530.       // ----- Read for bytes
  3531.       $v_binary_data = @fread($this->zip_fd, 4);
  3532.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
  3533.       $v_data = unpack('Vid', $v_binary_data);
  3534.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
  3535.  
  3536.       // ----- Check signature
  3537.       if ($v_data['id'] == 0x06054b50) {
  3538.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
  3539.         $v_found = 1;
  3540.       }
  3541.  
  3542.       $v_pos = ftell($this->zip_fd);
  3543.     }
  3544.  
  3545.     // ----- Go back to the maximum possible size of the Central Dir End Record
  3546.     if (!$v_found) {
  3547.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
  3548.       $v_maximum_size = 65557; // 0xFFFF + 22;
  3549.       if ($v_maximum_size > $v_size)
  3550.         $v_maximum_size = $v_size;
  3551.       @fseek($this->zip_fd, $v_size-$v_maximum_size);
  3552.       if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
  3553.       {
  3554.         // ----- Error log
  3555.         PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  3556.  
  3557.         // ----- Return
  3558.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3559.         return PclZip::errorCode();
  3560.       }
  3561.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\'');
  3562.  
  3563.       // ----- Read byte per byte in order to find the signature
  3564.       $v_pos = ftell($this->zip_fd);
  3565.       $v_bytes = 0x00000000;
  3566.       while ($v_pos < $v_size)
  3567.       {
  3568.         // ----- Read a byte
  3569.         $v_byte = @fread($this->zip_fd, 1);
  3570.  
  3571.         // -----  Add the byte
  3572.         $v_bytes = ($v_bytes << 8) | Ord($v_byte);
  3573.  
  3574.         // ----- Compare the bytes
  3575.         if ($v_bytes == 0x504b0506)
  3576.         {
  3577.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\'');
  3578.           $v_pos++;
  3579.           break;
  3580.         }
  3581.  
  3582.         $v_pos++;
  3583.       }
  3584.  
  3585.       // ----- Look if not found end of central dir
  3586.       if ($v_pos == $v_size)
  3587.       {
  3588.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
  3589.  
  3590.         // ----- Error log
  3591.         PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
  3592.  
  3593.         // ----- Return
  3594.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3595.         return PclZip::errorCode();
  3596.       }
  3597.     }
  3598.  
  3599.     // ----- Read the first 18 bytes of the header
  3600.     $v_binary_data = fread($this->zip_fd, 18);
  3601.  
  3602.     // ----- Look for invalid block size
  3603.     if (strlen($v_binary_data) != 18)
  3604.     {
  3605.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  3606.  
  3607.       // ----- Error log
  3608.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  3609.  
  3610.       // ----- Return
  3611.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3612.       return PclZip::errorCode();
  3613.     }
  3614.  
  3615.     // ----- Extract the values
  3616.     ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
  3617.     ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
  3618.     $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
  3619.  
  3620.     // ----- Check the global size
  3621.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
  3622.     if (($v_pos + $v_data['comment_size'] + 18) != $v_size)
  3623.     {
  3624.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Fail to find the right signature");
  3625.  
  3626.       // ----- Error log
  3627.       PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Fail to find the right signature");
  3628.  
  3629.       // ----- Return
  3630.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3631.       return PclZip::errorCode();
  3632.     }
  3633.  
  3634.     // ----- Get comment
  3635.     if ($v_data['comment_size'] != 0)
  3636.       $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
  3637.     else
  3638.       $p_central_dir['comment'] = '';
  3639.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\'');
  3640.  
  3641.     $p_central_dir['entries'] = $v_data['entries'];
  3642.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\'');
  3643.     $p_central_dir['disk_entries'] = $v_data['disk_entries'];
  3644.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\'');
  3645.     $p_central_dir['offset'] = $v_data['offset'];
  3646.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\'');
  3647.     $p_central_dir['size'] = $v_data['size'];
  3648.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\'');
  3649.     $p_central_dir['disk'] = $v_data['disk'];
  3650.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\'');
  3651.     $p_central_dir['disk_start'] = $v_data['disk_start'];
  3652.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\'');
  3653.  
  3654.     // TBC
  3655.     //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
  3656.     //  //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
  3657.     //}
  3658.  
  3659.     // ----- Return
  3660.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3661.     return $v_result;
  3662.   }
  3663.   // --------------------------------------------------------------------------------
  3664.  
  3665.   // --------------------------------------------------------------------------------
  3666.   // Function : privDeleteByRule()
  3667.   // Description :
  3668.   // Parameters :
  3669.   // Return Values :
  3670.   // --------------------------------------------------------------------------------
  3671.   function privDeleteByRule(&$p_result_list, &$p_options)
  3672.   {
  3673.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
  3674.     $v_result=1;
  3675.     $v_list_detail = array();
  3676.  
  3677.     // ----- Open the zip file
  3678.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  3679.     if (($v_result=$this->privOpenFd('rb')) != 1)
  3680.     {
  3681.       // ----- Return
  3682.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3683.       return $v_result;
  3684.     }
  3685.  
  3686.     // ----- Read the central directory informations
  3687.     $v_central_dir = array();
  3688.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3689.     {
  3690.       $this->privCloseFd();
  3691.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3692.       return $v_result;
  3693.     }
  3694.  
  3695.     // ----- Go to beginning of File
  3696.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  3697.     @rewind($this->zip_fd);
  3698.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
  3699.  
  3700.     // ----- Scan all the files
  3701.     // ----- Start at beginning of Central Dir
  3702.     $v_pos_entry = $v_central_dir['offset'];
  3703.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  3704.     @rewind($this->zip_fd);
  3705.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  3706.     if (@fseek($this->zip_fd, $v_pos_entry))
  3707.     {
  3708.       // ----- Close the zip file
  3709.       $this->privCloseFd();
  3710.  
  3711.       // ----- Error log
  3712.       PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3713.  
  3714.       // ----- Return
  3715.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3716.       return PclZip::errorCode();
  3717.     }
  3718.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  3719.  
  3720.     // ----- Read each entry
  3721.     $v_header_list = array();
  3722.     $j_start = 0;
  3723.     for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  3724.     {
  3725.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
  3726.  
  3727.       // ----- Read the file header
  3728.       $v_header_list[$v_nb_extracted] = array();
  3729.       if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
  3730.       {
  3731.         // ----- Close the zip file
  3732.         $this->privCloseFd();
  3733.  
  3734.         //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3735.         return $v_result;
  3736.       }
  3737.  
  3738.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
  3739.  
  3740.       // ----- Store the index
  3741.       $v_header_list[$v_nb_extracted]['index'] = $i;
  3742.  
  3743.       // ----- Look for the specific extract rules
  3744.       $v_found = false;
  3745.  
  3746.       // ----- Look for extract by name rule
  3747.       if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
  3748.           && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  3749.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
  3750.  
  3751.           // ----- Look if the filename is in the list
  3752.           for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
  3753.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
  3754.  
  3755.               // ----- Look for a directory
  3756.               if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  3757.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
  3758.  
  3759.                   // ----- Look if the directory is in the filename path
  3760.                   if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  3761.                       && (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])) {
  3762.                       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
  3763.                       $v_found = true;
  3764.                   }
  3765.                   elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
  3766.                           && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  3767.                       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
  3768.                       $v_found = true;
  3769.                   }
  3770.               }
  3771.               // ----- Look for a filename
  3772.               elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  3773.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
  3774.                   $v_found = true;
  3775.               }
  3776.           }
  3777.       }
  3778.  
  3779.       // ----- Look for extract by ereg rule
  3780.       else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
  3781.                && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  3782.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
  3783.  
  3784.           if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  3785.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  3786.               $v_found = true;
  3787.           }
  3788.       }
  3789.  
  3790.       // ----- Look for extract by preg rule
  3791.       else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
  3792.                && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  3793.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
  3794.  
  3795.           if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  3796.               //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
  3797.               $v_found = true;
  3798.           }
  3799.       }
  3800.  
  3801.       // ----- Look for extract by index rule
  3802.       else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  3803.                && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  3804.           //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
  3805.  
  3806.           // ----- Look if the index is in the list
  3807.           for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
  3808.               //--(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']."]");
  3809.  
  3810.               if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  3811.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
  3812.                   $v_found = true;
  3813.               }
  3814.               if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  3815.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
  3816.                   $j_start = $j+1;
  3817.               }
  3818.  
  3819.               if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  3820.                   //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
  3821.                   break;
  3822.               }
  3823.           }
  3824.       }
  3825.  
  3826.       // ----- Look for deletion
  3827.       if ($v_found)
  3828.       {
  3829.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
  3830.         unset($v_header_list[$v_nb_extracted]);
  3831.       }
  3832.       else
  3833.       {
  3834.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
  3835.         $v_nb_extracted++;
  3836.       }
  3837.     }
  3838.  
  3839.     // ----- Look if something need to be deleted
  3840.     if ($v_nb_extracted > 0) {
  3841.  
  3842.         // ----- Creates a temporay file
  3843.         $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  3844.  
  3845.         // ----- Creates a temporary zip archive
  3846.         $v_temp_zip = new PclZip($v_zip_temp_name);
  3847.  
  3848.         // ----- Open the temporary zip file in write mode
  3849.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
  3850.         if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
  3851.             $this->privCloseFd();
  3852.  
  3853.             // ----- Return
  3854.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3855.             return $v_result;
  3856.         }
  3857.  
  3858.         // ----- Look which file need to be kept
  3859.         for ($i=0; $i<sizeof($v_header_list); $i++) {
  3860.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
  3861.  
  3862.             // ----- Calculate the position of the header
  3863.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
  3864.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
  3865.             @rewind($this->zip_fd);
  3866.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
  3867.             if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
  3868.                 // ----- Close the zip file
  3869.                 $this->privCloseFd();
  3870.                 $v_temp_zip->privCloseFd();
  3871.                 @unlink($v_zip_temp_name);
  3872.  
  3873.                 // ----- Error log
  3874.                 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3875.  
  3876.                 // ----- Return
  3877.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  3878.                 return PclZip::errorCode();
  3879.             }
  3880.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
  3881.  
  3882.             // ----- Read the file header
  3883.             if (($v_result = $this->privReadFileHeader($v_header_list[$i])) != 1) {
  3884.                 // ----- Close the zip file
  3885.                 $this->privCloseFd();
  3886.                 $v_temp_zip->privCloseFd();
  3887.                 @unlink($v_zip_temp_name);
  3888.  
  3889.                 // ----- Return
  3890.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3891.                 return $v_result;
  3892.             }
  3893.  
  3894.             // ----- Write the file header
  3895.             if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
  3896.                 // ----- Close the zip file
  3897.                 $this->privCloseFd();
  3898.                 $v_temp_zip->privCloseFd();
  3899.                 @unlink($v_zip_temp_name);
  3900.  
  3901.                 // ----- Return
  3902.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3903.                 return $v_result;
  3904.             }
  3905.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
  3906.  
  3907.             // ----- Read/write the data block
  3908.             if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
  3909.                 // ----- Close the zip file
  3910.                 $this->privCloseFd();
  3911.                 $v_temp_zip->privCloseFd();
  3912.                 @unlink($v_zip_temp_name);
  3913.  
  3914.                 // ----- Return
  3915.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3916.                 return $v_result;
  3917.             }
  3918.         }
  3919.  
  3920.         // ----- Store the offset of the central dir
  3921.         $v_offset = @ftell($v_temp_zip->zip_fd);
  3922.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
  3923.  
  3924.         // ----- Re-Create the Central Dir files header
  3925.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
  3926.         for ($i=0; $i<sizeof($v_header_list); $i++) {
  3927.             // ----- Create the file header
  3928.             //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
  3929.             if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  3930.                 $v_temp_zip->privCloseFd();
  3931.                 $this->privCloseFd();
  3932.                 @unlink($v_zip_temp_name);
  3933.  
  3934.                 // ----- Return
  3935.                 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3936.                 return $v_result;
  3937.             }
  3938.  
  3939.             // ----- Transform the header to a 'usable' info
  3940.             $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  3941.         }
  3942.  
  3943.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
  3944.  
  3945.         // ----- Zip file comment
  3946.         $v_comment = '';
  3947.  
  3948.         // ----- Calculate the size of the central header
  3949.         $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
  3950.  
  3951.         // ----- Create the central dir footer
  3952.         if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
  3953.             // ----- Reset the file list
  3954.             unset($v_header_list);
  3955.             $v_temp_zip->privCloseFd();
  3956.             $this->privCloseFd();
  3957.             @unlink($v_zip_temp_name);
  3958.  
  3959.             // ----- Return
  3960.             //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3961.             return $v_result;
  3962.         }
  3963.  
  3964.         // ----- Close
  3965.         $v_temp_zip->privCloseFd();
  3966.         $this->privCloseFd();
  3967.  
  3968.         // ----- Delete the zip file
  3969.         // TBC : I should test the result ...
  3970.         @unlink($this->zipname);
  3971.  
  3972.         // ----- Rename the temporary file
  3973.         // TBC : I should test the result ...
  3974.         //@rename($v_zip_temp_name, $this->zipname);
  3975.         PclZipUtilRename($v_zip_temp_name, $this->zipname);
  3976.     
  3977.         // ----- Destroy the temporary archive
  3978.         unset($v_temp_zip);
  3979.     }
  3980.  
  3981.     // ----- Return
  3982.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  3983.     return $v_result;
  3984.   }
  3985.   // --------------------------------------------------------------------------------
  3986.  
  3987.   // --------------------------------------------------------------------------------
  3988.   // Function : privDirCheck()
  3989.   // Description :
  3990.   //   Check if a directory exists, if not it creates it and all the parents directory
  3991.   //   which may be useful.
  3992.   // Parameters :
  3993.   //   $p_dir : Directory path to check.
  3994.   // Return Values :
  3995.   //    1 : OK
  3996.   //   -1 : Unable to create directory
  3997.   // --------------------------------------------------------------------------------
  3998.   function privDirCheck($p_dir, $p_is_dir=false)
  3999.   {
  4000.     $v_result = 1;
  4001.  
  4002.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'");
  4003.  
  4004.     // ----- Remove the final '/'
  4005.     if (($p_is_dir) && (substr($p_dir, -1)=='/'))
  4006.     {
  4007.       $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
  4008.     }
  4009.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'");
  4010.  
  4011.     // ----- Check the directory availability
  4012.     if ((is_dir($p_dir)) || ($p_dir == ""))
  4013.     {
  4014.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
  4015.       return 1;
  4016.     }
  4017.  
  4018.     // ----- Extract parent directory
  4019.     $p_parent_dir = dirname($p_dir);
  4020.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
  4021.  
  4022.     // ----- Just a check
  4023.     if ($p_parent_dir != $p_dir)
  4024.     {
  4025.       // ----- Look for parent directory
  4026.       if ($p_parent_dir != "")
  4027.       {
  4028.         if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
  4029.         {
  4030.           //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4031.           return $v_result;
  4032.         }
  4033.       }
  4034.     }
  4035.  
  4036.     // ----- Create the directory
  4037.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
  4038.     if (!@mkdir($p_dir, 0777))
  4039.     {
  4040.       // ----- Error log
  4041.       PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
  4042.  
  4043.       // ----- Return
  4044.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4045.       return PclZip::errorCode();
  4046.     }
  4047.  
  4048.     // ----- Return
  4049.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
  4050.     return $v_result;
  4051.   }
  4052.   // --------------------------------------------------------------------------------
  4053.  
  4054.   // --------------------------------------------------------------------------------
  4055.   // Function : privMerge()
  4056.   // Description :
  4057.   //   If $p_archive_to_add does not exist, the function exit with a success result.
  4058.   // Parameters :
  4059.   // Return Values :
  4060.   // --------------------------------------------------------------------------------
  4061.   function privMerge(&$p_archive_to_add)
  4062.   {
  4063.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
  4064.     $v_result=1;
  4065.  
  4066.     // ----- Look if the archive_to_add exists
  4067.     if (!is_file($p_archive_to_add->zipname))
  4068.     {
  4069.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");
  4070.  
  4071.       // ----- Nothing to merge, so merge is a success
  4072.       $v_result = 1;
  4073.  
  4074.       // ----- Return
  4075.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4076.       return $v_result;
  4077.     }
  4078.  
  4079.     // ----- Look if the archive exists
  4080.     if (!is_file($this->zipname))
  4081.     {
  4082.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");
  4083.  
  4084.       // ----- Do a duplicate
  4085.       $v_result = $this->privDuplicate($p_archive_to_add->zipname);
  4086.  
  4087.       // ----- Return
  4088.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4089.       return $v_result;
  4090.     }
  4091.  
  4092.     // ----- Open the zip file
  4093.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  4094.     if (($v_result=$this->privOpenFd('rb')) != 1)
  4095.     {
  4096.       // ----- Return
  4097.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4098.       return $v_result;
  4099.     }
  4100.  
  4101.     // ----- Read the central directory informations
  4102.     $v_central_dir = array();
  4103.     if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  4104.     {
  4105.       $this->privCloseFd();
  4106.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4107.       return $v_result;
  4108.     }
  4109.  
  4110.     // ----- Go to beginning of File
  4111.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  4112.     @rewind($this->zip_fd);
  4113.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
  4114.  
  4115.     // ----- Open the archive_to_add file
  4116.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
  4117.     if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
  4118.     {
  4119.       $this->privCloseFd();
  4120.  
  4121.       // ----- Return
  4122.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4123.       return $v_result;
  4124.     }
  4125.  
  4126.     // ----- Read the central directory informations
  4127.     $v_central_dir_to_add = array();
  4128.     if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
  4129.     {
  4130.       $this->privCloseFd();
  4131.       $p_archive_to_add->privCloseFd();
  4132.  
  4133.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4134.       return $v_result;
  4135.     }
  4136.  
  4137.     // ----- Go to beginning of File
  4138.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  4139.     @rewind($p_archive_to_add->zip_fd);
  4140.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
  4141.  
  4142.     // ----- Creates a temporay file
  4143.     $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  4144.  
  4145.     // ----- Open the temporary file in write mode
  4146.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  4147.     if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  4148.     {
  4149.       $this->privCloseFd();
  4150.       $p_archive_to_add->privCloseFd();
  4151.  
  4152.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  4153.  
  4154.       // ----- Return
  4155.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4156.       return PclZip::errorCode();
  4157.     }
  4158.  
  4159.     // ----- Copy the files from the archive to the temporary file
  4160.     // TBC : Here I should better append the file and go back to erase the central dir
  4161.     $v_size = $v_central_dir['offset'];
  4162.     while ($v_size != 0)
  4163.     {
  4164.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4165.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4166.       $v_buffer = fread($this->zip_fd, $v_read_size);
  4167.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  4168.       $v_size -= $v_read_size;
  4169.     }
  4170.  
  4171.     // ----- Copy the files from the archive_to_add into the temporary file
  4172.     $v_size = $v_central_dir_to_add['offset'];
  4173.     while ($v_size != 0)
  4174.     {
  4175.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4176.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4177.       $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
  4178.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  4179.       $v_size -= $v_read_size;
  4180.     }
  4181.  
  4182.     // ----- Store the offset of the central dir
  4183.     $v_offset = @ftell($v_zip_temp_fd);
  4184.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
  4185.  
  4186.     // ----- Copy the block of file headers from the old archive
  4187.     $v_size = $v_central_dir['size'];
  4188.     while ($v_size != 0)
  4189.     {
  4190.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4191.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4192.       $v_buffer = @fread($this->zip_fd, $v_read_size);
  4193.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  4194.       $v_size -= $v_read_size;
  4195.     }
  4196.  
  4197.     // ----- Copy the block of file headers from the archive_to_add
  4198.     $v_size = $v_central_dir_to_add['size'];
  4199.     while ($v_size != 0)
  4200.     {
  4201.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4202.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4203.       $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
  4204.       @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  4205.       $v_size -= $v_read_size;
  4206.     }
  4207.  
  4208.     // ----- Zip file comment
  4209.     // TBC : I should merge the two comments
  4210.     $v_comment = '';
  4211.  
  4212.     // ----- Calculate the size of the (new) central header
  4213.     $v_size = @ftell($v_zip_temp_fd)-$v_offset;
  4214.  
  4215.     // ----- Swap the file descriptor
  4216.     // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  4217.     // the following methods on the temporary fil and not the real archive fd
  4218.     $v_swap = $this->zip_fd;
  4219.     $this->zip_fd = $v_zip_temp_fd;
  4220.     $v_zip_temp_fd = $v_swap;
  4221.  
  4222.     // ----- Create the central dir footer
  4223.     if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
  4224.     {
  4225.       $this->privCloseFd();
  4226.       $p_archive_to_add->privCloseFd();
  4227.       @fclose($v_zip_temp_fd);
  4228.       $this->zip_fd = null;
  4229.  
  4230.       // ----- Reset the file list
  4231.       unset($v_header_list);
  4232.  
  4233.       // ----- Return
  4234.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4235.       return $v_result;
  4236.     }
  4237.  
  4238.     // ----- Swap back the file descriptor
  4239.     $v_swap = $this->zip_fd;
  4240.     $this->zip_fd = $v_zip_temp_fd;
  4241.     $v_zip_temp_fd = $v_swap;
  4242.  
  4243.     // ----- Close
  4244.     $this->privCloseFd();
  4245.     $p_archive_to_add->privCloseFd();
  4246.  
  4247.     // ----- Close the temporary file
  4248.     @fclose($v_zip_temp_fd);
  4249.  
  4250.     // ----- Delete the zip file
  4251.     // TBC : I should test the result ...
  4252.     @unlink($this->zipname);
  4253.  
  4254.     // ----- Rename the temporary file
  4255.     // TBC : I should test the result ...
  4256.     //@rename($v_zip_temp_name, $this->zipname);
  4257.     PclZipUtilRename($v_zip_temp_name, $this->zipname);
  4258.  
  4259.     // ----- Return
  4260.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4261.     return $v_result;
  4262.   }
  4263.   // --------------------------------------------------------------------------------
  4264.  
  4265.   // --------------------------------------------------------------------------------
  4266.   // Function : privDuplicate()
  4267.   // Description :
  4268.   // Parameters :
  4269.   // Return Values :
  4270.   // --------------------------------------------------------------------------------
  4271.   function privDuplicate($p_archive_filename)
  4272.   {
  4273.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'");
  4274.     $v_result=1;
  4275.  
  4276.     // ----- Look if the $p_archive_filename exists
  4277.     if (!is_file($p_archive_filename))
  4278.     {
  4279.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate.");
  4280.  
  4281.       // ----- Nothing to duplicate, so duplicate is a success.
  4282.       $v_result = 1;
  4283.  
  4284.       // ----- Return
  4285.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4286.       return $v_result;
  4287.     }
  4288.  
  4289.     // ----- Open the zip file
  4290.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  4291.     if (($v_result=$this->privOpenFd('wb')) != 1)
  4292.     {
  4293.       // ----- Return
  4294.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4295.       return $v_result;
  4296.     }
  4297.  
  4298.     // ----- Open the temporary file in write mode
  4299.     //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
  4300.     if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
  4301.     {
  4302.       $this->privCloseFd();
  4303.  
  4304.       PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
  4305.  
  4306.       // ----- Return
  4307.       //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
  4308.       return PclZip::errorCode();
  4309.     }
  4310.  
  4311.     // ----- Copy the files from the archive to the temporary file
  4312.     // TBC : Here I should better append the file and go back to erase the central dir
  4313.     $v_size = filesize($p_archive_filename);
  4314.     while ($v_size != 0)
  4315.     {
  4316.       $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4317.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes");
  4318.       $v_buffer = fread($v_zip_temp_fd, $v_read_size);
  4319.       @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  4320.       $v_size -= $v_read_size;
  4321.     }
  4322.  
  4323.     // ----- Close
  4324.     $this->privCloseFd();
  4325.  
  4326.     // ----- Close the temporary file
  4327.     @fclose($v_zip_temp_fd);
  4328.  
  4329.     // ----- Return
  4330.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4331.     return $v_result;
  4332.   }
  4333.   // --------------------------------------------------------------------------------
  4334.  
  4335.   // --------------------------------------------------------------------------------
  4336.   // Function : privErrorLog()
  4337.   // Description :
  4338.   // Parameters :
  4339.   // --------------------------------------------------------------------------------
  4340.   function privErrorLog($p_error_code=0, $p_error_string='')
  4341.   {
  4342.     if (PCLZIP_ERROR_EXTERNAL == 1) {
  4343.       PclError($p_error_code, $p_error_string);
  4344.     }
  4345.     else {
  4346.       $this->error_code = $p_error_code;
  4347.       $this->error_string = $p_error_string;
  4348.     }
  4349.   }
  4350.   // --------------------------------------------------------------------------------
  4351.  
  4352.   // --------------------------------------------------------------------------------
  4353.   // Function : privErrorReset()
  4354.   // Description :
  4355.   // Parameters :
  4356.   // --------------------------------------------------------------------------------
  4357.   function privErrorReset()
  4358.   {
  4359.     if (PCLZIP_ERROR_EXTERNAL == 1) {
  4360.       PclErrorReset();
  4361.     }
  4362.     else {
  4363.       $this->error_code = 1;
  4364.       $this->error_string = '';
  4365.     }
  4366.   }
  4367.   // --------------------------------------------------------------------------------
  4368.  
  4369.   }
  4370.   // End of class
  4371.   // --------------------------------------------------------------------------------
  4372.  
  4373.   // --------------------------------------------------------------------------------
  4374.   // Function : PclZipUtilPathReduction()
  4375.   // Description :
  4376.   // Parameters :
  4377.   // Return Values :
  4378.   // --------------------------------------------------------------------------------
  4379.   function PclZipUtilPathReduction($p_dir)
  4380.   {
  4381.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'");
  4382.     $v_result = "";
  4383.  
  4384.     // ----- Look for not empty path
  4385.     if ($p_dir != "")
  4386.     {
  4387.       // ----- Explode path by directory names
  4388.       $v_list = explode("/", $p_dir);
  4389.  
  4390.       // ----- Study directories from last to first
  4391.       for ($i=sizeof($v_list)-1; $i>=0; $i--)
  4392.       {
  4393.         // ----- Look for current path
  4394.         if ($v_list[$i] == ".")
  4395.         {
  4396.           // ----- Ignore this directory
  4397.           // Should be the first $i=0, but no check is done
  4398.         }
  4399.         else if ($v_list[$i] == "..")
  4400.         {
  4401.           // ----- Ignore it and ignore the $i-1
  4402.           $i--;
  4403.         }
  4404.         else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0))
  4405.         {
  4406.           // ----- Ignore only the double '//' in path,
  4407.           // but not the first and last '/'
  4408.         }
  4409.         else
  4410.         {
  4411.           $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
  4412.         }
  4413.       }
  4414.     }
  4415.  
  4416.     // ----- Return
  4417.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4418.     return $v_result;
  4419.   }
  4420.   // --------------------------------------------------------------------------------
  4421.  
  4422.   // --------------------------------------------------------------------------------
  4423.   // Function : PclZipUtilPathInclusion()
  4424.   // Description :
  4425.   //   This function indicates if the path $p_path is under the $p_dir tree. Or,
  4426.   //   said in an other way, if the file or sub-dir $p_path is inside the dir
  4427.   //   $p_dir.
  4428.   //   The function indicates also if the path is exactly the same as the dir.
  4429.   //   This function supports path with duplicated '/' like '//', but does not
  4430.   //   support '.' or '..' statements.
  4431.   // Parameters :
  4432.   // Return Values :
  4433.   //   0 if $p_path is not inside directory $p_dir
  4434.   //   1 if $p_path is inside directory $p_dir
  4435.   //   2 if $p_path is exactly the same as $p_dir
  4436.   // --------------------------------------------------------------------------------
  4437.   function PclZipUtilPathInclusion($p_dir, $p_path)
  4438.   {
  4439.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'");
  4440.     $v_result = 1;
  4441.  
  4442.     // ----- Explode dir and path by directory separator
  4443.     $v_list_dir = explode("/", $p_dir);
  4444.     $v_list_dir_size = sizeof($v_list_dir);
  4445.     $v_list_path = explode("/", $p_path);
  4446.     $v_list_path_size = sizeof($v_list_path);
  4447.  
  4448.     // ----- Study directories paths
  4449.     $i = 0;
  4450.     $j = 0;
  4451.     while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
  4452.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
  4453.  
  4454.       // ----- Look for empty dir (path reduction)
  4455.       if ($v_list_dir[$i] == '') {
  4456.         $i++;
  4457.         continue;
  4458.       }
  4459.       if ($v_list_path[$j] == '') {
  4460.         $j++;
  4461.         continue;
  4462.       }
  4463.  
  4464.       // ----- Compare the items
  4465.       if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
  4466.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different");
  4467.         $v_result = 0;
  4468.       }
  4469.  
  4470.       // ----- Next items
  4471.       $i++;
  4472.       $j++;
  4473.     }
  4474.  
  4475.     // ----- Look if everything seems to be the same
  4476.     if ($v_result) {
  4477.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
  4478.       // ----- Skip all the empty items
  4479.       while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
  4480.       while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
  4481.       //--(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]:'')."'");
  4482.  
  4483.       if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
  4484.         // ----- There are exactly the same
  4485.         $v_result = 2;
  4486.       }
  4487.       else if ($i < $v_list_dir_size) {
  4488.         // ----- The path is shorter than the dir
  4489.         $v_result = 0;
  4490.       }
  4491.     }
  4492.  
  4493.     // ----- Return
  4494.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4495.     return $v_result;
  4496.   }
  4497.   // --------------------------------------------------------------------------------
  4498.  
  4499.   // --------------------------------------------------------------------------------
  4500.   // Function : PclZipUtilCopyBlock()
  4501.   // Description :
  4502.   // Parameters :
  4503.   //   $p_mode : read/write compression mode
  4504.   //             0 : src & dest normal
  4505.   //             1 : src gzip, dest normal
  4506.   //             2 : src normal, dest gzip
  4507.   //             3 : src & dest gzip
  4508.   // Return Values :
  4509.   // --------------------------------------------------------------------------------
  4510.   function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
  4511.   {
  4512.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode");
  4513.     $v_result = 1;
  4514.  
  4515.     if ($p_mode==0)
  4516.     {
  4517.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src)));
  4518.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest)));
  4519.       while ($p_size != 0)
  4520.       {
  4521.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  4522.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4523.         $v_buffer = @fread($p_src, $v_read_size);
  4524.         @fwrite($p_dest, $v_buffer, $v_read_size);
  4525.         $p_size -= $v_read_size;
  4526.       }
  4527.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src)));
  4528.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest)));
  4529.     }
  4530.     else if ($p_mode==1)
  4531.     {
  4532.       while ($p_size != 0)
  4533.       {
  4534.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  4535.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4536.         $v_buffer = @gzread($p_src, $v_read_size);
  4537.         @fwrite($p_dest, $v_buffer, $v_read_size);
  4538.         $p_size -= $v_read_size;
  4539.       }
  4540.     }
  4541.     else if ($p_mode==2)
  4542.     {
  4543.       while ($p_size != 0)
  4544.       {
  4545.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  4546.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4547.         $v_buffer = @fread($p_src, $v_read_size);
  4548.         @gzwrite($p_dest, $v_buffer, $v_read_size);
  4549.         $p_size -= $v_read_size;
  4550.       }
  4551.     }
  4552.     else if ($p_mode==3)
  4553.     {
  4554.       while ($p_size != 0)
  4555.       {
  4556.         $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  4557.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
  4558.         $v_buffer = @gzread($p_src, $v_read_size);
  4559.         @gzwrite($p_dest, $v_buffer, $v_read_size);
  4560.         $p_size -= $v_read_size;
  4561.       }
  4562.     }
  4563.  
  4564.     // ----- Return
  4565.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4566.     return $v_result;
  4567.   }
  4568.   // --------------------------------------------------------------------------------
  4569.  
  4570.   // --------------------------------------------------------------------------------
  4571.   // Function : PclZipUtilRename()
  4572.   // Description :
  4573.   //   This function tries to do a simple rename() function. If it fails, it
  4574.   //   tries to copy the $p_src file in a new $p_dest file and then unlink the
  4575.   //   first one.
  4576.   // Parameters :
  4577.   //   $p_src : Old filename
  4578.   //   $p_dest : New filename
  4579.   // Return Values :
  4580.   //   1 on success, 0 on failure.
  4581.   // --------------------------------------------------------------------------------
  4582.   function PclZipUtilRename($p_src, $p_dest)
  4583.   {
  4584.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest");
  4585.     $v_result = 1;
  4586.  
  4587.     // ----- Try to rename the files
  4588.     if (!@rename($p_src, $p_dest)) {
  4589.       //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink");
  4590.  
  4591.       // ----- Try to copy & unlink the src
  4592.       if (!@copy($p_src, $p_dest)) {
  4593.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file");
  4594.         $v_result = 0;
  4595.       }
  4596.       else if (!@unlink($p_src)) {
  4597.         //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename");
  4598.         $v_result = 0;
  4599.       }
  4600.     }
  4601.  
  4602.     // ----- Return
  4603.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4604.     return $v_result;
  4605.   }
  4606.   // --------------------------------------------------------------------------------
  4607.  
  4608.   // --------------------------------------------------------------------------------
  4609.   // Function : PclZipUtilOptionText()
  4610.   // Description :
  4611.   //   Translate option value in text. Mainly for debug purpose.
  4612.   // Parameters :
  4613.   //   $p_option : the option value.
  4614.   // Return Values :
  4615.   //   The option text value.
  4616.   // --------------------------------------------------------------------------------
  4617.   function PclZipUtilOptionText($p_option)
  4618.   {
  4619.     //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'");
  4620.  
  4621.     switch ($p_option) {
  4622.       case PCLZIP_OPT_PATH :
  4623.         $v_result = 'PCLZIP_OPT_PATH';
  4624.       break;
  4625.       case PCLZIP_OPT_ADD_PATH :
  4626.         $v_result = 'PCLZIP_OPT_ADD_PATH';
  4627.       break;
  4628.       case PCLZIP_OPT_REMOVE_PATH :
  4629.         $v_result = 'PCLZIP_OPT_REMOVE_PATH';
  4630.       break;
  4631.       case PCLZIP_OPT_REMOVE_ALL_PATH :
  4632.         $v_result = 'PCLZIP_OPT_REMOVE_ALL_PATH';
  4633.       break;
  4634.       case PCLZIP_OPT_EXTRACT_AS_STRING :
  4635.         $v_result = 'PCLZIP_OPT_EXTRACT_AS_STRING';
  4636.       break;
  4637.       case PCLZIP_OPT_SET_CHMOD :
  4638.         $v_result = 'PCLZIP_OPT_SET_CHMOD';
  4639.       break;
  4640.       case PCLZIP_OPT_BY_NAME :
  4641.         $v_result = 'PCLZIP_OPT_BY_NAME';
  4642.       break;
  4643.       case PCLZIP_OPT_BY_INDEX :
  4644.         $v_result = 'PCLZIP_OPT_BY_INDEX';
  4645.       break;
  4646.       case PCLZIP_OPT_BY_EREG :
  4647.         $v_result = 'PCLZIP_OPT_BY_EREG';
  4648.       break;
  4649.       case PCLZIP_OPT_BY_PREG :
  4650.         $v_result = 'PCLZIP_OPT_BY_PREG';
  4651.       break;
  4652.  
  4653.  
  4654.       case PCLZIP_CB_PRE_EXTRACT :
  4655.         $v_result = 'PCLZIP_CB_PRE_EXTRACT';
  4656.       break;
  4657.       case PCLZIP_CB_POST_EXTRACT :
  4658.         $v_result = 'PCLZIP_CB_POST_EXTRACT';
  4659.       break;
  4660.       case PCLZIP_CB_PRE_ADD :
  4661.         $v_result = 'PCLZIP_CB_PRE_ADD';
  4662.       break;
  4663.       case PCLZIP_CB_POST_ADD :
  4664.         $v_result = 'PCLZIP_CB_POST_ADD';
  4665.       break;
  4666.  
  4667.       default :
  4668.         $v_result = 'Unknown';
  4669.     }
  4670.  
  4671.     // ----- Return
  4672.     //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
  4673.     return $v_result;
  4674.   }
  4675.   // --------------------------------------------------------------------------------
  4676.  
  4677.   // --------------------------------------------------------------------------------
  4678.   // Function : PclZipUtilTranslateWinPath()
  4679.   // Description :
  4680.   //   Translate windows path by replacing '\' by '/' and optionally removing
  4681.   //   drive letter.
  4682.   // Parameters :
  4683.   //   $p_path : path to translate.
  4684.   //   $p_remove_disk_letter : true | false
  4685.   // Return Values :
  4686.   //   The path translated.
  4687.   // --------------------------------------------------------------------------------
  4688.   function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
  4689.   {
  4690.     if (stristr(php_uname(), 'windows')) {
  4691.       // ----- Look for potential disk letter
  4692.       if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
  4693.           $p_path = substr($p_path, $v_position+1);
  4694.       }
  4695.       // ----- Change potential windows directory separator
  4696.       if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
  4697.           $p_path = strtr($p_path, '\\', '/');
  4698.       }
  4699.     }
  4700.     return $p_path;
  4701.   }
  4702.   // --------------------------------------------------------------------------------
  4703.  
  4704. ?>
  4705.