[ Index ]

PHP Cross Reference of Mambo 4.6.5

[ Variables ]     [ Functions ]     [ Classes ]     [ Constants ]     [ Statistics ]

title

Body

[close]

/administrator/includes/pcl/ -> pclzip.lib.php (source)

   1  <?php
   2  // --------------------------------------------------------------------------------

   3  // PhpConcept Library - Zip Module 2.5

   4  // --------------------------------------------------------------------------------

   5  // License GNU/LGPL - Vincent Blavet - March 2006

   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.44 2006/03/08 21:23:59 vblavet Exp $

  26  // --------------------------------------------------------------------------------

  27  
  28    // ----- Constants

  29    define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
  30    
  31    // ----- File list separator

  32    // In version 1.x of PclZip, the separator for file list is a space

  33    // (which is not a very smart choice, specifically for windows paths !).

  34    // A better separator should be a comma (,). This constant gives you the

  35    // abilty to change that.

  36    // However notice that changing this value, may have impact on existing

  37    // scripts, using space separated filenames.

  38    // Recommanded values for compatibility with older versions :

  39    //define( 'PCLZIP_SEPARATOR', ' ' );

  40    // Recommanded values for smart separation of filenames.

  41    define( 'PCLZIP_SEPARATOR', ',' );
  42  
  43    // ----- Error configuration

  44    // 0 : PclZip Class integrated error handling

  45    // 1 : PclError external library error handling. By enabling this

  46    //     you must ensure that you have included PclError library.

  47    // [2,...] : reserved for futur use

  48    define( 'PCLZIP_ERROR_EXTERNAL', 0 );
  49  
  50    // ----- Optional static temporary directory

  51    //       By default temporary files are generated in the script current

  52    //       path.

  53    //       If defined :

  54    //       - MUST BE terminated by a '/'.

  55    //       - MUST be a valid, already created directory

  56    //       Samples :

  57    // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );

  58    // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );

  59    define( 'PCLZIP_TEMPORARY_DIR', mamboCore::get('rootPath').'/media/' );
  60  
  61  // --------------------------------------------------------------------------------

  62  // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****

  63  // --------------------------------------------------------------------------------

  64  
  65    // ----- Global variables

  66    $g_pclzip_version = "2.5";
  67  
  68    // ----- Error codes

  69    //   -1 : Unable to open file in binary write mode

  70    //   -2 : Unable to open file in binary read mode

  71    //   -3 : Invalid parameters

  72    //   -4 : File does not exist

  73    //   -5 : Filename is too long (max. 255)

  74    //   -6 : Not a valid zip file

  75    //   -7 : Invalid extracted file size

  76    //   -8 : Unable to create directory

  77    //   -9 : Invalid archive extension

  78    //  -10 : Invalid archive format

  79    //  -11 : Unable to delete file (unlink)

  80    //  -12 : Unable to rename file (rename)

  81    //  -13 : Invalid header checksum

  82    //  -14 : Invalid archive size

  83    define( 'PCLZIP_ERR_USER_ABORTED', 2 );
  84    define( 'PCLZIP_ERR_NO_ERROR', 0 );
  85    define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
  86    define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
  87    define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
  88    define( 'PCLZIP_ERR_MISSING_FILE', -4 );
  89    define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
  90    define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
  91    define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
  92    define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
  93    define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
  94    define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
  95    define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
  96    define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
  97    define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
  98    define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
  99    define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
 100    define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
 101    define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
 102    define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
 103    define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
 104    define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
 105    define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
 106  
 107    // ----- Options values

 108    define( 'PCLZIP_OPT_PATH', 77001 );
 109    define( 'PCLZIP_OPT_ADD_PATH', 77002 );
 110    define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
 111    define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
 112    define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
 113    define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
 114    define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
 115    define( 'PCLZIP_OPT_BY_NAME', 77008 );
 116    define( 'PCLZIP_OPT_BY_INDEX', 77009 );
 117    define( 'PCLZIP_OPT_BY_EREG', 77010 );
 118    define( 'PCLZIP_OPT_BY_PREG', 77011 );
 119    define( 'PCLZIP_OPT_COMMENT', 77012 );
 120    define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
 121    define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
 122    define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
 123    define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
 124    define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
 125    // Having big trouble with crypt. Need to multiply 2 long int

 126    // which is not correctly supported by PHP ...

 127    //define( 'PCLZIP_OPT_CRYPT', 77018 );

 128    define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
 129    
 130    // ----- File description attributes

 131    define( 'PCLZIP_ATT_FILE_NAME', 79001 );
 132    define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
 133    define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
 134  
 135    // ----- Call backs values

 136    define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
 137    define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
 138    define( 'PCLZIP_CB_PRE_ADD', 78003 );
 139    define( 'PCLZIP_CB_POST_ADD', 78004 );
 140    /* For futur use

 141    define( 'PCLZIP_CB_PRE_LIST', 78005 );

 142    define( 'PCLZIP_CB_POST_LIST', 78006 );

 143    define( 'PCLZIP_CB_PRE_DELETE', 78007 );

 144    define( 'PCLZIP_CB_POST_DELETE', 78008 );

 145    */
 146  
 147    // --------------------------------------------------------------------------------

 148    // Class : PclZip

 149    // Description :

 150    //   PclZip is the class that represent a Zip archive.

 151    //   The public methods allow the manipulation of the archive.

 152    // Attributes :

 153    //   Attributes must not be accessed directly.

 154    // Methods :

 155    //   PclZip() : Object creator

 156    //   create() : Creates the Zip archive

 157    //   listContent() : List the content of the Zip archive

 158    //   extract() : Extract the content of the archive

 159    //   properties() : List the properties of the archive

 160    // --------------------------------------------------------------------------------

 161    class PclZip
 162    {
 163      // ----- Filename of the zip file

 164      var $zipname = '';
 165  
 166      // ----- File descriptor of the zip file

 167      var $zip_fd = 0;
 168  
 169      // ----- Internal error handling

 170      var $error_code = 1;
 171      var $error_string = '';
 172      
 173      // ----- Current status of the magic_quotes_runtime

 174      // This value store the php configuration for magic_quotes

 175      // The class can then disable the magic_quotes and reset it after

 176      var $magic_quotes_status;
 177  
 178    // --------------------------------------------------------------------------------

 179    // Function : PclZip()

 180    // Description :

 181    //   Creates a PclZip object and set the name of the associated Zip archive

 182    //   filename.

 183    //   Note that no real action is taken, if the archive does not exist it is not

 184    //   created. Use create() for that.

 185    // --------------------------------------------------------------------------------

 186    function PclZip($p_zipname)
 187    {
 188      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");

 189  
 190      // ----- Tests the zlib

 191      if (!function_exists('gzopen'))
 192      {
 193        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");

 194        die('Abort '.basename(__FILE__).' : Missing zlib extensions');
 195      }
 196  
 197      // ----- Set the attributes

 198      $this->zipname = $p_zipname;
 199      $this->zip_fd = 0;
 200      $this->magic_quotes_status = -1;
 201  
 202      // ----- Return

 203      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);

 204      return;
 205    }
 206    // --------------------------------------------------------------------------------

 207  
 208    // --------------------------------------------------------------------------------

 209    // Function :

 210    //   create($p_filelist, $p_add_dir="", $p_remove_dir="")

 211    //   create($p_filelist, $p_option, $p_option_value, ...)

 212    // Description :

 213    //   This method supports two different synopsis. The first one is historical.

 214    //   This method creates a Zip Archive. The Zip file is created in the

 215    //   filesystem. The files and directories indicated in $p_filelist

 216    //   are added in the archive. See the parameters description for the

 217    //   supported format of $p_filelist.

 218    //   When a directory is in the list, the directory and its content is added

 219    //   in the archive.

 220    //   In this synopsis, the function takes an optional variable list of

 221    //   options. See bellow the supported options.

 222    // Parameters :

 223    //   $p_filelist : An array containing file or directory names, or

 224    //                 a string containing one filename or one directory name, or

 225    //                 a string containing a list of filenames and/or directory

 226    //                 names separated by spaces.

 227    //   $p_add_dir : A path to add before the real path of the archived file,

 228    //                in order to have it memorized in the archive.

 229    //   $p_remove_dir : A path to remove from the real path of the file to archive,

 230    //                   in order to have a shorter path memorized in the archive.

 231    //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir

 232    //                   is removed first, before $p_add_dir is added.

 233    // Options :

 234    //   PCLZIP_OPT_ADD_PATH :

 235    //   PCLZIP_OPT_REMOVE_PATH :

 236    //   PCLZIP_OPT_REMOVE_ALL_PATH :

 237    //   PCLZIP_OPT_COMMENT :

 238    //   PCLZIP_CB_PRE_ADD :

 239    //   PCLZIP_CB_POST_ADD :

 240    // Return Values :

 241    //   0 on failure,

 242    //   The list of the added files, with a status of the add action.

 243    //   (see PclZip::listContent() for list entry format)

 244    // --------------------------------------------------------------------------------

 245    function create($p_filelist)
 246    {
 247      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");

 248      $v_result=1;
 249  
 250      // ----- Reset the error handler

 251      $this->privErrorReset();
 252  
 253      // ----- Set default values

 254      $v_options = array();
 255      $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
 256  
 257      // ----- Look for variable options arguments

 258      $v_size = func_num_args();
 259      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");

 260  
 261      // ----- Look for arguments

 262      if ($v_size > 1) {
 263        // ----- Get the arguments

 264        $v_arg_list = func_get_args();
 265  
 266        // ----- Remove from the options list the first argument

 267        array_shift($v_arg_list);
 268        $v_size--;
 269  
 270        // ----- Look for first arg

 271        if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
 272          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");

 273  
 274          // ----- Parse the options

 275          $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
 276                                              array (PCLZIP_OPT_REMOVE_PATH => 'optional',
 277                                                     PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
 278                                                     PCLZIP_OPT_ADD_PATH => 'optional',
 279                                                     PCLZIP_CB_PRE_ADD => 'optional',
 280                                                     PCLZIP_CB_POST_ADD => 'optional',
 281                                                     PCLZIP_OPT_NO_COMPRESSION => 'optional',
 282                                                     PCLZIP_OPT_COMMENT => 'optional'
 283                                                     //, PCLZIP_OPT_CRYPT => 'optional'

 284                                               ));
 285          if ($v_result != 1) {
 286            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 287            return 0;
 288          }
 289        }
 290  
 291        // ----- Look for 2 args

 292        // Here we need to support the first historic synopsis of the

 293        // method.

 294        else {
 295          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");

 296  
 297          // ----- Get the first argument

 298          $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
 299  
 300          // ----- Look for the optional second argument

 301          if ($v_size == 2) {
 302            $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
 303          }
 304          else if ($v_size > 2) {
 305            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
 306                                 "Invalid number / type of arguments");
 307            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

 308            return 0;
 309          }
 310        }
 311      }
 312  
 313      // ----- Init

 314      $v_string_list = array();
 315      $v_att_list = array();
 316      $v_filedescr_list = array();
 317      $p_result_list = array();
 318      
 319      // ----- Look if the $p_filelist is really an array

 320      if (is_array($p_filelist)) {
 321      
 322        // ----- Look if the first element is also an array

 323        //       This will mean that this is a file description entry

 324        if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
 325          $v_att_list = $p_filelist;
 326        }
 327        
 328        // ----- The list is a list of string names

 329        else {
 330          $v_string_list = $p_filelist;
 331        }
 332      }
 333  
 334      // ----- Look if the $p_filelist is a string

 335      else if (is_string($p_filelist)) {
 336        // ----- Create a list from the string

 337        $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
 338      }
 339  
 340      // ----- Invalid variable type for $p_filelist

 341      else {
 342        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
 343        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 344        return 0;
 345      }
 346      
 347      // ----- Reformat the string list

 348      if (sizeof($v_string_list) != 0) {
 349        foreach ($v_string_list as $v_string) {
 350          if ($v_string != '') {
 351            $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
 352          }
 353          else {
 354            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename");

 355          }
 356        }
 357      }
 358      
 359      // ----- For each file in the list check the attributes

 360      $v_supported_attributes
 361      = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
 362               ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
 363               ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
 364                          );
 365      foreach ($v_att_list as $v_entry) {
 366        $v_result = $this->privFileDescrParseAtt($v_entry,
 367                                                 $v_filedescr_list[],
 368                                                 $v_options,
 369                                                 $v_supported_attributes);
 370        if ($v_result != 1) {
 371          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 372          return 0;
 373        }
 374      }
 375  
 376      // ----- Expand the filelist (expand directories)

 377      $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
 378      if ($v_result != 1) {
 379        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 380        return 0;
 381      }
 382  
 383      // ----- Call the create fct

 384      $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
 385      if ($v_result != 1) {
 386        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 387        return 0;
 388      }
 389  
 390      // ----- Return

 391      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);

 392      return $p_result_list;
 393    }
 394    // --------------------------------------------------------------------------------

 395  
 396    // --------------------------------------------------------------------------------

 397    // Function :

 398    //   add($p_filelist, $p_add_dir="", $p_remove_dir="")

 399    //   add($p_filelist, $p_option, $p_option_value, ...)

 400    // Description :

 401    //   This method supports two synopsis. The first one is historical.

 402    //   This methods add the list of files in an existing archive.

 403    //   If a file with the same name already exists, it is added at the end of the

 404    //   archive, the first one is still present.

 405    //   If the archive does not exist, it is created.

 406    // Parameters :

 407    //   $p_filelist : An array containing file or directory names, or

 408    //                 a string containing one filename or one directory name, or

 409    //                 a string containing a list of filenames and/or directory

 410    //                 names separated by spaces.

 411    //   $p_add_dir : A path to add before the real path of the archived file,

 412    //                in order to have it memorized in the archive.

 413    //   $p_remove_dir : A path to remove from the real path of the file to archive,

 414    //                   in order to have a shorter path memorized in the archive.

 415    //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir

 416    //                   is removed first, before $p_add_dir is added.

 417    // Options :

 418    //   PCLZIP_OPT_ADD_PATH :

 419    //   PCLZIP_OPT_REMOVE_PATH :

 420    //   PCLZIP_OPT_REMOVE_ALL_PATH :

 421    //   PCLZIP_OPT_COMMENT :

 422    //   PCLZIP_OPT_ADD_COMMENT :

 423    //   PCLZIP_OPT_PREPEND_COMMENT :

 424    //   PCLZIP_CB_PRE_ADD :

 425    //   PCLZIP_CB_POST_ADD :

 426    // Return Values :

 427    //   0 on failure,

 428    //   The list of the added files, with a status of the add action.

 429    //   (see PclZip::listContent() for list entry format)

 430    // --------------------------------------------------------------------------------

 431    function add($p_filelist)
 432    {
 433      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");

 434      $v_result=1;
 435  
 436      // ----- Reset the error handler

 437      $this->privErrorReset();
 438  
 439      // ----- Set default values

 440      $v_options = array();
 441      $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
 442  
 443      // ----- Look for variable options arguments

 444      $v_size = func_num_args();
 445      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");

 446  
 447      // ----- Look for arguments

 448      if ($v_size > 1) {
 449        // ----- Get the arguments

 450        $v_arg_list = func_get_args();
 451  
 452        // ----- Remove form the options list the first argument

 453        array_shift($v_arg_list);
 454        $v_size--;
 455  
 456        // ----- Look for first arg

 457        if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
 458          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");

 459  
 460          // ----- Parse the options

 461          $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
 462                                              array (PCLZIP_OPT_REMOVE_PATH => 'optional',
 463                                                     PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
 464                                                     PCLZIP_OPT_ADD_PATH => 'optional',
 465                                                     PCLZIP_CB_PRE_ADD => 'optional',
 466                                                     PCLZIP_CB_POST_ADD => 'optional',
 467                                                     PCLZIP_OPT_NO_COMPRESSION => 'optional',
 468                                                     PCLZIP_OPT_COMMENT => 'optional',
 469                                                     PCLZIP_OPT_ADD_COMMENT => 'optional',
 470                                                     PCLZIP_OPT_PREPEND_COMMENT => 'optional'
 471                                                     //, PCLZIP_OPT_CRYPT => 'optional'

 472                                                     ));
 473          if ($v_result != 1) {
 474            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 475            return 0;
 476          }
 477        }
 478  
 479        // ----- Look for 2 args

 480        // Here we need to support the first historic synopsis of the

 481        // method.

 482        else {
 483          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");

 484  
 485          // ----- Get the first argument

 486          $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
 487  
 488          // ----- Look for the optional second argument

 489          if ($v_size == 2) {
 490            $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
 491          }
 492          else if ($v_size > 2) {
 493            // ----- Error log

 494            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
 495  
 496            // ----- Return

 497            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

 498            return 0;
 499          }
 500        }
 501      }
 502  
 503      // ----- Init

 504      $v_string_list = array();
 505      $v_att_list = array();
 506      $v_filedescr_list = array();
 507      $p_result_list = array();
 508      
 509      // ----- Look if the $p_filelist is really an array

 510      if (is_array($p_filelist)) {
 511      
 512        // ----- Look if the first element is also an array

 513        //       This will mean that this is a file description entry

 514        if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
 515          $v_att_list = $p_filelist;
 516        }
 517        
 518        // ----- The list is a list of string names

 519        else {
 520          $v_string_list = $p_filelist;
 521        }
 522      }
 523  
 524      // ----- Look if the $p_filelist is a string

 525      else if (is_string($p_filelist)) {
 526        // ----- Create a list from the string

 527        $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
 528      }
 529  
 530      // ----- Invalid variable type for $p_filelist

 531      else {
 532        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
 533        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 534        return 0;
 535      }
 536      
 537      // ----- Reformat the string list

 538      if (sizeof($v_string_list) != 0) {
 539        foreach ($v_string_list as $v_string) {
 540          $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
 541        }
 542      }
 543      
 544      // ----- For each file in the list check the attributes

 545      $v_supported_attributes
 546      = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
 547               ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
 548               ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
 549                          );
 550      foreach ($v_att_list as $v_entry) {
 551        $v_result = $this->privFileDescrParseAtt($v_entry,
 552                                                 $v_filedescr_list[],
 553                                                 $v_options,
 554                                                 $v_supported_attributes);
 555        if ($v_result != 1) {
 556          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 557          return 0;
 558        }
 559      }
 560  
 561      // ----- Expand the filelist (expand directories)

 562      $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
 563      if ($v_result != 1) {
 564        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 565        return 0;
 566      }
 567  
 568      // ----- Call the create fct

 569      $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
 570      if ($v_result != 1) {
 571        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 572        return 0;
 573      }
 574  
 575      // ----- Return

 576      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);

 577      return $p_result_list;
 578    }
 579    // --------------------------------------------------------------------------------

 580  
 581    // --------------------------------------------------------------------------------

 582    // Function : listContent()

 583    // Description :

 584    //   This public method, gives the list of the files and directories, with their

 585    //   properties.

 586    //   The properties of each entries in the list are (used also in other functions) :

 587    //     filename : Name of the file. For a create or add action it is the filename

 588    //                given by the user. For an extract function it is the filename

 589    //                of the extracted file.

 590    //     stored_filename : Name of the file / directory stored in the archive.

 591    //     size : Size of the stored file.

 592    //     compressed_size : Size of the file's data compressed in the archive

 593    //                       (without the headers overhead)

 594    //     mtime : Last known modification date of the file (UNIX timestamp)

 595    //     comment : Comment associated with the file

 596    //     folder : true | false

 597    //     index : index of the file in the archive

 598    //     status : status of the action (depending of the action) :

 599    //              Values are :

 600    //                ok : OK !

 601    //                filtered : the file / dir is not extracted (filtered by user)

 602    //                already_a_directory : the file can not be extracted because a

 603    //                                      directory with the same name already exists

 604    //                write_protected : the file can not be extracted because a file

 605    //                                  with the same name already exists and is

 606    //                                  write protected

 607    //                newer_exist : the file was not extracted because a newer file exists

 608    //                path_creation_fail : the file is not extracted because the folder

 609    //                                     does not exists and can not be created

 610    //                write_error : the file was not extracted because there was a

 611    //                              error while writing the file

 612    //                read_error : the file was not extracted because there was a error

 613    //                             while reading the file

 614    //                invalid_header : the file was not extracted because of an archive

 615    //                                 format error (bad file header)

 616    //   Note that each time a method can continue operating when there

 617    //   is an action error on a file, the error is only logged in the file status.

 618    // Return Values :

 619    //   0 on an unrecoverable failure,

 620    //   The list of the files in the archive.

 621    // --------------------------------------------------------------------------------

 622    function listContent()
 623    {
 624      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");

 625      $v_result=1;
 626  
 627      // ----- Reset the error handler

 628      $this->privErrorReset();
 629  
 630      // ----- Check archive

 631      if (!$this->privCheckFormat()) {
 632        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 633        return(0);
 634      }
 635  
 636      // ----- Call the extracting fct

 637      $p_list = array();
 638      if (($v_result = $this->privList($p_list)) != 1)
 639      {
 640        unset($p_list);
 641        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());

 642        return(0);
 643      }
 644  
 645      // ----- Return

 646      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);

 647      return $p_list;
 648    }
 649    // --------------------------------------------------------------------------------

 650  
 651    // --------------------------------------------------------------------------------

 652    // Function :

 653    //   extract($p_path="./", $p_remove_path="")

 654    //   extract([$p_option, $p_option_value, ...])

 655    // Description :

 656    //   This method supports two synopsis. The first one is historical.

 657    //   This method extract all the files / directories from the archive to the

 658    //   folder indicated in $p_path.

 659    //   If you want to ignore the 'root' part of path of the memorized files

 660    //   you can indicate this in the optional $p_remove_path parameter.

 661    //   By default, if a newer file with the same name already exists, the

 662    //   file is not extracted.

 663    //

 664    //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions

 665    //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append

 666    //   at the end of the path value of PCLZIP_OPT_PATH.

 667    // Parameters :

 668    //   $p_path : Path where the files and directories are to be extracted

 669    //   $p_remove_path : First part ('root' part) of the memorized path

 670    //                    (if any similar) to remove while extracting.

 671    // Options :

 672    //   PCLZIP_OPT_PATH :

 673    //   PCLZIP_OPT_ADD_PATH :

 674    //   PCLZIP_OPT_REMOVE_PATH :

 675    //   PCLZIP_OPT_REMOVE_ALL_PATH :

 676    //   PCLZIP_CB_PRE_EXTRACT :

 677    //   PCLZIP_CB_POST_EXTRACT :

 678    // Return Values :

 679    //   0 or a negative value on failure,

 680    //   The list of the extracted files, with a status of the action.

 681    //   (see PclZip::listContent() for list entry format)

 682    // --------------------------------------------------------------------------------

 683    function extract()
 684    {
 685      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");

 686      $v_result=1;
 687  
 688      // ----- Reset the error handler

 689      $this->privErrorReset();
 690  
 691      // ----- Check archive

 692      if (!$this->privCheckFormat()) {
 693        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 694        return(0);
 695      }
 696  
 697      // ----- Set default values

 698      $v_options = array();
 699  //    $v_path = "./";

 700      $v_path = '';
 701      $v_remove_path = "";
 702      $v_remove_all_path = false;
 703  
 704      // ----- Look for variable options arguments

 705      $v_size = func_num_args();
 706      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");

 707  
 708      // ----- Default values for option

 709      $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
 710  
 711      // ----- Look for arguments

 712      if ($v_size > 0) {
 713        // ----- Get the arguments

 714        $v_arg_list = func_get_args();
 715  
 716        // ----- Look for first arg

 717        if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
 718          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");

 719  
 720          // ----- Parse the options

 721          $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
 722                                              array (PCLZIP_OPT_PATH => 'optional',
 723                                                     PCLZIP_OPT_REMOVE_PATH => 'optional',
 724                                                     PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
 725                                                     PCLZIP_OPT_ADD_PATH => 'optional',
 726                                                     PCLZIP_CB_PRE_EXTRACT => 'optional',
 727                                                     PCLZIP_CB_POST_EXTRACT => 'optional',
 728                                                     PCLZIP_OPT_SET_CHMOD => 'optional',
 729                                                     PCLZIP_OPT_BY_NAME => 'optional',
 730                                                     PCLZIP_OPT_BY_EREG => 'optional',
 731                                                     PCLZIP_OPT_BY_PREG => 'optional',
 732                                                     PCLZIP_OPT_BY_INDEX => 'optional',
 733                                                     PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
 734                                                     PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
 735                                                     PCLZIP_OPT_REPLACE_NEWER => 'optional'
 736                                                     ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
 737                                                     ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
 738                                                      ));
 739          if ($v_result != 1) {
 740            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 741            return 0;
 742          }
 743  
 744          // ----- Set the arguments

 745          if (isset($v_options[PCLZIP_OPT_PATH])) {
 746            $v_path = $v_options[PCLZIP_OPT_PATH];
 747          }
 748          if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
 749            $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
 750          }
 751          if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
 752            $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
 753          }
 754          if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
 755            // ----- Check for '/' in last path char

 756            if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
 757              $v_path .= '/';
 758            }
 759            $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
 760          }
 761        }
 762  
 763        // ----- Look for 2 args

 764        // Here we need to support the first historic synopsis of the

 765        // method.

 766        else {
 767          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");

 768  
 769          // ----- Get the first argument

 770          $v_path = $v_arg_list[0];
 771  
 772          // ----- Look for the optional second argument

 773          if ($v_size == 2) {
 774            $v_remove_path = $v_arg_list[1];
 775          }
 776          else if ($v_size > 2) {
 777            // ----- Error log

 778            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
 779  
 780            // ----- Return

 781            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());

 782            return 0;
 783          }
 784        }
 785      }
 786  
 787      // ----- Trace

 788      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");

 789  
 790      // ----- Call the extracting fct

 791      $p_list = array();
 792      $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
 793                                           $v_remove_all_path, $v_options);
 794      if ($v_result < 1) {
 795        unset($p_list);
 796        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());

 797        return(0);
 798      }
 799  
 800      // ----- Return

 801      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);

 802      return $p_list;
 803    }
 804    // --------------------------------------------------------------------------------

 805  
 806  
 807    // --------------------------------------------------------------------------------

 808    // Function :

 809    //   extractByIndex($p_index, $p_path="./", $p_remove_path="")

 810    //   extractByIndex($p_index, [$p_option, $p_option_value, ...])

 811    // Description :

 812    //   This method supports two synopsis. The first one is historical.

 813    //   This method is doing a partial extract of the archive.

 814    //   The extracted files or folders are identified by their index in the

 815    //   archive (from 0 to n).

 816    //   Note that if the index identify a folder, only the folder entry is

 817    //   extracted, not all the files included in the archive.

 818    // Parameters :

 819    //   $p_index : A single index (integer) or a string of indexes of files to

 820    //              extract. The form of the string is "0,4-6,8-12" with only numbers

 821    //              and '-' for range or ',' to separate ranges. No spaces or ';'

 822    //              are allowed.

 823    //   $p_path : Path where the files and directories are to be extracted

 824    //   $p_remove_path : First part ('root' part) of the memorized path

 825    //                    (if any similar) to remove while extracting.

 826    // Options :

 827    //   PCLZIP_OPT_PATH :

 828    //   PCLZIP_OPT_ADD_PATH :

 829    //   PCLZIP_OPT_REMOVE_PATH :

 830    //   PCLZIP_OPT_REMOVE_ALL_PATH :

 831    //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and

 832    //     not as files.

 833    //     The resulting content is in a new field 'content' in the file

 834    //     structure.

 835    //     This option must be used alone (any other options are ignored).

 836    //   PCLZIP_CB_PRE_EXTRACT :

 837    //   PCLZIP_CB_POST_EXTRACT :

 838    // Return Values :

 839    //   0 on failure,

 840    //   The list of the extracted files, with a status of the action.

 841    //   (see PclZip::listContent() for list entry format)

 842    // --------------------------------------------------------------------------------

 843    //function extractByIndex($p_index, options...)

 844    function extractByIndex($p_index)
 845    {
 846      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");

 847      $v_result=1;
 848  
 849      // ----- Reset the error handler

 850      $this->privErrorReset();
 851  
 852      // ----- Check archive

 853      if (!$this->privCheckFormat()) {
 854        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 855        return(0);
 856      }
 857  
 858      // ----- Set default values

 859      $v_options = array();
 860  //    $v_path = "./";

 861      $v_path = '';
 862      $v_remove_path = "";
 863      $v_remove_all_path = false;
 864  
 865      // ----- Look for variable options arguments

 866      $v_size = func_num_args();
 867      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");

 868  
 869      // ----- Default values for option

 870      $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
 871  
 872      // ----- Look for arguments

 873      if ($v_size > 1) {
 874        // ----- Get the arguments

 875        $v_arg_list = func_get_args();
 876  
 877        // ----- Remove form the options list the first argument

 878        array_shift($v_arg_list);
 879        $v_size--;
 880  
 881        // ----- Look for first arg

 882        if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
 883          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");

 884  
 885          // ----- Parse the options

 886          $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
 887                                              array (PCLZIP_OPT_PATH => 'optional',
 888                                                     PCLZIP_OPT_REMOVE_PATH => 'optional',
 889                                                     PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
 890                                                     PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
 891                                                     PCLZIP_OPT_ADD_PATH => 'optional',
 892                                                     PCLZIP_CB_PRE_EXTRACT => 'optional',
 893                                                     PCLZIP_CB_POST_EXTRACT => 'optional',
 894                                                     PCLZIP_OPT_SET_CHMOD => 'optional',
 895                                                     PCLZIP_OPT_REPLACE_NEWER => 'optional'
 896                                                     ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
 897                                                     ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
 898                                                     ));
 899          if ($v_result != 1) {
 900            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 901            return 0;
 902          }
 903  
 904          // ----- Set the arguments

 905          if (isset($v_options[PCLZIP_OPT_PATH])) {
 906            $v_path = $v_options[PCLZIP_OPT_PATH];
 907          }
 908          if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
 909            $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
 910          }
 911          if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
 912            $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
 913          }
 914          if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
 915            // ----- Check for '/' in last path char

 916            if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
 917              $v_path .= '/';
 918            }
 919            $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
 920          }
 921          if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
 922            $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
 923            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");

 924          }
 925          else {
 926              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");

 927          }
 928        }
 929  
 930        // ----- Look for 2 args

 931        // Here we need to support the first historic synopsis of the

 932        // method.

 933        else {
 934          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");

 935  
 936          // ----- Get the first argument

 937          $v_path = $v_arg_list[0];
 938  
 939          // ----- Look for the optional second argument

 940          if ($v_size == 2) {
 941            $v_remove_path = $v_arg_list[1];
 942          }
 943          else if ($v_size > 2) {
 944            // ----- Error log

 945            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
 946  
 947            // ----- Return

 948            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

 949            return 0;
 950          }
 951        }
 952      }
 953  
 954      // ----- Trace

 955      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");

 956  
 957      // ----- Trick

 958      // Here I want to reuse extractByRule(), so I need to parse the $p_index

 959      // with privParseOptions()

 960      $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
 961      $v_options_trick = array();
 962      $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
 963                                          array (PCLZIP_OPT_BY_INDEX => 'optional' ));
 964      if ($v_result != 1) {
 965          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

 966          return 0;
 967      }
 968      $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
 969  
 970      // ----- Call the extracting fct

 971      if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
 972          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());

 973          return(0);
 974      }
 975  
 976      // ----- Return

 977      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);

 978      return $p_list;
 979    }
 980    // --------------------------------------------------------------------------------

 981  
 982    // --------------------------------------------------------------------------------

 983    // Function :

 984    //   delete([$p_option, $p_option_value, ...])

 985    // Description :

 986    //   This method removes files from the archive.

 987    //   If no parameters are given, then all the archive is emptied.

 988    // Parameters :

 989    //   None or optional arguments.

 990    // Options :

 991    //   PCLZIP_OPT_BY_INDEX :

 992    //   PCLZIP_OPT_BY_NAME :

 993    //   PCLZIP_OPT_BY_EREG : 

 994    //   PCLZIP_OPT_BY_PREG :

 995    // Return Values :

 996    //   0 on failure,

 997    //   The list of the files which are still present in the archive.

 998    //   (see PclZip::listContent() for list entry format)

 999    // --------------------------------------------------------------------------------

