Changeset 5089


Ignore:
Timestamp:
Mar 9, 2010, 12:39:53 AM (11 years ago)
Author:
plg
Message:

feature 1489: integrate UploadForm into Piwigo core. The integration is not
100% done, I just "made it work" on trunk.

pclzip library was updated to version 2.8.2 for memory usage improvement.

Location:
trunk
Files:
13 added
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/admin.php

    r5067 r5089  
    123123    'U_LOGOUT'=> PHPWG_ROOT_PATH.'index.php?act=logout',
    124124    'U_PLUGINS'=> $link_start.'plugins_list',
     125    'U_ADD_PHOTOS' => $link_start.'photos_add',
    125126    )
    126127  );
  • trunk/admin/include/pclzip.lib.php

    r3823 r5089  
    11<?php
    22// --------------------------------------------------------------------------------
    3 // PhpConcept Library - Zip Module 2.8.1
     3// PhpConcept Library - Zip Module 2.8.2
    44// --------------------------------------------------------------------------------
    55// License GNU/LGPL - Vincent Blavet - August 2009
     
    2323//
    2424// --------------------------------------------------------------------------------
    25 
    26 if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
    27   define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
    28 }
    29 
    30 if (!defined('PCLZIP_SEPARATOR')) {
    31   define( 'PCLZIP_SEPARATOR', ',' );
    32 }
    33 
    34 if (!defined('PCLZIP_ERROR_EXTERNAL')) {
    35   define( 'PCLZIP_ERROR_EXTERNAL', 0 );
    36 }
    37 
    38 if (!defined('PCLZIP_TEMPORARY_DIR')) {
    39   define( 'PCLZIP_TEMPORARY_DIR', '' );
    40 }
    41 
    42 if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
    43   define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
    44 }
    45 
    46 
    47 $g_pclzip_version = "2.8.1";
    48 
    49 define( 'PCLZIP_ERR_USER_ABORTED', 2 );
    50 define( 'PCLZIP_ERR_NO_ERROR', 0 );
    51 define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
    52 define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
    53 define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
    54 define( 'PCLZIP_ERR_MISSING_FILE', -4 );
    55 define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
    56 define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
    57 define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
    58 define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
    59 define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
    60 define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
    61 define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
    62 define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
    63 define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
    64 define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
    65 define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
    66 define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
    67 define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
    68 define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
    69 define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
    70 define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
    71 define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
    72 
    73 define( 'PCLZIP_OPT_PATH', 77001 );
    74 define( 'PCLZIP_OPT_ADD_PATH', 77002 );
    75 define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
    76 define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
    77 define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
    78 define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
    79 define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
    80 define( 'PCLZIP_OPT_BY_NAME', 77008 );
    81 define( 'PCLZIP_OPT_BY_INDEX', 77009 );
    82 define( 'PCLZIP_OPT_BY_EREG', 77010 );
    83 define( 'PCLZIP_OPT_BY_PREG', 77011 );
    84 define( 'PCLZIP_OPT_COMMENT', 77012 );
    85 define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
    86 define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
    87 define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
    88 define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
    89 define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
    90 define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
    91 define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
    92 define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
    93 define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
    94 
    95 define( 'PCLZIP_ATT_FILE_NAME', 79001 );
    96 define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
    97 define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
    98 define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
    99 define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
    100 define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
    101 
    102 define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
    103 define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
    104 define( 'PCLZIP_CB_PRE_ADD', 78003 );
    105 define( 'PCLZIP_CB_POST_ADD', 78004 );
    106 /* For futur use
    107 define( 'PCLZIP_CB_PRE_LIST', 78005 );
    108 define( 'PCLZIP_CB_POST_LIST', 78006 );
    109 define( 'PCLZIP_CB_PRE_DELETE', 78007 );
    110 define( 'PCLZIP_CB_POST_DELETE', 78008 );
    111 */
    112 
    113 class PclZip
    114 {
    115   var $zipname = '';
    116 
    117   var $zip_fd = 0;
    118 
    119   var $error_code = 1;
    120   var $error_string = '';
     25// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
     26// --------------------------------------------------------------------------------
     27
     28  // ----- Constants
     29  if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
     30    define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
     31  }
    12132 
    122   var $magic_quotes_status;
    123 
    124 function PclZip($p_zipname)
    125 {
    126 
    127   if (!function_exists('gzopen'))
     33  // ----- File list separator
     34  // In version 1.x of PclZip, the separator for file list is a space
     35  // (which is not a very smart choice, specifically for windows paths !).
     36  // A better separator should be a comma (,). This constant gives you the
     37  // abilty to change that.
     38  // However notice that changing this value, may have impact on existing
     39  // scripts, using space separated filenames.
     40  // Recommanded values for compatibility with older versions :
     41  //define( 'PCLZIP_SEPARATOR', ' ' );
     42  // Recommanded values for smart separation of filenames.
     43  if (!defined('PCLZIP_SEPARATOR')) {
     44    define( 'PCLZIP_SEPARATOR', ',' );
     45  }
     46
     47  // ----- Error configuration
     48  // 0 : PclZip Class integrated error handling
     49  // 1 : PclError external library error handling. By enabling this
     50  //     you must ensure that you have included PclError library.
     51  // [2,...] : reserved for futur use
     52  if (!defined('PCLZIP_ERROR_EXTERNAL')) {
     53    define( 'PCLZIP_ERROR_EXTERNAL', 0 );
     54  }
     55
     56  // ----- Optional static temporary directory
     57  //       By default temporary files are generated in the script current
     58  //       path.
     59  //       If defined :
     60  //       - MUST BE terminated by a '/'.
     61  //       - MUST be a valid, already created directory
     62  //       Samples :
     63  // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
     64  // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
     65  if (!defined('PCLZIP_TEMPORARY_DIR')) {
     66    define( 'PCLZIP_TEMPORARY_DIR', '' );
     67  }
     68
     69  // ----- Optional threshold ratio for use of temporary files
     70  //       Pclzip sense the size of the file to add/extract and decide to
     71  //       use or not temporary file. The algorythm is looking for
     72  //       memory_limit of PHP and apply a ratio.
     73  //       threshold = memory_limit * ratio.
     74  //       Recommended values are under 0.5. Default 0.47.
     75  //       Samples :
     76  // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
     77  if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
     78    define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
     79  }
     80
     81// --------------------------------------------------------------------------------
     82// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
     83// --------------------------------------------------------------------------------
     84
     85  // ----- Global variables
     86  $g_pclzip_version = "2.8.2";
     87
     88  // ----- Error codes
     89  //   -1 : Unable to open file in binary write mode
     90  //   -2 : Unable to open file in binary read mode
     91  //   -3 : Invalid parameters
     92  //   -4 : File does not exist
     93  //   -5 : Filename is too long (max. 255)
     94  //   -6 : Not a valid zip file
     95  //   -7 : Invalid extracted file size
     96  //   -8 : Unable to create directory
     97  //   -9 : Invalid archive extension
     98  //  -10 : Invalid archive format
     99  //  -11 : Unable to delete file (unlink)
     100  //  -12 : Unable to rename file (rename)
     101  //  -13 : Invalid header checksum
     102  //  -14 : Invalid archive size
     103  define( 'PCLZIP_ERR_USER_ABORTED', 2 );
     104  define( 'PCLZIP_ERR_NO_ERROR', 0 );
     105  define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
     106  define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
     107  define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
     108  define( 'PCLZIP_ERR_MISSING_FILE', -4 );
     109  define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
     110  define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
     111  define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
     112  define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
     113  define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
     114  define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
     115  define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
     116  define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
     117  define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
     118  define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
     119  define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
     120  define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
     121  define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
     122  define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
     123  define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
     124  define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
     125  define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
     126
     127  // ----- Options values
     128  define( 'PCLZIP_OPT_PATH', 77001 );
     129  define( 'PCLZIP_OPT_ADD_PATH', 77002 );
     130  define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
     131  define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
     132  define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
     133  define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
     134  define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
     135  define( 'PCLZIP_OPT_BY_NAME', 77008 );
     136  define( 'PCLZIP_OPT_BY_INDEX', 77009 );
     137  define( 'PCLZIP_OPT_BY_EREG', 77010 );
     138  define( 'PCLZIP_OPT_BY_PREG', 77011 );
     139  define( 'PCLZIP_OPT_COMMENT', 77012 );
     140  define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
     141  define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
     142  define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
     143  define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
     144  define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
     145  // Having big trouble with crypt. Need to multiply 2 long int
     146  // which is not correctly supported by PHP ...
     147  //define( 'PCLZIP_OPT_CRYPT', 77018 );
     148  define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
     149  define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
     150  define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
     151  define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
     152  define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
     153  define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
     154  define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
     155 
     156  // ----- File description attributes
     157  define( 'PCLZIP_ATT_FILE_NAME', 79001 );
     158  define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
     159  define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
     160  define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
     161  define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
     162  define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
     163
     164  // ----- Call backs values
     165  define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
     166  define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
     167  define( 'PCLZIP_CB_PRE_ADD', 78003 );
     168  define( 'PCLZIP_CB_POST_ADD', 78004 );
     169  /* For futur use
     170  define( 'PCLZIP_CB_PRE_LIST', 78005 );
     171  define( 'PCLZIP_CB_POST_LIST', 78006 );
     172  define( 'PCLZIP_CB_PRE_DELETE', 78007 );
     173  define( 'PCLZIP_CB_POST_DELETE', 78008 );
     174  */
     175
     176  // --------------------------------------------------------------------------------
     177  // Class : PclZip
     178  // Description :
     179  //   PclZip is the class that represent a Zip archive.
     180  //   The public methods allow the manipulation of the archive.
     181  // Attributes :
     182  //   Attributes must not be accessed directly.
     183  // Methods :
     184  //   PclZip() : Object creator
     185  //   create() : Creates the Zip archive
     186  //   listContent() : List the content of the Zip archive
     187  //   extract() : Extract the content of the archive
     188  //   properties() : List the properties of the archive
     189  // --------------------------------------------------------------------------------
     190  class PclZip
    128191  {
    129     die('Abort '.basename(__FILE__).' : Missing zlib extensions');
    130   }
    131 
    132   $this->zipname = $p_zipname;
    133   $this->zip_fd = 0;
    134   $this->magic_quotes_status = -1;
    135 
    136   return;
    137 }
    138 
    139 function create($p_filelist)
    140 {
    141   $v_result=1;
    142 
    143   $this->privErrorReset();
    144 
    145   $v_options = array();
    146   $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
    147 
    148   $v_size = func_num_args();
    149 
    150   if ($v_size > 1) {
    151     $v_arg_list = func_get_args();
    152 
    153     array_shift($v_arg_list);
    154     $v_size--;
    155 
    156     if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
    157 
    158       $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
    159                                           array (PCLZIP_OPT_REMOVE_PATH => 'optional',
    160                                                  PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
    161                                                  PCLZIP_OPT_ADD_PATH => 'optional',
    162                                                  PCLZIP_CB_PRE_ADD => 'optional',
    163                                                  PCLZIP_CB_POST_ADD => 'optional',
    164                                                  PCLZIP_OPT_NO_COMPRESSION => 'optional',
    165                                                  PCLZIP_OPT_COMMENT => 'optional',
    166                                                  PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
    167                                                  PCLZIP_OPT_TEMP_FILE_ON => 'optional',
    168                                                  PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
    169                                            ));
     192    // ----- Filename of the zip file
     193    var $zipname = '';
     194
     195    // ----- File descriptor of the zip file
     196    var $zip_fd = 0;
     197
     198    // ----- Internal error handling
     199    var $error_code = 1;
     200    var $error_string = '';
     201   
     202    // ----- Current status of the magic_quotes_runtime
     203    // This value store the php configuration for magic_quotes
     204    // The class can then disable the magic_quotes and reset it after
     205    var $magic_quotes_status;
     206
     207  // --------------------------------------------------------------------------------
     208  // Function : PclZip()
     209  // Description :
     210  //   Creates a PclZip object and set the name of the associated Zip archive
     211  //   filename.
     212  //   Note that no real action is taken, if the archive does not exist it is not
     213  //   created. Use create() for that.
     214  // --------------------------------------------------------------------------------
     215  function PclZip($p_zipname)
     216  {
     217
     218    // ----- Tests the zlib
     219    if (!function_exists('gzopen'))
     220    {
     221      die('Abort '.basename(__FILE__).' : Missing zlib extensions');
     222    }
     223
     224    // ----- Set the attributes
     225    $this->zipname = $p_zipname;
     226    $this->zip_fd = 0;
     227    $this->magic_quotes_status = -1;
     228
     229    // ----- Return
     230    return;
     231  }
     232  // --------------------------------------------------------------------------------
     233
     234  // --------------------------------------------------------------------------------
     235  // Function :
     236  //   create($p_filelist, $p_add_dir="", $p_remove_dir="")
     237  //   create($p_filelist, $p_option, $p_option_value, ...)
     238  // Description :
     239  //   This method supports two different synopsis. The first one is historical.
     240  //   This method creates a Zip Archive. The Zip file is created in the
     241  //   filesystem. The files and directories indicated in $p_filelist
     242  //   are added in the archive. See the parameters description for the
     243  //   supported format of $p_filelist.
     244  //   When a directory is in the list, the directory and its content is added
     245  //   in the archive.
     246  //   In this synopsis, the function takes an optional variable list of
     247  //   options. See bellow the supported options.
     248  // Parameters :
     249  //   $p_filelist : An array containing file or directory names, or
     250  //                 a string containing one filename or one directory name, or
     251  //                 a string containing a list of filenames and/or directory
     252  //                 names separated by spaces.
     253  //   $p_add_dir : A path to add before the real path of the archived file,
     254  //                in order to have it memorized in the archive.
     255  //   $p_remove_dir : A path to remove from the real path of the file to archive,
     256  //                   in order to have a shorter path memorized in the archive.
     257  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
     258  //                   is removed first, before $p_add_dir is added.
     259  // Options :
     260  //   PCLZIP_OPT_ADD_PATH :
     261  //   PCLZIP_OPT_REMOVE_PATH :
     262  //   PCLZIP_OPT_REMOVE_ALL_PATH :
     263  //   PCLZIP_OPT_COMMENT :
     264  //   PCLZIP_CB_PRE_ADD :
     265  //   PCLZIP_CB_POST_ADD :
     266  // Return Values :
     267  //   0 on failure,
     268  //   The list of the added files, with a status of the add action.
     269  //   (see PclZip::listContent() for list entry format)
     270  // --------------------------------------------------------------------------------
     271  function create($p_filelist)
     272  {
     273    $v_result=1;
     274
     275    // ----- Reset the error handler
     276    $this->privErrorReset();
     277
     278    // ----- Set default values
     279    $v_options = array();
     280    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
     281
     282    // ----- Look for variable options arguments
     283    $v_size = func_num_args();
     284
     285    // ----- Look for arguments
     286    if ($v_size > 1) {
     287      // ----- Get the arguments
     288      $v_arg_list = func_get_args();
     289
     290      // ----- Remove from the options list the first argument
     291      array_shift($v_arg_list);
     292      $v_size--;
     293
     294      // ----- Look for first arg
     295      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
     296
     297        // ----- Parse the options
     298        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
     299                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
     300                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
     301                                                   PCLZIP_OPT_ADD_PATH => 'optional',
     302                                                   PCLZIP_CB_PRE_ADD => 'optional',
     303                                                   PCLZIP_CB_POST_ADD => 'optional',
     304                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
     305                                                   PCLZIP_OPT_COMMENT => 'optional',
     306                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
     307                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
     308                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
     309                                                   //, PCLZIP_OPT_CRYPT => 'optional'
     310                                             ));
     311        if ($v_result != 1) {
     312          return 0;
     313        }
     314      }
     315
     316      // ----- Look for 2 args
     317      // Here we need to support the first historic synopsis of the
     318      // method.
     319      else {
     320
     321        // ----- Get the first argument
     322        $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
     323
     324        // ----- Look for the optional second argument
     325        if ($v_size == 2) {
     326          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
     327        }
     328        else if ($v_size > 2) {
     329          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
     330                                       "Invalid number / type of arguments");
     331          return 0;
     332        }
     333      }
     334    }
     335   
     336    // ----- Look for default option values
     337    $this->privOptionDefaultThreshold($v_options);
     338
     339    // ----- Init
     340    $v_string_list = array();
     341    $v_att_list = array();
     342    $v_filedescr_list = array();
     343    $p_result_list = array();
     344   
     345    // ----- Look if the $p_filelist is really an array
     346    if (is_array($p_filelist)) {
     347   
     348      // ----- Look if the first element is also an array
     349      //       This will mean that this is a file description entry
     350      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
     351        $v_att_list = $p_filelist;
     352      }
     353     
     354      // ----- The list is a list of string names
     355      else {
     356        $v_string_list = $p_filelist;
     357      }
     358    }
     359
     360    // ----- Look if the $p_filelist is a string
     361    else if (is_string($p_filelist)) {
     362      // ----- Create a list from the string
     363      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
     364    }
     365
     366    // ----- Invalid variable type for $p_filelist
     367    else {
     368      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
     369      return 0;
     370    }
     371   
     372    // ----- Reformat the string list
     373    if (sizeof($v_string_list) != 0) {
     374      foreach ($v_string_list as $v_string) {
     375        if ($v_string != '') {
     376          $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
     377        }
     378        else {
     379        }
     380      }
     381    }
     382   
     383    // ----- For each file in the list check the attributes
     384    $v_supported_attributes
     385    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
     386             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
     387             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
     388             ,PCLZIP_ATT_FILE_MTIME => 'optional'
     389             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
     390             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
     391                                                );
     392    foreach ($v_att_list as $v_entry) {
     393      $v_result = $this->privFileDescrParseAtt($v_entry,
     394                                               $v_filedescr_list[],
     395                                               $v_options,
     396                                               $v_supported_attributes);
    170397      if ($v_result != 1) {
    171398        return 0;
     
    173400    }
    174401
    175     else {
    176 
    177       $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
    178 
    179       if ($v_size == 2) {
    180         $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
    181       }
    182       else if ($v_size > 2) {
    183         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
    184                          "Invalid number / type of arguments");
    185         return 0;
    186       }
    187     }
    188   }
    189  
    190   $this->privOptionDefaultThreshold($v_options);
    191 
    192   $v_string_list = array();
    193   $v_att_list = array();
    194   $v_filedescr_list = array();
    195   $p_result_list = array();
    196  
    197   if (is_array($p_filelist)) {
    198  
    199     if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
    200       $v_att_list = $p_filelist;
    201     }
    202    
    203     else {
    204       $v_string_list = $p_filelist;
    205     }
    206   }
    207 
    208   else if (is_string($p_filelist)) {
    209     $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
    210   }
    211 
    212   else {
    213     PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
    214     return 0;
    215   }
    216  
    217   if (sizeof($v_string_list) != 0) {
    218     foreach ($v_string_list as $v_string) {
    219       if ($v_string != '') {
    220         $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
    221       }
    222       else {
    223       }
    224     }
    225   }
    226  
    227   $v_supported_attributes
    228   = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
    229            ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
    230            ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
    231            ,PCLZIP_ATT_FILE_MTIME => 'optional'
    232            ,PCLZIP_ATT_FILE_CONTENT => 'optional'
    233            ,PCLZIP_ATT_FILE_COMMENT => 'optional'
    234           );
    235   foreach ($v_att_list as $v_entry) {
    236     $v_result = $this->privFileDescrParseAtt($v_entry,
    237                                              $v_filedescr_list[],
    238                                              $v_options,
    239                                              $v_supported_attributes);
     402    // ----- Expand the filelist (expand directories)
     403    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
    240404    if ($v_result != 1) {
    241405      return 0;
    242406    }
    243   }
    244 
    245   $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
    246   if ($v_result != 1) {
    247     return 0;
    248   }
    249 
    250   $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
    251   if ($v_result != 1) {
    252     return 0;
    253   }
    254 
    255   return $p_result_list;
    256 }
    257 
    258 function add($p_filelist)
    259 {
    260   $v_result=1;
    261 
    262   $this->privErrorReset();
    263 
    264   $v_options = array();
    265   $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
    266 
    267   $v_size = func_num_args();
    268 
    269   if ($v_size > 1) {
    270     $v_arg_list = func_get_args();
    271 
    272     array_shift($v_arg_list);
    273     $v_size--;
    274 
    275     if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
    276 
    277       $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
    278                                           array (PCLZIP_OPT_REMOVE_PATH => 'optional',
    279                                                  PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
    280                                                  PCLZIP_OPT_ADD_PATH => 'optional',
    281                                                  PCLZIP_CB_PRE_ADD => 'optional',
    282                                                  PCLZIP_CB_POST_ADD => 'optional',
    283                                                  PCLZIP_OPT_NO_COMPRESSION => 'optional',
    284                                                  PCLZIP_OPT_COMMENT => 'optional',
    285                                                  PCLZIP_OPT_ADD_COMMENT => 'optional',
    286                                                  PCLZIP_OPT_PREPEND_COMMENT => 'optional',
    287                                                  PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
    288                                                  PCLZIP_OPT_TEMP_FILE_ON => 'optional',
    289                                                  PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
    290                          ));
     407
     408    // ----- Call the create fct
     409    $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
     410    if ($v_result != 1) {
     411      return 0;
     412    }
     413
     414    // ----- Return
     415    return $p_result_list;
     416  }
     417  // --------------------------------------------------------------------------------
     418
     419  // --------------------------------------------------------------------------------
     420  // Function :
     421  //   add($p_filelist, $p_add_dir="", $p_remove_dir="")
     422  //   add($p_filelist, $p_option, $p_option_value, ...)
     423  // Description :
     424  //   This method supports two synopsis. The first one is historical.
     425  //   This methods add the list of files in an existing archive.
     426  //   If a file with the same name already exists, it is added at the end of the
     427  //   archive, the first one is still present.
     428  //   If the archive does not exist, it is created.
     429  // Parameters :
     430  //   $p_filelist : An array containing file or directory names, or
     431  //                 a string containing one filename or one directory name, or
     432  //                 a string containing a list of filenames and/or directory
     433  //                 names separated by spaces.
     434  //   $p_add_dir : A path to add before the real path of the archived file,
     435  //                in order to have it memorized in the archive.
     436  //   $p_remove_dir : A path to remove from the real path of the file to archive,
     437  //                   in order to have a shorter path memorized in the archive.
     438  //                   When $p_add_dir and $p_remove_dir are set, $p_remove_dir
     439  //                   is removed first, before $p_add_dir is added.
     440  // Options :
     441  //   PCLZIP_OPT_ADD_PATH :
     442  //   PCLZIP_OPT_REMOVE_PATH :
     443  //   PCLZIP_OPT_REMOVE_ALL_PATH :
     444  //   PCLZIP_OPT_COMMENT :
     445  //   PCLZIP_OPT_ADD_COMMENT :
     446  //   PCLZIP_OPT_PREPEND_COMMENT :
     447  //   PCLZIP_CB_PRE_ADD :
     448  //   PCLZIP_CB_POST_ADD :
     449  // Return Values :
     450  //   0 on failure,
     451  //   The list of the added files, with a status of the add action.
     452  //   (see PclZip::listContent() for list entry format)
     453  // --------------------------------------------------------------------------------
     454  function add($p_filelist)
     455  {
     456    $v_result=1;
     457
     458    // ----- Reset the error handler
     459    $this->privErrorReset();
     460
     461    // ----- Set default values
     462    $v_options = array();
     463    $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
     464
     465    // ----- Look for variable options arguments
     466    $v_size = func_num_args();
     467
     468    // ----- Look for arguments
     469    if ($v_size > 1) {
     470      // ----- Get the arguments
     471      $v_arg_list = func_get_args();
     472
     473      // ----- Remove form the options list the first argument
     474      array_shift($v_arg_list);
     475      $v_size--;
     476
     477      // ----- Look for first arg
     478      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
     479
     480        // ----- Parse the options
     481        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
     482                                            array (PCLZIP_OPT_REMOVE_PATH => 'optional',
     483                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
     484                                                   PCLZIP_OPT_ADD_PATH => 'optional',
     485                                                   PCLZIP_CB_PRE_ADD => 'optional',
     486                                                   PCLZIP_CB_POST_ADD => 'optional',
     487                                                   PCLZIP_OPT_NO_COMPRESSION => 'optional',
     488                                                   PCLZIP_OPT_COMMENT => 'optional',
     489                                                   PCLZIP_OPT_ADD_COMMENT => 'optional',
     490                                                   PCLZIP_OPT_PREPEND_COMMENT => 'optional',
     491                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
     492                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
     493                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
     494                                                   //, PCLZIP_OPT_CRYPT => 'optional'
     495                                                                                                   ));
     496        if ($v_result != 1) {
     497          return 0;
     498        }
     499      }
     500
     501      // ----- Look for 2 args
     502      // Here we need to support the first historic synopsis of the
     503      // method.
     504      else {
     505
     506        // ----- Get the first argument
     507        $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
     508
     509        // ----- Look for the optional second argument
     510        if ($v_size == 2) {
     511          $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
     512        }
     513        else if ($v_size > 2) {
     514          // ----- Error log
     515          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
     516
     517          // ----- Return
     518          return 0;
     519        }
     520      }
     521    }
     522
     523    // ----- Look for default option values
     524    $this->privOptionDefaultThreshold($v_options);
     525
     526    // ----- Init
     527    $v_string_list = array();
     528    $v_att_list = array();
     529    $v_filedescr_list = array();
     530    $p_result_list = array();
     531   
     532    // ----- Look if the $p_filelist is really an array
     533    if (is_array($p_filelist)) {
     534   
     535      // ----- Look if the first element is also an array
     536      //       This will mean that this is a file description entry
     537      if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
     538        $v_att_list = $p_filelist;
     539      }
     540     
     541      // ----- The list is a list of string names
     542      else {
     543        $v_string_list = $p_filelist;
     544      }
     545    }
     546
     547    // ----- Look if the $p_filelist is a string
     548    else if (is_string($p_filelist)) {
     549      // ----- Create a list from the string
     550      $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
     551    }
     552
     553    // ----- Invalid variable type for $p_filelist
     554    else {
     555      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
     556      return 0;
     557    }
     558   
     559    // ----- Reformat the string list
     560    if (sizeof($v_string_list) != 0) {
     561      foreach ($v_string_list as $v_string) {
     562        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
     563      }
     564    }
     565   
     566    // ----- For each file in the list check the attributes
     567    $v_supported_attributes
     568    = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
     569             ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
     570             ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
     571             ,PCLZIP_ATT_FILE_MTIME => 'optional'
     572             ,PCLZIP_ATT_FILE_CONTENT => 'optional'
     573             ,PCLZIP_ATT_FILE_COMMENT => 'optional'
     574                                                );
     575    foreach ($v_att_list as $v_entry) {
     576      $v_result = $this->privFileDescrParseAtt($v_entry,
     577                                               $v_filedescr_list[],
     578                                               $v_options,
     579                                               $v_supported_attributes);
    291580      if ($v_result != 1) {
    292581        return 0;
     
    294583    }
    295584
    296     else {
    297 
    298       $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
    299 
    300       if ($v_size == 2) {
    301         $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
    302       }
    303       else if ($v_size > 2) {
    304         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
    305 
    306         return 0;
    307       }
    308     }
    309   }
    310 
    311   $this->privOptionDefaultThreshold($v_options);
    312 
    313   $v_string_list = array();
    314   $v_att_list = array();
    315   $v_filedescr_list = array();
    316   $p_result_list = array();
    317  
    318   if (is_array($p_filelist)) {
    319  
    320     if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
    321       $v_att_list = $p_filelist;
    322     }
    323    
    324     else {
    325       $v_string_list = $p_filelist;
    326     }
    327   }
    328 
    329   else if (is_string($p_filelist)) {
    330     $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
    331   }
    332 
    333   else {
    334     PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
    335     return 0;
    336   }
    337  
    338   if (sizeof($v_string_list) != 0) {
    339     foreach ($v_string_list as $v_string) {
    340       $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
    341     }
    342   }
    343  
    344   $v_supported_attributes
    345   = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
    346            ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
    347            ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
    348            ,PCLZIP_ATT_FILE_MTIME => 'optional'
    349            ,PCLZIP_ATT_FILE_CONTENT => 'optional'
    350            ,PCLZIP_ATT_FILE_COMMENT => 'optional'
    351           );
    352   foreach ($v_att_list as $v_entry) {
    353     $v_result = $this->privFileDescrParseAtt($v_entry,
    354                                              $v_filedescr_list[],
    355                                              $v_options,
    356                                              $v_supported_attributes);
     585    // ----- Expand the filelist (expand directories)
     586    $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
    357587    if ($v_result != 1) {
    358588      return 0;
    359589    }
    360   }
    361 
    362   $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
    363   if ($v_result != 1) {
    364     return 0;
    365   }
    366 
    367   $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
    368   if ($v_result != 1) {
    369     return 0;
    370   }
    371 
    372   return $p_result_list;
    373 }
    374 
    375 function listContent()
    376 {
    377   $v_result=1;
    378 
    379   $this->privErrorReset();
    380 
    381   if (!$this->privCheckFormat()) {
    382     return(0);
    383   }
    384 
    385   $p_list = array();
    386   if (($v_result = $this->privList($p_list)) != 1)
     590
     591    // ----- Call the create fct
     592    $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
     593    if ($v_result != 1) {
     594      return 0;
     595    }
     596
     597    // ----- Return
     598    return $p_result_list;
     599  }
     600  // --------------------------------------------------------------------------------
     601
     602  // --------------------------------------------------------------------------------
     603  // Function : listContent()
     604  // Description :
     605  //   This public method, gives the list of the files and directories, with their
     606  //   properties.
     607  //   The properties of each entries in the list are (used also in other functions) :
     608  //     filename : Name of the file. For a create or add action it is the filename
     609  //                given by the user. For an extract function it is the filename
     610  //                of the extracted file.
     611  //     stored_filename : Name of the file / directory stored in the archive.
     612  //     size : Size of the stored file.
     613  //     compressed_size : Size of the file's data compressed in the archive
     614  //                       (without the headers overhead)
     615  //     mtime : Last known modification date of the file (UNIX timestamp)
     616  //     comment : Comment associated with the file
     617  //     folder : true | false
     618  //     index : index of the file in the archive
     619  //     status : status of the action (depending of the action) :
     620  //              Values are :
     621  //                ok : OK !
     622  //                filtered : the file / dir is not extracted (filtered by user)
     623  //                already_a_directory : the file can not be extracted because a
     624  //                                      directory with the same name already exists
     625  //                write_protected : the file can not be extracted because a file
     626  //                                  with the same name already exists and is
     627  //                                  write protected
     628  //                newer_exist : the file was not extracted because a newer file exists
     629  //                path_creation_fail : the file is not extracted because the folder
     630  //                                     does not exist and can not be created
     631  //                write_error : the file was not extracted because there was a
     632  //                              error while writing the file
     633  //                read_error : the file was not extracted because there was a error
     634  //                             while reading the file
     635  //                invalid_header : the file was not extracted because of an archive
     636  //                                 format error (bad file header)
     637  //   Note that each time a method can continue operating when there
     638  //   is an action error on a file, the error is only logged in the file status.
     639  // Return Values :
     640  //   0 on an unrecoverable failure,
     641  //   The list of the files in the archive.
     642  // --------------------------------------------------------------------------------
     643  function listContent()
    387644  {
    388     unset($p_list);
    389     return(0);
    390   }
    391 
    392   return $p_list;
    393 }
    394 
    395 function extract()
    396 {
    397   $v_result=1;
    398 
    399   $this->privErrorReset();
    400 
    401   if (!$this->privCheckFormat()) {
    402     return(0);
    403   }
    404 
    405   $v_options = array();
    406   $v_path = '';
    407   $v_remove_path = "";
    408   $v_remove_all_path = false;
    409 
    410   $v_size = func_num_args();
    411 
    412   $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
    413 
    414   if ($v_size > 0) {
    415     $v_arg_list = func_get_args();
    416 
    417     if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
    418 
    419       $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
    420                                           array (PCLZIP_OPT_PATH => 'optional',
    421                                                  PCLZIP_OPT_REMOVE_PATH => 'optional',
    422                                                  PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
    423                                                  PCLZIP_OPT_ADD_PATH => 'optional',
    424                                                  PCLZIP_CB_PRE_EXTRACT => 'optional',
    425                                                  PCLZIP_CB_POST_EXTRACT => 'optional',
    426                                                  PCLZIP_OPT_SET_CHMOD => 'optional',
    427                                                  PCLZIP_OPT_BY_NAME => 'optional',
    428                                                  PCLZIP_OPT_BY_EREG => 'optional',
    429                                                  PCLZIP_OPT_BY_PREG => 'optional',
    430                                                  PCLZIP_OPT_BY_INDEX => 'optional',
    431                                                  PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
    432                                                  PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
    433                                                  PCLZIP_OPT_REPLACE_NEWER => 'optional'
    434                                                  ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
    435                                                  ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
    436                                                  PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
    437                                                  PCLZIP_OPT_TEMP_FILE_ON => 'optional',
    438                                                  PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
    439                           ));
    440       if ($v_result != 1) {
    441         return 0;
    442       }
    443 
    444       if (isset($v_options[PCLZIP_OPT_PATH])) {
    445         $v_path = $v_options[PCLZIP_OPT_PATH];
    446       }
    447       if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
    448         $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
    449       }
    450       if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
    451         $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
    452       }
    453       if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
    454         if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
    455           $v_path .= '/';
    456         }
    457         $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
    458       }
    459     }
    460 
    461     else {
    462 
    463       $v_path = $v_arg_list[0];
    464 
    465       if ($v_size == 2) {
    466         $v_remove_path = $v_arg_list[1];
    467       }
    468       else if ($v_size > 2) {
    469         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
    470 
    471         return 0;
    472       }
    473     }
    474   }
    475 
    476   $this->privOptionDefaultThreshold($v_options);
    477 
    478 
    479   $p_list = array();
    480   $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
    481                                      $v_remove_all_path, $v_options);
    482   if ($v_result < 1) {
    483     unset($p_list);
    484     return(0);
    485   }
    486 
    487   return $p_list;
    488 }
    489 
    490 
    491 function extractByIndex($p_index)
    492 {
    493   $v_result=1;
    494 
    495   $this->privErrorReset();
    496 
    497   if (!$this->privCheckFormat()) {
    498     return(0);
    499   }
    500 
    501   $v_options = array();
    502   $v_path = '';
    503   $v_remove_path = "";
    504   $v_remove_all_path = false;
    505 
    506   $v_size = func_num_args();
    507 
    508   $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
    509 
    510   if ($v_size > 1) {
    511     $v_arg_list = func_get_args();
    512 
    513     array_shift($v_arg_list);
    514     $v_size--;
    515 
    516     if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
    517 
    518       $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
    519                                           array (PCLZIP_OPT_PATH => 'optional',
    520                                                  PCLZIP_OPT_REMOVE_PATH => 'optional',
    521                                                  PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
    522                                                  PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
    523                                                  PCLZIP_OPT_ADD_PATH => 'optional',
    524                                                  PCLZIP_CB_PRE_EXTRACT => 'optional',
    525                                                  PCLZIP_CB_POST_EXTRACT => 'optional',
    526                                                  PCLZIP_OPT_SET_CHMOD => 'optional',
    527                                                  PCLZIP_OPT_REPLACE_NEWER => 'optional'
    528                                                  ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
    529                                                  ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
    530                                                  PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
    531                                                  PCLZIP_OPT_TEMP_FILE_ON => 'optional',
    532                                                  PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
    533                          ));
    534       if ($v_result != 1) {
    535         return 0;
    536       }
    537 
    538       if (isset($v_options[PCLZIP_OPT_PATH])) {
    539         $v_path = $v_options[PCLZIP_OPT_PATH];
    540       }
    541       if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
    542         $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
    543       }
    544       if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
    545         $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
    546       }
    547       if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
    548         if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
    549           $v_path .= '/';
    550         }
    551         $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
    552       }
    553       if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
    554         $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
    555       }
     645    $v_result=1;
     646
     647    // ----- Reset the error handler
     648    $this->privErrorReset();
     649
     650    // ----- Check archive
     651    if (!$this->privCheckFormat()) {
     652      return(0);
     653    }
     654
     655    // ----- Call the extracting fct
     656    $p_list = array();
     657    if (($v_result = $this->privList($p_list)) != 1)
     658    {
     659      unset($p_list);
     660      return(0);
     661    }
     662
     663    // ----- Return
     664    return $p_list;
     665  }
     666  // --------------------------------------------------------------------------------
     667
     668  // --------------------------------------------------------------------------------
     669  // Function :
     670  //   extract($p_path="./", $p_remove_path="")
     671  //   extract([$p_option, $p_option_value, ...])
     672  // Description :
     673  //   This method supports two synopsis. The first one is historical.
     674  //   This method extract all the files / directories from the archive to the
     675  //   folder indicated in $p_path.
     676  //   If you want to ignore the 'root' part of path of the memorized files
     677  //   you can indicate this in the optional $p_remove_path parameter.
     678  //   By default, if a newer file with the same name already exists, the
     679  //   file is not extracted.
     680  //
     681  //   If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
     682  //   are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
     683  //   at the end of the path value of PCLZIP_OPT_PATH.
     684  // Parameters :
     685  //   $p_path : Path where the files and directories are to be extracted
     686  //   $p_remove_path : First part ('root' part) of the memorized path
     687  //                    (if any similar) to remove while extracting.
     688  // Options :
     689  //   PCLZIP_OPT_PATH :
     690  //   PCLZIP_OPT_ADD_PATH :
     691  //   PCLZIP_OPT_REMOVE_PATH :
     692  //   PCLZIP_OPT_REMOVE_ALL_PATH :
     693  //   PCLZIP_CB_PRE_EXTRACT :
     694  //   PCLZIP_CB_POST_EXTRACT :
     695  // Return Values :
     696  //   0 or a negative value on failure,
     697  //   The list of the extracted files, with a status of the action.
     698  //   (see PclZip::listContent() for list entry format)
     699  // --------------------------------------------------------------------------------
     700  function extract()
     701  {
     702    $v_result=1;
     703
     704    // ----- Reset the error handler
     705    $this->privErrorReset();
     706
     707    // ----- Check archive
     708    if (!$this->privCheckFormat()) {
     709      return(0);
     710    }
     711
     712    // ----- Set default values
     713    $v_options = array();
     714//    $v_path = "./";
     715    $v_path = '';
     716    $v_remove_path = "";
     717    $v_remove_all_path = false;
     718
     719    // ----- Look for variable options arguments
     720    $v_size = func_num_args();
     721
     722    // ----- Default values for option
     723    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
     724
     725    // ----- Look for arguments
     726    if ($v_size > 0) {
     727      // ----- Get the arguments
     728      $v_arg_list = func_get_args();
     729
     730      // ----- Look for first arg
     731      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
     732
     733        // ----- Parse the options
     734        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
     735                                            array (PCLZIP_OPT_PATH => 'optional',
     736                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
     737                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
     738                                                   PCLZIP_OPT_ADD_PATH => 'optional',
     739                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
     740                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
     741                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
     742                                                   PCLZIP_OPT_BY_NAME => 'optional',
     743                                                   PCLZIP_OPT_BY_EREG => 'optional',
     744                                                   PCLZIP_OPT_BY_PREG => 'optional',
     745                                                   PCLZIP_OPT_BY_INDEX => 'optional',
     746                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
     747                                                   PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
     748                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
     749                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
     750                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
     751                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
     752                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
     753                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
     754                                                                                                    ));
     755        if ($v_result != 1) {
     756          return 0;
     757        }
     758
     759        // ----- Set the arguments
     760        if (isset($v_options[PCLZIP_OPT_PATH])) {
     761          $v_path = $v_options[PCLZIP_OPT_PATH];
     762        }
     763        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
     764          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
     765        }
     766        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
     767          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
     768        }
     769        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
     770          // ----- Check for '/' in last path char
     771          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
     772            $v_path .= '/';
     773          }
     774          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
     775        }
     776      }
     777
     778      // ----- Look for 2 args
     779      // Here we need to support the first historic synopsis of the
     780      // method.
    556781      else {
    557       }
    558     }
    559 
    560     else {
    561 
    562       $v_path = $v_arg_list[0];
    563 
    564       if ($v_size == 2) {
    565         $v_remove_path = $v_arg_list[1];
    566       }
    567       else if ($v_size > 2) {
    568         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
    569 
    570         return 0;
    571       }
    572     }
    573   }
    574 
    575 
    576   $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
    577   $v_options_trick = array();
    578   $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
    579                                       array (PCLZIP_OPT_BY_INDEX => 'optional' ));
    580   if ($v_result != 1) {
    581       return 0;
    582   }
    583   $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
    584 
    585   $this->privOptionDefaultThreshold($v_options);
    586 
    587   if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
     782
     783        // ----- Get the first argument
     784        $v_path = $v_arg_list[0];
     785
     786        // ----- Look for the optional second argument
     787        if ($v_size == 2) {
     788          $v_remove_path = $v_arg_list[1];
     789        }
     790        else if ($v_size > 2) {
     791          // ----- Error log
     792          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
     793
     794          // ----- Return
     795          return 0;
     796        }
     797      }
     798    }
     799
     800    // ----- Look for default option values
     801    $this->privOptionDefaultThreshold($v_options);
     802
     803    // ----- Trace
     804
     805    // ----- Call the extracting fct
     806    $p_list = array();
     807    $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
     808                                             $v_remove_all_path, $v_options);
     809    if ($v_result < 1) {
     810      unset($p_list);
    588811      return(0);
    589   }
    590 
    591   return $p_list;
    592 }
    593 
    594 function delete()
    595 {
    596   $v_result=1;
    597 
    598   $this->privErrorReset();
    599 
    600   if (!$this->privCheckFormat()) {
    601     return(0);
    602   }
    603 
    604   $v_options = array();
    605 
    606   $v_size = func_num_args();
    607 
    608   if ($v_size > 0) {
    609     $v_arg_list = func_get_args();
    610 
    611     $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
    612                                       array (PCLZIP_OPT_BY_NAME => 'optional',
    613                                              PCLZIP_OPT_BY_EREG => 'optional',
    614                                              PCLZIP_OPT_BY_PREG => 'optional',
    615                                              PCLZIP_OPT_BY_INDEX => 'optional' ));
     812    }
     813
     814    // ----- Return
     815    return $p_list;
     816  }
     817  // --------------------------------------------------------------------------------
     818
     819
     820  // --------------------------------------------------------------------------------
     821  // Function :
     822  //   extractByIndex($p_index, $p_path="./", $p_remove_path="")
     823  //   extractByIndex($p_index, [$p_option, $p_option_value, ...])
     824  // Description :
     825  //   This method supports two synopsis. The first one is historical.
     826  //   This method is doing a partial extract of the archive.
     827  //   The extracted files or folders are identified by their index in the
     828  //   archive (from 0 to n).
     829  //   Note that if the index identify a folder, only the folder entry is
     830  //   extracted, not all the files included in the archive.
     831  // Parameters :
     832  //   $p_index : A single index (integer) or a string of indexes of files to
     833  //              extract. The form of the string is "0,4-6,8-12" with only numbers
     834  //              and '-' for range or ',' to separate ranges. No spaces or ';'
     835  //              are allowed.
     836  //   $p_path : Path where the files and directories are to be extracted
     837  //   $p_remove_path : First part ('root' part) of the memorized path
     838  //                    (if any similar) to remove while extracting.
     839  // Options :
     840  //   PCLZIP_OPT_PATH :
     841  //   PCLZIP_OPT_ADD_PATH :
     842  //   PCLZIP_OPT_REMOVE_PATH :
     843  //   PCLZIP_OPT_REMOVE_ALL_PATH :
     844  //   PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
     845  //     not as files.
     846  //     The resulting content is in a new field 'content' in the file
     847  //     structure.
     848  //     This option must be used alone (any other options are ignored).
     849  //   PCLZIP_CB_PRE_EXTRACT :
     850  //   PCLZIP_CB_POST_EXTRACT :
     851  // Return Values :
     852  //   0 on failure,
     853  //   The list of the extracted files, with a status of the action.
     854  //   (see PclZip::listContent() for list entry format)
     855  // --------------------------------------------------------------------------------
     856  //function extractByIndex($p_index, options...)
     857  function extractByIndex($p_index)
     858  {
     859    $v_result=1;
     860
     861    // ----- Reset the error handler
     862    $this->privErrorReset();
     863
     864    // ----- Check archive
     865    if (!$this->privCheckFormat()) {
     866      return(0);
     867    }
     868
     869    // ----- Set default values
     870    $v_options = array();
     871//    $v_path = "./";
     872    $v_path = '';
     873    $v_remove_path = "";
     874    $v_remove_all_path = false;
     875
     876    // ----- Look for variable options arguments
     877    $v_size = func_num_args();
     878
     879    // ----- Default values for option
     880    $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
     881
     882    // ----- Look for arguments
     883    if ($v_size > 1) {
     884      // ----- Get the arguments
     885      $v_arg_list = func_get_args();
     886
     887      // ----- Remove form the options list the first argument
     888      array_shift($v_arg_list);
     889      $v_size--;
     890
     891      // ----- Look for first arg
     892      if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
     893
     894        // ----- Parse the options
     895        $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
     896                                            array (PCLZIP_OPT_PATH => 'optional',
     897                                                   PCLZIP_OPT_REMOVE_PATH => 'optional',
     898                                                   PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
     899                                                   PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
     900                                                   PCLZIP_OPT_ADD_PATH => 'optional',
     901                                                   PCLZIP_CB_PRE_EXTRACT => 'optional',
     902                                                   PCLZIP_CB_POST_EXTRACT => 'optional',
     903                                                   PCLZIP_OPT_SET_CHMOD => 'optional',
     904                                                   PCLZIP_OPT_REPLACE_NEWER => 'optional'
     905                                                   ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
     906                                                   ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
     907                                                   PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
     908                                                   PCLZIP_OPT_TEMP_FILE_ON => 'optional',
     909                                                   PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
     910                                                                                                   ));
     911        if ($v_result != 1) {
     912          return 0;
     913        }
     914
     915        // ----- Set the arguments
     916        if (isset($v_options[PCLZIP_OPT_PATH])) {
     917          $v_path = $v_options[PCLZIP_OPT_PATH];
     918        }
     919        if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
     920          $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
     921        }
     922        if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
     923          $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
     924        }
     925        if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
     926          // ----- Check for '/' in last path char
     927          if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
     928            $v_path .= '/';
     929          }
     930          $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
     931        }
     932        if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
     933          $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
     934        }
     935        else {
     936        }
     937      }
     938
     939      // ----- Look for 2 args
     940      // Here we need to support the first historic synopsis of the
     941      // method.
     942      else {
     943
     944        // ----- Get the first argument
     945        $v_path = $v_arg_list[0];
     946
     947        // ----- Look for the optional second argument
     948        if ($v_size == 2) {
     949          $v_remove_path = $v_arg_list[1];
     950        }
     951        else if ($v_size > 2) {
     952          // ----- Error log
     953          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
     954
     955          // ----- Return
     956          return 0;
     957        }
     958      }
     959    }
     960
     961    // ----- Trace
     962
     963    // ----- Trick
     964    // Here I want to reuse extractByRule(), so I need to parse the $p_index
     965    // with privParseOptions()
     966    $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
     967    $v_options_trick = array();
     968    $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
     969                                        array (PCLZIP_OPT_BY_INDEX => 'optional' ));
    616970    if ($v_result != 1) {
    617971        return 0;
    618972    }
    619   }
    620 
    621   $this->privDisableMagicQuotes();
    622 
    623   $v_list = array();
    624   if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
     973    $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
     974
     975    // ----- Look for default option values
     976    $this->privOptionDefaultThreshold($v_options);
     977
     978    // ----- Call the extracting fct
     979    if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
     980        return(0);
     981    }
     982
     983    // ----- Return
     984    return $p_list;
     985  }
     986  // --------------------------------------------------------------------------------
     987
     988  // --------------------------------------------------------------------------------
     989  // Function :
     990  //   delete([$p_option, $p_option_value, ...])
     991  // Description :
     992  //   This method removes files from the archive.
     993  //   If no parameters are given, then all the archive is emptied.
     994  // Parameters :
     995  //   None or optional arguments.
     996  // Options :
     997  //   PCLZIP_OPT_BY_INDEX :
     998  //   PCLZIP_OPT_BY_NAME :
     999  //   PCLZIP_OPT_BY_EREG :
     1000  //   PCLZIP_OPT_BY_PREG :
     1001  // Return Values :
     1002  //   0 on failure,
     1003  //   The list of the files which are still present in the archive.
     1004  //   (see PclZip::listContent() for list entry format)
     1005  // --------------------------------------------------------------------------------
     1006  function delete()
     1007  {
     1008    $v_result=1;
     1009
     1010    // ----- Reset the error handler
     1011    $this->privErrorReset();
     1012
     1013    // ----- Check archive
     1014    if (!$this->privCheckFormat()) {
     1015      return(0);
     1016    }
     1017
     1018    // ----- Set default values
     1019    $v_options = array();
     1020
     1021    // ----- Look for variable options arguments
     1022    $v_size = func_num_args();
     1023
     1024    // ----- Look for arguments
     1025    if ($v_size > 0) {
     1026      // ----- Get the arguments
     1027      $v_arg_list = func_get_args();
     1028
     1029      // ----- Parse the options
     1030      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
     1031                                        array (PCLZIP_OPT_BY_NAME => 'optional',
     1032                                               PCLZIP_OPT_BY_EREG => 'optional',
     1033                                               PCLZIP_OPT_BY_PREG => 'optional',
     1034                                               PCLZIP_OPT_BY_INDEX => 'optional' ));
     1035      if ($v_result != 1) {
     1036          return 0;
     1037      }
     1038    }
     1039
     1040    // ----- Magic quotes trick
     1041    $this->privDisableMagicQuotes();
     1042
     1043    // ----- Call the delete fct
     1044    $v_list = array();
     1045    if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
     1046      $this->privSwapBackMagicQuotes();
     1047      unset($v_list);
     1048      return(0);
     1049    }
     1050
     1051    // ----- Magic quotes trick
    6251052    $this->privSwapBackMagicQuotes();
    626     unset($v_list);
    627     return(0);
    628   }
    629 
    630   $this->privSwapBackMagicQuotes();
    631 
    632   return $v_list;
    633 }
    634 
    635 function deleteByIndex($p_index)
    636 {
     1053
     1054    // ----- Return
     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   
     1068    $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
     1069
     1070    // ----- Return
     1071    return $p_list;
     1072  }
     1073  // --------------------------------------------------------------------------------
     1074
     1075  // --------------------------------------------------------------------------------
     1076  // Function : properties()
     1077  // Description :
     1078  //   This method gives the properties of the archive.
     1079  //   The properties are :
     1080  //     nb : Number of files in the archive
     1081  //     comment : Comment associated with the archive file
     1082  //     status : not_exist, ok
     1083  // Parameters :
     1084  //   None
     1085  // Return Values :
     1086  //   0 on failure,
     1087  //   An array with the archive properties.
     1088  // --------------------------------------------------------------------------------
     1089  function properties()
     1090  {
     1091
     1092    // ----- Reset the error handler
     1093    $this->privErrorReset();
     1094
     1095    // ----- Magic quotes trick
     1096    $this->privDisableMagicQuotes();
     1097
     1098    // ----- Check archive
     1099    if (!$this->privCheckFormat()) {
     1100      $this->privSwapBackMagicQuotes();
     1101      return(0);
     1102    }
     1103
     1104    // ----- Default properties
     1105    $v_prop = array();
     1106    $v_prop['comment'] = '';
     1107    $v_prop['nb'] = 0;
     1108    $v_prop['status'] = 'not_exist';
     1109
     1110    // ----- Look if file exists
     1111    if (@is_file($this->zipname))
     1112    {
     1113      // ----- Open the zip file
     1114      if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
     1115      {
     1116        $this->privSwapBackMagicQuotes();
     1117       
     1118        // ----- Error log
     1119        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
     1120
     1121        // ----- Return
     1122        return 0;
     1123      }
     1124
     1125      // ----- Read the central directory informations
     1126      $v_central_dir = array();
     1127      if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
     1128      {
     1129        $this->privSwapBackMagicQuotes();
     1130        return 0;
     1131      }
     1132
     1133      // ----- Close the zip file
     1134      $this->privCloseFd();
     1135
     1136      // ----- Set the user attributes
     1137      $v_prop['comment'] = $v_central_dir['comment'];
     1138      $v_prop['nb'] = $v_central_dir['entries'];
     1139      $v_prop['status'] = 'ok';
     1140    }
     1141
     1142    // ----- Magic quotes trick
     1143    $this->privSwapBackMagicQuotes();
     1144
     1145    // ----- Return
     1146    return $v_prop;
     1147  }
     1148  // --------------------------------------------------------------------------------
     1149
     1150  // --------------------------------------------------------------------------------
     1151  // Function : duplicate()
     1152  // Description :
     1153  //   This method creates an archive by copying the content of an other one. If
     1154  //   the archive already exist, it is replaced by the new one without any warning.
     1155  // Parameters :
     1156  //   $p_archive : The filename of a valid archive, or
     1157  //                a valid PclZip object.
     1158  // Return Values :
     1159  //   1 on success.
     1160  //   0 or a negative value on error (error code).
     1161  // --------------------------------------------------------------------------------
     1162  function duplicate($p_archive)
     1163  {
     1164    $v_result = 1;
     1165
     1166    // ----- Reset the error handler
     1167    $this->privErrorReset();
     1168
     1169    // ----- Look if the $p_archive is a PclZip object
     1170    if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
     1171    {
     1172
     1173      // ----- Duplicate the archive
     1174      $v_result = $this->privDuplicate($p_archive->zipname);
     1175    }
     1176
     1177    // ----- Look if the $p_archive is a string (so a filename)
     1178    else if (is_string($p_archive))
     1179    {
     1180
     1181      // ----- Check that $p_archive is a valid zip file
     1182      // TBC : Should also check the archive format
     1183      if (!is_file($p_archive)) {
     1184        // ----- Error log
     1185        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
     1186        $v_result = PCLZIP_ERR_MISSING_FILE;
     1187      }
     1188      else {
     1189        // ----- Duplicate the archive
     1190        $v_result = $this->privDuplicate($p_archive);
     1191      }
     1192    }
     1193
     1194    // ----- Invalid variable
     1195    else
     1196    {
     1197      // ----- Error log
     1198      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
     1199      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
     1200    }
     1201
     1202    // ----- Return
     1203    return $v_result;
     1204  }
     1205  // --------------------------------------------------------------------------------
     1206
     1207  // --------------------------------------------------------------------------------
     1208  // Function : merge()
     1209  // Description :
     1210  //   This method merge the $p_archive_to_add archive at the end of the current
     1211  //   one ($this).
     1212  //   If the archive ($this) does not exist, the merge becomes a duplicate.
     1213  //   If the $p_archive_to_add archive does not exist, the merge is a success.
     1214  // Parameters :
     1215  //   $p_archive_to_add : It can be directly the filename of a valid zip archive,
     1216  //                       or a PclZip object archive.
     1217  // Return Values :
     1218  //   1 on success,
     1219  //   0 or negative values on error (see below).
     1220  // --------------------------------------------------------------------------------
     1221  function merge($p_archive_to_add)
     1222  {
     1223    $v_result = 1;
     1224
     1225    // ----- Reset the error handler
     1226    $this->privErrorReset();
     1227
     1228    // ----- Check archive
     1229    if (!$this->privCheckFormat()) {
     1230      return(0);
     1231    }
     1232
     1233    // ----- Look if the $p_archive_to_add is a PclZip object
     1234    if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
     1235    {
     1236
     1237      // ----- Merge the archive
     1238      $v_result = $this->privMerge($p_archive_to_add);
     1239    }
     1240
     1241    // ----- Look if the $p_archive_to_add is a string (so a filename)
     1242    else if (is_string($p_archive_to_add))
     1243    {
     1244
     1245      // ----- Create a temporary archive
     1246      $v_object_archive = new PclZip($p_archive_to_add);
     1247
     1248      // ----- Merge the archive
     1249      $v_result = $this->privMerge($v_object_archive);
     1250    }
     1251
     1252    // ----- Invalid variable
     1253    else
     1254    {
     1255      // ----- Error log
     1256      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
     1257      $v_result = PCLZIP_ERR_INVALID_PARAMETER;
     1258    }
     1259
     1260    // ----- Return
     1261    return $v_result;
     1262  }
     1263  // --------------------------------------------------------------------------------
     1264
     1265
     1266
     1267  // --------------------------------------------------------------------------------
     1268  // Function : errorCode()
     1269  // Description :
     1270  // Parameters :
     1271  // --------------------------------------------------------------------------------
     1272  function errorCode()
     1273  {
     1274    if (PCLZIP_ERROR_EXTERNAL == 1) {
     1275      return(PclErrorCode());
     1276    }
     1277    else {
     1278      return($this->error_code);
     1279    }
     1280  }
     1281  // --------------------------------------------------------------------------------
     1282
     1283  // --------------------------------------------------------------------------------
     1284  // Function : errorName()
     1285  // Description :
     1286  // Parameters :
     1287  // --------------------------------------------------------------------------------
     1288  function errorName($p_with_code=false)
     1289  {
     1290    $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
     1291                      PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
     1292                      PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
     1293                      PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
     1294                      PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
     1295                      PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
     1296                      PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
     1297                      PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
     1298                      PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
     1299                      PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
     1300                      PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
     1301                      PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
     1302                      PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
     1303                      PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
     1304                      PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
     1305                      PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
     1306                      PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
     1307                      PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
     1308                      PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
     1309                      ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
     1310                      ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
     1311                    );
     1312
     1313    if (isset($v_name[$this->error_code])) {
     1314      $v_value = $v_name[$this->error_code];
     1315    }
     1316    else {
     1317      $v_value = 'NoName';
     1318    }
     1319
     1320    if ($p_with_code) {
     1321      return($v_value.' ('.$this->error_code.')');
     1322    }
     1323    else {
     1324      return($v_value);
     1325    }
     1326  }
     1327  // --------------------------------------------------------------------------------
     1328
     1329  // --------------------------------------------------------------------------------
     1330  // Function : errorInfo()
     1331  // Description :
     1332  // Parameters :
     1333  // --------------------------------------------------------------------------------
     1334  function errorInfo($p_full=false)
     1335  {
     1336    if (PCLZIP_ERROR_EXTERNAL == 1) {
     1337      return(PclErrorString());
     1338    }
     1339    else {
     1340      if ($p_full) {
     1341        return($this->errorName(true)." : ".$this->error_string);
     1342      }
     1343      else {
     1344        return($this->error_string." [code ".$this->error_code."]");
     1345      }
     1346    }
     1347  }
     1348  // --------------------------------------------------------------------------------
     1349
     1350
     1351// --------------------------------------------------------------------------------
     1352// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
     1353// *****                                                        *****
     1354// *****       THESES FUNCTIONS MUST NOT BE USED DIRECTLY       *****
     1355// --------------------------------------------------------------------------------
     1356
     1357
     1358
     1359  // --------------------------------------------------------------------------------
     1360  // Function : privCheckFormat()
     1361  // Description :
     1362  //   This method check that the archive exists and is a valid zip archive.
     1363  //   Several level of check exists. (futur)
     1364  // Parameters :
     1365  //   $p_level : Level of check. Default 0.
     1366  //              0 : Check the first bytes (magic codes) (default value))
     1367  //              1 : 0 + Check the central directory (futur)
     1368  //              2 : 1 + Check each file header (futur)
     1369  // Return Values :
     1370  //   true on success,
     1371  //   false on error, the error code is set.
     1372  // --------------------------------------------------------------------------------
     1373  function privCheckFormat($p_level=0)
     1374  {
     1375    $v_result = true;
     1376
     1377        // ----- Reset the file system cache
     1378    clearstatcache();
     1379
     1380    // ----- Reset the error handler
     1381    $this->privErrorReset();
     1382
     1383    // ----- Look if the file exits
     1384    if (!is_file($this->zipname)) {
     1385      // ----- Error log
     1386      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
     1387      return(false);
     1388    }
     1389
     1390    // ----- Check that the file is readeable
     1391    if (!is_readable($this->zipname)) {
     1392      // ----- Error log
     1393      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
     1394      return(false);
     1395    }
     1396
     1397    // ----- Check the magic code
     1398    // TBC
     1399
     1400    // ----- Check the central header
     1401    // TBC
     1402
     1403    // ----- Check each file header
     1404    // TBC
     1405
     1406    // ----- Return
     1407    return $v_result;
     1408  }
     1409  // --------------------------------------------------------------------------------
     1410
     1411  // --------------------------------------------------------------------------------
     1412  // Function : privParseOptions()
     1413  // Description :
     1414  //   This internal methods reads the variable list of arguments ($p_options_list,
     1415  //   $p_size) and generate an array with the options and values ($v_result_list).
     1416  //   $v_requested_options contains the options that can be present and those that
     1417  //   must be present.
     1418  //   $v_requested_options is an array, with the option value as key, and 'optional',
     1419  //   or 'mandatory' as value.
     1420  // Parameters :
     1421  //   See above.
     1422  // Return Values :
     1423  //   1 on success.
     1424  //   0 on failure.
     1425  // --------------------------------------------------------------------------------
     1426  function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
     1427  {
     1428    $v_result=1;
     1429   
     1430    // ----- Read the options
     1431    $i=0;
     1432    while ($i<$p_size) {
     1433
     1434      // ----- Check if the option is supported
     1435      if (!isset($v_requested_options[$p_options_list[$i]])) {
     1436        // ----- Error log
     1437        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
     1438
     1439        // ----- Return
     1440        return PclZip::errorCode();
     1441      }
     1442
     1443      // ----- Look for next option
     1444      switch ($p_options_list[$i]) {
     1445        // ----- Look for options that request a path value
     1446        case PCLZIP_OPT_PATH :
     1447        case PCLZIP_OPT_REMOVE_PATH :
     1448        case PCLZIP_OPT_ADD_PATH :
     1449          // ----- Check the number of parameters
     1450          if (($i+1) >= $p_size) {
     1451            // ----- Error log
     1452            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1453
     1454            // ----- Return
     1455            return PclZip::errorCode();
     1456          }
     1457
     1458          // ----- Get the value
     1459          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
     1460          $i++;
     1461        break;
     1462
     1463        case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
     1464          // ----- Check the number of parameters
     1465          if (($i+1) >= $p_size) {
     1466            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1467            return PclZip::errorCode();
     1468          }
     1469         
     1470          // ----- Check for incompatible options
     1471          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
     1472            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
     1473            return PclZip::errorCode();
     1474          }
     1475         
     1476          // ----- Check the value
     1477          $v_value = $p_options_list[$i+1];
     1478          if ((!is_integer($v_value)) || ($v_value<0)) {
     1479            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1480            return PclZip::errorCode();
     1481          }
     1482
     1483          // ----- Get the value (and convert it in bytes)
     1484          $v_result_list[$p_options_list[$i]] = $v_value*1048576;
     1485          $i++;
     1486        break;
     1487
     1488        case PCLZIP_OPT_TEMP_FILE_ON :
     1489          // ----- Check for incompatible options
     1490          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
     1491            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
     1492            return PclZip::errorCode();
     1493          }
     1494         
     1495          $v_result_list[$p_options_list[$i]] = true;
     1496        break;
     1497
     1498        case PCLZIP_OPT_TEMP_FILE_OFF :
     1499          // ----- Check for incompatible options
     1500          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
     1501            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
     1502            return PclZip::errorCode();
     1503          }
     1504          // ----- Check for incompatible options
     1505          if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
     1506            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
     1507            return PclZip::errorCode();
     1508          }
     1509         
     1510          $v_result_list[$p_options_list[$i]] = true;
     1511        break;
     1512
     1513        case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
     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            return PclZip::errorCode();
     1521          }
     1522
     1523          // ----- Get the value
     1524          if (   is_string($p_options_list[$i+1])
     1525              && ($p_options_list[$i+1] != '')) {
     1526            $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
     1527            $i++;
     1528          }
     1529          else {
     1530          }
     1531        break;
     1532
     1533        // ----- Look for options that request an array of string for value
     1534        case PCLZIP_OPT_BY_NAME :
     1535          // ----- Check the number of parameters
     1536          if (($i+1) >= $p_size) {
     1537            // ----- Error log
     1538            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1539
     1540            // ----- Return
     1541            return PclZip::errorCode();
     1542          }
     1543
     1544          // ----- Get the value
     1545          if (is_string($p_options_list[$i+1])) {
     1546              $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
     1547          }
     1548          else if (is_array($p_options_list[$i+1])) {
     1549              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
     1550          }
     1551          else {
     1552            // ----- Error log
     1553            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1554
     1555            // ----- Return
     1556            return PclZip::errorCode();
     1557          }
     1558          $i++;
     1559        break;
     1560
     1561        // ----- Look for options that request an EREG or PREG expression
     1562        case PCLZIP_OPT_BY_EREG :
     1563          // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
     1564          // to PCLZIP_OPT_BY_PREG
     1565          $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
     1566        case PCLZIP_OPT_BY_PREG :
     1567        //case PCLZIP_OPT_CRYPT :
     1568          // ----- Check the number of parameters
     1569          if (($i+1) >= $p_size) {
     1570            // ----- Error log
     1571            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1572
     1573            // ----- Return
     1574            return PclZip::errorCode();
     1575          }
     1576
     1577          // ----- Get the value
     1578          if (is_string($p_options_list[$i+1])) {
     1579              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
     1580          }
     1581          else {
     1582            // ----- Error log
     1583            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1584
     1585            // ----- Return
     1586            return PclZip::errorCode();
     1587          }
     1588          $i++;
     1589        break;
     1590
     1591        // ----- Look for options that takes a string
     1592        case PCLZIP_OPT_COMMENT :
     1593        case PCLZIP_OPT_ADD_COMMENT :
     1594        case PCLZIP_OPT_PREPEND_COMMENT :
     1595          // ----- Check the number of parameters
     1596          if (($i+1) >= $p_size) {
     1597            // ----- Error log
     1598            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
     1599                                             "Missing parameter value for option '"
     1600                                                                 .PclZipUtilOptionText($p_options_list[$i])
     1601                                                                 ."'");
     1602
     1603            // ----- Return
     1604            return PclZip::errorCode();
     1605          }
     1606
     1607          // ----- Get the value
     1608          if (is_string($p_options_list[$i+1])) {
     1609              $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
     1610          }
     1611          else {
     1612            // ----- Error log
     1613            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
     1614                                             "Wrong parameter value for option '"
     1615                                                                 .PclZipUtilOptionText($p_options_list[$i])
     1616                                                                 ."'");
     1617
     1618            // ----- Return
     1619            return PclZip::errorCode();
     1620          }
     1621          $i++;
     1622        break;
     1623
     1624        // ----- Look for options that request an array of index
     1625        case PCLZIP_OPT_BY_INDEX :
     1626          // ----- Check the number of parameters
     1627          if (($i+1) >= $p_size) {
     1628            // ----- Error log
     1629            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1630
     1631            // ----- Return
     1632            return PclZip::errorCode();
     1633          }
     1634
     1635          // ----- Get the value
     1636          $v_work_list = array();
     1637          if (is_string($p_options_list[$i+1])) {
     1638
     1639              // ----- Remove spaces
     1640              $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
     1641
     1642              // ----- Parse items
     1643              $v_work_list = explode(",", $p_options_list[$i+1]);
     1644          }
     1645          else if (is_integer($p_options_list[$i+1])) {
     1646              $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
     1647          }
     1648          else if (is_array($p_options_list[$i+1])) {
     1649              $v_work_list = $p_options_list[$i+1];
     1650          }
     1651          else {
     1652            // ----- Error log
     1653            PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1654
     1655            // ----- Return
     1656            return PclZip::errorCode();
     1657          }
     1658         
     1659          // ----- Reduce the index list
     1660          // each index item in the list must be a couple with a start and
     1661          // an end value : [0,3], [5-5], [8-10], ...
     1662          // ----- Check the format of each item
     1663          $v_sort_flag=false;
     1664          $v_sort_value=0;
     1665          for ($j=0; $j<sizeof($v_work_list); $j++) {
     1666              // ----- Explode the item
     1667              $v_item_list = explode("-", $v_work_list[$j]);
     1668              $v_size_item_list = sizeof($v_item_list);
     1669             
     1670              // ----- TBC : Here we might check that each item is a
     1671              // real integer ...
     1672             
     1673              // ----- Look for single value
     1674              if ($v_size_item_list == 1) {
     1675                  // ----- Set the option value
     1676                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
     1677                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
     1678              }
     1679              elseif ($v_size_item_list == 2) {
     1680                  // ----- Set the option value
     1681                  $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
     1682                  $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
     1683              }
     1684              else {
     1685                  // ----- Error log
     1686                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1687
     1688                  // ----- Return
     1689                  return PclZip::errorCode();
     1690              }
     1691
     1692
     1693              // ----- Look for list sort
     1694              if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
     1695                  $v_sort_flag=true;
     1696
     1697                  // ----- TBC : An automatic sort should be writen ...
     1698                  // ----- Error log
     1699                  PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1700
     1701                  // ----- Return
     1702                  return PclZip::errorCode();
     1703              }
     1704              $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
     1705          }
     1706         
     1707          // ----- Sort the items
     1708          if ($v_sort_flag) {
     1709              // TBC : To Be Completed
     1710          }
     1711
     1712          // ----- Next option
     1713          $i++;
     1714        break;
     1715
     1716        // ----- Look for options that request no value
     1717        case PCLZIP_OPT_REMOVE_ALL_PATH :
     1718        case PCLZIP_OPT_EXTRACT_AS_STRING :
     1719        case PCLZIP_OPT_NO_COMPRESSION :
     1720        case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
     1721        case PCLZIP_OPT_REPLACE_NEWER :
     1722        case PCLZIP_OPT_STOP_ON_ERROR :
     1723          $v_result_list[$p_options_list[$i]] = true;
     1724        break;
     1725
     1726        // ----- Look for options that request an octal value
     1727        case PCLZIP_OPT_SET_CHMOD :
     1728          // ----- Check the number of parameters
     1729          if (($i+1) >= $p_size) {
     1730            // ----- Error log
     1731            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1732
     1733            // ----- Return
     1734            return PclZip::errorCode();
     1735          }
     1736
     1737          // ----- Get the value
     1738          $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
     1739          $i++;
     1740        break;
     1741
     1742        // ----- Look for options that request a call-back
     1743        case PCLZIP_CB_PRE_EXTRACT :
     1744        case PCLZIP_CB_POST_EXTRACT :
     1745        case PCLZIP_CB_PRE_ADD :
     1746        case PCLZIP_CB_POST_ADD :
     1747        /* for futur use
     1748        case PCLZIP_CB_PRE_DELETE :
     1749        case PCLZIP_CB_POST_DELETE :
     1750        case PCLZIP_CB_PRE_LIST :
     1751        case PCLZIP_CB_POST_LIST :
     1752        */
     1753          // ----- Check the number of parameters
     1754          if (($i+1) >= $p_size) {
     1755            // ----- Error log
     1756            PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
     1757
     1758            // ----- Return
     1759            return PclZip::errorCode();
     1760          }
     1761
     1762          // ----- Get the value
     1763          $v_function_name = $p_options_list[$i+1];
     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            return PclZip::errorCode();
     1772          }
     1773
     1774          // ----- Set the attribute
     1775          $v_result_list[$p_options_list[$i]] = $v_function_name;
     1776          $i++;
     1777        break;
     1778
     1779        default :
     1780          // ----- Error log
     1781          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
     1782                                       "Unknown parameter '"
     1783                                                           .$p_options_list[$i]."'");
     1784
     1785          // ----- Return
     1786          return PclZip::errorCode();
     1787      }
     1788
     1789      // ----- Next options
     1790      $i++;
     1791    }
     1792
     1793    // ----- Look for mandatory options
     1794    if ($v_requested_options !== false) {
     1795      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
     1796        // ----- Look for mandatory option
     1797        if ($v_requested_options[$key] == 'mandatory') {
     1798          // ----- Look if present
     1799          if (!isset($v_result_list[$key])) {
     1800            // ----- Error log
     1801            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
     1802
     1803            // ----- Return
     1804            return PclZip::errorCode();
     1805          }
     1806        }
     1807      }
     1808    }
     1809   
     1810    // ----- Look for default values
     1811    if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
     1812     
     1813    }
     1814
     1815    // ----- Return
     1816    return $v_result;
     1817  }
     1818  // --------------------------------------------------------------------------------
     1819
     1820  // --------------------------------------------------------------------------------
     1821  // Function : privOptionDefaultThreshold()
     1822  // Description :
     1823  // Parameters :
     1824  // Return Values :
     1825  // --------------------------------------------------------------------------------
     1826  function privOptionDefaultThreshold(&$p_options)
     1827  {
     1828    $v_result=1;
     1829   
     1830    if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
     1831        || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
     1832      return $v_result;
     1833    }
     1834   
     1835    // ----- Get 'memory_limit' configuration value
     1836    $v_memory_limit = ini_get('memory_limit');
     1837    $v_memory_limit = trim($v_memory_limit);
     1838    $last = strtolower(substr($v_memory_limit, -1));
     1839 
     1840    if($last == 'g')
     1841        //$v_memory_limit = $v_memory_limit*1024*1024*1024;
     1842        $v_memory_limit = $v_memory_limit*1073741824;
     1843    if($last == 'm')
     1844        //$v_memory_limit = $v_memory_limit*1024*1024;
     1845        $v_memory_limit = $v_memory_limit*1048576;
     1846    if($last == 'k')
     1847        $v_memory_limit = $v_memory_limit*1024;
     1848           
     1849    $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
     1850   
     1851
     1852    // ----- Sanity check : No threshold if value lower than 1M
     1853    if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
     1854      unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
     1855    }
     1856         
     1857    // ----- Return
     1858    return $v_result;
     1859  }
     1860  // --------------------------------------------------------------------------------
     1861
     1862  // --------------------------------------------------------------------------------
     1863  // Function : privFileDescrParseAtt()
     1864  // Description :
     1865  // Parameters :
     1866  // Return Values :
     1867  //   1 on success.
     1868  //   0 on failure.
     1869  // --------------------------------------------------------------------------------
     1870  function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
     1871  {
     1872    $v_result=1;
     1873   
     1874    // ----- For each file in the list check the attributes
     1875    foreach ($p_file_list as $v_key => $v_value) {
     1876   
     1877      // ----- Check if the option is supported
     1878      if (!isset($v_requested_options[$v_key])) {
     1879        // ----- Error log
     1880        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
     1881
     1882        // ----- Return
     1883        return PclZip::errorCode();
     1884      }
     1885
     1886      // ----- Look for attribute
     1887      switch ($v_key) {
     1888        case PCLZIP_ATT_FILE_NAME :
     1889          if (!is_string($v_value)) {
     1890            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
     1891            return PclZip::errorCode();
     1892          }
     1893
     1894          $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
     1895         
     1896          if ($p_filedescr['filename'] == '') {
     1897            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
     1898            return PclZip::errorCode();
     1899          }
     1900
     1901        break;
     1902
     1903        case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
     1904          if (!is_string($v_value)) {
     1905            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
     1906            return PclZip::errorCode();
     1907          }
     1908
     1909          $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
     1910
     1911          if ($p_filedescr['new_short_name'] == '') {
     1912            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
     1913            return PclZip::errorCode();
     1914          }
     1915        break;
     1916
     1917        case PCLZIP_ATT_FILE_NEW_FULL_NAME :
     1918          if (!is_string($v_value)) {
     1919            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
     1920            return PclZip::errorCode();
     1921          }
     1922
     1923          $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
     1924
     1925          if ($p_filedescr['new_full_name'] == '') {
     1926            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
     1927            return PclZip::errorCode();
     1928          }
     1929        break;
     1930
     1931        // ----- Look for options that takes a string
     1932        case PCLZIP_ATT_FILE_COMMENT :
     1933          if (!is_string($v_value)) {
     1934            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
     1935            return PclZip::errorCode();
     1936          }
     1937
     1938          $p_filedescr['comment'] = $v_value;
     1939        break;
     1940
     1941        case PCLZIP_ATT_FILE_MTIME :
     1942          if (!is_integer($v_value)) {
     1943            PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
     1944            return PclZip::errorCode();
     1945          }
     1946
     1947          $p_filedescr['mtime'] = $v_value;
     1948        break;
     1949
     1950        case PCLZIP_ATT_FILE_CONTENT :
     1951          $p_filedescr['content'] = $v_value;
     1952        break;
     1953
     1954        default :
     1955          // ----- Error log
     1956          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
     1957                                           "Unknown parameter '".$v_key."'");
     1958
     1959          // ----- Return
     1960          return PclZip::errorCode();
     1961      }
     1962
     1963      // ----- Look for mandatory options
     1964      if ($v_requested_options !== false) {
     1965        for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
     1966          // ----- Look for mandatory option
     1967          if ($v_requested_options[$key] == 'mandatory') {
     1968            // ----- Look if present
     1969            if (!isset($p_file_list[$key])) {
     1970              PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
     1971              return PclZip::errorCode();
     1972            }
     1973          }
     1974        }
     1975      }
     1976   
     1977    // end foreach
     1978    }
     1979   
     1980    // ----- Return
     1981    return $v_result;
     1982  }
     1983  // --------------------------------------------------------------------------------
     1984
     1985  // --------------------------------------------------------------------------------
     1986  // Function : privFileDescrExpand()
     1987  // Description :
     1988  //   This method look for each item of the list to see if its a file, a folder
     1989  //   or a string to be added as file. For any other type of files (link, other)
     1990  //   just ignore the item.
     1991  //   Then prepare the information that will be stored for that file.
     1992  //   When its a folder, expand the folder with all the files that are in that
     1993  //   folder (recursively).
     1994  // Parameters :
     1995  // Return Values :
     1996  //   1 on success.
     1997  //   0 on failure.
     1998  // --------------------------------------------------------------------------------
     1999  function privFileDescrExpand(&$p_filedescr_list, &$p_options)
     2000  {
     2001    $v_result=1;
     2002   
     2003    // ----- Create a result list
     2004    $v_result_list = array();
     2005   
     2006    // ----- Look each entry
     2007    for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
     2008     
     2009      // ----- Get filedescr
     2010      $v_descr = $p_filedescr_list[$i];
     2011     
     2012      // ----- Reduce the filename
     2013      $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
     2014      $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
     2015     
     2016      // ----- Look for real file or folder
     2017      if (file_exists($v_descr['filename'])) {
     2018        if (@is_file($v_descr['filename'])) {
     2019          $v_descr['type'] = 'file';
     2020        }
     2021        else if (@is_dir($v_descr['filename'])) {
     2022          $v_descr['type'] = 'folder';
     2023        }
     2024        else if (@is_link($v_descr['filename'])) {
     2025          // skip
     2026          continue;
     2027        }
     2028        else {
     2029          // skip
     2030          continue;
     2031        }
     2032      }
     2033     
     2034      // ----- Look for string added as file
     2035      else if (isset($v_descr['content'])) {
     2036        $v_descr['type'] = 'virtual_file';
     2037      }
     2038     
     2039      // ----- Missing file
     2040      else {
     2041        // ----- Error log
     2042        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
     2043
     2044        // ----- Return
     2045        return PclZip::errorCode();
     2046      }
     2047     
     2048      // ----- Calculate the stored filename
     2049      $this->privCalculateStoredFilename($v_descr, $p_options);
     2050     
     2051      // ----- Add the descriptor in result list
     2052      $v_result_list[sizeof($v_result_list)] = $v_descr;
     2053     
     2054      // ----- Look for folder
     2055      if ($v_descr['type'] == 'folder') {
     2056        // ----- List of items in folder
     2057        $v_dirlist_descr = array();
     2058        $v_dirlist_nb = 0;
     2059        if ($v_folder_handler = @opendir($v_descr['filename'])) {
     2060          while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
     2061
     2062            // ----- Skip '.' and '..'
     2063            if (($v_item_handler == '.') || ($v_item_handler == '..')) {
     2064                continue;
     2065            }
     2066           
     2067            // ----- Compose the full filename
     2068            $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
     2069           
     2070            // ----- Look for different stored filename
     2071            // Because the name of the folder was changed, the name of the
     2072            // files/sub-folders also change
     2073            if (($v_descr['stored_filename'] != $v_descr['filename'])
     2074                 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
     2075              if ($v_descr['stored_filename'] != '') {
     2076                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
     2077              }
     2078              else {
     2079                $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
     2080              }
     2081            }
     2082     
     2083            $v_dirlist_nb++;
     2084          }
     2085         
     2086          @closedir($v_folder_handler);
     2087        }
     2088        else {
     2089          // TBC : unable to open folder in read mode
     2090        }
     2091       
     2092        // ----- Expand each element of the list
     2093        if ($v_dirlist_nb != 0) {
     2094          // ----- Expand
     2095          if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
     2096            return $v_result;
     2097          }
     2098         
     2099          // ----- Concat the resulting list
     2100          $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
     2101        }
     2102        else {
     2103        }
     2104         
     2105        // ----- Free local array
     2106        unset($v_dirlist_descr);
     2107      }
     2108    }
     2109   
     2110    // ----- Get the result list
     2111    $p_filedescr_list = $v_result_list;
     2112
     2113    // ----- Return
     2114    return $v_result;
     2115  }
     2116  // --------------------------------------------------------------------------------
     2117
     2118  // --------------------------------------------------------------------------------
     2119  // Function : privCreate()
     2120  // Description :
     2121  // Parameters :
     2122  // Return Values :
     2123  // --------------------------------------------------------------------------------
     2124  function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
     2125  {
     2126    $v_result=1;
     2127    $v_list_detail = array();
     2128   
     2129    // ----- Magic quotes trick
     2130    $this->privDisableMagicQuotes();
     2131
     2132    // ----- Open the file in write mode
     2133    if (($v_result = $this->privOpenFd('wb')) != 1)
     2134    {
     2135      // ----- Return
     2136      return $v_result;
     2137    }
     2138
     2139    // ----- Add the list of files
     2140    $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
     2141
     2142    // ----- Close
     2143    $this->privCloseFd();
     2144
     2145    // ----- Magic quotes trick
     2146    $this->privSwapBackMagicQuotes();
     2147
     2148    // ----- Return
     2149    return $v_result;
     2150  }
     2151  // --------------------------------------------------------------------------------
     2152
     2153  // --------------------------------------------------------------------------------
     2154  // Function : privAdd()
     2155  // Description :
     2156  // Parameters :
     2157  // Return Values :
     2158  // --------------------------------------------------------------------------------
     2159  function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
     2160  {
     2161    $v_result=1;
     2162    $v_list_detail = array();
     2163
     2164    // ----- Look if the archive exists or is empty
     2165    if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
     2166    {
     2167
     2168      // ----- Do a create
     2169      $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
     2170
     2171      // ----- Return
     2172      return $v_result;
     2173    }
     2174    // ----- Magic quotes trick
     2175    $this->privDisableMagicQuotes();
     2176
     2177    // ----- Open the zip file
     2178    if (($v_result=$this->privOpenFd('rb')) != 1)
     2179    {
     2180      // ----- Magic quotes trick
     2181      $this->privSwapBackMagicQuotes();
     2182
     2183      // ----- Return
     2184      return $v_result;
     2185    }
     2186
     2187    // ----- Read the central directory informations
     2188    $v_central_dir = array();
     2189    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
     2190    {
     2191      $this->privCloseFd();
     2192      $this->privSwapBackMagicQuotes();
     2193      return $v_result;
     2194    }
     2195
     2196    // ----- Go to beginning of File
     2197    @rewind($this->zip_fd);
     2198
     2199    // ----- Creates a temporay file
     2200    $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
     2201
     2202    // ----- Open the temporary file in write mode
     2203    if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
     2204    {
     2205      $this->privCloseFd();
     2206      $this->privSwapBackMagicQuotes();
     2207
     2208      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
     2209
     2210      // ----- Return
     2211      return PclZip::errorCode();
     2212    }
     2213
     2214    // ----- Copy the files from the archive to the temporary file
     2215    // TBC : Here I should better append the file and go back to erase the central dir
     2216    $v_size = $v_central_dir['offset'];
     2217    while ($v_size != 0)
     2218    {
     2219      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
     2220      $v_buffer = fread($this->zip_fd, $v_read_size);
     2221      @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
     2222      $v_size -= $v_read_size;
     2223    }
     2224
     2225    // ----- Swap the file descriptor
     2226    // Here is a trick : I swap the temporary fd with the zip fd, in order to use
     2227    // the following methods on the temporary fil and not the real archive
     2228    $v_swap = $this->zip_fd;
     2229    $this->zip_fd = $v_zip_temp_fd;
     2230    $v_zip_temp_fd = $v_swap;
     2231
     2232    // ----- Add the files
     2233    $v_header_list = array();
     2234    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
     2235    {
     2236      fclose($v_zip_temp_fd);
     2237      $this->privCloseFd();
     2238      @unlink($v_zip_temp_name);
     2239      $this->privSwapBackMagicQuotes();
     2240
     2241      // ----- Return
     2242      return $v_result;
     2243    }
     2244
     2245    // ----- Store the offset of the central dir
     2246    $v_offset = @ftell($this->zip_fd);
     2247
     2248    // ----- Copy the block of file headers from the old archive
     2249    $v_size = $v_central_dir['size'];
     2250    while ($v_size != 0)
     2251    {
     2252      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
     2253      $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
     2254      @fwrite($this->zip_fd, $v_buffer, $v_read_size);
     2255      $v_size -= $v_read_size;
     2256    }
     2257
     2258    // ----- Create the Central Dir files header
     2259    for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
     2260    {
     2261      // ----- Create the file header
     2262      if ($v_header_list[$i]['status'] == 'ok') {
     2263        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
     2264          fclose($v_zip_temp_fd);
     2265          $this->privCloseFd();
     2266          @unlink($v_zip_temp_name);
     2267          $this->privSwapBackMagicQuotes();
     2268
     2269          // ----- Return
     2270          return $v_result;
     2271        }
     2272        $v_count++;
     2273      }
     2274
     2275      // ----- Transform the header to a 'usable' info
     2276      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
     2277    }
     2278
     2279    // ----- Zip file comment
     2280    $v_comment = $v_central_dir['comment'];
     2281    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
     2282      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
     2283    }
     2284    if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
     2285      $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
     2286    }
     2287    if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
     2288      $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
     2289    }
     2290
     2291    // ----- Calculate the size of the central header
     2292    $v_size = @ftell($this->zip_fd)-$v_offset;
     2293
     2294    // ----- Create the central dir footer
     2295    if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
     2296    {
     2297      // ----- Reset the file list
     2298      unset($v_header_list);
     2299      $this->privSwapBackMagicQuotes();
     2300
     2301      // ----- Return
     2302      return $v_result;
     2303    }
     2304
     2305    // ----- Swap back the file descriptor
     2306    $v_swap = $this->zip_fd;
     2307    $this->zip_fd = $v_zip_temp_fd;
     2308    $v_zip_temp_fd = $v_swap;
     2309
     2310    // ----- Close
     2311    $this->privCloseFd();
     2312
     2313    // ----- Close the temporary file
     2314    @fclose($v_zip_temp_fd);
     2315
     2316    // ----- Magic quotes trick
     2317    $this->privSwapBackMagicQuotes();
     2318
     2319    // ----- Delete the zip file
     2320    // TBC : I should test the result ...
     2321    @unlink($this->zipname);
     2322
     2323    // ----- Rename the temporary file
     2324    // TBC : I should test the result ...
     2325    //@rename($v_zip_temp_name, $this->zipname);
     2326    PclZipUtilRename($v_zip_temp_name, $this->zipname);
     2327
     2328    // ----- Return
     2329    return $v_result;
     2330  }
     2331  // --------------------------------------------------------------------------------
     2332
     2333  // --------------------------------------------------------------------------------
     2334  // Function : privOpenFd()
     2335  // Description :
     2336  // Parameters :
     2337  // --------------------------------------------------------------------------------
     2338  function privOpenFd($p_mode)
     2339  {
     2340    $v_result=1;
     2341
     2342    // ----- Look if already open
     2343    if ($this->zip_fd != 0)
     2344    {
     2345      // ----- Error log
     2346      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
     2347
     2348      // ----- Return
     2349      return PclZip::errorCode();
     2350    }
     2351
     2352    // ----- Open the zip file
     2353    if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
     2354    {
     2355      // ----- Error log
     2356      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
     2357
     2358      // ----- Return
     2359      return PclZip::errorCode();
     2360    }
     2361
     2362    // ----- Return
     2363    return $v_result;
     2364  }
     2365  // --------------------------------------------------------------------------------
     2366
     2367  // --------------------------------------------------------------------------------
     2368  // Function : privCloseFd()
     2369  // Description :
     2370  // Parameters :
     2371  // --------------------------------------------------------------------------------
     2372  function privCloseFd()
     2373  {
     2374    $v_result=1;
     2375
     2376    if ($this->zip_fd != 0)
     2377      @fclose($this->zip_fd);
     2378    $this->zip_fd = 0;
     2379
     2380    // ----- Return
     2381    return $v_result;
     2382  }
     2383  // --------------------------------------------------------------------------------
     2384
     2385  // --------------------------------------------------------------------------------
     2386  // Function : privAddList()
     2387  // Description :
     2388  //   $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
     2389  //   different from the real path of the file. This is usefull if you want to have PclTar
     2390  //   running in any directory, and memorize relative path from an other directory.
     2391  // Parameters :
     2392  //   $p_list : An array containing the file or directory names to add in the tar
     2393  //   $p_result_list : list of added files with their properties (specially the status field)
     2394  //   $p_add_dir : Path to add in the filename path archived
     2395  //   $p_remove_dir : Path to remove in the filename path archived
     2396  // Return Values :
     2397  // --------------------------------------------------------------------------------
     2398//  function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
     2399  function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
     2400  {
     2401    $v_result=1;
     2402
     2403    // ----- Add the files
     2404    $v_header_list = array();
     2405    if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
     2406    {
     2407      // ----- Return
     2408      return $v_result;
     2409    }
     2410
     2411    // ----- Store the offset of the central dir
     2412    $v_offset = @ftell($this->zip_fd);
     2413
     2414    // ----- Create the Central Dir files header
     2415    for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
     2416    {
     2417      // ----- Create the file header
     2418      if ($v_header_list[$i]['status'] == 'ok') {
     2419        if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
     2420          // ----- Return
     2421          return $v_result;
     2422        }
     2423        $v_count++;
     2424      }
     2425
     2426      // ----- Transform the header to a 'usable' info
     2427      $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
     2428    }
     2429
     2430    // ----- Zip file comment
     2431    $v_comment = '';
     2432    if (isset($p_options[PCLZIP_OPT_COMMENT])) {
     2433      $v_comment = $p_options[PCLZIP_OPT_COMMENT];
     2434    }
     2435
     2436    // ----- Calculate the size of the central header
     2437    $v_size = @ftell($this->zip_fd)-$v_offset;
     2438
     2439    // ----- Create the central dir footer
     2440    if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
     2441    {
     2442      // ----- Reset the file list
     2443      unset($v_header_list);
     2444
     2445      // ----- Return
     2446      return $v_result;
     2447    }
     2448
     2449    // ----- Return
     2450    return $v_result;
     2451  }
     2452  // --------------------------------------------------------------------------------
     2453
     2454  // --------------------------------------------------------------------------------
     2455  // Function : privAddFileList()
     2456  // Description :
     2457  // Parameters :
     2458  //   $p_filedescr_list : An array containing the file description
     2459  //                      or directory names to add in the zip
     2460  //   $p_result_list : list of added files with their properties (specially the status field)
     2461  // Return Values :
     2462  // --------------------------------------------------------------------------------
     2463  function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
     2464  {
     2465    $v_result=1;
     2466    $v_header = array();
     2467
     2468    // ----- Recuperate the current number of elt in list
     2469    $v_nb = sizeof($p_result_list);
     2470
     2471    // ----- Loop on the files
     2472    for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
     2473      // ----- Format the filename
     2474      $p_filedescr_list[$j]['filename']
     2475      = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
     2476     
     2477
     2478      // ----- Skip empty file names
     2479      // TBC : Can this be possible ? not checked in DescrParseAtt ?
     2480      if ($p_filedescr_list[$j]['filename'] == "") {
     2481        continue;
     2482      }
     2483
     2484      // ----- Check the filename
     2485      if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
     2486          && (!file_exists($p_filedescr_list[$j]['filename']))) {
     2487        PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
     2488        return PclZip::errorCode();
     2489      }
     2490
     2491      // ----- Look if it is a file or a dir with no all path remove option
     2492      // or a dir with all its path removed
     2493//      if (   (is_file($p_filedescr_list[$j]['filename']))
     2494//          || (   is_dir($p_filedescr_list[$j]['filename'])
     2495      if (   ($p_filedescr_list[$j]['type'] == 'file')
     2496          || ($p_filedescr_list[$j]['type'] == 'virtual_file')
     2497          || (   ($p_filedescr_list[$j]['type'] == 'folder')
     2498              && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
     2499                  || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
     2500          ) {
     2501
     2502        // ----- Add the file
     2503        $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
     2504                                       $p_options);
     2505        if ($v_result != 1) {
     2506          return $v_result;
     2507        }
     2508
     2509        // ----- Store the file infos
     2510        $p_result_list[$v_nb++] = $v_header;
     2511      }
     2512    }
     2513
     2514    // ----- Return
     2515    return $v_result;
     2516  }
     2517  // --------------------------------------------------------------------------------
     2518
     2519  // --------------------------------------------------------------------------------
     2520  // Function : privAddFile()
     2521  // Description :
     2522  // Parameters :
     2523  // Return Values :
     2524  // --------------------------------------------------------------------------------
     2525  function privAddFile($p_filedescr, &$p_header, &$p_options)
     2526  {
     2527    $v_result=1;
     2528   
     2529    // ----- Working variable
     2530    $p_filename = $p_filedescr['filename'];
     2531
     2532    // TBC : Already done in the fileAtt check ... ?
     2533    if ($p_filename == "") {
     2534      // ----- Error log
     2535      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
     2536
     2537      // ----- Return
     2538      return PclZip::errorCode();
     2539    }
    6372540 
    638   $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
    639 
    640   return $p_list;
    641 }
    642 
    643 function properties()
    644 {
    645 
    646   $this->privErrorReset();
    647 
    648   $this->privDisableMagicQuotes();
    649 
    650   if (!$this->privCheckFormat()) {
    651     $this->privSwapBackMagicQuotes();
    652     return(0);
    653   }
    654 
    655   $v_prop = array();
    656   $v_prop['comment'] = '';
    657   $v_prop['nb'] = 0;
    658   $v_prop['status'] = 'not_exist';
    659 
    660   if (@is_file($this->zipname))
     2541    // ----- Look for a stored different filename
     2542    /* TBC : Removed
     2543    if (isset($p_filedescr['stored_filename'])) {
     2544      $v_stored_filename = $p_filedescr['stored_filename'];
     2545    }
     2546    else {
     2547      $v_stored_filename = $p_filedescr['stored_filename'];
     2548    }
     2549    */
     2550
     2551    // ----- Set the file properties
     2552    clearstatcache();
     2553    $p_header['version'] = 20;
     2554    $p_header['version_extracted'] = 10;
     2555    $p_header['flag'] = 0;
     2556    $p_header['compression'] = 0;
     2557    $p_header['crc'] = 0;
     2558    $p_header['compressed_size'] = 0;
     2559    $p_header['filename_len'] = strlen($p_filename);
     2560    $p_header['extra_len'] = 0;
     2561    $p_header['disk'] = 0;
     2562    $p_header['internal'] = 0;
     2563    $p_header['offset'] = 0;
     2564    $p_header['filename'] = $p_filename;
     2565// TBC : Removed    $p_header['stored_filename'] = $v_stored_filename;
     2566    $p_header['stored_filename'] = $p_filedescr['stored_filename'];
     2567    $p_header['extra'] = '';
     2568    $p_header['status'] = 'ok';
     2569    $p_header['index'] = -1;
     2570
     2571    // ----- Look for regular file
     2572    if ($p_filedescr['type']=='file') {
     2573      $p_header['external'] = 0x00000000;
     2574      $p_header['size'] = filesize($p_filename);
     2575    }
     2576   
     2577    // ----- Look for regular folder
     2578    else if ($p_filedescr['type']=='folder') {
     2579      $p_header['external'] = 0x00000010;
     2580      $p_header['mtime'] = filemtime($p_filename);
     2581      $p_header['size'] = filesize($p_filename);
     2582    }
     2583   
     2584    // ----- Look for virtual file
     2585    else if ($p_filedescr['type'] == 'virtual_file') {
     2586      $p_header['external'] = 0x00000000;
     2587      $p_header['size'] = strlen($p_filedescr['content']);
     2588    }
     2589   
     2590
     2591    // ----- Look for filetime
     2592    if (isset($p_filedescr['mtime'])) {
     2593      $p_header['mtime'] = $p_filedescr['mtime'];
     2594    }
     2595    else if ($p_filedescr['type'] == 'virtual_file') {
     2596      $p_header['mtime'] = time();
     2597    }
     2598    else {
     2599      $p_header['mtime'] = filemtime($p_filename);
     2600    }
     2601
     2602    // ------ Look for file comment
     2603    if (isset($p_filedescr['comment'])) {
     2604      $p_header['comment_len'] = strlen($p_filedescr['comment']);
     2605      $p_header['comment'] = $p_filedescr['comment'];
     2606    }
     2607    else {
     2608      $p_header['comment_len'] = 0;
     2609      $p_header['comment'] = '';
     2610    }
     2611
     2612    // ----- Look for pre-add callback
     2613    if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
     2614
     2615      // ----- Generate a local information
     2616      $v_local_header = array();
     2617      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
     2618
     2619      // ----- Call the callback
     2620      // Here I do not use call_user_func() because I need to send a reference to the
     2621      // header.
     2622//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
     2623      $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
     2624      if ($v_result == 0) {
     2625        // ----- Change the file status
     2626        $p_header['status'] = "skipped";
     2627        $v_result = 1;
     2628      }
     2629
     2630      // ----- Update the informations
     2631      // Only some fields can be modified
     2632      if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
     2633        $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
     2634      }
     2635    }
     2636
     2637    // ----- Look for empty stored filename
     2638    if ($p_header['stored_filename'] == "") {
     2639      $p_header['status'] = "filtered";
     2640    }
     2641   
     2642    // ----- Check the path length
     2643    if (strlen($p_header['stored_filename']) > 0xFF) {
     2644      $p_header['status'] = 'filename_too_long';
     2645    }
     2646
     2647    // ----- Look if no error, or file not skipped
     2648    if ($p_header['status'] == 'ok') {
     2649
     2650      // ----- Look for a file
     2651      if ($p_filedescr['type'] == 'file') {
     2652        // ----- Look for using temporary file to zip
     2653        if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
     2654            && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
     2655                || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
     2656                    && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
     2657          $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
     2658          if ($v_result < PCLZIP_ERR_NO_ERROR) {
     2659            return $v_result;
     2660          }
     2661        }
     2662       
     2663        // ----- Use "in memory" zip algo
     2664        else {
     2665
     2666        // ----- Open the source file
     2667        if (($v_file = @fopen($p_filename, "rb")) == 0) {
     2668          PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
     2669          return PclZip::errorCode();
     2670        }
     2671
     2672        // ----- Read the file content
     2673        $v_content = @fread($v_file, $p_header['size']);
     2674
     2675        // ----- Close the file
     2676        @fclose($v_file);
     2677
     2678        // ----- Calculate the CRC
     2679        $p_header['crc'] = @crc32($v_content);
     2680       
     2681        // ----- Look for no compression
     2682        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
     2683          // ----- Set header parameters
     2684          $p_header['compressed_size'] = $p_header['size'];
     2685          $p_header['compression'] = 0;
     2686        }
     2687       
     2688        // ----- Look for normal compression
     2689        else {
     2690          // ----- Compress the content
     2691          $v_content = @gzdeflate($v_content);
     2692
     2693          // ----- Set header parameters
     2694          $p_header['compressed_size'] = strlen($v_content);
     2695          $p_header['compression'] = 8;
     2696        }
     2697       
     2698        // ----- Call the header generation
     2699        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
     2700          @fclose($v_file);
     2701          return $v_result;
     2702        }
     2703
     2704        // ----- Write the compressed (or not) content
     2705        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
     2706
     2707        }
     2708
     2709      }
     2710
     2711      // ----- Look for a virtual file (a file from string)
     2712      else if ($p_filedescr['type'] == 'virtual_file') {
     2713         
     2714        $v_content = $p_filedescr['content'];
     2715
     2716        // ----- Calculate the CRC
     2717        $p_header['crc'] = @crc32($v_content);
     2718       
     2719        // ----- Look for no compression
     2720        if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
     2721          // ----- Set header parameters
     2722          $p_header['compressed_size'] = $p_header['size'];
     2723          $p_header['compression'] = 0;
     2724        }
     2725       
     2726        // ----- Look for normal compression
     2727        else {
     2728          // ----- Compress the content
     2729          $v_content = @gzdeflate($v_content);
     2730
     2731          // ----- Set header parameters
     2732          $p_header['compressed_size'] = strlen($v_content);
     2733          $p_header['compression'] = 8;
     2734        }
     2735       
     2736        // ----- Call the header generation
     2737        if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
     2738          @fclose($v_file);
     2739          return $v_result;
     2740        }
     2741
     2742        // ----- Write the compressed (or not) content
     2743        @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
     2744      }
     2745
     2746      // ----- Look for a directory
     2747      else if ($p_filedescr['type'] == 'folder') {
     2748        // ----- Look for directory last '/'
     2749        if (@substr($p_header['stored_filename'], -1) != '/') {
     2750          $p_header['stored_filename'] .= '/';
     2751        }
     2752
     2753        // ----- Set the file properties
     2754        $p_header['size'] = 0;
     2755        //$p_header['external'] = 0x41FF0010;   // Value for a folder : to be checked
     2756        $p_header['external'] = 0x00000010;   // Value for a folder : to be checked
     2757
     2758        // ----- Call the header generation
     2759        if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
     2760        {
     2761          return $v_result;
     2762        }
     2763      }
     2764    }
     2765
     2766    // ----- Look for post-add callback
     2767    if (isset($p_options[PCLZIP_CB_POST_ADD])) {
     2768
     2769      // ----- Generate a local information
     2770      $v_local_header = array();
     2771      $this->privConvertHeader2FileInfo($p_header, $v_local_header);
     2772
     2773      // ----- Call the callback
     2774      // Here I do not use call_user_func() because I need to send a reference to the
     2775      // header.
     2776//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
     2777      $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
     2778      if ($v_result == 0) {
     2779        // ----- Ignored
     2780        $v_result = 1;
     2781      }
     2782
     2783      // ----- Update the informations
     2784      // Nothing can be modified
     2785    }
     2786
     2787    // ----- Return
     2788    return $v_result;
     2789  }
     2790  // --------------------------------------------------------------------------------
     2791
     2792  // --------------------------------------------------------------------------------
     2793  // Function : privAddFileUsingTempFile()
     2794  // Description :
     2795  // Parameters :
     2796  // Return Values :
     2797  // --------------------------------------------------------------------------------
     2798  function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
    6612799  {
     2800    $v_result=PCLZIP_ERR_NO_ERROR;
     2801   
     2802    // ----- Working variable
     2803    $p_filename = $p_filedescr['filename'];
     2804
     2805
     2806    // ----- Open the source file
     2807    if (($v_file = @fopen($p_filename, "rb")) == 0) {
     2808      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
     2809      return PclZip::errorCode();
     2810    }
     2811
     2812    // ----- Creates a compressed temporary file
     2813    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
     2814    if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
     2815      fclose($v_file);
     2816      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
     2817      return PclZip::errorCode();
     2818    }
     2819
     2820    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
     2821    $v_size = filesize($p_filename);
     2822    while ($v_size != 0) {
     2823      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
     2824      $v_buffer = @fread($v_file, $v_read_size);
     2825      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
     2826      @gzputs($v_file_compressed, $v_buffer, $v_read_size);
     2827      $v_size -= $v_read_size;
     2828    }
     2829
     2830    // ----- Close the file
     2831    @fclose($v_file);
     2832    @gzclose($v_file_compressed);
     2833
     2834    // ----- Check the minimum file size
     2835    if (filesize($v_gzip_temp_name) < 18) {
     2836      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
     2837      return PclZip::errorCode();
     2838    }
     2839
     2840    // ----- Extract the compressed attributes
     2841    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
     2842      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
     2843      return PclZip::errorCode();
     2844    }
     2845
     2846    // ----- Read the gzip file header
     2847    $v_binary_data = @fread($v_file_compressed, 10);
     2848    $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
     2849
     2850    // ----- Check some parameters
     2851    $v_data_header['os'] = bin2hex($v_data_header['os']);
     2852
     2853    // ----- Read the gzip file footer
     2854    @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
     2855    $v_binary_data = @fread($v_file_compressed, 8);
     2856    $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
     2857
     2858    // ----- Set the attributes
     2859    $p_header['compression'] = ord($v_data_header['cm']);
     2860    //$p_header['mtime'] = $v_data_header['mtime'];
     2861    $p_header['crc'] = $v_data_footer['crc'];
     2862    $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
     2863
     2864    // ----- Close the file
     2865    @fclose($v_file_compressed);
     2866
     2867    // ----- Call the header generation
     2868    if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
     2869      return $v_result;
     2870    }
     2871
     2872    // ----- Add the compressed data
     2873    if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
     2874    {
     2875      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
     2876      return PclZip::errorCode();
     2877    }
     2878
     2879    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
     2880    fseek($v_file_compressed, 10);
     2881    $v_size = $p_header['compressed_size'];
     2882    while ($v_size != 0)
     2883    {
     2884      $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
     2885      $v_buffer = @fread($v_file_compressed, $v_read_size);
     2886      //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
     2887      @fwrite($this->zip_fd, $v_buffer, $v_read_size);
     2888      $v_size -= $v_read_size;
     2889    }
     2890
     2891    // ----- Close the file
     2892    @fclose($v_file_compressed);
     2893
     2894    // ----- Unlink the temporary file
     2895    @unlink($v_gzip_temp_name);
     2896   
     2897    // ----- Return
     2898    return $v_result;
     2899  }
     2900  // --------------------------------------------------------------------------------
     2901
     2902  // --------------------------------------------------------------------------------
     2903  // Function : privCalculateStoredFilename()
     2904  // Description :
     2905  //   Based on file descriptor properties and global options, this method
     2906  //   calculate the filename that will be stored in the archive.
     2907  // Parameters :
     2908  // Return Values :
     2909  // --------------------------------------------------------------------------------
     2910  function privCalculateStoredFilename(&$p_filedescr, &$p_options)
     2911  {
     2912    $v_result=1;
     2913   
     2914    // ----- Working variables
     2915    $p_filename = $p_filedescr['filename'];
     2916    if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
     2917      $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
     2918    }
     2919    else {
     2920      $p_add_dir = '';
     2921    }
     2922    if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
     2923      $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
     2924    }
     2925    else {
     2926      $p_remove_dir = '';
     2927    }
     2928    if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
     2929      $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
     2930    }
     2931    else {
     2932      $p_remove_all_dir = 0;
     2933    }
     2934
     2935
     2936    // ----- Look for full name change
     2937    if (isset($p_filedescr['new_full_name'])) {
     2938      // ----- Remove drive letter if any
     2939      $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
     2940    }
     2941   
     2942    // ----- Look for path and/or short name change
     2943    else {
     2944
     2945      // ----- Look for short name change
     2946      // Its when we cahnge just the filename but not the path
     2947      if (isset($p_filedescr['new_short_name'])) {
     2948        $v_path_info = pathinfo($p_filename);
     2949        $v_dir = '';
     2950        if ($v_path_info['dirname'] != '') {
     2951          $v_dir = $v_path_info['dirname'].'/';
     2952        }
     2953        $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
     2954      }
     2955      else {
     2956        // ----- Calculate the stored filename
     2957        $v_stored_filename = $p_filename;
     2958      }
     2959
     2960      // ----- Look for all path to remove
     2961      if ($p_remove_all_dir) {
     2962        $v_stored_filename = basename($p_filename);
     2963      }
     2964      // ----- Look for partial path remove
     2965      else if ($p_remove_dir != "") {
     2966        if (substr($p_remove_dir, -1) != '/')
     2967          $p_remove_dir .= "/";
     2968
     2969        if (   (substr($p_filename, 0, 2) == "./")
     2970            || (substr($p_remove_dir, 0, 2) == "./")) {
     2971           
     2972          if (   (substr($p_filename, 0, 2) == "./")
     2973              && (substr($p_remove_dir, 0, 2) != "./")) {
     2974            $p_remove_dir = "./".$p_remove_dir;
     2975          }
     2976          if (   (substr($p_filename, 0, 2) != "./")
     2977              && (substr($p_remove_dir, 0, 2) == "./")) {
     2978            $p_remove_dir = substr($p_remove_dir, 2);
     2979          }
     2980        }
     2981
     2982        $v_compare = PclZipUtilPathInclusion($p_remove_dir,
     2983                                             $v_stored_filename);
     2984        if ($v_compare > 0) {
     2985          if ($v_compare == 2) {
     2986            $v_stored_filename = "";
     2987          }
     2988          else {
     2989            $v_stored_filename = substr($v_stored_filename,
     2990                                        strlen($p_remove_dir));
     2991          }
     2992        }
     2993      }
     2994     
     2995      // ----- Remove drive letter if any
     2996      $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
     2997     
     2998      // ----- Look for path to add
     2999      if ($p_add_dir != "") {
     3000        if (substr($p_add_dir, -1) == "/")
     3001          $v_stored_filename = $p_add_dir.$v_stored_filename;
     3002        else
     3003          $v_stored_filename = $p_add_dir."/".$v_stored_filename;
     3004      }
     3005    }
     3006
     3007    // ----- Filename (reduce the path of stored name)
     3008    $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
     3009    $p_filedescr['stored_filename'] = $v_stored_filename;
     3010   
     3011    // ----- Return
     3012    return $v_result;
     3013  }
     3014  // --------------------------------------------------------------------------------
     3015
     3016  // --------------------------------------------------------------------------------
     3017  // Function : privWriteFileHeader()
     3018  // Description :
     3019  // Parameters :
     3020  // Return Values :
     3021  // --------------------------------------------------------------------------------
     3022  function privWriteFileHeader(&$p_header)
     3023  {
     3024    $v_result=1;
     3025
     3026    // ----- Store the offset position of the file
     3027    $p_header['offset'] = ftell($this->zip_fd);
     3028
     3029    // ----- Transform UNIX mtime to DOS format mdate/mtime
     3030    $v_date = getdate($p_header['mtime']);
     3031    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
     3032    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
     3033
     3034    // ----- Packed data
     3035    $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
     3036                              $p_header['version_extracted'], $p_header['flag'],
     3037                          $p_header['compression'], $v_mtime, $v_mdate,
     3038                          $p_header['crc'], $p_header['compressed_size'],
     3039                                                  $p_header['size'],
     3040                          strlen($p_header['stored_filename']),
     3041                                                  $p_header['extra_len']);
     3042
     3043    // ----- Write the first 148 bytes of the header in the archive
     3044    fputs($this->zip_fd, $v_binary_data, 30);
     3045
     3046    // ----- Write the variable fields
     3047    if (strlen($p_header['stored_filename']) != 0)
     3048    {
     3049      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
     3050    }
     3051    if ($p_header['extra_len'] != 0)
     3052    {
     3053      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
     3054    }
     3055
     3056    // ----- Return
     3057    return $v_result;
     3058  }
     3059  // --------------------------------------------------------------------------------
     3060
     3061  // --------------------------------------------------------------------------------
     3062  // Function : privWriteCentralFileHeader()
     3063  // Description :
     3064  // Parameters :
     3065  // Return Values :
     3066  // --------------------------------------------------------------------------------
     3067  function privWriteCentralFileHeader(&$p_header)
     3068  {
     3069    $v_result=1;
     3070
     3071    // TBC
     3072    //for(reset($p_header); $key = key($p_header); next($p_header)) {
     3073    //}
     3074
     3075    // ----- Transform UNIX mtime to DOS format mdate/mtime
     3076    $v_date = getdate($p_header['mtime']);
     3077    $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
     3078    $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
     3079
     3080
     3081    // ----- Packed data
     3082    $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
     3083                              $p_header['version'], $p_header['version_extracted'],
     3084                          $p_header['flag'], $p_header['compression'],
     3085                                                  $v_mtime, $v_mdate, $p_header['crc'],
     3086                          $p_header['compressed_size'], $p_header['size'],
     3087                          strlen($p_header['stored_filename']),
     3088                                                  $p_header['extra_len'], $p_header['comment_len'],
     3089                          $p_header['disk'], $p_header['internal'],
     3090                                                  $p_header['external'], $p_header['offset']);
     3091
     3092    // ----- Write the 42 bytes of the header in the zip file
     3093    fputs($this->zip_fd, $v_binary_data, 46);
     3094
     3095    // ----- Write the variable fields
     3096    if (strlen($p_header['stored_filename']) != 0)
     3097    {
     3098      fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
     3099    }
     3100    if ($p_header['extra_len'] != 0)
     3101    {
     3102      fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
     3103    }
     3104    if ($p_header['comment_len'] != 0)
     3105    {
     3106      fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
     3107    }
     3108
     3109    // ----- Return
     3110    return $v_result;
     3111  }
     3112  // --------------------------------------------------------------------------------
     3113
     3114  // --------------------------------------------------------------------------------
     3115  // Function : privWriteCentralHeader()
     3116  // Description :
     3117  // Parameters :
     3118  // Return Values :
     3119  // --------------------------------------------------------------------------------
     3120  function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
     3121  {
     3122    $v_result=1;
     3123
     3124    // ----- Packed data
     3125    $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
     3126                              $p_nb_entries, $p_size,
     3127                                                  $p_offset, strlen($p_comment));
     3128
     3129    // ----- Write the 22 bytes of the header in the zip file
     3130    fputs($this->zip_fd, $v_binary_data, 22);
     3131
     3132    // ----- Write the variable fields
     3133    if (strlen($p_comment) != 0)
     3134    {
     3135      fputs($this->zip_fd, $p_comment, strlen($p_comment));
     3136    }
     3137
     3138    // ----- Return
     3139    return $v_result;
     3140  }
     3141  // --------------------------------------------------------------------------------
     3142
     3143  // --------------------------------------------------------------------------------
     3144  // Function : privList()
     3145  // Description :
     3146  // Parameters :
     3147  // Return Values :
     3148  // --------------------------------------------------------------------------------
     3149  function privList(&$p_list)
     3150  {
     3151    $v_result=1;
     3152
     3153    // ----- Magic quotes trick
     3154    $this->privDisableMagicQuotes();
     3155
     3156    // ----- Open the zip file
    6623157    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
    6633158    {
     3159      // ----- Magic quotes trick
    6643160      $this->privSwapBackMagicQuotes();
    6653161     
     3162      // ----- Error log
    6663163      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
    6673164
    668       return 0;
    669     }
    670 
     3165      // ----- Return
     3166      return PclZip::errorCode();
     3167    }
     3168
     3169    // ----- Read the central directory informations
    6713170    $v_central_dir = array();
    6723171    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
    6733172    {
    6743173      $this->privSwapBackMagicQuotes();
    675       return 0;
    676     }
    677 
     3174      return $v_result;
     3175    }
     3176
     3177    // ----- Go to beginning of Central Dir
     3178    @rewind($this->zip_fd);
     3179    if (@fseek($this->zip_fd, $v_central_dir['offset']))
     3180    {
     3181      $this->privSwapBackMagicQuotes();
     3182
     3183      // ----- Error log
     3184      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
     3185
     3186      // ----- Return
     3187      return PclZip::errorCode();
     3188    }
     3189
     3190    // ----- Read each entry
     3191    for ($i=0; $i<$v_central_dir['entries']; $i++)
     3192    {
     3193      // ----- Read the file header
     3194      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
     3195      {
     3196        $this->privSwapBackMagicQuotes();
     3197        return $v_result;
     3198      }
     3199      $v_header['index'] = $i;
     3200
     3201      // ----- Get the only interesting attributes
     3202      $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
     3203      unset($v_header);
     3204    }
     3205
     3206    // ----- Close the zip file
    6783207    $this->privCloseFd();
    6793208
    680     $v_prop['comment'] = $v_central_dir['comment'];
    681     $v_prop['nb'] = $v_central_dir['entries'];
    682     $v_prop['status'] = 'ok';
    683   }
    684 
    685   $this->privSwapBackMagicQuotes();
    686 
    687   return $v_prop;
    688 }
    689 
    690 function duplicate($p_archive)
    691 {
    692   $v_result = 1;
    693 
    694   $this->privErrorReset();
    695 
    696   if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
     3209    // ----- Magic quotes trick
     3210    $this->privSwapBackMagicQuotes();
     3211
     3212    // ----- Return
     3213    return $v_result;
     3214  }
     3215  // --------------------------------------------------------------------------------
     3216
     3217  // --------------------------------------------------------------------------------
     3218  // Function : privConvertHeader2FileInfo()
     3219  // Description :
     3220  //   This function takes the file informations from the central directory
     3221  //   entries and extract the interesting parameters that will be given back.
     3222  //   The resulting file infos are set in the array $p_info
     3223  //     $p_info['filename'] : Filename with full path. Given by user (add),
     3224  //                           extracted in the filesystem (extract).
     3225  //     $p_info['stored_filename'] : Stored filename in the archive.
     3226  //     $p_info['size'] = Size of the file.
     3227  //     $p_info['compressed_size'] = Compressed size of the file.
     3228  //     $p_info['mtime'] = Last modification date of the file.
     3229  //     $p_info['comment'] = Comment associated with the file.
     3230  //     $p_info['folder'] = true/false : indicates if the entry is a folder or not.
     3231  //     $p_info['status'] = status of the action on the file.
     3232  //     $p_info['crc'] = CRC of the file content.
     3233  // Parameters :
     3234  // Return Values :
     3235  // --------------------------------------------------------------------------------
     3236  function privConvertHeader2FileInfo($p_header, &$p_info)
    6973237  {
    698 
    699     $v_result = $this->privDuplicate($p_archive->zipname);
    700   }
    701 
    702   else if (is_string($p_archive))
     3238    $v_result=1;
     3239
     3240    // ----- Get the interesting attributes
     3241    $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
     3242    $p_info['filename'] = $v_temp_path;
     3243    $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
     3244    $p_info['stored_filename'] = $v_temp_path;
     3245    $p_info['size'] = $p_header['size'];
     3246    $p_info['compressed_size'] = $p_header['compressed_size'];
     3247    $p_info['mtime'] = $p_header['mtime'];
     3248    $p_info['comment'] = $p_header['comment'];
     3249    $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
     3250    $p_info['index'] = $p_header['index'];
     3251    $p_info['status'] = $p_header['status'];
     3252    $p_info['crc'] = $p_header['crc'];
     3253
     3254    // ----- Return
     3255    return $v_result;
     3256  }
     3257  // --------------------------------------------------------------------------------
     3258
     3259  // --------------------------------------------------------------------------------
     3260  // Function : privExtractByRule()
     3261  // Description :
     3262  //   Extract a file or directory depending of rules (by index, by name, ...)
     3263  // Parameters :
     3264  //   $p_file_list : An array where will be placed the properties of each
     3265  //                  extracted file
     3266  //   $p_path : Path to add while writing the extracted files
     3267  //   $p_remove_path : Path to remove (from the file memorized path) while writing the
     3268  //                    extracted files. If the path does not match the file path,
     3269  //                    the file is extracted with its memorized path.
     3270  //                    $p_remove_path does not apply to 'list' mode.
     3271  //                    $p_path and $p_remove_path are commulative.
     3272  // Return Values :
     3273  //   1 on success,0 or less on error (see error code list)
     3274  // --------------------------------------------------------------------------------
     3275  function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
    7033276  {
    704 
    705     if (!is_file($p_archive)) {
    706       PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
    707       $v_result = PCLZIP_ERR_MISSING_FILE;
    708     }
    709     else {
    710       $v_result = $this->privDuplicate($p_archive);
    711     }
    712   }
    713 
    714   else
    715   {
    716     PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
    717     $v_result = PCLZIP_ERR_INVALID_PARAMETER;
    718   }
    719 
    720   return $v_result;
    721 }
    722 
    723 function merge($p_archive_to_add)
    724 {
    725   $v_result = 1;
    726 
    727   $this->privErrorReset();
    728 
    729   if (!$this->privCheckFormat()) {
    730     return(0);
    731   }
    732 
    733   if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
    734   {
    735 
    736     $v_result = $this->privMerge($p_archive_to_add);
    737   }
    738 
    739   else if (is_string($p_archive_to_add))
    740   {
    741 
    742     $v_object_archive = new PclZip($p_archive_to_add);
    743 
    744     $v_result = $this->privMerge($v_object_archive);
    745   }
    746 
    747   else
    748   {
    749     PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
    750     $v_result = PCLZIP_ERR_INVALID_PARAMETER;
    751   }
    752 
    753   return $v_result;
    754 }
    755 
    756 
    757 
    758 function errorCode()
    759 {
    760   if (PCLZIP_ERROR_EXTERNAL == 1) {
    761     return(PclErrorCode());
    762   }
    763   else {
    764     return($this->error_code);
    765   }
    766 }
    767 
    768 function errorName($p_with_code=false)
    769 {
    770   $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
    771                     PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
    772                     PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
    773                     PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
    774                     PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
    775                     PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
    776                     PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
    777                     PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
    778                     PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
    779                     PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
    780                     PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
    781                     PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
    782                     PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
    783                     PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
    784                     PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
    785                     PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
    786                     PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
    787                     PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
    788                     PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
    789                     ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
    790                     ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
    791                   );
    792 
    793   if (isset($v_name[$this->error_code])) {
    794     $v_value = $v_name[$this->error_code];
    795   }
    796   else {
    797     $v_value = 'NoName';
    798   }
    799 
    800   if ($p_with_code) {
    801     return($v_value.' ('.$this->error_code.')');
    802   }
    803   else {
    804     return($v_value);
    805   }
    806 }
    807 
    808 function errorInfo($p_full=false)
    809 {
    810   if (PCLZIP_ERROR_EXTERNAL == 1) {
    811     return(PclErrorString());
    812   }
    813   else {
    814     if ($p_full) {
    815       return($this->errorName(true)." : ".$this->error_string);
    816     }
    817     else {
    818       return($this->error_string." [code ".$this->error_code."]");
    819     }
    820   }
    821 }
    822 
    823 
    824 
    825 
    826 
    827 function privCheckFormat($p_level=0)
    828 {
    829   $v_result = true;
    830 
    831   clearstatcache();
    832 
    833   $this->privErrorReset();
    834 
    835   if (!is_file($this->zipname)) {
    836     PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
    837     return(false);
    838   }
    839 
    840   if (!is_readable($this->zipname)) {
    841     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
    842     return(false);
    843   }
    844 
    845 
    846 
    847 
    848   return $v_result;
    849 }
    850 
    851 function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
    852 {
    853   $v_result=1;
    854  
    855   $i=0;
    856   while ($i<$p_size) {
    857 
    858     if (!isset($v_requested_options[$p_options_list[$i]])) {
    859       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
    860 
    861       return PclZip::errorCode();
    862     }
    863 
    864     switch ($p_options_list[$i]) {
    865       case PCLZIP_OPT_PATH :
    866       case PCLZIP_OPT_REMOVE_PATH :
    867       case PCLZIP_OPT_ADD_PATH :
    868         if (($i+1) >= $p_size) {
    869           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    870 
    871           return PclZip::errorCode();
    872         }
    873 
    874         $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
    875         $i++;
    876       break;
    877 
    878       case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
    879         if (($i+1) >= $p_size) {
    880           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    881           return PclZip::errorCode();
    882         }
    883        
    884         if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
    885           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
    886           return PclZip::errorCode();
    887         }
    888        
    889         $v_value = $p_options_list[$i+1];
    890         if ((!is_integer($v_value)) || ($v_value<0)) {
    891           PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    892           return PclZip::errorCode();
    893         }
    894 
    895         $v_result_list[$p_options_list[$i]] = $v_value*1048576;
    896         $i++;
    897       break;
    898 
    899       case PCLZIP_OPT_TEMP_FILE_ON :
    900         if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
    901           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
    902           return PclZip::errorCode();
    903         }
    904        
    905         $v_result_list[$p_options_list[$i]] = true;
    906       break;
    907 
    908       case PCLZIP_OPT_TEMP_FILE_OFF :
    909         if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
    910           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
    911           return PclZip::errorCode();
    912         }
    913         if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
    914           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
    915           return PclZip::errorCode();
    916         }
    917        
    918         $v_result_list[$p_options_list[$i]] = true;
    919       break;
    920 
    921       case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
    922         if (($i+1) >= $p_size) {
    923           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    924 
    925           return PclZip::errorCode();
    926         }
    927 
    928         if (   is_string($p_options_list[$i+1])
    929             && ($p_options_list[$i+1] != '')) {
    930           $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
    931           $i++;
    932         }
    933         else {
    934         }
    935       break;
    936 
    937       case PCLZIP_OPT_BY_NAME :
    938         if (($i+1) >= $p_size) {
    939           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    940 
    941           return PclZip::errorCode();
    942         }
    943 
    944         if (is_string($p_options_list[$i+1])) {
    945             $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
    946         }
    947         else if (is_array($p_options_list[$i+1])) {
    948             $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
    949         }
    950         else {
    951           PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    952 
    953           return PclZip::errorCode();
    954         }
    955         $i++;
    956       break;
    957 
    958       case PCLZIP_OPT_BY_EREG :
    959         $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
    960       case PCLZIP_OPT_BY_PREG :
    961         if (($i+1) >= $p_size) {
    962           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    963 
    964           return PclZip::errorCode();
    965         }
    966 
    967         if (is_string($p_options_list[$i+1])) {
    968             $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
    969         }
    970         else {
    971           PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    972 
    973           return PclZip::errorCode();
    974         }
    975         $i++;
    976       break;
    977 
    978       case PCLZIP_OPT_COMMENT :
    979       case PCLZIP_OPT_ADD_COMMENT :
    980       case PCLZIP_OPT_PREPEND_COMMENT :
    981         if (($i+1) >= $p_size) {
    982           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
    983                          "Missing parameter value for option '"
    984                .PclZipUtilOptionText($p_options_list[$i])
    985                ."'");
    986 
    987           return PclZip::errorCode();
    988         }
    989 
    990         if (is_string($p_options_list[$i+1])) {
    991             $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
    992         }
    993         else {
    994           PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
    995                          "Wrong parameter value for option '"
    996                .PclZipUtilOptionText($p_options_list[$i])
    997                ."'");
    998 
    999           return PclZip::errorCode();
    1000         }
    1001         $i++;
    1002       break;
    1003 
    1004       case PCLZIP_OPT_BY_INDEX :
    1005         if (($i+1) >= $p_size) {
    1006           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1007 
    1008           return PclZip::errorCode();
    1009         }
    1010 
    1011         $v_work_list = array();
    1012         if (is_string($p_options_list[$i+1])) {
    1013 
    1014             $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
    1015 
    1016             $v_work_list = explode(",", $p_options_list[$i+1]);
    1017         }
    1018         else if (is_integer($p_options_list[$i+1])) {
    1019             $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
    1020         }
    1021         else if (is_array($p_options_list[$i+1])) {
    1022             $v_work_list = $p_options_list[$i+1];
    1023         }
    1024         else {
    1025           PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1026 
    1027           return PclZip::errorCode();
    1028         }
    1029        
    1030         $v_sort_flag=false;
    1031         $v_sort_value=0;
    1032         for ($j=0; $j<sizeof($v_work_list); $j++) {
    1033             $v_item_list = explode("-", $v_work_list[$j]);
    1034             $v_size_item_list = sizeof($v_item_list);
    1035            
    1036            
    1037             if ($v_size_item_list == 1) {
    1038                 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
    1039                 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
    1040             }
    1041             elseif ($v_size_item_list == 2) {
    1042                 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
    1043                 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
    1044             }
    1045             else {
    1046                 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1047 
    1048                 return PclZip::errorCode();
    1049             }
    1050 
    1051 
    1052             if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
    1053                 $v_sort_flag=true;
    1054 
    1055                 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1056 
    1057                 return PclZip::errorCode();
    1058             }
    1059             $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
    1060         }
    1061        
    1062         if ($v_sort_flag) {
    1063         }
    1064 
    1065         $i++;
    1066       break;
    1067 
    1068       case PCLZIP_OPT_REMOVE_ALL_PATH :
    1069       case PCLZIP_OPT_EXTRACT_AS_STRING :
    1070       case PCLZIP_OPT_NO_COMPRESSION :
    1071       case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
    1072       case PCLZIP_OPT_REPLACE_NEWER :
    1073       case PCLZIP_OPT_STOP_ON_ERROR :
    1074         $v_result_list[$p_options_list[$i]] = true;
    1075       break;
    1076 
    1077       case PCLZIP_OPT_SET_CHMOD :
    1078         if (($i+1) >= $p_size) {
    1079           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1080 
    1081           return PclZip::errorCode();
    1082         }
    1083 
    1084         $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
    1085         $i++;
    1086       break;
    1087 
    1088       case PCLZIP_CB_PRE_EXTRACT :
    1089       case PCLZIP_CB_POST_EXTRACT :
    1090       case PCLZIP_CB_PRE_ADD :
    1091       case PCLZIP_CB_POST_ADD :
    1092       /* for futur use
    1093       case PCLZIP_CB_PRE_DELETE :
    1094       case PCLZIP_CB_POST_DELETE :
    1095       case PCLZIP_CB_PRE_LIST :
    1096       case PCLZIP_CB_POST_LIST :
    1097       */
    1098         if (($i+1) >= $p_size) {
    1099           PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1100 
    1101           return PclZip::errorCode();
    1102         }
    1103 
    1104         $v_function_name = $p_options_list[$i+1];
    1105 
    1106         if (!function_exists($v_function_name)) {
    1107           PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
    1108 
    1109           return PclZip::errorCode();
    1110         }
    1111 
    1112         $v_result_list[$p_options_list[$i]] = $v_function_name;
    1113         $i++;
    1114       break;
    1115 
    1116       default :
    1117         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
    1118                          "Unknown parameter '"
    1119                .$p_options_list[$i]."'");
    1120 
    1121         return PclZip::errorCode();
    1122     }
    1123 
    1124     $i++;
    1125   }
    1126 
    1127   if ($v_requested_options !== false) {
    1128     for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
    1129       if ($v_requested_options[$key] == 'mandatory') {
    1130         if (!isset($v_result_list[$key])) {
    1131           PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
    1132 
    1133           return PclZip::errorCode();
    1134         }
    1135       }
    1136     }
    1137   }
    1138  
    1139   if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
    1140    
    1141   }
    1142 
    1143   return $v_result;
    1144 }
    1145 
    1146 function privOptionDefaultThreshold(&$p_options)
    1147 {
    1148   $v_result=1;
    1149  
    1150   if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
    1151       || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
    1152     return $v_result;
    1153   }
    1154  
    1155   $v_memory_limit = ini_get('memory_limit');
    1156   $v_memory_limit = trim($v_memory_limit);
    1157   $last = strtolower(substr($v_memory_limit, -1));
    1158 
    1159   if($last == 'g')
    1160       $v_memory_limit = $v_memory_limit*1073741824;
    1161   if($last == 'm')
    1162       $v_memory_limit = $v_memory_limit*1048576;
    1163   if($last == 'k')
    1164       $v_memory_limit = $v_memory_limit*1024;
    1165          
    1166   $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
    1167  
    1168 
    1169   if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
    1170     unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
    1171   }
    1172        
    1173   return $v_result;
    1174 }
    1175 
    1176 function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
    1177 {
    1178   $v_result=1;
    1179  
    1180   foreach ($p_file_list as $v_key => $v_value) {
    1181  
    1182     if (!isset($v_requested_options[$v_key])) {
    1183       PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
    1184 
    1185       return PclZip::errorCode();
    1186     }
    1187 
    1188     switch ($v_key) {
    1189       case PCLZIP_ATT_FILE_NAME :
    1190         if (!is_string($v_value)) {
    1191           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
    1192           return PclZip::errorCode();
    1193         }
    1194 
    1195         $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
    1196        
    1197         if ($p_filedescr['filename'] == '') {
    1198           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
    1199           return PclZip::errorCode();
    1200         }
    1201 
    1202       break;
    1203 
    1204       case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
    1205         if (!is_string($v_value)) {
    1206           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
    1207           return PclZip::errorCode();
    1208         }
    1209 
    1210         $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
    1211 
    1212         if ($p_filedescr['new_short_name'] == '') {
    1213           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
    1214           return PclZip::errorCode();
    1215         }
    1216       break;
    1217 
    1218       case PCLZIP_ATT_FILE_NEW_FULL_NAME :
    1219         if (!is_string($v_value)) {
    1220           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
    1221           return PclZip::errorCode();
    1222         }
    1223 
    1224         $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
    1225 
    1226         if ($p_filedescr['new_full_name'] == '') {
    1227           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
    1228           return PclZip::errorCode();
    1229         }
    1230       break;
    1231 
    1232       case PCLZIP_ATT_FILE_COMMENT :
    1233         if (!is_string($v_value)) {
    1234           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
    1235           return PclZip::errorCode();
    1236         }
    1237 
    1238         $p_filedescr['comment'] = $v_value;
    1239       break;
    1240 
    1241       case PCLZIP_ATT_FILE_MTIME :
    1242         if (!is_integer($v_value)) {
    1243           PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
    1244           return PclZip::errorCode();
    1245         }
    1246 
    1247         $p_filedescr['mtime'] = $v_value;
    1248       break;
    1249 
    1250       case PCLZIP_ATT_FILE_CONTENT :
    1251         $p_filedescr['content'] = $v_value;
    1252       break;
    1253 
    1254       default :
    1255         PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
    1256                              "Unknown parameter '".$v_key."'");
    1257 
    1258         return PclZip::errorCode();
    1259     }
    1260 
    1261     if ($v_requested_options !== false) {
    1262       for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
    1263         if ($v_requested_options[$key] == 'mandatory') {
    1264           if (!isset($p_file_list[$key])) {
    1265             PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
    1266             return PclZip::errorCode();
    1267           }
    1268         }
    1269       }
    1270     }
    1271  
    1272   }
    1273  
    1274   return $v_result;
    1275 }
    1276 
    1277 function privFileDescrExpand(&$p_filedescr_list, &$p_options)
    1278 {
    1279   $v_result=1;
    1280  
    1281   $v_result_list = array();
    1282  
    1283   for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
    1284    
    1285     $v_descr = $p_filedescr_list[$i];
    1286    
    1287     $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
    1288     $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
    1289    
    1290     if (file_exists($v_descr['filename'])) {
    1291       if (@is_file($v_descr['filename'])) {
    1292         $v_descr['type'] = 'file';
    1293       }
    1294       else if (@is_dir($v_descr['filename'])) {
    1295         $v_descr['type'] = 'folder';
    1296       }
    1297       else if (@is_link($v_descr['filename'])) {
    1298         continue;
    1299       }
    1300       else {
    1301         continue;
    1302       }
    1303     }
    1304    
    1305     else if (isset($v_descr['content'])) {
    1306       $v_descr['type'] = 'virtual_file';
    1307     }
    1308    
    1309     else {
    1310       PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
    1311 
    1312       return PclZip::errorCode();
    1313     }
    1314    
    1315     $this->privCalculateStoredFilename($v_descr, $p_options);
    1316    
    1317     $v_result_list[sizeof($v_result_list)] = $v_descr;
    1318    
    1319     if ($v_descr['type'] == 'folder') {
    1320       $v_dirlist_descr = array();
    1321       $v_dirlist_nb = 0;
    1322       if ($v_folder_handler = @opendir($v_descr['filename'])) {
    1323         while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
    1324 
    1325           if (($v_item_handler == '.') || ($v_item_handler == '..')) {
    1326               continue;
    1327           }
    1328          
    1329           $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
    1330          
    1331           if ($v_descr['stored_filename'] != $v_descr['filename']) {
    1332             if ($v_descr['stored_filename'] != '') {
    1333               $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
    1334             }
    1335             else {
    1336               $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
    1337             }
    1338           }
    1339    
    1340           $v_dirlist_nb++;
    1341         }
    1342        
    1343         @closedir($v_folder_handler);
    1344       }
    1345       else {
    1346       }
    1347      
    1348       if ($v_dirlist_nb != 0) {
    1349         if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
    1350           return $v_result;
    1351         }
    1352        
    1353         $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
    1354       }
    1355       else {
    1356       }
    1357        
    1358       unset($v_dirlist_descr);
    1359     }
    1360   }
    1361  
    1362   $p_filedescr_list = $v_result_list;
    1363 
    1364   return $v_result;
    1365 }
    1366 
    1367 function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
    1368 {
    1369   $v_result=1;
    1370   $v_list_detail = array();
    1371  
    1372   $this->privDisableMagicQuotes();
    1373 
    1374   if (($v_result = $this->privOpenFd('wb')) != 1)
    1375   {
    1376     return $v_result;
    1377   }
    1378 
    1379   $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
    1380 
    1381   $this->privCloseFd();
    1382 
    1383   $this->privSwapBackMagicQuotes();
    1384 
    1385   return $v_result;
    1386 }
    1387 
    1388 function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
    1389 {
    1390   $v_result=1;
    1391   $v_list_detail = array();
    1392 
    1393   if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
    1394   {
    1395 
    1396     $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
    1397 
    1398     return $v_result;
    1399   }
    1400   $this->privDisableMagicQuotes();
    1401 
    1402   if (($v_result=$this->privOpenFd('rb')) != 1)
    1403   {
    1404     $this->privSwapBackMagicQuotes();
    1405 
    1406     return $v_result;
    1407   }
    1408 
    1409   $v_central_dir = array();
    1410   if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
    1411   {
    1412     $this->privCloseFd();
    1413     $this->privSwapBackMagicQuotes();
    1414     return $v_result;
    1415   }
    1416 
    1417   @rewind($this->zip_fd);
    1418 
    1419   $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
    1420 
    1421   if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
    1422   {
    1423     $this->privCloseFd();
    1424     $this->privSwapBackMagicQuotes();
    1425 
    1426     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
    1427 
    1428     return PclZip::errorCode();
    1429   }
    1430 
    1431   $v_size = $v_central_dir['offset'];
    1432   while ($v_size != 0)
    1433   {
    1434     $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
    1435     $v_buffer = fread($this->zip_fd, $v_read_size);
    1436     @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
    1437     $v_size -= $v_read_size;
    1438   }
    1439 
    1440   $v_swap = $this->zip_fd;
    1441   $this->zip_fd = $v_zip_temp_fd;
    1442   $v_zip_temp_fd = $v_swap;
    1443 
    1444   $v_header_list = array();
    1445   if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
    1446   {
    1447     fclose($v_zip_temp_fd);
    1448     $this->privCloseFd();
    1449     @unlink($v_zip_temp_name);
    1450     $this->privSwapBackMagicQuotes();
    1451 
    1452     return $v_result;
    1453   }
    1454 
    1455   $v_offset = @ftell($this->zip_fd);
    1456 
    1457   $v_size = $v_central_dir['size'];
    1458   while ($v_size != 0)
    1459   {
    1460     $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
    1461     $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
    1462     @fwrite($this->zip_fd, $v_buffer, $v_read_size);
    1463     $v_size -= $v_read_size;
    1464   }
    1465 
    1466   for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
    1467   {
    1468     if ($v_header_list[$i]['status'] == 'ok') {
    1469       if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
    1470         fclose($v_zip_temp_fd);
    1471         $this->privCloseFd();
    1472         @unlink($v_zip_temp_name);
    1473         $this->privSwapBackMagicQuotes();
    1474 
    1475         return $v_result;
    1476       }
    1477       $v_count++;
    1478     }
    1479 
    1480     $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
    1481   }
    1482 
    1483   $v_comment = $v_central_dir['comment'];
    1484   if (isset($p_options[PCLZIP_OPT_COMMENT])) {
    1485     $v_comment = $p_options[PCLZIP_OPT_COMMENT];
    1486   }
    1487   if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
    1488     $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
    1489   }
    1490   if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
    1491     $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
    1492   }
    1493 
    1494   $v_size = @ftell($this->zip_fd)-$v_offset;
    1495 
    1496   if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
    1497   {
    1498     unset($v_header_list);
    1499     $this->privSwapBackMagicQuotes();
    1500 
    1501     return $v_result;
    1502   }
    1503 
    1504   $v_swap = $this->zip_fd;
    1505   $this->zip_fd = $v_zip_temp_fd;
    1506   $v_zip_temp_fd = $v_swap;
    1507 
    1508   $this->privCloseFd();
    1509 
    1510   @fclose($v_zip_temp_fd);
    1511 
    1512   $this->privSwapBackMagicQuotes();
    1513 
    1514   @unlink($this->zipname);
    1515 
    1516   PclZipUtilRename($v_zip_temp_name, $this->zipname);
    1517 
    1518   return $v_result;
    1519 }
    1520 
    1521 function privOpenFd($p_mode)
    1522 {
    1523   $v_result=1;
    1524 
    1525   if ($this->zip_fd != 0)
    1526   {
    1527     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
    1528 
    1529     return PclZip::errorCode();
    1530   }
    1531 
    1532   if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
    1533   {
    1534     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
    1535 
    1536     return PclZip::errorCode();
    1537   }
    1538 
    1539   return $v_result;
    1540 }
    1541 
    1542 function privCloseFd()
    1543 {
    1544   $v_result=1;
    1545 
    1546   if ($this->zip_fd != 0)
    1547     @fclose($this->zip_fd);
    1548   $this->zip_fd = 0;
    1549 
    1550   return $v_result;
    1551 }
    1552 
    1553 function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
    1554 {
    1555   $v_result=1;
    1556 
    1557   $v_header_list = array();
    1558   if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
    1559   {
    1560     return $v_result;
    1561   }
    1562 
    1563   $v_offset = @ftell($this->zip_fd);
    1564 
    1565   for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
    1566   {
    1567     if ($v_header_list[$i]['status'] == 'ok') {
    1568       if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
    1569         return $v_result;
    1570       }
    1571       $v_count++;
    1572     }
    1573 
    1574     $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
    1575   }
    1576 
    1577   $v_comment = '';
    1578   if (isset($p_options[PCLZIP_OPT_COMMENT])) {
    1579     $v_comment = $p_options[PCLZIP_OPT_COMMENT];
    1580   }
    1581 
    1582   $v_size = @ftell($this->zip_fd)-$v_offset;
    1583 
    1584   if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
    1585   {
    1586     unset($v_header_list);
    1587 
    1588     return $v_result;
    1589   }
    1590 
    1591   return $v_result;
    1592 }
    1593 
    1594 function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
    1595 {
    1596   $v_result=1;
    1597   $v_header = array();
    1598 
    1599   $v_nb = sizeof($p_result_list);
    1600 
    1601   for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
    1602     $p_filedescr_list[$j]['filename']
    1603     = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
    1604    
    1605 
    1606     if ($p_filedescr_list[$j]['filename'] == "") {
    1607       continue;
    1608     }
    1609 
    1610     if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
    1611         && (!file_exists($p_filedescr_list[$j]['filename']))) {
    1612       PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
    1613       return PclZip::errorCode();
    1614     }
    1615 
    1616     if (   ($p_filedescr_list[$j]['type'] == 'file')
    1617         || ($p_filedescr_list[$j]['type'] == 'virtual_file')
    1618         || (   ($p_filedescr_list[$j]['type'] == 'folder')
    1619             && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
    1620                 || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
    1621         ) {
    1622 
    1623       $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
    1624                                      $p_options);
    1625       if ($v_result != 1) {
    1626         return $v_result;
    1627       }
    1628 
    1629       $p_result_list[$v_nb++] = $v_header;
    1630     }
    1631   }
    1632 
    1633   return $v_result;
    1634 }
    1635 
    1636 function privAddFile($p_filedescr, &$p_header, &$p_options)
    1637 {
    1638   $v_result=1;
    1639  
    1640   $p_filename = $p_filedescr['filename'];
    1641 
    1642   if ($p_filename == "") {
    1643     PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
    1644 
    1645     return PclZip::errorCode();
    1646   }
    1647 
    1648   /* TBC : Removed
    1649   if (isset($p_filedescr['stored_filename'])) {
    1650     $v_stored_filename = $p_filedescr['stored_filename'];
    1651   }
    1652   else {
    1653     $v_stored_filename = $p_filedescr['stored_filename'];
    1654   }
    1655   */
    1656 
    1657   clearstatcache();
    1658   $p_header['version'] = 20;
    1659   $p_header['version_extracted'] = 10;
    1660   $p_header['flag'] = 0;
    1661   $p_header['compression'] = 0;
    1662   $p_header['crc'] = 0;
    1663   $p_header['compressed_size'] = 0;
    1664   $p_header['filename_len'] = strlen($p_filename);
    1665   $p_header['extra_len'] = 0;
    1666   $p_header['disk'] = 0;
    1667   $p_header['internal'] = 0;
    1668   $p_header['offset'] = 0;
    1669   $p_header['filename'] = $p_filename;
    1670   $p_header['stored_filename'] = $p_filedescr['stored_filename'];
    1671   $p_header['extra'] = '';
    1672   $p_header['status'] = 'ok';
    1673   $p_header['index'] = -1;
    1674 
    1675   if ($p_filedescr['type']=='file') {
    1676     $p_header['external'] = 0x00000000;
    1677     $p_header['size'] = filesize($p_filename);
    1678   }
    1679  
    1680   else if ($p_filedescr['type']=='folder') {
    1681     $p_header['external'] = 0x00000010;
    1682     $p_header['mtime'] = filemtime($p_filename);
    1683     $p_header['size'] = filesize($p_filename);
    1684   }
    1685  
    1686   else if ($p_filedescr['type'] == 'virtual_file') {
    1687     $p_header['external'] = 0x00000000;
    1688     $p_header['size'] = strlen($p_filedescr['content']);
    1689   }
    1690  
    1691 
    1692   if (isset($p_filedescr['mtime'])) {
    1693     $p_header['mtime'] = $p_filedescr['mtime'];
    1694   }
    1695   else if ($p_filedescr['type'] == 'virtual_file') {
    1696     $p_header['mtime'] = time();
    1697   }
    1698   else {
    1699     $p_header['mtime'] = filemtime($p_filename);
    1700   }
    1701 
    1702   if (isset($p_filedescr['comment'])) {
    1703     $p_header['comment_len'] = strlen($p_filedescr['comment']);
    1704     $p_header['comment'] = $p_filedescr['comment'];
    1705   }
    1706   else {
    1707     $p_header['comment_len'] = 0;
    1708     $p_header['comment'] = '';
    1709   }
    1710 
    1711   if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
    1712 
    1713     $v_local_header = array();
    1714     $this->privConvertHeader2FileInfo($p_header, $v_local_header);
    1715 
    1716     eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
    1717     if ($v_result == 0) {
    1718       $p_header['status'] = "skipped";
    1719       $v_result = 1;
    1720     }
    1721 
    1722     if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
    1723       $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
    1724     }
    1725   }
    1726 
    1727   if ($p_header['stored_filename'] == "") {
    1728     $p_header['status'] = "filtered";
    1729   }
    1730  
    1731   if (strlen($p_header['stored_filename']) > 0xFF) {
    1732     $p_header['status'] = 'filename_too_long';
    1733   }
    1734 
    1735   if ($p_header['status'] == 'ok') {
    1736 
    1737     if ($p_filedescr['type'] == 'file') {
    1738       if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
    1739           && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
    1740               || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
    1741                   && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
    1742         $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
    1743         if ($v_result < PCLZIP_ERR_NO_ERROR) {
    1744           return $v_result;
    1745         }
    1746       }
    1747      
    1748       else {
    1749 
    1750       if (($v_file = @fopen($p_filename, "rb")) == 0) {
    1751         PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
    1752         return PclZip::errorCode();
    1753       }
    1754 
    1755       $v_content = @fread($v_file, $p_header['size']);
    1756 
    1757       @fclose($v_file);
    1758 
    1759       $p_header['crc'] = @crc32($v_content);
    1760      
    1761       if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
    1762         $p_header['compressed_size'] = $p_header['size'];
    1763         $p_header['compression'] = 0;
    1764       }
    1765      
    1766       else {
    1767         $v_content = @gzdeflate($v_content);
    1768 
    1769         $p_header['compressed_size'] = strlen($v_content);
    1770         $p_header['compression'] = 8;
    1771       }
    1772      
    1773       if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
    1774         @fclose($v_file);
    1775         return $v_result;
    1776       }
    1777 
    1778       @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
    1779 
    1780       }
    1781 
    1782     }
    1783 
    1784     else if ($p_filedescr['type'] == 'virtual_file') {
    1785        
    1786       $v_content = $p_filedescr['content'];
    1787 
    1788       $p_header['crc'] = @crc32($v_content);
    1789      
    1790       if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
    1791         $p_header['compressed_size'] = $p_header['size'];
    1792         $p_header['compression'] = 0;
    1793       }
    1794      
    1795       else {
    1796         $v_content = @gzdeflate($v_content);
    1797 
    1798         $p_header['compressed_size'] = strlen($v_content);
    1799         $p_header['compression'] = 8;
    1800       }
    1801      
    1802       if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
    1803         @fclose($v_file);
    1804         return $v_result;
    1805       }
    1806 
    1807       @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
    1808     }
    1809 
    1810     else if ($p_filedescr['type'] == 'folder') {
    1811       if (@substr($p_header['stored_filename'], -1) != '/') {
    1812         $p_header['stored_filename'] .= '/';
    1813       }
    1814 
    1815       $p_header['size'] = 0;
    1816 
    1817       if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
     3277    $v_result=1;
     3278
     3279    // ----- Magic quotes trick
     3280    $this->privDisableMagicQuotes();
     3281
     3282    // ----- Check the path
     3283    if (   ($p_path == "")
     3284            || (   (substr($p_path, 0, 1) != "/")
     3285                    && (substr($p_path, 0, 3) != "../")
     3286                        && (substr($p_path,1,2)!=":/")))
     3287      $p_path = "./".$p_path;
     3288
     3289    // ----- Reduce the path last (and duplicated) '/'
     3290    if (($p_path != "./") && ($p_path != "/"))
     3291    {
     3292      // ----- Look for the path end '/'
     3293      while (substr($p_path, -1) == "/")
    18183294      {
    1819         return $v_result;
    1820       }
    1821     }
    1822   }
    1823 
    1824   if (isset($p_options[PCLZIP_CB_POST_ADD])) {
    1825 
    1826     $v_local_header = array();
    1827     $this->privConvertHeader2FileInfo($p_header, $v_local_header);
    1828 
    1829     eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
    1830     if ($v_result == 0) {
    1831       $v_result = 1;
    1832     }
    1833 
    1834   }
    1835 
    1836   return $v_result;
    1837 }
    1838 
    1839 function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
    1840 {
    1841   $v_result=PCLZIP_ERR_NO_ERROR;
    1842  
    1843   $p_filename = $p_filedescr['filename'];
    1844 
    1845 
    1846   if (($v_file = @fopen($p_filename, "rb")) == 0) {
    1847     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
    1848     return PclZip::errorCode();
    1849   }
    1850 
    1851   $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
    1852   if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
    1853     fclose($v_file);
    1854     PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
    1855     return PclZip::errorCode();
    1856   }
    1857 
    1858   $v_size = filesize($p_filename);
    1859   while ($v_size != 0) {
    1860     $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
    1861     $v_buffer = @fread($v_file, $v_read_size);
    1862     @gzputs($v_file_compressed, $v_buffer, $v_read_size);
    1863     $v_size -= $v_read_size;
    1864   }
    1865 
    1866   @fclose($v_file);
    1867   @gzclose($v_file_compressed);
    1868 
    1869   if (filesize($v_gzip_temp_name) < 18) {
    1870     PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
    1871     return PclZip::errorCode();
    1872   }
    1873 
    1874   if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
    1875     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
    1876     return PclZip::errorCode();
    1877   }
    1878 
    1879   $v_binary_data = @fread($v_file_compressed, 10);
    1880   $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
    1881 
    1882   $v_data_header['os'] = bin2hex($v_data_header['os']);
    1883 
    1884   @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
    1885   $v_binary_data = @fread($v_file_compressed, 8);
    1886   $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
    1887 
    1888   $p_header['compression'] = ord($v_data_header['cm']);
    1889   $p_header['crc'] = $v_data_footer['crc'];
    1890   $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
    1891 
    1892   @fclose($v_file_compressed);
    1893 
    1894   if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
    1895     return $v_result;
    1896   }
    1897 
    1898   if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
    1899   {
    1900     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
    1901     return PclZip::errorCode();
    1902   }
    1903 
    1904   fseek($v_file_compressed, 10);
    1905   $v_size = $p_header['compressed_size'];
    1906   while ($v_size != 0)
    1907   {
    1908     $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
    1909     $v_buffer = @fread($v_file_compressed, $v_read_size);
    1910     @fwrite($this->zip_fd, $v_buffer, $v_read_size);
    1911     $v_size -= $v_read_size;
    1912   }
    1913 
    1914   @fclose($v_file_compressed);
    1915 
    1916   @unlink($v_gzip_temp_name);
    1917  
    1918   return $v_result;
    1919 }
    1920 
    1921 function privCalculateStoredFilename(&$p_filedescr, &$p_options)
    1922 {
    1923   $v_result=1;
    1924  
    1925   $p_filename = $p_filedescr['filename'];
    1926   if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
    1927     $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
    1928   }
    1929   else {
    1930     $p_add_dir = '';
    1931   }
    1932   if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
    1933     $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
    1934   }
    1935   else {
    1936     $p_remove_dir = '';
    1937   }
    1938   if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
    1939     $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
    1940   }
    1941   else {
    1942     $p_remove_all_dir = 0;
    1943   }
    1944 
    1945   if (isset($p_filedescr['new_full_name'])) {
    1946     $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
    1947   }
    1948  
    1949   else {
    1950 
    1951     if (isset($p_filedescr['new_short_name'])) {
    1952       $v_path_info = pathinfo($p_filename);
    1953       $v_dir = '';
    1954       if ($v_path_info['dirname'] != '') {
    1955         $v_dir = $v_path_info['dirname'].'/';
    1956       }
    1957       $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
    1958     }
    1959     else {
    1960       $v_stored_filename = $p_filename;
    1961     }
    1962 
    1963     if ($p_remove_all_dir) {
    1964       $v_stored_filename = basename($p_filename);
    1965     }
    1966     else if ($p_remove_dir != "") {
    1967       if (substr($p_remove_dir, -1) != '/')
    1968         $p_remove_dir .= "/";
    1969 
    1970       if (   (substr($p_filename, 0, 2) == "./")
    1971           || (substr($p_remove_dir, 0, 2) == "./")) {
    1972          
    1973         if (   (substr($p_filename, 0, 2) == "./")
    1974             && (substr($p_remove_dir, 0, 2) != "./")) {
    1975           $p_remove_dir = "./".$p_remove_dir;
    1976         }
    1977         if (   (substr($p_filename, 0, 2) != "./")
    1978             && (substr($p_remove_dir, 0, 2) == "./")) {
    1979           $p_remove_dir = substr($p_remove_dir, 2);
    1980         }
    1981       }
    1982 
    1983       $v_compare = PclZipUtilPathInclusion($p_remove_dir,
    1984                                            $v_stored_filename);
    1985       if ($v_compare > 0) {
    1986         if ($v_compare == 2) {
    1987           $v_stored_filename = "";
    1988         }
    1989         else {
    1990           $v_stored_filename = substr($v_stored_filename,
    1991                                       strlen($p_remove_dir));
    1992         }
    1993       }
    1994     }
    1995    
    1996     $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
    1997    
    1998     if ($p_add_dir != "") {
    1999       if (substr($p_add_dir, -1) == "/")
    2000         $v_stored_filename = $p_add_dir.$v_stored_filename;
    2001       else
    2002         $v_stored_filename = $p_add_dir."/".$v_stored_filename;
    2003     }
    2004   }
    2005 
    2006   $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
    2007   $p_filedescr['stored_filename'] = $v_stored_filename;
    2008  
    2009   return $v_result;
    2010 }
    2011 
    2012 function privWriteFileHeader(&$p_header)
    2013 {
    2014   $v_result=1;
    2015 
    2016   $p_header['offset'] = ftell($this->zip_fd);
    2017 
    2018   $v_date = getdate($p_header['mtime']);
    2019   $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
    2020   $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
    2021 
    2022   $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
    2023                       $p_header['version_extracted'], $p_header['flag'],
    2024                         $p_header['compression'], $v_mtime, $v_mdate,
    2025                         $p_header['crc'], $p_header['compressed_size'],
    2026             $p_header['size'],
    2027                         strlen($p_header['stored_filename']),
    2028             $p_header['extra_len']);
    2029 
    2030   fputs($this->zip_fd, $v_binary_data, 30);
    2031 
    2032   if (strlen($p_header['stored_filename']) != 0)
    2033   {
    2034     fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
    2035   }
    2036   if ($p_header['extra_len'] != 0)
    2037   {
    2038     fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
    2039   }
    2040 
    2041   return $v_result;
    2042 }
    2043 
    2044 function privWriteCentralFileHeader(&$p_header)
    2045 {
    2046   $v_result=1;
    2047 
    2048 
    2049   $v_date = getdate($p_header['mtime']);
    2050   $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
    2051   $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
    2052 
    2053 
    2054   $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
    2055                       $p_header['version'], $p_header['version_extracted'],
    2056                         $p_header['flag'], $p_header['compression'],
    2057             $v_mtime, $v_mdate, $p_header['crc'],
    2058                         $p_header['compressed_size'], $p_header['size'],
    2059                         strlen($p_header['stored_filename']),
    2060             $p_header['extra_len'], $p_header['comment_len'],
    2061                         $p_header['disk'], $p_header['internal'],
    2062             $p_header['external'], $p_header['offset']);
    2063 
    2064   fputs($this->zip_fd, $v_binary_data, 46);
    2065 
    2066   if (strlen($p_header['stored_filename']) != 0)
    2067   {
    2068     fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
    2069   }
    2070   if ($p_header['extra_len'] != 0)
    2071   {
    2072     fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
    2073   }
    2074   if ($p_header['comment_len'] != 0)
    2075   {
    2076     fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
    2077   }
    2078 
    2079   return $v_result;
    2080 }
    2081 
    2082 function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
    2083 {
    2084   $v_result=1;
    2085 
    2086   $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
    2087                       $p_nb_entries, $p_size,
    2088             $p_offset, strlen($p_comment));
    2089 
    2090   fputs($this->zip_fd, $v_binary_data, 22);
    2091 
    2092   if (strlen($p_comment) != 0)
    2093   {
    2094     fputs($this->zip_fd, $p_comment, strlen($p_comment));
    2095   }
    2096 
    2097   return $v_result;
    2098 }
    2099 
    2100 function privList(&$p_list)
    2101 {
    2102   $v_result=1;
    2103 
    2104   $this->privDisableMagicQuotes();
    2105 
    2106   if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
    2107   {
    2108     $this->privSwapBackMagicQuotes();
    2109    
    2110     PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
    2111 
    2112     return PclZip::errorCode();
    2113   }
    2114 
    2115   $v_central_dir = array();
    2116   if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
    2117   {
    2118     $this->privSwapBackMagicQuotes();
    2119     return $v_result;
    2120   }
    2121 
    2122   @rewind($this->zip_fd);
    2123   if (@fseek($this->zip_fd, $v_central_dir['offset']))
    2124   {
    2125     $this->privSwapBackMagicQuotes();
    2126 
    2127     PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
    2128 
    2129     return PclZip::errorCode();
    2130   }
    2131 
    2132   for ($i=0; $i<$v_central_dir['entries']; $i++)
    2133   {
    2134     if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
     3295        $p_path = substr($p_path, 0, strlen($p_path)-1);
     3296      }
     3297    }
     3298
     3299    // ----- Look for path to remove format (should end by /)
     3300    if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
     3301    {
     3302      $p_remove_path .= '/';
     3303    }
     3304    $p_remove_path_size = strlen($p_remove_path);
     3305
     3306    // ----- Open the zip file
     3307    if (($v_result = $this->privOpenFd('rb')) != 1)
    21353308    {
    21363309      $this->privSwapBackMagicQuotes();
    21373310      return $v_result;
    21383311    }
    2139     $v_header['index'] = $i;
    2140 
    2141     $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
    2142     unset($v_header);
    2143   }
    2144 
    2145   $this->privCloseFd();
    2146 
    2147   $this->privSwapBackMagicQuotes();
    2148 
    2149   return $v_result;
    2150 }
    2151 
    2152 function privConvertHeader2FileInfo($p_header, &$p_info)
    2153 {
    2154   $v_result=1;
    2155 
    2156   $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
    2157   $p_info['filename'] = $v_temp_path;
    2158   $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
    2159   $p_info['stored_filename'] = $v_temp_path;
    2160   $p_info['size'] = $p_header['size'];
    2161   $p_info['compressed_size'] = $p_header['compressed_size'];
    2162   $p_info['mtime'] = $p_header['mtime'];
    2163   $p_info['comment'] = $p_header['comment'];
    2164   $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
    2165   $p_info['index'] = $p_header['index'];
    2166   $p_info['status'] = $p_header['status'];
    2167   $p_info['crc'] = $p_header['crc'];
    2168 
    2169   return $v_result;
    2170 }
    2171 
    2172 function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
    2173 {
    2174   $v_result=1;
    2175 
    2176   $this->privDisableMagicQuotes();
    2177 
    2178   if (   ($p_path == "")
    2179     || (   (substr($p_path, 0, 1) != "/")
    2180       && (substr($p_path, 0, 3) != "../")
    2181     && (substr($p_path,1,2)!=":/")))
    2182     $p_path = "./".$p_path;
    2183 
    2184   if (($p_path != "./") && ($p_path != "/"))
    2185   {
    2186     while (substr($p_path, -1) == "/")
    2187     {
    2188       $p_path = substr($p_path, 0, strlen($p_path)-1);
    2189     }
    2190   }
    2191 
    2192   if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
    2193   {
    2194     $p_remove_path .= '/';
    2195   }
    2196   $p_remove_path_size = strlen($p_remove_path);
    2197 
    2198   if (($v_result = $this->privOpenFd('rb')) != 1)
    2199   {
    2200     $this->privSwapBackMagicQuotes();
    2201     return $v_result;
    2202   }
    2203 
    2204   $v_central_dir = array();
    2205   if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
    2206   {
    2207     $this->privCloseFd();
    2208     $this->privSwapBackMagicQuotes();
    2209 
    2210     return $v_result;
    2211   }
    2212 
    2213   $v_pos_entry = $v_central_dir['offset'];
    2214 
    2215   $j_start = 0;
    2216   for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
    2217   {
    2218 
    2219     @rewind($this->zip_fd);
    2220     if (@fseek($this->zip_fd, $v_pos_entry))
    2221     {
     3312
     3313    // ----- Read the central directory informations
     3314    $v_central_dir = array();
     3315    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
     3316    {
     3317      // ----- Close the zip file
    22223318      $this->privCloseFd();
    22233319      $this->privSwapBackMagicQuotes();
    22243320
    2225       PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
    2226 
    2227       return PclZip::errorCode();
    2228     }
    2229 
    2230     $v_header = array();
    2231     if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
    2232     {
    2233       $this->privCloseFd();
    2234       $this->privSwapBackMagicQuotes();
    2235 
    22363321      return $v_result;
    22373322    }
    22383323
    2239     $v_header['index'] = $i;
    2240 
    2241     $v_pos_entry = ftell($this->zip_fd);
    2242 
    2243     $v_extract = false;
    2244 
    2245     if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
    2246         && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
    2247 
    2248         for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
    2249 
    2250             if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
    2251 
    2252                 if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
    2253                     && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
    2254                     $v_extract = true;
    2255                 }
    2256             }
    2257             elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
    2258                 $v_extract = true;
    2259             }
    2260         }
    2261     }
    2262 
    2263     else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
    2264              && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
    2265 
    2266         if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
    2267             $v_extract = true;
    2268         }
    2269     }
    2270 
    2271     else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
    2272              && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
    2273        
    2274         for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
    2275 
    2276             if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
    2277                 $v_extract = true;
    2278             }
    2279             if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
    2280                 $j_start = $j+1;
    2281             }
    2282 
    2283             if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
    2284                 break;
    2285             }
    2286         }
    2287     }
    2288 
    2289     else {
    2290         $v_extract = true;
    2291     }
    2292 
    2293   if (   ($v_extract)
    2294       && (   ($v_header['compression'] != 8)
    2295         && ($v_header['compression'] != 0))) {
    2296         $v_header['status'] = 'unsupported_compression';
    2297 
    2298         if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
    2299         && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
    2300 
     3324    // ----- Start at beginning of Central Dir
     3325    $v_pos_entry = $v_central_dir['offset'];
     3326
     3327    // ----- Read each entry
     3328    $j_start = 0;
     3329    for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
     3330    {
     3331
     3332      // ----- Read next Central dir entry
     3333      @rewind($this->zip_fd);
     3334      if (@fseek($this->zip_fd, $v_pos_entry))
     3335      {
     3336        // ----- Close the zip file
     3337        $this->privCloseFd();
     3338        $this->privSwapBackMagicQuotes();
     3339
     3340        // ----- Error log
     3341        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
     3342
     3343        // ----- Return
     3344        return PclZip::errorCode();
     3345      }
     3346
     3347      // ----- Read the file header
     3348      $v_header = array();
     3349      if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
     3350      {
     3351        // ----- Close the zip file
     3352        $this->privCloseFd();
     3353        $this->privSwapBackMagicQuotes();
     3354
     3355        return $v_result;
     3356      }
     3357
     3358      // ----- Store the index
     3359      $v_header['index'] = $i;
     3360
     3361      // ----- Store the file position
     3362      $v_pos_entry = ftell($this->zip_fd);
     3363
     3364      // ----- Look for the specific extract rules
     3365      $v_extract = false;
     3366
     3367      // ----- Look for extract by name rule
     3368      if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
     3369          && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
     3370
     3371          // ----- Look if the filename is in the list
     3372          for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
     3373
     3374              // ----- Look for a directory
     3375              if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
     3376
     3377                  // ----- Look if the directory is in the filename path
     3378                  if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
     3379                      && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
     3380                      $v_extract = true;
     3381                  }
     3382              }
     3383              // ----- Look for a filename
     3384              elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
     3385                  $v_extract = true;
     3386              }
     3387          }
     3388      }
     3389
     3390      // ----- Look for extract by ereg rule
     3391      // ereg() is deprecated with PHP 5.3
     3392      /*
     3393      else if (   (isset($p_options[PCLZIP_OPT_BY_EREG]))
     3394               && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
     3395
     3396          if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
     3397              $v_extract = true;
     3398          }
     3399      }
     3400      */
     3401
     3402      // ----- Look for extract by preg rule
     3403      else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
     3404               && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
     3405
     3406          if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
     3407              $v_extract = true;
     3408          }
     3409      }
     3410
     3411      // ----- Look for extract by index rule
     3412      else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
     3413               && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
     3414         
     3415          // ----- Look if the index is in the list
     3416          for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
     3417
     3418              if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
     3419                  $v_extract = true;
     3420              }
     3421              if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
     3422                  $j_start = $j+1;
     3423              }
     3424
     3425              if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
     3426                  break;
     3427              }
     3428          }
     3429      }
     3430
     3431      // ----- Look for no rule, which means extract all the archive
     3432      else {
     3433          $v_extract = true;
     3434      }
     3435
     3436          // ----- Check compression method
     3437          if (   ($v_extract)
     3438              && (   ($v_header['compression'] != 8)
     3439                      && ($v_header['compression'] != 0))) {
     3440          $v_header['status'] = 'unsupported_compression';
     3441
     3442          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
     3443          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
     3444                      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
     3445
     3446              $this->privSwapBackMagicQuotes();
     3447             
     3448              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
     3449                                               "Filename '".$v_header['stored_filename']."' is "
     3450                                                           ."compressed by an unsupported compression "
     3451                                                           ."method (".$v_header['compression'].") ");
     3452
     3453              return PclZip::errorCode();
     3454                  }
     3455          }
     3456         
     3457          // ----- Check encrypted files
     3458          if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
     3459          $v_header['status'] = 'unsupported_encryption';
     3460
     3461          // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
     3462          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
     3463                      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
     3464
     3465              $this->privSwapBackMagicQuotes();
     3466
     3467              PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
     3468                                               "Unsupported encryption for "
     3469                                                           ." filename '".$v_header['stored_filename']
     3470                                                                   ."'");
     3471
     3472              return PclZip::errorCode();
     3473                  }
     3474    }
     3475
     3476      // ----- Look for real extraction
     3477      if (($v_extract) && ($v_header['status'] != 'ok')) {
     3478          $v_result = $this->privConvertHeader2FileInfo($v_header,
     3479                                                        $p_file_list[$v_nb_extracted++]);
     3480          if ($v_result != 1) {
     3481              $this->privCloseFd();
     3482              $this->privSwapBackMagicQuotes();
     3483              return $v_result;
     3484          }
     3485
     3486          $v_extract = false;
     3487      }
     3488     
     3489      // ----- Look for real extraction
     3490      if ($v_extract)
     3491      {
     3492
     3493        // ----- Go to the file position
     3494        @rewind($this->zip_fd);
     3495        if (@fseek($this->zip_fd, $v_header['offset']))
     3496        {
     3497          // ----- Close the zip file
     3498          $this->privCloseFd();
     3499
     3500          $this->privSwapBackMagicQuotes();
     3501
     3502          // ----- Error log
     3503          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
     3504
     3505          // ----- Return
     3506          return PclZip::errorCode();
     3507        }
     3508
     3509        // ----- Look for extraction as string
     3510        if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
     3511
     3512          $v_string = '';
     3513
     3514          // ----- Extracting the file
     3515          $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
     3516          if ($v_result1 < 1) {
     3517            $this->privCloseFd();
    23013518            $this->privSwapBackMagicQuotes();
    2302            
    2303             PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
    2304                            "Filename '".$v_header['stored_filename']."' is "
    2305                        ."compressed by an unsupported compression "
    2306                        ."method (".$v_header['compression'].") ");
    2307 
    2308             return PclZip::errorCode();
    2309     }
    2310   }
    2311  
    2312   if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
    2313         $v_header['status'] = 'unsupported_encryption';
    2314 
    2315         if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
    2316         && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
    2317 
     3519            return $v_result1;
     3520          }
     3521
     3522          // ----- Get the only interesting attributes
     3523          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
     3524          {
     3525            // ----- Close the zip file
     3526            $this->privCloseFd();
    23183527            $this->privSwapBackMagicQuotes();
    23193528
    2320             PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
    2321                            "Unsupported encryption for "
    2322                        ." filename '".$v_header['stored_filename']
    2323                  ."'");
    2324 
    2325             return PclZip::errorCode();
    2326     }
    2327   }
    2328 
    2329     if (($v_extract) && ($v_header['status'] != 'ok')) {
    2330         $v_result = $this->privConvertHeader2FileInfo($v_header,
    2331                                           $p_file_list[$v_nb_extracted++]);
    2332         if ($v_result != 1) {
     3529            return $v_result;
     3530          }
     3531
     3532          // ----- Set the file content
     3533          $p_file_list[$v_nb_extracted]['content'] = $v_string;
     3534
     3535          // ----- Next extracted file
     3536          $v_nb_extracted++;
     3537         
     3538          // ----- Look for user callback abort
     3539          if ($v_result1 == 2) {
     3540                break;
     3541          }
     3542        }
     3543        // ----- Look for extraction in standard output
     3544        elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
     3545                        && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
     3546          // ----- Extracting the file in standard output
     3547          $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
     3548          if ($v_result1 < 1) {
     3549            $this->privCloseFd();
     3550            $this->privSwapBackMagicQuotes();
     3551            return $v_result1;
     3552          }
     3553
     3554          // ----- Get the only interesting attributes
     3555          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
    23333556            $this->privCloseFd();
    23343557            $this->privSwapBackMagicQuotes();
    23353558            return $v_result;
    2336         }
    2337 
    2338         $v_extract = false;
     3559          }
     3560
     3561          // ----- Look for user callback abort
     3562          if ($v_result1 == 2) {
     3563                break;
     3564          }
     3565        }
     3566        // ----- Look for normal extraction
     3567        else {
     3568          // ----- Extracting the file
     3569          $v_result1 = $this->privExtractFile($v_header,
     3570                                                      $p_path, $p_remove_path,
     3571                                                                                          $p_remove_all_path,
     3572                                                                                          $p_options);
     3573          if ($v_result1 < 1) {
     3574            $this->privCloseFd();
     3575            $this->privSwapBackMagicQuotes();
     3576            return $v_result1;
     3577          }
     3578
     3579          // ----- Get the only interesting attributes
     3580          if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
     3581          {
     3582            // ----- Close the zip file
     3583            $this->privCloseFd();
     3584            $this->privSwapBackMagicQuotes();
     3585
     3586            return $v_result;
     3587          }
     3588
     3589          // ----- Look for user callback abort
     3590          if ($v_result1 == 2) {
     3591                break;
     3592          }
     3593        }
     3594      }
     3595    }
     3596
     3597    // ----- Close the zip file
     3598    $this->privCloseFd();
     3599    $this->privSwapBackMagicQuotes();
     3600
     3601    // ----- Return
     3602    return $v_result;
     3603  }
     3604  // --------------------------------------------------------------------------------
     3605
     3606  // --------------------------------------------------------------------------------
     3607  // Function : privExtractFile()
     3608  // Description :
     3609  // Parameters :
     3610  // Return Values :
     3611  //
     3612  // 1 : ... ?
     3613  // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
     3614  // --------------------------------------------------------------------------------
     3615  function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
     3616  {
     3617    $v_result=1;
     3618
     3619    // ----- Read the file header
     3620    if (($v_result = $this->privReadFileHeader($v_header)) != 1)
     3621    {
     3622      // ----- Return
     3623      return $v_result;
     3624    }
     3625
     3626
     3627    // ----- Check that the file header is coherent with $p_entry info
     3628    if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
     3629        // TBC
     3630    }
     3631
     3632    // ----- Look for all path to remove
     3633    if ($p_remove_all_path == true) {
     3634        // ----- Look for folder entry that not need to be extracted
     3635        if (($p_entry['external']&0x00000010)==0x00000010) {
     3636
     3637            $p_entry['status'] = "filtered";
     3638
     3639            return $v_result;
     3640        }
     3641
     3642        // ----- Get the basename of the path
     3643        $p_entry['filename'] = basename($p_entry['filename']);
     3644    }
     3645
     3646    // ----- Look for path to remove
     3647    else if ($p_remove_path != "")
     3648    {
     3649      if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
     3650      {
     3651
     3652        // ----- Change the file status
     3653        $p_entry['status'] = "filtered";
     3654
     3655        // ----- Return
     3656        return $v_result;
     3657      }
     3658
     3659      $p_remove_path_size = strlen($p_remove_path);
     3660      if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
     3661      {
     3662
     3663        // ----- Remove the path
     3664        $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
     3665
     3666      }
     3667    }
     3668
     3669    // ----- Add the path
     3670    if ($p_path != '') {
     3671      $p_entry['filename'] = $p_path."/".$p_entry['filename'];
    23393672    }
    23403673   
    2341     if ($v_extract)
    2342     {
    2343 
    2344       @rewind($this->zip_fd);
    2345       if (@fseek($this->zip_fd, $v_header['offset']))
     3674    // ----- Check a base_dir_restriction
     3675    if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
     3676      $v_inclusion
     3677      = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
     3678                                $p_entry['filename']);
     3679      if ($v_inclusion == 0) {
     3680
     3681        PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
     3682                                             "Filename '".$p_entry['filename']."' is "
     3683                                                                 ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
     3684
     3685        return PclZip::errorCode();
     3686      }
     3687    }
     3688
     3689    // ----- Look for pre-extract callback
     3690    if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
     3691
     3692      // ----- Generate a local information
     3693      $v_local_header = array();
     3694      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
     3695
     3696      // ----- Call the callback
     3697      // Here I do not use call_user_func() because I need to send a reference to the
     3698      // header.
     3699//      eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
     3700      $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
     3701      if ($v_result == 0) {
     3702        // ----- Change the file status
     3703        $p_entry['status'] = "skipped";
     3704        $v_result = 1;
     3705      }
     3706     
     3707      // ----- Look for abort result
     3708      if ($v_result == 2) {
     3709        // ----- This status is internal and will be changed in 'skipped'
     3710        $p_entry['status'] = "aborted";
     3711        $v_result = PCLZIP_ERR_USER_ABORTED;
     3712      }
     3713
     3714      // ----- Update the informations
     3715      // Only some fields can be modified
     3716      $p_entry['filename'] = $v_local_header['filename'];
     3717    }
     3718
     3719
     3720    // ----- Look if extraction should be done
     3721    if ($p_entry['status'] == 'ok') {
     3722
     3723    // ----- Look for specific actions while the file exist
     3724    if (file_exists($p_entry['filename']))
     3725    {
     3726
     3727      // ----- Look if file is a directory
     3728      if (is_dir($p_entry['filename']))
    23463729      {
    2347         $this->privCloseFd();
    2348 
    2349         $this->privSwapBackMagicQuotes();
    2350 
    2351         PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
    2352 
    2353         return PclZip::errorCode();
    2354       }
    2355 
    2356       if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
    2357 
    2358         $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
    2359         if ($v_result1 < 1) {
    2360           $this->privCloseFd();
    2361           $this->privSwapBackMagicQuotes();
    2362           return $v_result1;
    2363         }
    2364 
    2365         if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
    2366         {
    2367           $this->privCloseFd();
    2368           $this->privSwapBackMagicQuotes();
    2369 
    2370           return $v_result;
    2371         }
    2372 
    2373         $p_file_list[$v_nb_extracted]['content'] = $v_string;
    2374 
    2375         $v_nb_extracted++;
     3730
     3731        // ----- Change the file status
     3732        $p_entry['status'] = "already_a_directory";
    23763733       
    2377         if ($v_result1 == 2) {
    2378           break;
    2379         }
    2380       }
    2381       elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
    2382           && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
    2383         $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
    2384         if ($v_result1 < 1) {
    2385           $this->privCloseFd();
    2386           $this->privSwapBackMagicQuotes();
    2387           return $v_result1;
    2388         }
    2389 
    2390         if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
    2391           $this->privCloseFd();
    2392           $this->privSwapBackMagicQuotes();
    2393           return $v_result;
    2394         }
    2395 
    2396         if ($v_result1 == 2) {
    2397           break;
    2398         }
     3734        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
     3735        // For historical reason first PclZip implementation does not stop
     3736        // when this kind of error occurs.
     3737        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
     3738                    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
     3739
     3740            PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
     3741                                             "Filename '".$p_entry['filename']."' is "
     3742                                                                 ."already used by an existing directory");
     3743
     3744            return PclZip::errorCode();
     3745                    }
     3746      }
     3747      // ----- Look if file is write protected
     3748      else if (!is_writeable($p_entry['filename']))
     3749      {
     3750
     3751        // ----- Change the file status
     3752        $p_entry['status'] = "write_protected";
     3753
     3754        // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
     3755        // For historical reason first PclZip implementation does not stop
     3756        // when this kind of error occurs.
     3757        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
     3758                    && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
     3759
     3760            PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
     3761                                             "Filename '".$p_entry['filename']."' exists "
     3762                                                                 ."and is write protected");
     3763
     3764            return PclZip::errorCode();
     3765                    }
     3766      }
     3767
     3768      // ----- Look if the extracted file is older
     3769      else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
     3770      {
     3771        // ----- Change the file status
     3772        if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
     3773                    && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
     3774                  }
     3775                    else {
     3776            $p_entry['status'] = "newer_exist";
     3777
     3778            // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
     3779            // For historical reason first PclZip implementation does not stop
     3780            // when this kind of error occurs.
     3781            if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
     3782                        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
     3783
     3784                PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
     3785                                     "Newer version of '".$p_entry['filename']."' exists "
     3786                                            ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
     3787
     3788                return PclZip::errorCode();
     3789                      }
     3790                    }
    23993791      }
    24003792      else {
    2401         $v_result1 = $this->privExtractFile($v_header,
    2402                                         $p_path, $p_remove_path,
    2403                       $p_remove_all_path,
    2404                       $p_options);
    2405         if ($v_result1 < 1) {
    2406           $this->privCloseFd();
    2407           $this->privSwapBackMagicQuotes();
    2408           return $v_result1;
    2409         }
    2410 
    2411         if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
    2412         {
    2413           $this->privCloseFd();
    2414           $this->privSwapBackMagicQuotes();
    2415 
    2416           return $v_result;
    2417         }
    2418 
    2419         if ($v_result1 == 2) {
    2420           break;
    2421         }
    2422       }
    2423     }
    2424   }
    2425 
    2426   $this->privCloseFd();
    2427   $this->privSwapBackMagicQuotes();
    2428 
    2429   return $v_result;
    2430 }
    2431 
    2432 function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
    2433 {
    2434   $v_result=1;
    2435 
    2436   if (($v_result = $this->privReadFileHeader($v_header)) != 1)
     3793      }
     3794    }
     3795
     3796    // ----- Check the directory availability and create it if necessary
     3797    else {
     3798      if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
     3799        $v_dir_to_check = $p_entry['filename'];
     3800      else if (!strstr($p_entry['filename'], "/"))
     3801        $v_dir_to_check = "";
     3802      else
     3803        $v_dir_to_check = dirname($p_entry['filename']);
     3804
     3805        if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
     3806 
     3807          // ----- Change the file status
     3808          $p_entry['status'] = "path_creation_fail";
     3809 
     3810          // ----- Return
     3811          //return $v_result;
     3812          $v_result = 1;
     3813        }
     3814      }
     3815    }
     3816
     3817    // ----- Look if extraction should be done
     3818    if ($p_entry['status'] == 'ok') {
     3819
     3820      // ----- Do the extraction (if not a folder)
     3821      if (!(($p_entry['external']&0x00000010)==0x00000010))
     3822      {
     3823        // ----- Look for not compressed file
     3824        if ($p_entry['compression'] == 0) {
     3825
     3826                  // ----- Opening destination file
     3827          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
     3828          {
     3829
     3830            // ----- Change the file status
     3831            $p_entry['status'] = "write_error";
     3832
     3833            // ----- Return
     3834            return $v_result;
     3835          }
     3836
     3837
     3838          // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
     3839          $v_size = $p_entry['compressed_size'];
     3840          while ($v_size != 0)
     3841          {
     3842            $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
     3843            $v_buffer = @fread($this->zip_fd, $v_read_size);
     3844            /* Try to speed up the code
     3845            $v_binary_data = pack('a'.$v_read_size, $v_buffer);
     3846            @fwrite($v_dest_file, $v_binary_data, $v_read_size);
     3847            */
     3848            @fwrite($v_dest_file, $v_buffer, $v_read_size);           
     3849            $v_size -= $v_read_size;
     3850          }
     3851
     3852          // ----- Closing the destination file
     3853          fclose($v_dest_file);
     3854
     3855          // ----- Change the file mtime
     3856          touch($p_entry['filename'], $p_entry['mtime']);
     3857         
     3858
     3859        }
     3860        else {
     3861          // ----- TBC
     3862          // Need to be finished
     3863          if (($p_entry['flag'] & 1) == 1) {
     3864            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
     3865            return PclZip::errorCode();
     3866          }
     3867
     3868
     3869          // ----- Look for using temporary file to unzip
     3870          if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
     3871              && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
     3872                  || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
     3873                      && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
     3874            $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
     3875            if ($v_result < PCLZIP_ERR_NO_ERROR) {
     3876              return $v_result;
     3877            }
     3878          }
     3879         
     3880          // ----- Look for extract in memory
     3881          else {
     3882
     3883         
     3884            // ----- Read the compressed file in a buffer (one shot)
     3885            $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
     3886           
     3887            // ----- Decompress the file
     3888            $v_file_content = @gzinflate($v_buffer);
     3889            unset($v_buffer);
     3890            if ($v_file_content === FALSE) {
     3891 
     3892              // ----- Change the file status
     3893              // TBC
     3894              $p_entry['status'] = "error";
     3895             
     3896              return $v_result;
     3897            }
     3898           
     3899            // ----- Opening destination file
     3900            if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
     3901 
     3902              // ----- Change the file status
     3903              $p_entry['status'] = "write_error";
     3904 
     3905              return $v_result;
     3906            }
     3907 
     3908            // ----- Write the uncompressed data
     3909            @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
     3910            unset($v_file_content);
     3911 
     3912            // ----- Closing the destination file
     3913            @fclose($v_dest_file);
     3914           
     3915          }
     3916
     3917          // ----- Change the file mtime
     3918          @touch($p_entry['filename'], $p_entry['mtime']);
     3919        }
     3920
     3921        // ----- Look for chmod option
     3922        if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
     3923
     3924          // ----- Change the mode of the file
     3925          @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
     3926        }
     3927
     3928      }
     3929    }
     3930
     3931        // ----- Change abort status
     3932        if ($p_entry['status'] == "aborted") {
     3933        $p_entry['status'] = "skipped";
     3934        }
     3935       
     3936    // ----- Look for post-extract callback
     3937    elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
     3938
     3939      // ----- Generate a local information
     3940      $v_local_header = array();
     3941      $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
     3942
     3943      // ----- Call the callback
     3944      // Here I do not use call_user_func() because I need to send a reference to the
     3945      // header.
     3946//      eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
     3947      $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
     3948
     3949      // ----- Look for abort result
     3950      if ($v_result == 2) {
     3951        $v_result = PCLZIP_ERR_USER_ABORTED;
     3952      }
     3953    }
     3954
     3955    // ----- Return
     3956    return $v_result;
     3957  }
     3958  // --------------------------------------------------------------------------------
     3959
     3960  // --------------------------------------------------------------------------------
     3961  // Function : privExtractFileUsingTempFile()
     3962  // Description :
     3963  // Parameters :
     3964  // Return Values :
     3965  // --------------------------------------------------------------------------------
     3966  function privExtractFileUsingTempFile(&$p_entry, &$p_options)
    24373967  {
     3968    $v_result=1;
     3969       
     3970    // ----- Creates a temporary file
     3971    $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
     3972    if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
     3973      fclose($v_file);
     3974      PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
     3975      return PclZip::errorCode();
     3976    }
     3977
     3978
     3979    // ----- Write gz file format header
     3980    $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
     3981    @fwrite($v_dest_file, $v_binary_data, 10);
     3982
     3983    // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
     3984    $v_size = $p_entry['compressed_size'];
     3985    while ($v_size != 0)
     3986    {