PHPExcel
[ class tree: PHPExcel ] [ index: PHPExcel ] [ all elements ]

Source for file pclzip.lib.php

Documentation is available at pclzip.lib.php

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

Documentation generated on Sat, 19 May 2012 14:39:34 +0200 by phpDocumentor 1.4.4