1000    function delete()
1001    {
1002      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");

1003      $v_result=1;
1004  
1005      // ----- Reset the error handler

1006      $this->privErrorReset();
1007  
1008      // ----- Check archive

1009      if (!$this->privCheckFormat()) {
1010        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

1011        return(0);
1012      }
1013  
1014      // ----- Set default values

1015      $v_options = array();
1016  
1017      // ----- Look for variable options arguments

1018      $v_size = func_num_args();
1019      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");

1020  
1021      // ----- Look for arguments

1022      if ($v_size > 0) {
1023        // ----- Get the arguments

1024        $v_arg_list = func_get_args();
1025  
1026        // ----- Parse the options

1027        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1028                                          array (PCLZIP_OPT_BY_NAME => 'optional',
1029                                                 PCLZIP_OPT_BY_EREG => 'optional',
1030                                                 PCLZIP_OPT_BY_PREG => 'optional',
1031                                                 PCLZIP_OPT_BY_INDEX => 'optional' ));
1032        if ($v_result != 1) {
1033            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

1034            return 0;
1035        }
1036      }
1037  
1038      // ----- Magic quotes trick

1039      $this->privDisableMagicQuotes();
1040  
1041      // ----- Call the delete fct

1042      $v_list = array();
1043      if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1044        $this->privSwapBackMagicQuotes();
1045        unset($v_list);
1046        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());

