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