1047        return(0);
1048      }
1049  
1050      // ----- Magic quotes trick

1051      $this->privSwapBackMagicQuotes();
1052  
1053      // ----- Return

1054      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);

1055      return $v_list;
1056    }
1057    // --------------------------------------------------------------------------------

1058  
1059    // --------------------------------------------------------------------------------

1060    // Function : deleteByIndex()

1061    // Description :

1062    //   ***** Deprecated *****

1063    //   delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.

1064    // --------------------------------------------------------------------------------

1065    function deleteByIndex($p_index)
1066    {
1067      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");

1068      
1069      $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1070  
1071      // ----- Return

1072      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);

1073      return $p_list;
1074    }
1075    // --------------------------------------------------------------------------------

1076  
1077    // --------------------------------------------------------------------------------

1078    // Function : properties()

1079    // Description :

1080    //   This method gives the properties of the archive.

1081    //   The properties are :

1082    //     nb : Number of files in the archive

1083    //     comment : Comment associated with the archive file

1084    //     status : not_exist, ok

1085    // Parameters :

1086    //   None

1087    // Return Values :

1088    //   0 on failure,

1089    //   An array with the archive properties.

1090    // --------------------------------------------------------------------------------

1091    function properties()
1092    {
1093      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");

1094  
1095      // ----- Reset the error handler

1096      $this->privErrorReset();
1097  
1098      // ----- Magic quotes trick

1099      $this->privDisableMagicQuotes();
1100  
1101      // ----- Check archive

1102      if (!$this->privCheckFormat()) {
1103        $this->privSwapBackMagicQuotes();
1104        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

1105        return(0);
1106      }
1107  
1108      // ----- Default properties

1109      $v_prop = array();
1110      $v_prop['comment'] = '';
1111      $v_prop['nb'] = 0;
1112      $v_prop['status'] = 'not_exist';
1113  
1114      // ----- Look if file exists

1115      if (@is_file($this->zipname))
1116      {
1117        // ----- Open the zip file

1118        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");

1119        if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1120        {
1121          $this->privSwapBackMagicQuotes();
1122          
1123          // ----- Error log

1124          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1125  
1126          // ----- Return

1127          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);

1128          return 0;
1129        }
1130  
1131        // ----- Read the central directory informations

1132        $v_central_dir = array();
1133        if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1134        {
1135          $this->privSwapBackMagicQuotes();
1136          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

1137          return 0;
1138        }
1139  
1140        // ----- Close the zip file

1141        $this->privCloseFd();
1142  
1143        // ----- Set the user attributes

1144        $v_prop['comment'] = $v_central_dir['comment'];
1145        $v_prop['nb'] = $v_central_dir['entries'];
1146        $v_prop['status'] = 'ok';
1147      }
1148  
1149      // ----- Magic quotes trick

1150      $this->privSwapBackMagicQuotes();
1151  
1152      // ----- Return

1153      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);

1154      return $v_prop;
1155    }
1156    // --------------------------------------------------------------------------------

1157  
1158    // --------------------------------------------------------------------------------

1159    // Function : duplicate()

1160    // Description :

1161    //   This method creates an archive by copying the content of an other one. If

1162    //   the archive already exist, it is replaced by the new one without any warning.

1163    // Parameters :

1164    //   $p_archive : The filename of a valid archive, or

1165    //                a valid PclZip object.

1166    // Return Values :

1167    //   1 on success.

1168    //   0 or a negative value on error (error code).

1169    // --------------------------------------------------------------------------------

1170    function duplicate($p_archive)
1171    {
1172      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");

1173      $v_result = 1;
1174  
1175      // ----- Reset the error handler

1176      $this->privErrorReset();
1177  
1178      // ----- Look if the $p_archive is a PclZip object

1179      if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1180      {
1181        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");

1182  
1183        // ----- Duplicate the archive

1184        $v_result = $this->privDuplicate($p_archive->zipname);
1185      }
1186  
1187      // ----- Look if the $p_archive is a string (so a filename)

1188      else if (is_string($p_archive))
1189      {
1190        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");

1191  
1192        // ----- Check that $p_archive is a valid zip file

1193        // TBC : Should also check the archive format

1194        if (!is_file($p_archive)) {
1195          // ----- Error log

1196          PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1197          $v_result = PCLZIP_ERR_MISSING_FILE;
1198        }
1199        else {
1200          // ----- Duplicate the archive

1201          $v_result = $this->privDuplicate($p_archive);
1202        }
1203      }
1204  
1205      // ----- Invalid variable

1206      else
1207      {
1208        // ----- Error log

1209        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1210        $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1211      }
1212  
1213      // ----- Return

1214      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

1215      return $v_result;
1216    }
1217    // --------------------------------------------------------------------------------

1218  
1219    // --------------------------------------------------------------------------------

1220    // Function : merge()

1221    // Description :

1222    //   This method merge the $p_archive_to_add archive at the end of the current

1223    //   one ($this).

1224    //   If the archive ($this) does not exist, the merge becomes a duplicate.

1225    //   If the $p_archive_to_add archive does not exist, the merge is a success.

1226    // Parameters :

1227    //   $p_archive_to_add : It can be directly the filename of a valid zip archive,

1228    //                       or a PclZip object archive.

1229    // Return Values :

1230    //   1 on success,

1231    //   0 or negative values on error (see below).

1232    // --------------------------------------------------------------------------------

1233    function merge($p_archive_to_add)
1234    {
1235      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");

1236      $v_result = 1;
1237  
1238      // ----- Reset the error handler

1239      $this->privErrorReset();
1240  
1241      // ----- Check archive

1242      if (!$this->privCheckFormat()) {
1243        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);

1244        return(0);
1245      }
1246  
1247      // ----- Look if the $p_archive_to_add is a PclZip object

1248      if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1249      {
1250        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");

1251  
1252        // ----- Merge the archive

1253        $v_result = $this->privMerge($p_archive_to_add);
1254      }
1255  
1256      // ----- Look if the $p_archive_to_add is a string (so a filename)

1257      else if (is_string($p_archive_to_add))
1258      {
1259        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");

1260  
1261        // ----- Create a temporary archive

1262        $v_object_archive = new PclZip($p_archive_to_add);
1263  
1264        // ----- Merge the archive

1265        $v_result = $this->privMerge($v_object_archive);
1266      }
1267  
1268      // ----- Invalid variable

1269      else
1270      {
1271        // ----- Error log

1272        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1273        $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1274      }
1275  
1276      // ----- Return

1277      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

1278      return $v_result;
1279    }
1280    // --------------------------------------------------------------------------------

1281  
1282  
1283  
1284    // --------------------------------------------------------------------------------

1285    // Function : errorCode()

1286    // Description :

1287    // Parameters :

1288    // --------------------------------------------------------------------------------

1289    function errorCode()
1290    {
1291      if (PCLZIP_ERROR_EXTERNAL == 1) {
1292        return(PclErrorCode());
1293      }
1294      else {
1295        return($this->error_code);
1296      }
1297    }
1298    // --------------------------------------------------------------------------------

1299  
1300    // --------------------------------------------------------------------------------

1301    // Function : errorName()

1302    // Description :

1303    // Parameters :

1304    // --------------------------------------------------------------------------------

1305    function errorName($p_with_code=false)
1306    {
1307      $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1308                        PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1309                        PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1310                        PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1311                        PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1312                        PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1313                        PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1314                        PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1315                        PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1316                        PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1317                        PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1318                        PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1319                        PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1320                        PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1321                        PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1322                        PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1323                        PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1324                        PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1325                        PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1326                        ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1327                        ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1328                      );
1329  
1330      if (isset($v_name[$this->error_code])) {
1331        $v_value = $v_name[$this->error_code];
1332      }
1333      else {
1334        $v_value = 'NoName';
1335      }
1336  
1337      if ($p_with_code) {
1338        return($v_value.' ('.$this->error_code.')');
1339      }
1340      else {
1341        return($v_value);
1342      }
1343    }
1344    // --------------------------------------------------------------------------------

1345  
1346    // --------------------------------------------------------------------------------

1347    // Function : errorInfo()

1348    // Description :

1349    // Parameters :

1350    // --------------------------------------------------------------------------------

1351    function errorInfo($p_full=false)
1352    {
1353      if (PCLZIP_ERROR_EXTERNAL == 1) {
1354        return(PclErrorString());
1355      }
1356      else {
1357        if ($p_full) {
1358          return($this->errorName(true)." : ".$this->error_string);
1359        }
1360        else {
1361          return($this->error_string." [code ".$this->error_code."]");
1362        }
1363      }
1364    }
1365    // --------------------------------------------------------------------------------

1366  
1367  
1368  // --------------------------------------------------------------------------------

1369  // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****

1370  // *****                                                        *****

1371  // *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****

1372  // --------------------------------------------------------------------------------

1373  
1374  
1375  
1376    // --------------------------------------------------------------------------------

1377    // Function : privCheckFormat()

1378    // Description :

1379    //   This method check that the archive exists and is a valid zip archive.

1380    //   Several level of check exists. (futur)

1381    // Parameters :

1382    //   $p_level : Level of check. Default 0.

1383    //              0 : Check the first bytes (magic codes) (default value))

1384    //              1 : 0 + Check the central directory (futur)

1385    //              2 : 1 + Check each file header (futur)

1386    // Return Values :

1387    //   true on success,

1388    //   false on error, the error code is set.

1389    // --------------------------------------------------------------------------------

1390    function privCheckFormat($p_level=0)
1391    {
1392      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");

1393      $v_result = true;
1394  
1395      // ----- Reset the file system cache

1396      clearstatcache();
1397  
1398      // ----- Reset the error handler

1399      $this->privErrorReset();
1400  
1401      // ----- Look if the file exits

1402      if (!is_file($this->zipname)) {
1403        // ----- Error log

1404        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1405        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());

1406        return(false);
1407      }
1408  
1409      // ----- Check that the file is readeable

1410      if (!is_readable($this->zipname)) {
1411        // ----- Error log

1412        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1413        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());

1414        return(false);
1415      }
1416  
1417      // ----- Check the magic code

1418      // TBC

1419  
1420      // ----- Check the central header

1421      // TBC

1422  
1423      // ----- Check each file header

1424      // TBC

1425  
1426      // ----- Return

1427      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

1428      return $v_result;
1429    }
1430    // --------------------------------------------------------------------------------

1431  
1432    // --------------------------------------------------------------------------------

1433    // Function : privParseOptions()

1434    // Description :

1435    //   This internal methods reads the variable list of arguments ($p_options_list,

1436    //   $p_size) and generate an array with the options and values ($v_result_list).

1437    //   $v_requested_options contains the options that can be present and those that

1438    //   must be present.

1439    //   $v_requested_options is an array, with the option value as key, and 'optional',

1440    //   or 'mandatory' as value.

1441    // Parameters :

1442    //   See above.

1443    // Return Values :

1444    //   1 on success.

1445    //   0 on failure.

1446    // --------------------------------------------------------------------------------

1447    function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1448    {
1449      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");

1450      $v_result=1;
1451      
1452      // ----- Read the options

1453      $i=0;
1454      while ($i<$p_size) {
1455        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");

1456  
1457        // ----- Check if the option is supported

1458        if (!isset($v_requested_options[$p_options_list[$i]])) {
1459          // ----- Error log

1460          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1461  
1462          // ----- Return

1463          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1464          return PclZip::errorCode();
1465        }
1466  
1467        // ----- Look for next option

1468        switch ($p_options_list[$i]) {
1469          // ----- Look for options that request a path value

1470          case PCLZIP_OPT_PATH :
1471          case PCLZIP_OPT_REMOVE_PATH :
1472          case PCLZIP_OPT_ADD_PATH :
1473            // ----- Check the number of parameters

1474            if (($i+1) >= $p_size) {
1475              // ----- Error log

1476              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1477  
1478              // ----- Return

1479              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1480              return PclZip::errorCode();
1481            }
1482  
1483            // ----- Get the value

1484            $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1485            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1486            $i++;
1487          break;
1488  
1489          case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1490            // ----- Check the number of parameters

1491            if (($i+1) >= $p_size) {
1492              // ----- Error log

1493              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1494  
1495              // ----- Return

1496              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1497              return PclZip::errorCode();
1498            }
1499  
1500            // ----- Get the value

1501            if (   is_string($p_options_list[$i+1])
1502                && ($p_options_list[$i+1] != '')) {
1503              $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1504              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1505              $i++;
1506            }
1507            else {
1508              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored.");

1509            }
1510          break;
1511  
1512          // ----- Look for options that request an array of string for value

1513          case PCLZIP_OPT_BY_NAME :
1514            // ----- Check the number of parameters

1515            if (($i+1) >= $p_size) {
1516              // ----- Error log

1517              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1518  
1519              // ----- Return

1520              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1521              return PclZip::errorCode();
1522            }
1523  
1524            // ----- Get the value

1525            if (is_string($p_options_list[$i+1])) {
1526                $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1527            }
1528            else if (is_array($p_options_list[$i+1])) {
1529                $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1530            }
1531            else {
1532              // ----- Error log

1533              PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1534  
1535              // ----- Return

1536              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1537              return PclZip::errorCode();
1538            }
1539            ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1540            $i++;
1541          break;
1542  
1543          // ----- Look for options that request an EREG or PREG expression

1544          case PCLZIP_OPT_BY_EREG :
1545          case PCLZIP_OPT_BY_PREG :
1546          //case PCLZIP_OPT_CRYPT :

1547            // ----- Check the number of parameters

1548            if (($i+1) >= $p_size) {
1549              // ----- Error log

1550              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1551  
1552              // ----- Return

1553              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1554              return PclZip::errorCode();
1555            }
1556  
1557            // ----- Get the value

1558            if (is_string($p_options_list[$i+1])) {
1559                $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1560            }
1561            else {
1562              // ----- Error log

1563              PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1564  
1565              // ----- Return

1566              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1567              return PclZip::errorCode();
1568            }
1569            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1570            $i++;
1571          break;
1572  
1573          // ----- Look for options that takes a string

1574          case PCLZIP_OPT_COMMENT :
1575          case PCLZIP_OPT_ADD_COMMENT :
1576          case PCLZIP_OPT_PREPEND_COMMENT :
1577            // ----- Check the number of parameters

1578            if (($i+1) >= $p_size) {
1579              // ----- Error log

1580              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1581                                   "Missing parameter value for option '"
1582                                   .PclZipUtilOptionText($p_options_list[$i])
1583                                   ."'");
1584  
1585              // ----- Return

1586              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1587              return PclZip::errorCode();
1588            }
1589  
1590            // ----- Get the value

1591            if (is_string($p_options_list[$i+1])) {
1592                $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1593            }
1594            else {
1595              // ----- Error log

1596              PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1597                                   "Wrong parameter value for option '"
1598                                   .PclZipUtilOptionText($p_options_list[$i])
1599                                   ."'");
1600  
1601              // ----- Return

1602              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1603              return PclZip::errorCode();
1604            }
1605            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1606            $i++;
1607          break;
1608  
1609          // ----- Look for options that request an array of index

1610          case PCLZIP_OPT_BY_INDEX :
1611            // ----- Check the number of parameters

1612            if (($i+1) >= $p_size) {
1613              // ----- Error log

1614              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1615  
1616              // ----- Return

1617              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1618              return PclZip::errorCode();
1619            }
1620  
1621            // ----- Get the value

1622            $v_work_list = array();
1623            if (is_string($p_options_list[$i+1])) {
1624                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");

1625  
1626                // ----- Remove spaces

1627                $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1628  
1629                // ----- Parse items

1630                $v_work_list = explode(",", $p_options_list[$i+1]);
1631            }
1632            else if (is_integer($p_options_list[$i+1])) {
1633                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");

1634                $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1635            }
1636            else if (is_array($p_options_list[$i+1])) {
1637                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");

1638                $v_work_list = $p_options_list[$i+1];
1639            }
1640            else {
1641              // ----- Error log

1642              PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1643  
1644              // ----- Return

1645              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1646              return PclZip::errorCode();
1647            }
1648            
1649            // ----- Reduce the index list

1650            // each index item in the list must be a couple with a start and

1651            // an end value : [0,3], [5-5], [8-10], ...

1652            // ----- Check the format of each item

1653            $v_sort_flag=false;
1654            $v_sort_value=0;
1655            for ($j=0; $j<sizeof($v_work_list); $j++) {
1656                // ----- Explode the item

1657                $v_item_list = explode("-", $v_work_list[$j]);
1658                $v_size_item_list = sizeof($v_item_list);
1659                
1660                // ----- TBC : Here we might check that each item is a

1661                // real integer ...

1662                
1663                // ----- Look for single value

1664                if ($v_size_item_list == 1) {
1665                    // ----- Set the option value

1666                    $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1667                    $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1668                }
1669                elseif ($v_size_item_list == 2) {
1670                    // ----- Set the option value

1671                    $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1672                    $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1673                }
1674                else {
1675                    // ----- Error log

1676                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1677  
1678                    // ----- Return

1679                    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1680                    return PclZip::errorCode();
1681                }
1682  
1683                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");

1684  
1685                // ----- Look for list sort

1686                if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1687                    //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");

1688                    $v_sort_flag=true;
1689  
1690                    // ----- TBC : An automatic sort should be writen ...

1691                    // ----- Error log

1692                    PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1693  
1694                    // ----- Return

1695                    //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1696                    return PclZip::errorCode();
1697                }
1698                $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1699            }
1700            
1701            // ----- Sort the items

1702            if ($v_sort_flag) {
1703                // TBC : To Be Completed

1704                //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");

1705            }
1706  
1707            // ----- Next option

1708            $i++;
1709          break;
1710  
1711          // ----- Look for options that request no value

1712          case PCLZIP_OPT_REMOVE_ALL_PATH :
1713          case PCLZIP_OPT_EXTRACT_AS_STRING :
1714          case PCLZIP_OPT_NO_COMPRESSION :
1715          case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1716          case PCLZIP_OPT_REPLACE_NEWER :
1717          case PCLZIP_OPT_STOP_ON_ERROR :
1718            $v_result_list[$p_options_list[$i]] = true;
1719            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1720          break;
1721  
1722          // ----- Look for options that request an octal value

1723          case PCLZIP_OPT_SET_CHMOD :
1724            // ----- Check the number of parameters

1725            if (($i+1) >= $p_size) {
1726              // ----- Error log

1727              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1728  
1729              // ----- Return

1730              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1731              return PclZip::errorCode();
1732            }
1733  
1734            // ----- Get the value

1735            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1736            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");

1737            $i++;
1738          break;
1739  
1740          // ----- Look for options that request a call-back

1741          case PCLZIP_CB_PRE_EXTRACT :
1742          case PCLZIP_CB_POST_EXTRACT :
1743          case PCLZIP_CB_PRE_ADD :
1744          case PCLZIP_CB_POST_ADD :
1745          /* for futur use

1746          case PCLZIP_CB_PRE_DELETE :

1747          case PCLZIP_CB_POST_DELETE :

1748          case PCLZIP_CB_PRE_LIST :

1749          case PCLZIP_CB_POST_LIST :

1750          */
1751            // ----- Check the number of parameters

1752            if (($i+1) >= $p_size) {
1753              // ----- Error log

1754              PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1755  
1756              // ----- Return

1757              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1758              return PclZip::errorCode();
1759            }
1760  
1761            // ----- Get the value

1762            $v_function_name = $p_options_list[$i+1];
1763            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");

1764  
1765            // ----- Check that the value is a valid existing function

1766            if (!function_exists($v_function_name)) {
1767              // ----- Error log

1768              PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1769  
1770              // ----- Return

1771              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1772              return PclZip::errorCode();
1773            }
1774  
1775            // ----- Set the attribute

1776            $v_result_list[$p_options_list[$i]] = $v_function_name;
1777            $i++;
1778          break;
1779  
1780          default :
1781            // ----- Error log

1782            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1783                                 "Unknown parameter '"
1784                                 .$p_options_list[$i]."'");
1785  
1786            // ----- Return

1787            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1788            return PclZip::errorCode();
1789        }
1790  
1791        // ----- Next options

1792        $i++;
1793      }
1794  
1795      // ----- Look for mandatory options

1796      if ($v_requested_options !== false) {
1797        for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1798          // ----- Look for mandatory option

1799          if ($v_requested_options[$key] == 'mandatory') {
1800            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");

1801            // ----- Look if present

1802            if (!isset($v_result_list[$key])) {
1803              // ----- Error log

1804              PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1805  
1806              // ----- Return

1807              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1808              return PclZip::errorCode();
1809            }
1810          }
1811        }
1812      }
1813  
1814      // ----- Return

1815      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

1816      return $v_result;
1817    }
1818    // --------------------------------------------------------------------------------

1819  
1820    // --------------------------------------------------------------------------------

1821    // Function : privFileDescrParseAtt()

1822    // Description :

1823    // Parameters :

1824    // Return Values :

1825    //   1 on success.

1826    //   0 on failure.

1827    // --------------------------------------------------------------------------------

1828    function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1829    {
1830      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", "");

1831      $v_result=1;
1832      
1833      // ----- For each file in the list check the attributes

1834      foreach ($p_file_list as $v_key => $v_value) {
1835      
1836        // ----- Check if the option is supported

1837        if (!isset($v_requested_options[$v_key])) {
1838          // ----- Error log

1839          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1840  
1841          // ----- Return

1842          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1843          return PclZip::errorCode();
1844        }
1845  
1846        // ----- Look for attribute

1847        switch ($v_key) {
1848          case PCLZIP_ATT_FILE_NAME :
1849            if (!is_string($v_value)) {
1850              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1851              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1852              return PclZip::errorCode();
1853            }
1854  
1855            $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1856            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");

1857            
1858            if ($p_filedescr['filename'] == '') {
1859              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1860              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1861              return PclZip::errorCode();
1862            }
1863  
1864          break;
1865  
1866          case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1867            if (!is_string($v_value)) {
1868              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1869              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1870              return PclZip::errorCode();
1871            }
1872  
1873            $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1874            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");

1875  
1876            if ($p_filedescr['new_short_name'] == '') {
1877              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1878              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1879              return PclZip::errorCode();
1880            }
1881          break;
1882  
1883          case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1884            if (!is_string($v_value)) {
1885              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1886              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1887              return PclZip::errorCode();
1888            }
1889  
1890            $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1891            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");

1892  
1893            if ($p_filedescr['new_full_name'] == '') {
1894              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1895              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1896              return PclZip::errorCode();
1897            }
1898          break;
1899  
1900          default :
1901            // ----- Error log

1902            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1903                                     "Unknown parameter '".$v_key."'");
1904  
1905            // ----- Return

1906            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1907            return PclZip::errorCode();
1908        }
1909  
1910        // ----- Look for mandatory options

1911        if ($v_requested_options !== false) {
1912          for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1913            // ----- Look for mandatory option

1914            if ($v_requested_options[$key] == 'mandatory') {
1915              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");

1916              // ----- Look if present

1917              if (!isset($p_file_list[$key])) {
1918                PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1919                //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1920                return PclZip::errorCode();
1921              }
1922            }
1923          }
1924        }
1925      
1926      // end foreach

1927      }
1928      
1929      // ----- Return

1930      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

1931      return $v_result;
1932    }
1933    // --------------------------------------------------------------------------------

1934  
1935    // --------------------------------------------------------------------------------

1936    // Function : privFileDescrExpand()

1937    // Description :

1938    // Parameters :

1939    // Return Values :

1940    //   1 on success.

1941    //   0 on failure.

1942    // --------------------------------------------------------------------------------

1943    function privFileDescrExpand(&$p_filedescr_list, &$p_options)
1944    {
1945      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", "");

1946      $v_result=1;
1947      
1948      // ----- Create a result list

1949      $v_result_list = array();
1950      
1951      // ----- Look each entry

1952      for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
1953        // ----- Get filedescr

1954        $v_descr = $p_filedescr_list[$i];
1955        
1956        // ----- Reduce the filename

1957        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'");

1958        $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
1959        $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
1960        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'");

1961        
1962        // ----- Get type of descr

1963        if (!file_exists($v_descr['filename'])) {
1964          // ----- Error log

1965          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists");

1966          PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists");
1967  
1968          // ----- Return

1969          //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

1970          return PclZip::errorCode();
1971        }
1972        if (@is_file($v_descr['filename'])) {
1973          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file");

1974          $v_descr['type'] = 'file';
1975        }
1976        else if (@is_dir($v_descr['filename'])) {
1977          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder");

1978          $v_descr['type'] = 'folder';
1979        }
1980        else if (@is_link($v_descr['filename'])) {
1981          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link");

1982          // skip

1983          continue;
1984        }
1985        else {
1986          //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type");

1987          // skip

1988          continue;
1989        }
1990        
1991        // ----- Calculate the stored filename

1992        $this->privCalculateStoredFilename($v_descr, $p_options);
1993        
1994        // ----- Add the descriptor in result list

1995        $v_result_list[sizeof($v_result_list)] = $v_descr;
1996        
1997        // ----- Look for folder

1998        if ($v_descr['type'] == 'folder') {
1999          // ----- List of items in folder

2000          $v_dirlist_descr = array();
2001          $v_dirlist_nb = 0;
2002          if ($v_folder_handler = @opendir($v_descr['filename'])) {
2003            while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2004              //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory");

2005  
2006              // ----- Skip '.' and '..'

2007              if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2008                  continue;
2009              }
2010              
2011              // ----- Compose the full filename

2012              $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2013              
2014              // ----- Look for different stored filename

2015              // Because the name of the folder was changed, the name of the

2016              // files/sub-folders also change

2017              if ($v_descr['stored_filename'] != $v_descr['filename']) {
2018                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2019              }
2020        
2021              $v_dirlist_nb++;
2022            }
2023          }
2024          else {
2025            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped.");

2026            // TBC : unable to open folder in read mode

2027          }
2028          
2029          // ----- Expand each element of the list

2030          if ($v_dirlist_nb != 0) {
2031            // ----- Expand

2032            if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2033              //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2034              return $v_result;
2035            }
2036            
2037            // ----- Concat the resulting list

2038            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')");

2039            $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2040            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'");

2041          }
2042          else {
2043            //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand.");

2044          }
2045            
2046          // ----- Free local array

2047          unset($v_dirlist_descr);
2048        }
2049      }
2050      
2051      // ----- Get the result list

2052      $p_filedescr_list = $v_result_list;
2053  
2054      // ----- Return

2055      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2056      return $v_result;
2057    }
2058    // --------------------------------------------------------------------------------

2059  
2060    // --------------------------------------------------------------------------------

2061    // Function : privCreate()

2062    // Description :

2063    // Parameters :

2064    // Return Values :

2065    // --------------------------------------------------------------------------------

2066    function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2067    {
2068      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list");

2069      $v_result=1;
2070      $v_list_detail = array();
2071      
2072      // ----- Magic quotes trick

2073      $this->privDisableMagicQuotes();
2074  
2075      // ----- Open the file in write mode

2076      if (($v_result = $this->privOpenFd('wb')) != 1)
2077      {
2078        // ----- Return

2079        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2080        return $v_result;
2081      }
2082  
2083      // ----- Add the list of files

2084      $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2085  
2086      // ----- Close

2087      $this->privCloseFd();
2088  
2089      // ----- Magic quotes trick

2090      $this->privSwapBackMagicQuotes();
2091  
2092      // ----- Return

2093      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2094      return $v_result;
2095    }
2096    // --------------------------------------------------------------------------------

2097  
2098    // --------------------------------------------------------------------------------

2099    // Function : privAdd()

2100    // Description :

2101    // Parameters :

2102    // Return Values :

2103    // --------------------------------------------------------------------------------

2104    function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2105    {
2106      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list");

2107      $v_result=1;
2108      $v_list_detail = array();
2109  
2110      // ----- Look if the archive exists or is empty

2111      if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2112      {
2113        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");

2114  
2115        // ----- Do a create

2116        $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2117  
2118        // ----- Return

2119        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2120        return $v_result;
2121      }
2122      // ----- Magic quotes trick

2123      $this->privDisableMagicQuotes();
2124  
2125      // ----- Open the zip file

2126      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");

2127      if (($v_result=$this->privOpenFd('rb')) != 1)
2128      {
2129        // ----- Magic quotes trick

2130        $this->privSwapBackMagicQuotes();
2131  
2132        // ----- Return

2133        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2134        return $v_result;
2135      }
2136  
2137      // ----- Read the central directory informations

2138      $v_central_dir = array();
2139      if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2140      {
2141        $this->privCloseFd();
2142        $this->privSwapBackMagicQuotes();
2143        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2144        return $v_result;
2145      }
2146  
2147      // ----- Go to beginning of File

2148      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");

2149      @rewind($this->zip_fd);
2150      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");

2151  
2152      // ----- Creates a temporay file

2153      $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2154  
2155      // ----- Open the temporary file in write mode

2156      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");

2157      if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2158      {
2159        $this->privCloseFd();
2160        $this->privSwapBackMagicQuotes();
2161  
2162        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2163  
2164        // ----- Return

2165        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

2166        return PclZip::errorCode();
2167      }
2168  
2169      // ----- Copy the files from the archive to the temporary file

2170      // TBC : Here I should better append the file and go back to erase the central dir

2171      $v_size = $v_central_dir['offset'];
2172      while ($v_size != 0)
2173      {
2174        $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2175        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");

2176        $v_buffer = fread($this->zip_fd, $v_read_size);
2177        @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2178        $v_size -= $v_read_size;
2179      }
2180  
2181      // ----- Swap the file descriptor

2182      // Here is a trick : I swap the temporary fd with the zip fd, in order to use

2183      // the following methods on the temporary fil and not the real archive

2184      $v_swap = $this->zip_fd;
2185      $this->zip_fd = $v_zip_temp_fd;
2186      $v_zip_temp_fd = $v_swap;
2187  
2188      // ----- Add the files

2189      $v_header_list = array();
2190      if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2191      {
2192        fclose($v_zip_temp_fd);
2193        $this->privCloseFd();
2194        @unlink($v_zip_temp_name);
2195        $this->privSwapBackMagicQuotes();
2196  
2197        // ----- Return

2198        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2199        return $v_result;
2200      }
2201  
2202      // ----- Store the offset of the central dir

2203      $v_offset = @ftell($this->zip_fd);
2204      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");

2205  
2206      // ----- Copy the block of file headers from the old archive

2207      $v_size = $v_central_dir['size'];
2208      while ($v_size != 0)
2209      {
2210        $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2211        //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");

2212        $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2213        @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2214        $v_size -= $v_read_size;
2215      }
2216  
2217      // ----- Create the Central Dir files header

2218      for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2219      {
2220        // ----- Create the file header

2221        if ($v_header_list[$i]['status'] == 'ok') {
2222          if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2223            fclose($v_zip_temp_fd);
2224            $this->privCloseFd();
2225            @unlink($v_zip_temp_name);
2226            $this->privSwapBackMagicQuotes();
2227  
2228            // ----- Return

2229            //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2230            return $v_result;
2231          }
2232          $v_count++;
2233        }
2234  
2235        // ----- Transform the header to a 'usable' info

2236        $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2237      }
2238  
2239      // ----- Zip file comment

2240      $v_comment = $v_central_dir['comment'];
2241      if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2242        $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2243      }
2244      if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2245        $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2246      }
2247      if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2248        $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2249      }
2250  
2251      // ----- Calculate the size of the central header

2252      $v_size = @ftell($this->zip_fd)-$v_offset;
2253  
2254      // ----- Create the central dir footer

2255      if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2256      {
2257        // ----- Reset the file list

2258        unset($v_header_list);
2259        $this->privSwapBackMagicQuotes();
2260  
2261        // ----- Return

2262        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2263        return $v_result;
2264      }
2265  
2266      // ----- Swap back the file descriptor

2267      $v_swap = $this->zip_fd;
2268      $this->zip_fd = $v_zip_temp_fd;
2269      $v_zip_temp_fd = $v_swap;
2270  
2271      // ----- Close

2272      $this->privCloseFd();
2273  
2274      // ----- Close the temporary file

2275      @fclose($v_zip_temp_fd);
2276  
2277      // ----- Magic quotes trick

2278      $this->privSwapBackMagicQuotes();
2279  
2280      // ----- Delete the zip file

2281      // TBC : I should test the result ...

2282      @unlink($this->zipname);
2283  
2284      // ----- Rename the temporary file

2285      // TBC : I should test the result ...

2286      //@rename($v_zip_temp_name, $this->zipname);

2287      PclZipUtilRename($v_zip_temp_name, $this->zipname);
2288  
2289      // ----- Return

2290      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2291      return $v_result;
2292    }
2293    // --------------------------------------------------------------------------------

2294  
2295    // --------------------------------------------------------------------------------

2296    // Function : privOpenFd()

2297    // Description :

2298    // Parameters :

2299    // --------------------------------------------------------------------------------

2300    function privOpenFd($p_mode)
2301    {
2302      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);

2303      $v_result=1;
2304  
2305      // ----- Look if already open

2306      if ($this->zip_fd != 0)
2307      {
2308        // ----- Error log

2309        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2310  
2311        // ----- Return

2312        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

2313        return PclZip::errorCode();
2314      }
2315  
2316      // ----- Open the zip file

2317      //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');

2318      if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2319      {
2320        // ----- Error log

2321        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2322  
2323        // ----- Return

2324        //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());

2325        return PclZip::errorCode();
2326      }
2327  
2328      // ----- Return

2329      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2330      return $v_result;
2331    }
2332    // --------------------------------------------------------------------------------

2333  
2334    // --------------------------------------------------------------------------------

2335    // Function : privCloseFd()

2336    // Description :

2337    // Parameters :

2338    // --------------------------------------------------------------------------------

2339    function privCloseFd()
2340    {
2341      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");

2342      $v_result=1;
2343  
2344      if ($this->zip_fd != 0)
2345        @fclose($this->zip_fd);
2346      $this->zip_fd = 0;
2347  
2348      // ----- Return

2349      //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);

2350      return $v_result;
2351    }
2352    // --------------------------------------------------------------------------------

2353  
2354    // --------------------------------------------------------------------------------

2355    // Function : privAddList()

2356    // Description :

2357    //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is

2358    //   different from the real path of the file. This is usefull if you want to have PclTar

2359    //   running in any directory, and memorize relative path from an other directory.

2360    // Parameters :

2361    //   $p_list : An array containing the file or directory names to add in the tar

2362    //   $p_result_list : list of added files with their properties (specially the status field)

2363    //   $p_add_dir : Path to add in the filename path archived

2364    //   $p_remove_dir : Path to remove in the filename path archived

2365    // Return Values :

2366    // --------------------------------------------------------------------------------

2367  //  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)

2368    function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2369    {
2370      //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list");

2371      $v_result=1;
2372  
2373      // ----- Add the files

2374      $v_header_list = array();
2375      if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)