Commit 46dfc005502932b09b15fdf403e7f6d5b838b498

Authored by Charl Joseph Mert
1 parent 9924a9e2

Non-Queue bulk downloads fails on all 64bit environments

Jira:KTS-4513

Updated: Fixed internal zip path issues on windows.

Committed by: Charl Joseph Mert
lib/util/ktpclzip.inc.php
... ... @@ -117,6 +117,10 @@ class KTPclZip {
117 117 */
118 118 function createZipFile($sFolder) {
119 119 //Overriding $this->aPaths with specified
  120 + if (!is_dir($sFolder)) {
  121 + PEAR::raiseError( sprintf( _kt( "Couldn't create zip file, invalid folder was specified %s " ) , $sFolder ));
  122 + }
  123 +
120 124 if (!is_null($sFolder)) {
121 125 $this->aPaths = $sFolder;
122 126 }
... ... @@ -139,27 +143,36 @@ class KTPclZip {
139 143 return $sExportCode;
140 144 }
141 145  
142   - /*
  146 +
  147 + /*
143 148 * @params: $sPath folder to start from.
144 149 * @params: $ds directory separator
145 150 */
146 151 static function getExcludePath($sPath, $ds = '/') {
147 152 //Will grab the part of the full path to exclude from the zip contents
148 153  
149   - /*
150   - * For windows the pre drive letter needs to be removed for it to work with the pclzip class
151   - */
152   - if (stristr(PHP_OS,'WIN')) {
153   - $sPath = end(explode(':', $sPath));
154   - }
155   -
156   - //Chopping the last ds to make the keepPath contain an actual folder name
157   - $aDir = explode($ds, $sPath);
158   - $cutOff = count($aDir);
159   - for ($i = 0; $i < $cutOff; $i++) {
160   - $excludePath .= $aDir[$i] . '/';
161   - }
  154 + /*
  155 + * For windows the pre drive letter needs to be removed for it to work with the pclzip class for version 2.5
  156 + */
  157 + // Now using pclzip 2.8.2 so no need to strip the drive letter.
  158 + /*
  159 + if (stristr(PHP_OS,'WIN')) {
  160 + $sPath = end(explode(':', $sPath));
  161 + }
  162 + */
  163 +
  164 + //Generating the exclude path : Flexible method (Can set $cutOff = count($aDir) - 1;) to include the parent folder.
  165 + /*
  166 + $aDir = explode($ds, $sPath);
  167 + $cutOff = count($aDir);
  168 + for ($i = 0; $i < $cutOff; $i++) {
  169 + //echo $aDir[$i] . "\n";
  170 + $excludePath .= $aDir[$i] . '/';
  171 + }
  172 + */
162 173  
  174 + $excludePath = str_replace('\\', '/', $sPath);
  175 +
163 176 return $excludePath;
164 177 }
165 178  
... ...
thirdparty/peclzip/pclzip.lib.php 100755 → 100644
Changes suppressed. Click to show
1   -<?php
2   -// --------------------------------------------------------------------------------
3   -// PhpConcept Library - Zip Module 2.5
4   -// --------------------------------------------------------------------------------
5   -// License GNU/LGPL - Vincent Blavet - March 2006
6   -// http://www.phpconcept.net
7   -// --------------------------------------------------------------------------------
8   -//
9   -// Presentation :
10   -// PclZip is a PHP library that manage ZIP archives.
11   -// So far tests show that archives generated by PclZip are readable by
12   -// WinZip application and other tools.
13   -//
14   -// Description :
15   -// See readme.txt and http://www.phpconcept.net
16   -//
17   -// Warning :
18   -// This library and the associated files are non commercial, non professional
19   -// work.
20   -// It should not have unexpected results. However if any damage is caused by
21   -// this software the author can not be responsible.
22   -// The use of this software is at the risk of the user.
23   -//
24   -// --------------------------------------------------------------------------------
25   -// $Id: pclzip.lib.php,v 1.44 2006/03/08 21:23:59 vblavet Exp $
26   -// --------------------------------------------------------------------------------
27   -
28   - // ----- Constants
29   - define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
30   -
31   - // ----- File list separator
32   - // In version 1.x of PclZip, the separator for file list is a space
33   - // (which is not a very smart choice, specifically for windows paths !).
34   - // A better separator should be a comma (,). This constant gives you the
35   - // abilty to change that.
36   - // However notice that changing this value, may have impact on existing
37   - // scripts, using space separated filenames.
38   - // Recommanded values for compatibility with older versions :
39   - //define( 'PCLZIP_SEPARATOR', ' ' );
40   - // Recommanded values for smart separation of filenames.
41   - define( 'PCLZIP_SEPARATOR', ',' );
42   -
43   - // ----- Error configuration
44   - // 0 : PclZip Class integrated error handling
45   - // 1 : PclError external library error handling. By enabling this
46   - // you must ensure that you have included PclError library.
47   - // [2,...] : reserved for futur use
48   - define( 'PCLZIP_ERROR_EXTERNAL', 0 );
49   -
50   - // ----- Optional static temporary directory
51   - // By default temporary files are generated in the script current
52   - // path.
53   - // If defined :
54   - // - MUST BE terminated by a '/'.
55   - // - MUST be a valid, already created directory
56   - // Samples :
57   - // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
58   - // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
59   - define( 'PCLZIP_TEMPORARY_DIR', '' );
60   -
61   -// --------------------------------------------------------------------------------
62   -// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
63   -// --------------------------------------------------------------------------------
64   -
65   - // ----- Global variables
66   - $g_pclzip_version = "2.5";
67   -
68   - // ----- Error codes
69   - // -1 : Unable to open file in binary write mode
70   - // -2 : Unable to open file in binary read mode
71   - // -3 : Invalid parameters
72   - // -4 : File does not exist
73   - // -5 : Filename is too long (max. 255)
74   - // -6 : Not a valid zip file
75   - // -7 : Invalid extracted file size
76   - // -8 : Unable to create directory
77   - // -9 : Invalid archive extension
78   - // -10 : Invalid archive format
79   - // -11 : Unable to delete file (unlink)
80   - // -12 : Unable to rename file (rename)
81   - // -13 : Invalid header checksum
82   - // -14 : Invalid archive size
83   - define( 'PCLZIP_ERR_USER_ABORTED', 2 );
84   - define( 'PCLZIP_ERR_NO_ERROR', 0 );
85   - define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
86   - define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
87   - define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
88   - define( 'PCLZIP_ERR_MISSING_FILE', -4 );
89   - define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
90   - define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
91   - define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
92   - define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
93   - define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
94   - define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
95   - define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
96   - define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
97   - define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
98   - define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
99   - define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
100   - define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
101   - define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
102   - define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
103   - define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
104   - define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
105   - define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
106   -
107   - // ----- Options values
108   - define( 'PCLZIP_OPT_PATH', 77001 );
109   - define( 'PCLZIP_OPT_ADD_PATH', 77002 );
110   - define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
111   - define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
112   - define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
113   - define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
114   - define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
115   - define( 'PCLZIP_OPT_BY_NAME', 77008 );
116   - define( 'PCLZIP_OPT_BY_INDEX', 77009 );
117   - define( 'PCLZIP_OPT_BY_EREG', 77010 );
118   - define( 'PCLZIP_OPT_BY_PREG', 77011 );
119   - define( 'PCLZIP_OPT_COMMENT', 77012 );
120   - define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
121   - define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
122   - define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
123   - define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
124   - define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
125   - // Having big trouble with crypt. Need to multiply 2 long int
126   - // which is not correctly supported by PHP ...
127   - //define( 'PCLZIP_OPT_CRYPT', 77018 );
128   - define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
129   -
130   - // ----- File description attributes
131   - define( 'PCLZIP_ATT_FILE_NAME', 79001 );
132   - define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
133   - define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
134   -
135   - // ----- Call backs values
136   - define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
137   - define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
138   - define( 'PCLZIP_CB_PRE_ADD', 78003 );
139   - define( 'PCLZIP_CB_POST_ADD', 78004 );
140   - /* For futur use
141   - define( 'PCLZIP_CB_PRE_LIST', 78005 );
142   - define( 'PCLZIP_CB_POST_LIST', 78006 );
143   - define( 'PCLZIP_CB_PRE_DELETE', 78007 );
144   - define( 'PCLZIP_CB_POST_DELETE', 78008 );
145   - */
146   -
147   - // --------------------------------------------------------------------------------
148   - // Class : PclZip
149   - // Description :
150   - // PclZip is the class that represent a Zip archive.
151   - // The public methods allow the manipulation of the archive.
152   - // Attributes :
153   - // Attributes must not be accessed directly.
154   - // Methods :
155   - // PclZip() : Object creator
156   - // create() : Creates the Zip archive
157   - // listContent() : List the content of the Zip archive
158   - // extract() : Extract the content of the archive
159   - // properties() : List the properties of the archive
160   - // --------------------------------------------------------------------------------
161   - class PclZip
162   - {
163   - // ----- Filename of the zip file
164   - var $zipname = '';
165   -
166   - // ----- File descriptor of the zip file
167   - var $zip_fd = 0;
168   -
169   - // ----- Internal error handling
170   - var $error_code = 1;
171   - var $error_string = '';
172   -
173   - // ----- Current status of the magic_quotes_runtime
174   - // This value store the php configuration for magic_quotes
175   - // The class can then disable the magic_quotes and reset it after
176   - var $magic_quotes_status;
177   -
178   - // --------------------------------------------------------------------------------
179   - // Function : PclZip()
180   - // Description :
181   - // Creates a PclZip object and set the name of the associated Zip archive
182   - // filename.
183   - // Note that no real action is taken, if the archive does not exist it is not
184   - // created. Use create() for that.
185   - // --------------------------------------------------------------------------------
186   - function PclZip($p_zipname)
187   - {
188   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");
189   -
190   - // ----- Tests the zlib
191   - if (!function_exists('gzopen'))
192   - {
193   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");
194   - die('Abort '.basename(__FILE__).' : Missing zlib extensions');
195   - }
196   -
197   - // ----- Set the attributes
198   - $this->zipname = $p_zipname;
199   - $this->zip_fd = 0;
200   - $this->magic_quotes_status = -1;
201   -
202   - // ----- Return
203   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);
204   - return;
205   - }
206   - // --------------------------------------------------------------------------------
207   -
208   - // --------------------------------------------------------------------------------
209   - // Function :
210   - // create($p_filelist, $p_add_dir="", $p_remove_dir="")
211   - // create($p_filelist, $p_option, $p_option_value, ...)
212   - // Description :
213   - // This method supports two different synopsis. The first one is historical.
214   - // This method creates a Zip Archive. The Zip file is created in the
215   - // filesystem. The files and directories indicated in $p_filelist
216   - // are added in the archive. See the parameters description for the
217   - // supported format of $p_filelist.
218   - // When a directory is in the list, the directory and its content is added
219   - // in the archive.
220   - // In this synopsis, the function takes an optional variable list of
221   - // options. See bellow the supported options.
222   - // Parameters :
223   - // $p_filelist : An array containing file or directory names, or
224   - // a string containing one filename or one directory name, or
225   - // a string containing a list of filenames and/or directory
226   - // names separated by spaces.
227   - // $p_add_dir : A path to add before the real path of the archived file,
228   - // in order to have it memorized in the archive.
229   - // $p_remove_dir : A path to remove from the real path of the file to archive,
230   - // in order to have a shorter path memorized in the archive.
231   - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
232   - // is removed first, before $p_add_dir is added.
233   - // Options :
234   - // PCLZIP_OPT_ADD_PATH :
235   - // PCLZIP_OPT_REMOVE_PATH :
236   - // PCLZIP_OPT_REMOVE_ALL_PATH :
237   - // PCLZIP_OPT_COMMENT :
238   - // PCLZIP_CB_PRE_ADD :
239   - // PCLZIP_CB_POST_ADD :
240   - // Return Values :
241   - // 0 on failure,
242   - // The list of the added files, with a status of the add action.
243   - // (see PclZip::listContent() for list entry format)
244   - // --------------------------------------------------------------------------------
245   - function create($p_filelist)
246   - {
247   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");
248   - $v_result=1;
249   -
250   - // ----- Reset the error handler
251   - $this->privErrorReset();
252   -
253   - // ----- Set default values
254   - $v_options = array();
255   - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
256   -
257   - // ----- Look for variable options arguments
258   - $v_size = func_num_args();
259   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
260   -
261   - // ----- Look for arguments
262   - if ($v_size > 1) {
263   - // ----- Get the arguments
264   - $v_arg_list = func_get_args();
265   -
266   - // ----- Remove from the options list the first argument
267   - array_shift($v_arg_list);
268   - $v_size--;
269   -
270   - // ----- Look for first arg
271   - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
272   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
273   -
274   - // ----- Parse the options
275   - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
276   - array (PCLZIP_OPT_REMOVE_PATH => 'optional',
277   - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
278   - PCLZIP_OPT_ADD_PATH => 'optional',
279   - PCLZIP_CB_PRE_ADD => 'optional',
280   - PCLZIP_CB_POST_ADD => 'optional',
281   - PCLZIP_OPT_NO_COMPRESSION => 'optional',
282   - PCLZIP_OPT_COMMENT => 'optional'
283   - //, PCLZIP_OPT_CRYPT => 'optional'
284   - ));
285   - if ($v_result != 1) {
286   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
287   - return 0;
288   - }
289   - }
290   -
291   - // ----- Look for 2 args
292   - // Here we need to support the first historic synopsis of the
293   - // method.
294   - else {
295   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
296   -
297   - // ----- Get the first argument
298   - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
299   -
300   - // ----- Look for the optional second argument
301   - if ($v_size == 2) {
302   - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
303   - }
304   - else if ($v_size > 2) {
305   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
306   - "Invalid number / type of arguments");
307   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
308   - return 0;
309   - }
310   - }
311   - }
312   -
313   - // ----- Init
314   - $v_string_list = array();
315   - $v_att_list = array();
316   - $v_filedescr_list = array();
317   - $p_result_list = array();
318   -
319   - // ----- Look if the $p_filelist is really an array
320   - if (is_array($p_filelist)) {
321   -
322   - // ----- Look if the first element is also an array
323   - // This will mean that this is a file description entry
324   - if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
325   - $v_att_list = $p_filelist;
326   - }
327   -
328   - // ----- The list is a list of string names
329   - else {
330   - $v_string_list = $p_filelist;
331   - }
332   - }
333   -
334   - // ----- Look if the $p_filelist is a string
335   - else if (is_string($p_filelist)) {
336   - // ----- Create a list from the string
337   - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
338   - }
339   -
340   - // ----- Invalid variable type for $p_filelist
341   - else {
342   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
343   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
344   - return 0;
345   - }
346   -
347   - // ----- Reformat the string list
348   - if (sizeof($v_string_list) != 0) {
349   - foreach ($v_string_list as $v_string) {
350   - if ($v_string != '') {
351   - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
352   - }
353   - else {
354   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename");
355   - }
356   - }
357   - }
358   -
359   - // ----- For each file in the list check the attributes
360   - $v_supported_attributes
361   - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
362   - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
363   - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
364   - );
365   - foreach ($v_att_list as $v_entry) {
366   - $v_result = $this->privFileDescrParseAtt($v_entry,
367   - $v_filedescr_list[],
368   - $v_options,
369   - $v_supported_attributes);
370   - if ($v_result != 1) {
371   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
372   - return 0;
373   - }
374   - }
375   -
376   - // ----- Expand the filelist (expand directories)
377   - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
378   - if ($v_result != 1) {
379   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
380   - return 0;
381   - }
382   -
383   - // ----- Call the create fct
384   - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
385   - if ($v_result != 1) {
386   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
387   - return 0;
388   - }
389   -
390   - // ----- Return
391   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
392   - return $p_result_list;
393   - }
394   - // --------------------------------------------------------------------------------
395   -
396   - // --------------------------------------------------------------------------------
397   - // Function :
398   - // add($p_filelist, $p_add_dir="", $p_remove_dir="")
399   - // add($p_filelist, $p_option, $p_option_value, ...)
400   - // Description :
401   - // This method supports two synopsis. The first one is historical.
402   - // This methods add the list of files in an existing archive.
403   - // If a file with the same name already exists, it is added at the end of the
404   - // archive, the first one is still present.
405   - // If the archive does not exist, it is created.
406   - // Parameters :
407   - // $p_filelist : An array containing file or directory names, or
408   - // a string containing one filename or one directory name, or
409   - // a string containing a list of filenames and/or directory
410   - // names separated by spaces.
411   - // $p_add_dir : A path to add before the real path of the archived file,
412   - // in order to have it memorized in the archive.
413   - // $p_remove_dir : A path to remove from the real path of the file to archive,
414   - // in order to have a shorter path memorized in the archive.
415   - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
416   - // is removed first, before $p_add_dir is added.
417   - // Options :
418   - // PCLZIP_OPT_ADD_PATH :
419   - // PCLZIP_OPT_REMOVE_PATH :
420   - // PCLZIP_OPT_REMOVE_ALL_PATH :
421   - // PCLZIP_OPT_COMMENT :
422   - // PCLZIP_OPT_ADD_COMMENT :
423   - // PCLZIP_OPT_PREPEND_COMMENT :
424   - // PCLZIP_CB_PRE_ADD :
425   - // PCLZIP_CB_POST_ADD :
426   - // Return Values :
427   - // 0 on failure,
428   - // The list of the added files, with a status of the add action.
429   - // (see PclZip::listContent() for list entry format)
430   - // --------------------------------------------------------------------------------
431   - function add($p_filelist)
432   - {
433   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");
434   - $v_result=1;
435   -
436   - // ----- Reset the error handler
437   - $this->privErrorReset();
438   -
439   - // ----- Set default values
440   - $v_options = array();
441   - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
442   -
443   - // ----- Look for variable options arguments
444   - $v_size = func_num_args();
445   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
446   -
447   - // ----- Look for arguments
448   - if ($v_size > 1) {
449   - // ----- Get the arguments
450   - $v_arg_list = func_get_args();
451   -
452   - // ----- Remove form the options list the first argument
453   - array_shift($v_arg_list);
454   - $v_size--;
455   -
456   - // ----- Look for first arg
457   - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
458   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
459   -
460   - // ----- Parse the options
461   - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
462   - array (PCLZIP_OPT_REMOVE_PATH => 'optional',
463   - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
464   - PCLZIP_OPT_ADD_PATH => 'optional',
465   - PCLZIP_CB_PRE_ADD => 'optional',
466   - PCLZIP_CB_POST_ADD => 'optional',
467   - PCLZIP_OPT_NO_COMPRESSION => 'optional',
468   - PCLZIP_OPT_COMMENT => 'optional',
469   - PCLZIP_OPT_ADD_COMMENT => 'optional',
470   - PCLZIP_OPT_PREPEND_COMMENT => 'optional'
471   - //, PCLZIP_OPT_CRYPT => 'optional'
472   - ));
473   - if ($v_result != 1) {
474   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
475   - return 0;
476   - }
477   - }
478   -
479   - // ----- Look for 2 args
480   - // Here we need to support the first historic synopsis of the
481   - // method.
482   - else {
483   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
484   -
485   - // ----- Get the first argument
486   - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
487   -
488   - // ----- Look for the optional second argument
489   - if ($v_size == 2) {
490   - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
491   - }
492   - else if ($v_size > 2) {
493   - // ----- Error log
494   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
495   -
496   - // ----- Return
497   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
498   - return 0;
499   - }
500   - }
501   - }
502   -
503   - // ----- Init
504   - $v_string_list = array();
505   - $v_att_list = array();
506   - $v_filedescr_list = array();
507   - $p_result_list = array();
508   -
509   - // ----- Look if the $p_filelist is really an array
510   - if (is_array($p_filelist)) {
511   -
512   - // ----- Look if the first element is also an array
513   - // This will mean that this is a file description entry
514   - if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
515   - $v_att_list = $p_filelist;
516   - }
517   -
518   - // ----- The list is a list of string names
519   - else {
520   - $v_string_list = $p_filelist;
521   - }
522   - }
523   -
524   - // ----- Look if the $p_filelist is a string
525   - else if (is_string($p_filelist)) {
526   - // ----- Create a list from the string
527   - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
528   - }
529   -
530   - // ----- Invalid variable type for $p_filelist
531   - else {
532   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
533   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
534   - return 0;
535   - }
536   -
537   - // ----- Reformat the string list
538   - if (sizeof($v_string_list) != 0) {
539   - foreach ($v_string_list as $v_string) {
540   - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
541   - }
542   - }
543   -
544   - // ----- For each file in the list check the attributes
545   - $v_supported_attributes
546   - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
547   - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
548   - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
549   - );
550   - foreach ($v_att_list as $v_entry) {
551   - $v_result = $this->privFileDescrParseAtt($v_entry,
552   - $v_filedescr_list[],
553   - $v_options,
554   - $v_supported_attributes);
555   - if ($v_result != 1) {
556   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
557   - return 0;
558   - }
559   - }
560   -
561   - // ----- Expand the filelist (expand directories)
562   - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
563   - if ($v_result != 1) {
564   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
565   - return 0;
566   - }
567   -
568   - // ----- Call the create fct
569   - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
570   - if ($v_result != 1) {
571   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
572   - return 0;
573   - }
574   -
575   - // ----- Return
576   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
577   - return $p_result_list;
578   - }
579   - // --------------------------------------------------------------------------------
580   -
581   - // --------------------------------------------------------------------------------
582   - // Function : listContent()
583   - // Description :
584   - // This public method, gives the list of the files and directories, with their
585   - // properties.
586   - // The properties of each entries in the list are (used also in other functions) :
587   - // filename : Name of the file. For a create or add action it is the filename
588   - // given by the user. For an extract function it is the filename
589   - // of the extracted file.
590   - // stored_filename : Name of the file / directory stored in the archive.
591   - // size : Size of the stored file.
592   - // compressed_size : Size of the file's data compressed in the archive
593   - // (without the headers overhead)
594   - // mtime : Last known modification date of the file (UNIX timestamp)
595   - // comment : Comment associated with the file
596   - // folder : true | false
597   - // index : index of the file in the archive
598   - // status : status of the action (depending of the action) :
599   - // Values are :
600   - // ok : OK !
601   - // filtered : the file / dir is not extracted (filtered by user)
602   - // already_a_directory : the file can not be extracted because a
603   - // directory with the same name already exists
604   - // write_protected : the file can not be extracted because a file
605   - // with the same name already exists and is
606   - // write protected
607   - // newer_exist : the file was not extracted because a newer file exists
608   - // path_creation_fail : the file is not extracted because the folder
609   - // does not exists and can not be created
610   - // write_error : the file was not extracted because there was a
611   - // error while writing the file
612   - // read_error : the file was not extracted because there was a error
613   - // while reading the file
614   - // invalid_header : the file was not extracted because of an archive
615   - // format error (bad file header)
616   - // Note that each time a method can continue operating when there
617   - // is an action error on a file, the error is only logged in the file status.
618   - // Return Values :
619   - // 0 on an unrecoverable failure,
620   - // The list of the files in the archive.
621   - // --------------------------------------------------------------------------------
622   - function listContent()
623   - {
624   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");
625   - $v_result=1;
626   -
627   - // ----- Reset the error handler
628   - $this->privErrorReset();
629   -
630   - // ----- Check archive
631   - if (!$this->privCheckFormat()) {
632   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
633   - return(0);
634   - }
635   -
636   - // ----- Call the extracting fct
637   - $p_list = array();
638   - if (($v_result = $this->privList($p_list)) != 1)
639   - {
640   - unset($p_list);
641   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
642   - return(0);
643   - }
644   -
645   - // ----- Return
646   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
647   - return $p_list;
648   - }
649   - // --------------------------------------------------------------------------------
650   -
651   - // --------------------------------------------------------------------------------
652   - // Function :
653   - // extract($p_path="./", $p_remove_path="")
654   - // extract([$p_option, $p_option_value, ...])
655   - // Description :
656   - // This method supports two synopsis. The first one is historical.
657   - // This method extract all the files / directories from the archive to the
658   - // folder indicated in $p_path.
659   - // If you want to ignore the 'root' part of path of the memorized files
660   - // you can indicate this in the optional $p_remove_path parameter.
661   - // By default, if a newer file with the same name already exists, the
662   - // file is not extracted.
663   - //
664   - // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
665   - // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
666   - // at the end of the path value of PCLZIP_OPT_PATH.
667   - // Parameters :
668   - // $p_path : Path where the files and directories are to be extracted
669   - // $p_remove_path : First part ('root' part) of the memorized path
670   - // (if any similar) to remove while extracting.
671   - // Options :
672   - // PCLZIP_OPT_PATH :
673   - // PCLZIP_OPT_ADD_PATH :
674   - // PCLZIP_OPT_REMOVE_PATH :
675   - // PCLZIP_OPT_REMOVE_ALL_PATH :
676   - // PCLZIP_CB_PRE_EXTRACT :
677   - // PCLZIP_CB_POST_EXTRACT :
678   - // Return Values :
679   - // 0 or a negative value on failure,
680   - // The list of the extracted files, with a status of the action.
681   - // (see PclZip::listContent() for list entry format)
682   - // --------------------------------------------------------------------------------
683   - function extract()
684   - {
685   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
686   - $v_result=1;
687   -
688   - // ----- Reset the error handler
689   - $this->privErrorReset();
690   -
691   - // ----- Check archive
692   - if (!$this->privCheckFormat()) {
693   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
694   - return(0);
695   - }
696   -
697   - // ----- Set default values
698   - $v_options = array();
699   -// $v_path = "./";
700   - $v_path = '';
701   - $v_remove_path = "";
702   - $v_remove_all_path = false;
703   -
704   - // ----- Look for variable options arguments
705   - $v_size = func_num_args();
706   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
707   -
708   - // ----- Default values for option
709   - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
710   -
711   - // ----- Look for arguments
712   - if ($v_size > 0) {
713   - // ----- Get the arguments
714   - $v_arg_list = func_get_args();
715   -
716   - // ----- Look for first arg
717   - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
718   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
719   -
720   - // ----- Parse the options
721   - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
722   - array (PCLZIP_OPT_PATH => 'optional',
723   - PCLZIP_OPT_REMOVE_PATH => 'optional',
724   - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
725   - PCLZIP_OPT_ADD_PATH => 'optional',
726   - PCLZIP_CB_PRE_EXTRACT => 'optional',
727   - PCLZIP_CB_POST_EXTRACT => 'optional',
728   - PCLZIP_OPT_SET_CHMOD => 'optional',
729   - PCLZIP_OPT_BY_NAME => 'optional',
730   - PCLZIP_OPT_BY_EREG => 'optional',
731   - PCLZIP_OPT_BY_PREG => 'optional',
732   - PCLZIP_OPT_BY_INDEX => 'optional',
733   - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
734   - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
735   - PCLZIP_OPT_REPLACE_NEWER => 'optional'
736   - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
737   - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
738   - ));
739   - if ($v_result != 1) {
740   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
741   - return 0;
742   - }
743   -
744   - // ----- Set the arguments
745   - if (isset($v_options[PCLZIP_OPT_PATH])) {
746   - $v_path = $v_options[PCLZIP_OPT_PATH];
747   - }
748   - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
749   - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
750   - }
751   - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
752   - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
753   - }
754   - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
755   - // ----- Check for '/' in last path char
756   - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
757   - $v_path .= '/';
758   - }
759   - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
760   - }
761   - }
762   -
763   - // ----- Look for 2 args
764   - // Here we need to support the first historic synopsis of the
765   - // method.
766   - else {
767   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
768   -
769   - // ----- Get the first argument
770   - $v_path = $v_arg_list[0];
771   -
772   - // ----- Look for the optional second argument
773   - if ($v_size == 2) {
774   - $v_remove_path = $v_arg_list[1];
775   - }
776   - else if ($v_size > 2) {
777   - // ----- Error log
778   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
779   -
780   - // ----- Return
781   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
782   - return 0;
783   - }
784   - }
785   - }
786   -
787   - // ----- Trace
788   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
789   -
790   - // ----- Call the extracting fct
791   - $p_list = array();
792   - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
793   - $v_remove_all_path, $v_options);
794   - if ($v_result < 1) {
795   - unset($p_list);
796   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
797   - return(0);
798   - }
799   -
800   - // ----- Return
801   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
802   - return $p_list;
803   - }
804   - // --------------------------------------------------------------------------------
805   -
806   -
807   - // --------------------------------------------------------------------------------
808   - // Function :
809   - // extractByIndex($p_index, $p_path="./", $p_remove_path="")
810   - // extractByIndex($p_index, [$p_option, $p_option_value, ...])
811   - // Description :
812   - // This method supports two synopsis. The first one is historical.
813   - // This method is doing a partial extract of the archive.
814   - // The extracted files or folders are identified by their index in the
815   - // archive (from 0 to n).
816   - // Note that if the index identify a folder, only the folder entry is
817   - // extracted, not all the files included in the archive.
818   - // Parameters :
819   - // $p_index : A single index (integer) or a string of indexes of files to
820   - // extract. The form of the string is "0,4-6,8-12" with only numbers
821   - // and '-' for range or ',' to separate ranges. No spaces or ';'
822   - // are allowed.
823   - // $p_path : Path where the files and directories are to be extracted
824   - // $p_remove_path : First part ('root' part) of the memorized path
825   - // (if any similar) to remove while extracting.
826   - // Options :
827   - // PCLZIP_OPT_PATH :
828   - // PCLZIP_OPT_ADD_PATH :
829   - // PCLZIP_OPT_REMOVE_PATH :
830   - // PCLZIP_OPT_REMOVE_ALL_PATH :
831   - // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
832   - // not as files.
833   - // The resulting content is in a new field 'content' in the file
834   - // structure.
835   - // This option must be used alone (any other options are ignored).
836   - // PCLZIP_CB_PRE_EXTRACT :
837   - // PCLZIP_CB_POST_EXTRACT :
838   - // Return Values :
839   - // 0 on failure,
840   - // The list of the extracted files, with a status of the action.
841   - // (see PclZip::listContent() for list entry format)
842   - // --------------------------------------------------------------------------------
843   - //function extractByIndex($p_index, options...)
844   - function extractByIndex($p_index)
845   - {
846   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");
847   - $v_result=1;
848   -
849   - // ----- Reset the error handler
850   - $this->privErrorReset();
851   -
852   - // ----- Check archive
853   - if (!$this->privCheckFormat()) {
854   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
855   - return(0);
856   - }
857   -
858   - // ----- Set default values
859   - $v_options = array();
860   -// $v_path = "./";
861   - $v_path = '';
862   - $v_remove_path = "";
863   - $v_remove_all_path = false;
864   -
865   - // ----- Look for variable options arguments
866   - $v_size = func_num_args();
867   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
868   -
869   - // ----- Default values for option
870   - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
871   -
872   - // ----- Look for arguments
873   - if ($v_size > 1) {
874   - // ----- Get the arguments
875   - $v_arg_list = func_get_args();
876   -
877   - // ----- Remove form the options list the first argument
878   - array_shift($v_arg_list);
879   - $v_size--;
880   -
881   - // ----- Look for first arg
882   - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
883   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
884   -
885   - // ----- Parse the options
886   - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
887   - array (PCLZIP_OPT_PATH => 'optional',
888   - PCLZIP_OPT_REMOVE_PATH => 'optional',
889   - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
890   - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
891   - PCLZIP_OPT_ADD_PATH => 'optional',
892   - PCLZIP_CB_PRE_EXTRACT => 'optional',
893   - PCLZIP_CB_POST_EXTRACT => 'optional',
894   - PCLZIP_OPT_SET_CHMOD => 'optional',
895   - PCLZIP_OPT_REPLACE_NEWER => 'optional'
896   - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
897   - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
898   - ));
899   - if ($v_result != 1) {
900   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
901   - return 0;
902   - }
903   -
904   - // ----- Set the arguments
905   - if (isset($v_options[PCLZIP_OPT_PATH])) {
906   - $v_path = $v_options[PCLZIP_OPT_PATH];
907   - }
908   - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
909   - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
910   - }
911   - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
912   - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
913   - }
914   - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
915   - // ----- Check for '/' in last path char
916   - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
917   - $v_path .= '/';
918   - }
919   - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
920   - }
921   - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
922   - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
923   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");
924   - }
925   - else {
926   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");
927   - }
928   - }
929   -
930   - // ----- Look for 2 args
931   - // Here we need to support the first historic synopsis of the
932   - // method.
933   - else {
934   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
935   -
936   - // ----- Get the first argument
937   - $v_path = $v_arg_list[0];
938   -
939   - // ----- Look for the optional second argument
940   - if ($v_size == 2) {
941   - $v_remove_path = $v_arg_list[1];
942   - }
943   - else if ($v_size > 2) {
944   - // ----- Error log
945   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
946   -
947   - // ----- Return
948   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
949   - return 0;
950   - }
951   - }
952   - }
953   -
954   - // ----- Trace
955   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
956   -
957   - // ----- Trick
958   - // Here I want to reuse extractByRule(), so I need to parse the $p_index
959   - // with privParseOptions()
960   - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
961   - $v_options_trick = array();
962   - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
963   - array (PCLZIP_OPT_BY_INDEX => 'optional' ));
964   - if ($v_result != 1) {
965   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
966   - return 0;
967   - }
968   - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
969   -
970   - // ----- Call the extracting fct
971   - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
972   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
973   - return(0);
974   - }
975   -
976   - // ----- Return
977   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
978   - return $p_list;
979   - }
980   - // --------------------------------------------------------------------------------
981   -
982   - // --------------------------------------------------------------------------------
983   - // Function :
984   - // delete([$p_option, $p_option_value, ...])
985   - // Description :
986   - // This method removes files from the archive.
987   - // If no parameters are given, then all the archive is emptied.
988   - // Parameters :
989   - // None or optional arguments.
990   - // Options :
991   - // PCLZIP_OPT_BY_INDEX :
992   - // PCLZIP_OPT_BY_NAME :
993   - // PCLZIP_OPT_BY_EREG :
994   - // PCLZIP_OPT_BY_PREG :
995   - // Return Values :
996   - // 0 on failure,
997   - // The list of the files which are still present in the archive.
998   - // (see PclZip::listContent() for list entry format)
999   - // --------------------------------------------------------------------------------
1000   - function delete()
1001   - {
1002   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
1003   - $v_result=1;
1004   -
1005   - // ----- Reset the error handler
1006   - $this->privErrorReset();
1007   -
1008   - // ----- Check archive
1009   - if (!$this->privCheckFormat()) {
1010   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1011   - return(0);
1012   - }
1013   -
1014   - // ----- Set default values
1015   - $v_options = array();
1016   -
1017   - // ----- Look for variable options arguments
1018   - $v_size = func_num_args();
1019   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
1020   -
1021   - // ----- Look for arguments
1022   - if ($v_size > 0) {
1023   - // ----- Get the arguments
1024   - $v_arg_list = func_get_args();
1025   -
1026   - // ----- Parse the options
1027   - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1028   - array (PCLZIP_OPT_BY_NAME => 'optional',
1029   - PCLZIP_OPT_BY_EREG => 'optional',
1030   - PCLZIP_OPT_BY_PREG => 'optional',
1031   - PCLZIP_OPT_BY_INDEX => 'optional' ));
1032   - if ($v_result != 1) {
1033   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1034   - return 0;
1035   - }
1036   - }
1037   -
1038   - // ----- Magic quotes trick
1039   - $this->privDisableMagicQuotes();
1040   -
1041   - // ----- Call the delete fct
1042   - $v_list = array();
1043   - if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1044   - $this->privSwapBackMagicQuotes();
1045   - unset($v_list);
1046   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
1047   - return(0);
1048   - }
1049   -
1050   - // ----- Magic quotes trick
1051   - $this->privSwapBackMagicQuotes();
1052   -
1053   - // ----- Return
1054   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
1055   - return $v_list;
1056   - }
1057   - // --------------------------------------------------------------------------------
1058   -
1059   - // --------------------------------------------------------------------------------
1060   - // Function : deleteByIndex()
1061   - // Description :
1062   - // ***** Deprecated *****
1063   - // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1064   - // --------------------------------------------------------------------------------
1065   - function deleteByIndex($p_index)
1066   - {
1067   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
1068   -
1069   - $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1070   -
1071   - // ----- Return
1072   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
1073   - return $p_list;
1074   - }
1075   - // --------------------------------------------------------------------------------
1076   -
1077   - // --------------------------------------------------------------------------------
1078   - // Function : properties()
1079   - // Description :
1080   - // This method gives the properties of the archive.
1081   - // The properties are :
1082   - // nb : Number of files in the archive
1083   - // comment : Comment associated with the archive file
1084   - // status : not_exist, ok
1085   - // Parameters :
1086   - // None
1087   - // Return Values :
1088   - // 0 on failure,
1089   - // An array with the archive properties.
1090   - // --------------------------------------------------------------------------------
1091   - function properties()
1092   - {
1093   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");
1094   -
1095   - // ----- Reset the error handler
1096   - $this->privErrorReset();
1097   -
1098   - // ----- Magic quotes trick
1099   - $this->privDisableMagicQuotes();
1100   -
1101   - // ----- Check archive
1102   - if (!$this->privCheckFormat()) {
1103   - $this->privSwapBackMagicQuotes();
1104   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1105   - return(0);
1106   - }
1107   -
1108   - // ----- Default properties
1109   - $v_prop = array();
1110   - $v_prop['comment'] = '';
1111   - $v_prop['nb'] = 0;
1112   - $v_prop['status'] = 'not_exist';
1113   -
1114   - // ----- Look if file exists
1115   - if (@is_file($this->zipname))
1116   - {
1117   - // ----- Open the zip file
1118   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
1119   - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1120   - {
1121   - $this->privSwapBackMagicQuotes();
1122   -
1123   - // ----- Error log
1124   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1125   -
1126   - // ----- Return
1127   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);
1128   - return 0;
1129   - }
1130   -
1131   - // ----- Read the central directory informations
1132   - $v_central_dir = array();
1133   - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1134   - {
1135   - $this->privSwapBackMagicQuotes();
1136   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1137   - return 0;
1138   - }
1139   -
1140   - // ----- Close the zip file
1141   - $this->privCloseFd();
1142   -
1143   - // ----- Set the user attributes
1144   - $v_prop['comment'] = $v_central_dir['comment'];
1145   - $v_prop['nb'] = $v_central_dir['entries'];
1146   - $v_prop['status'] = 'ok';
1147   - }
1148   -
1149   - // ----- Magic quotes trick
1150   - $this->privSwapBackMagicQuotes();
1151   -
1152   - // ----- Return
1153   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);
1154   - return $v_prop;
1155   - }
1156   - // --------------------------------------------------------------------------------
1157   -
1158   - // --------------------------------------------------------------------------------
1159   - // Function : duplicate()
1160   - // Description :
1161   - // This method creates an archive by copying the content of an other one. If
1162   - // the archive already exist, it is replaced by the new one without any warning.
1163   - // Parameters :
1164   - // $p_archive : The filename of a valid archive, or
1165   - // a valid PclZip object.
1166   - // Return Values :
1167   - // 1 on success.
1168   - // 0 or a negative value on error (error code).
1169   - // --------------------------------------------------------------------------------
1170   - function duplicate($p_archive)
1171   - {
1172   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");
1173   - $v_result = 1;
1174   -
1175   - // ----- Reset the error handler
1176   - $this->privErrorReset();
1177   -
1178   - // ----- Look if the $p_archive is a PclZip object
1179   - if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1180   - {
1181   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");
1182   -
1183   - // ----- Duplicate the archive
1184   - $v_result = $this->privDuplicate($p_archive->zipname);
1185   - }
1186   -
1187   - // ----- Look if the $p_archive is a string (so a filename)
1188   - else if (is_string($p_archive))
1189   - {
1190   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");
1191   -
1192   - // ----- Check that $p_archive is a valid zip file
1193   - // TBC : Should also check the archive format
1194   - if (!is_file($p_archive)) {
1195   - // ----- Error log
1196   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1197   - $v_result = PCLZIP_ERR_MISSING_FILE;
1198   - }
1199   - else {
1200   - // ----- Duplicate the archive
1201   - $v_result = $this->privDuplicate($p_archive);
1202   - }
1203   - }
1204   -
1205   - // ----- Invalid variable
1206   - else
1207   - {
1208   - // ----- Error log
1209   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1210   - $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1211   - }
1212   -
1213   - // ----- Return
1214   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1215   - return $v_result;
1216   - }
1217   - // --------------------------------------------------------------------------------
1218   -
1219   - // --------------------------------------------------------------------------------
1220   - // Function : merge()
1221   - // Description :
1222   - // This method merge the $p_archive_to_add archive at the end of the current
1223   - // one ($this).
1224   - // If the archive ($this) does not exist, the merge becomes a duplicate.
1225   - // If the $p_archive_to_add archive does not exist, the merge is a success.
1226   - // Parameters :
1227   - // $p_archive_to_add : It can be directly the filename of a valid zip archive,
1228   - // or a PclZip object archive.
1229   - // Return Values :
1230   - // 1 on success,
1231   - // 0 or negative values on error (see below).
1232   - // --------------------------------------------------------------------------------
1233   - function merge($p_archive_to_add)
1234   - {
1235   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");
1236   - $v_result = 1;
1237   -
1238   - // ----- Reset the error handler
1239   - $this->privErrorReset();
1240   -
1241   - // ----- Check archive
1242   - if (!$this->privCheckFormat()) {
1243   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1244   - return(0);
1245   - }
1246   -
1247   - // ----- Look if the $p_archive_to_add is a PclZip object
1248   - if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1249   - {
1250   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");
1251   -
1252   - // ----- Merge the archive
1253   - $v_result = $this->privMerge($p_archive_to_add);
1254   - }
1255   -
1256   - // ----- Look if the $p_archive_to_add is a string (so a filename)
1257   - else if (is_string($p_archive_to_add))
1258   - {
1259   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");
1260   -
1261   - // ----- Create a temporary archive
1262   - $v_object_archive = new PclZip($p_archive_to_add);
1263   -
1264   - // ----- Merge the archive
1265   - $v_result = $this->privMerge($v_object_archive);
1266   - }
1267   -
1268   - // ----- Invalid variable
1269   - else
1270   - {
1271   - // ----- Error log
1272   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1273   - $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1274   - }
1275   -
1276   - // ----- Return
1277   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1278   - return $v_result;
1279   - }
1280   - // --------------------------------------------------------------------------------
1281   -
1282   -
1283   -
1284   - // --------------------------------------------------------------------------------
1285   - // Function : errorCode()
1286   - // Description :
1287   - // Parameters :
1288   - // --------------------------------------------------------------------------------
1289   - function errorCode()
1290   - {
1291   - if (PCLZIP_ERROR_EXTERNAL == 1) {
1292   - return(PclErrorCode());
1293   - }
1294   - else {
1295   - return($this->error_code);
1296   - }
1297   - }
1298   - // --------------------------------------------------------------------------------
1299   -
1300   - // --------------------------------------------------------------------------------
1301   - // Function : errorName()
1302   - // Description :
1303   - // Parameters :
1304   - // --------------------------------------------------------------------------------
1305   - function errorName($p_with_code=false)
1306   - {
1307   - $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1308   - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1309   - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1310   - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1311   - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1312   - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1313   - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1314   - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1315   - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1316   - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1317   - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1318   - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1319   - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1320   - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1321   - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1322   - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1323   - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1324   - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1325   - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1326   - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1327   - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1328   - );
1329   -
1330   - if (isset($v_name[$this->error_code])) {
1331   - $v_value = $v_name[$this->error_code];
1332   - }
1333   - else {
1334   - $v_value = 'NoName';
1335   - }
1336   -
1337   - if ($p_with_code) {
1338   - return($v_value.' ('.$this->error_code.')');
1339   - }
1340   - else {
1341   - return($v_value);
1342   - }
1343   - }
1344   - // --------------------------------------------------------------------------------
1345   -
1346   - // --------------------------------------------------------------------------------
1347   - // Function : errorInfo()
1348   - // Description :
1349   - // Parameters :
1350   - // --------------------------------------------------------------------------------
1351   - function errorInfo($p_full=false)
1352   - {
1353   - if (PCLZIP_ERROR_EXTERNAL == 1) {
1354   - return(PclErrorString());
1355   - }
1356   - else {
1357   - if ($p_full) {
1358   - return($this->errorName(true)." : ".$this->error_string);
1359   - }
1360   - else {
1361   - return($this->error_string." [code ".$this->error_code."]");
1362   - }
1363   - }
1364   - }
1365   - // --------------------------------------------------------------------------------
1366   -
1367   -
1368   -// --------------------------------------------------------------------------------
1369   -// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1370   -// ***** *****
1371   -// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1372   -// --------------------------------------------------------------------------------
1373   -
1374   -
1375   -
1376   - // --------------------------------------------------------------------------------
1377   - // Function : privCheckFormat()
1378   - // Description :
1379   - // This method check that the archive exists and is a valid zip archive.
1380   - // Several level of check exists. (futur)
1381   - // Parameters :
1382   - // $p_level : Level of check. Default 0.
1383   - // 0 : Check the first bytes (magic codes) (default value))
1384   - // 1 : 0 + Check the central directory (futur)
1385   - // 2 : 1 + Check each file header (futur)
1386   - // Return Values :
1387   - // true on success,
1388   - // false on error, the error code is set.
1389   - // --------------------------------------------------------------------------------
1390   - function privCheckFormat($p_level=0)
1391   - {
1392   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");
1393   - $v_result = true;
1394   -
1395   - // ----- Reset the file system cache
1396   - clearstatcache();
1397   -
1398   - // ----- Reset the error handler
1399   - $this->privErrorReset();
1400   -
1401   - // ----- Look if the file exits
1402   - if (!is_file($this->zipname)) {
1403   - // ----- Error log
1404   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1405   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
1406   - return(false);
1407   - }
1408   -
1409   - // ----- Check that the file is readeable
1410   - if (!is_readable($this->zipname)) {
1411   - // ----- Error log
1412   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1413   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
1414   - return(false);
1415   - }
1416   -
1417   - // ----- Check the magic code
1418   - // TBC
1419   -
1420   - // ----- Check the central header
1421   - // TBC
1422   -
1423   - // ----- Check each file header
1424   - // TBC
1425   -
1426   - // ----- Return
1427   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1428   - return $v_result;
1429   - }
1430   - // --------------------------------------------------------------------------------
1431   -
1432   - // --------------------------------------------------------------------------------
1433   - // Function : privParseOptions()
1434   - // Description :
1435   - // This internal methods reads the variable list of arguments ($p_options_list,
1436   - // $p_size) and generate an array with the options and values ($v_result_list).
1437   - // $v_requested_options contains the options that can be present and those that
1438   - // must be present.
1439   - // $v_requested_options is an array, with the option value as key, and 'optional',
1440   - // or 'mandatory' as value.
1441   - // Parameters :
1442   - // See above.
1443   - // Return Values :
1444   - // 1 on success.
1445   - // 0 on failure.
1446   - // --------------------------------------------------------------------------------
1447   - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1448   - {
1449   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");
1450   - $v_result=1;
1451   -
1452   - // ----- Read the options
1453   - $i=0;
1454   - while ($i<$p_size) {
1455   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");
1456   -
1457   - // ----- Check if the option is supported
1458   - if (!isset($v_requested_options[$p_options_list[$i]])) {
1459   - // ----- Error log
1460   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1461   -
1462   - // ----- Return
1463   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1464   - return PclZip::errorCode();
1465   - }
1466   -
1467   - // ----- Look for next option
1468   - switch ($p_options_list[$i]) {
1469   - // ----- Look for options that request a path value
1470   - case PCLZIP_OPT_PATH :
1471   - case PCLZIP_OPT_REMOVE_PATH :
1472   - case PCLZIP_OPT_ADD_PATH :
1473   - // ----- Check the number of parameters
1474   - if (($i+1) >= $p_size) {
1475   - // ----- Error log
1476   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1477   -
1478   - // ----- Return
1479   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1480   - return PclZip::errorCode();
1481   - }
1482   -
1483   - // ----- Get the value
1484   - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1485   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1486   - $i++;
1487   - break;
1488   -
1489   - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1490   - // ----- Check the number of parameters
1491   - if (($i+1) >= $p_size) {
1492   - // ----- Error log
1493   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1494   -
1495   - // ----- Return
1496   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1497   - return PclZip::errorCode();
1498   - }
1499   -
1500   - // ----- Get the value
1501   - if ( is_string($p_options_list[$i+1])
1502   - && ($p_options_list[$i+1] != '')) {
1503   - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1504   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1505   - $i++;
1506   - }
1507   - else {
1508   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored.");
1509   - }
1510   - break;
1511   -
1512   - // ----- Look for options that request an array of string for value
1513   - case PCLZIP_OPT_BY_NAME :
1514   - // ----- Check the number of parameters
1515   - if (($i+1) >= $p_size) {
1516   - // ----- Error log
1517   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1518   -
1519   - // ----- Return
1520   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1521   - return PclZip::errorCode();
1522   - }
1523   -
1524   - // ----- Get the value
1525   - if (is_string($p_options_list[$i+1])) {
1526   - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1527   - }
1528   - else if (is_array($p_options_list[$i+1])) {
1529   - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1530   - }
1531   - else {
1532   - // ----- Error log
1533   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1534   -
1535   - // ----- Return
1536   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1537   - return PclZip::errorCode();
1538   - }
1539   - ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1540   - $i++;
1541   - break;
1542   -
1543   - // ----- Look for options that request an EREG or PREG expression
1544   - case PCLZIP_OPT_BY_EREG :
1545   - case PCLZIP_OPT_BY_PREG :
1546   - //case PCLZIP_OPT_CRYPT :
1547   - // ----- Check the number of parameters
1548   - if (($i+1) >= $p_size) {
1549   - // ----- Error log
1550   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1551   -
1552   - // ----- Return
1553   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1554   - return PclZip::errorCode();
1555   - }
1556   -
1557   - // ----- Get the value
1558   - if (is_string($p_options_list[$i+1])) {
1559   - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1560   - }
1561   - else {
1562   - // ----- Error log
1563   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1564   -
1565   - // ----- Return
1566   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1567   - return PclZip::errorCode();
1568   - }
1569   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1570   - $i++;
1571   - break;
1572   -
1573   - // ----- Look for options that takes a string
1574   - case PCLZIP_OPT_COMMENT :
1575   - case PCLZIP_OPT_ADD_COMMENT :
1576   - case PCLZIP_OPT_PREPEND_COMMENT :
1577   - // ----- Check the number of parameters
1578   - if (($i+1) >= $p_size) {
1579   - // ----- Error log
1580   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1581   - "Missing parameter value for option '"
1582   - .PclZipUtilOptionText($p_options_list[$i])
1583   - ."'");
1584   -
1585   - // ----- Return
1586   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1587   - return PclZip::errorCode();
1588   - }
1589   -
1590   - // ----- Get the value
1591   - if (is_string($p_options_list[$i+1])) {
1592   - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1593   - }
1594   - else {
1595   - // ----- Error log
1596   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1597   - "Wrong parameter value for option '"
1598   - .PclZipUtilOptionText($p_options_list[$i])
1599   - ."'");
1600   -
1601   - // ----- Return
1602   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1603   - return PclZip::errorCode();
1604   - }
1605   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1606   - $i++;
1607   - break;
1608   -
1609   - // ----- Look for options that request an array of index
1610   - case PCLZIP_OPT_BY_INDEX :
1611   - // ----- Check the number of parameters
1612   - if (($i+1) >= $p_size) {
1613   - // ----- Error log
1614   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1615   -
1616   - // ----- Return
1617   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1618   - return PclZip::errorCode();
1619   - }
1620   -
1621   - // ----- Get the value
1622   - $v_work_list = array();
1623   - if (is_string($p_options_list[$i+1])) {
1624   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
1625   -
1626   - // ----- Remove spaces
1627   - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1628   -
1629   - // ----- Parse items
1630   - $v_work_list = explode(",", $p_options_list[$i+1]);
1631   - }
1632   - else if (is_integer($p_options_list[$i+1])) {
1633   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
1634   - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1635   - }
1636   - else if (is_array($p_options_list[$i+1])) {
1637   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
1638   - $v_work_list = $p_options_list[$i+1];
1639   - }
1640   - else {
1641   - // ----- Error log
1642   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1643   -
1644   - // ----- Return
1645   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1646   - return PclZip::errorCode();
1647   - }
1648   -
1649   - // ----- Reduce the index list
1650   - // each index item in the list must be a couple with a start and
1651   - // an end value : [0,3], [5-5], [8-10], ...
1652   - // ----- Check the format of each item
1653   - $v_sort_flag=false;
1654   - $v_sort_value=0;
1655   - for ($j=0; $j<sizeof($v_work_list); $j++) {
1656   - // ----- Explode the item
1657   - $v_item_list = explode("-", $v_work_list[$j]);
1658   - $v_size_item_list = sizeof($v_item_list);
1659   -
1660   - // ----- TBC : Here we might check that each item is a
1661   - // real integer ...
1662   -
1663   - // ----- Look for single value
1664   - if ($v_size_item_list == 1) {
1665   - // ----- Set the option value
1666   - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1667   - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1668   - }
1669   - elseif ($v_size_item_list == 2) {
1670   - // ----- Set the option value
1671   - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1672   - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1673   - }
1674   - else {
1675   - // ----- Error log
1676   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1677   -
1678   - // ----- Return
1679   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1680   - return PclZip::errorCode();
1681   - }
1682   -
1683   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");
1684   -
1685   - // ----- Look for list sort
1686   - if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1687   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
1688   - $v_sort_flag=true;
1689   -
1690   - // ----- TBC : An automatic sort should be writen ...
1691   - // ----- Error log
1692   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1693   -
1694   - // ----- Return
1695   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1696   - return PclZip::errorCode();
1697   - }
1698   - $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1699   - }
1700   -
1701   - // ----- Sort the items
1702   - if ($v_sort_flag) {
1703   - // TBC : To Be Completed
1704   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
1705   - }
1706   -
1707   - // ----- Next option
1708   - $i++;
1709   - break;
1710   -
1711   - // ----- Look for options that request no value
1712   - case PCLZIP_OPT_REMOVE_ALL_PATH :
1713   - case PCLZIP_OPT_EXTRACT_AS_STRING :
1714   - case PCLZIP_OPT_NO_COMPRESSION :
1715   - case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1716   - case PCLZIP_OPT_REPLACE_NEWER :
1717   - case PCLZIP_OPT_STOP_ON_ERROR :
1718   - $v_result_list[$p_options_list[$i]] = true;
1719   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1720   - break;
1721   -
1722   - // ----- Look for options that request an octal value
1723   - case PCLZIP_OPT_SET_CHMOD :
1724   - // ----- Check the number of parameters
1725   - if (($i+1) >= $p_size) {
1726   - // ----- Error log
1727   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1728   -
1729   - // ----- Return
1730   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1731   - return PclZip::errorCode();
1732   - }
1733   -
1734   - // ----- Get the value
1735   - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1736   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1737   - $i++;
1738   - break;
1739   -
1740   - // ----- Look for options that request a call-back
1741   - case PCLZIP_CB_PRE_EXTRACT :
1742   - case PCLZIP_CB_POST_EXTRACT :
1743   - case PCLZIP_CB_PRE_ADD :
1744   - case PCLZIP_CB_POST_ADD :
1745   - /* for futur use
1746   - case PCLZIP_CB_PRE_DELETE :
1747   - case PCLZIP_CB_POST_DELETE :
1748   - case PCLZIP_CB_PRE_LIST :
1749   - case PCLZIP_CB_POST_LIST :
1750   - */
1751   - // ----- Check the number of parameters
1752   - if (($i+1) >= $p_size) {
1753   - // ----- Error log
1754   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1755   -
1756   - // ----- Return
1757   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1758   - return PclZip::errorCode();
1759   - }
1760   -
1761   - // ----- Get the value
1762   - $v_function_name = $p_options_list[$i+1];
1763   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");
1764   -
1765   - // ----- Check that the value is a valid existing function
1766   - if (!function_exists($v_function_name)) {
1767   - // ----- Error log
1768   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1769   -
1770   - // ----- Return
1771   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1772   - return PclZip::errorCode();
1773   - }
1774   -
1775   - // ----- Set the attribute
1776   - $v_result_list[$p_options_list[$i]] = $v_function_name;
1777   - $i++;
1778   - break;
1779   -
1780   - default :
1781   - // ----- Error log
1782   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1783   - "Unknown parameter '"
1784   - .$p_options_list[$i]."'");
1785   -
1786   - // ----- Return
1787   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1788   - return PclZip::errorCode();
1789   - }
1790   -
1791   - // ----- Next options
1792   - $i++;
1793   - }
1794   -
1795   - // ----- Look for mandatory options
1796   - if ($v_requested_options !== false) {
1797   - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1798   - // ----- Look for mandatory option
1799   - if ($v_requested_options[$key] == 'mandatory') {
1800   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
1801   - // ----- Look if present
1802   - if (!isset($v_result_list[$key])) {
1803   - // ----- Error log
1804   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1805   -
1806   - // ----- Return
1807   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1808   - return PclZip::errorCode();
1809   - }
1810   - }
1811   - }
1812   - }
1813   -
1814   - // ----- Return
1815   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1816   - return $v_result;
1817   - }
1818   - // --------------------------------------------------------------------------------
1819   -
1820   - // --------------------------------------------------------------------------------
1821   - // Function : privFileDescrParseAtt()
1822   - // Description :
1823   - // Parameters :
1824   - // Return Values :
1825   - // 1 on success.
1826   - // 0 on failure.
1827   - // --------------------------------------------------------------------------------
1828   - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1829   - {
1830   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", "");
1831   - $v_result=1;
1832   -
1833   - // ----- For each file in the list check the attributes
1834   - foreach ($p_file_list as $v_key => $v_value) {
1835   -
1836   - // ----- Check if the option is supported
1837   - if (!isset($v_requested_options[$v_key])) {
1838   - // ----- Error log
1839   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1840   -
1841   - // ----- Return
1842   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1843   - return PclZip::errorCode();
1844   - }
1845   -
1846   - // ----- Look for attribute
1847   - switch ($v_key) {
1848   - case PCLZIP_ATT_FILE_NAME :
1849   - if (!is_string($v_value)) {
1850   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1851   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1852   - return PclZip::errorCode();
1853   - }
1854   -
1855   - $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1856   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
1857   -
1858   - if ($p_filedescr['filename'] == '') {
1859   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1860   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1861   - return PclZip::errorCode();
1862   - }
1863   -
1864   - break;
1865   -
1866   - case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1867   - if (!is_string($v_value)) {
1868   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1869   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1870   - return PclZip::errorCode();
1871   - }
1872   -
1873   - $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1874   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
1875   -
1876   - if ($p_filedescr['new_short_name'] == '') {
1877   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1878   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1879   - return PclZip::errorCode();
1880   - }
1881   - break;
1882   -
1883   - case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1884   - if (!is_string($v_value)) {
1885   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1886   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1887   - return PclZip::errorCode();
1888   - }
1889   -
1890   - $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1891   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
1892   -
1893   - if ($p_filedescr['new_full_name'] == '') {
1894   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1895   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1896   - return PclZip::errorCode();
1897   - }
1898   - break;
1899   -
1900   - default :
1901   - // ----- Error log
1902   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1903   - "Unknown parameter '".$v_key."'");
1904   -
1905   - // ----- Return
1906   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1907   - return PclZip::errorCode();
1908   - }
1909   -
1910   - // ----- Look for mandatory options
1911   - if ($v_requested_options !== false) {
1912   - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1913   - // ----- Look for mandatory option
1914   - if ($v_requested_options[$key] == 'mandatory') {
1915   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
1916   - // ----- Look if present
1917   - if (!isset($p_file_list[$key])) {
1918   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1919   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1920   - return PclZip::errorCode();
1921   - }
1922   - }
1923   - }
1924   - }
1925   -
1926   - // end foreach
1927   - }
1928   -
1929   - // ----- Return
1930   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1931   - return $v_result;
1932   - }
1933   - // --------------------------------------------------------------------------------
1934   -
1935   - // --------------------------------------------------------------------------------
1936   - // Function : privFileDescrExpand()
1937   - // Description :
1938   - // Parameters :
1939   - // Return Values :
1940   - // 1 on success.
1941   - // 0 on failure.
1942   - // --------------------------------------------------------------------------------
1943   - function privFileDescrExpand(&$p_filedescr_list, &$p_options)
1944   - {
1945   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", "");
1946   - $v_result=1;
1947   -
1948   - // ----- Create a result list
1949   - $v_result_list = array();
1950   -
1951   - // ----- Look each entry
1952   - for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
1953   - // ----- Get filedescr
1954   - $v_descr = $p_filedescr_list[$i];
1955   -
1956   - // ----- Reduce the filename
1957   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'");
1958   - $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']);
1959   - $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
1960   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'");
1961   -
1962   - // ----- Get type of descr
1963   - if (!file_exists($v_descr['filename'])) {
1964   - // ----- Error log
1965   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists");
1966   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists");
1967   -
1968   - // ----- Return
1969   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1970   - return PclZip::errorCode();
1971   - }
1972   - if (@is_file($v_descr['filename'])) {
1973   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file");
1974   - $v_descr['type'] = 'file';
1975   - }
1976   - else if (@is_dir($v_descr['filename'])) {
1977   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder");
1978   - $v_descr['type'] = 'folder';
1979   - }
1980   - else if (@is_link($v_descr['filename'])) {
1981   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link");
1982   - // skip
1983   - continue;
1984   - }
1985   - else {
1986   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type");
1987   - // skip
1988   - continue;
1989   - }
1990   -
1991   - // ----- Calculate the stored filename
1992   - $this->privCalculateStoredFilename($v_descr, $p_options);
1993   -
1994   - // ----- Add the descriptor in result list
1995   - $v_result_list[sizeof($v_result_list)] = $v_descr;
1996   -
1997   - // ----- Look for folder
1998   - if ($v_descr['type'] == 'folder') {
1999   - // ----- List of items in folder
2000   - $v_dirlist_descr = array();
2001   - $v_dirlist_nb = 0;
2002   - if ($v_folder_handler = @opendir($v_descr['filename'])) {
2003   - while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2004   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory");
2005   -
2006   - // ----- Skip '.' and '..'
2007   - if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2008   - continue;
2009   - }
2010   -
2011   - // ----- Compose the full filename
2012   - $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2013   -
2014   - // ----- Look for different stored filename
2015   - // Because the name of the folder was changed, the name of the
2016   - // files/sub-folders also change
2017   - if ($v_descr['stored_filename'] != $v_descr['filename']) {
2018   - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2019   - }
2020   -
2021   - $v_dirlist_nb++;
2022   - }
2023   - }
2024   - else {
2025   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped.");
2026   - // TBC : unable to open folder in read mode
2027   - }
2028   -
2029   - // ----- Expand each element of the list
2030   - if ($v_dirlist_nb != 0) {
2031   - // ----- Expand
2032   - if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2033   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2034   - return $v_result;
2035   - }
2036   -
2037   - // ----- Concat the resulting list
2038   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')");
2039   - $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2040   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'");
2041   - }
2042   - else {
2043   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand.");
2044   - }
2045   -
2046   - // ----- Free local array
2047   - unset($v_dirlist_descr);
2048   - }
2049   - }
2050   -
2051   - // ----- Get the result list
2052   - $p_filedescr_list = $v_result_list;
2053   -
2054   - // ----- Return
2055   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2056   - return $v_result;
2057   - }
2058   - // --------------------------------------------------------------------------------
2059   -
2060   - // --------------------------------------------------------------------------------
2061   - // Function : privCreate()
2062   - // Description :
2063   - // Parameters :
2064   - // Return Values :
2065   - // --------------------------------------------------------------------------------
2066   - function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2067   - {
2068   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list");
2069   - $v_result=1;
2070   - $v_list_detail = array();
2071   -
2072   - // ----- Magic quotes trick
2073   - $this->privDisableMagicQuotes();
2074   -
2075   - // ----- Open the file in write mode
2076   - if (($v_result = $this->privOpenFd('wb')) != 1)
2077   - {
2078   - // ----- Return
2079   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2080   - return $v_result;
2081   - }
2082   -
2083   - // ----- Add the list of files
2084   - $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2085   -
2086   - // ----- Close
2087   - $this->privCloseFd();
2088   -
2089   - // ----- Magic quotes trick
2090   - $this->privSwapBackMagicQuotes();
2091   -
2092   - // ----- Return
2093   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2094   - return $v_result;
2095   - }
2096   - // --------------------------------------------------------------------------------
2097   -
2098   - // --------------------------------------------------------------------------------
2099   - // Function : privAdd()
2100   - // Description :
2101   - // Parameters :
2102   - // Return Values :
2103   - // --------------------------------------------------------------------------------
2104   - function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2105   - {
2106   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list");
2107   - $v_result=1;
2108   - $v_list_detail = array();
2109   -
2110   - // ----- Look if the archive exists or is empty
2111   - if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2112   - {
2113   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
2114   -
2115   - // ----- Do a create
2116   - $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2117   -
2118   - // ----- Return
2119   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2120   - return $v_result;
2121   - }
2122   - // ----- Magic quotes trick
2123   - $this->privDisableMagicQuotes();
2124   -
2125   - // ----- Open the zip file
2126   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2127   - if (($v_result=$this->privOpenFd('rb')) != 1)
2128   - {
2129   - // ----- Magic quotes trick
2130   - $this->privSwapBackMagicQuotes();
2131   -
2132   - // ----- Return
2133   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2134   - return $v_result;
2135   - }
2136   -
2137   - // ----- Read the central directory informations
2138   - $v_central_dir = array();
2139   - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2140   - {
2141   - $this->privCloseFd();
2142   - $this->privSwapBackMagicQuotes();
2143   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2144   - return $v_result;
2145   - }
2146   -
2147   - // ----- Go to beginning of File
2148   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
2149   - @rewind($this->zip_fd);
2150   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
2151   -
2152   - // ----- Creates a temporay file
2153   - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2154   -
2155   - // ----- Open the temporary file in write mode
2156   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2157   - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2158   - {
2159   - $this->privCloseFd();
2160   - $this->privSwapBackMagicQuotes();
2161   -
2162   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2163   -
2164   - // ----- Return
2165   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2166   - return PclZip::errorCode();
2167   - }
2168   -
2169   - // ----- Copy the files from the archive to the temporary file
2170   - // TBC : Here I should better append the file and go back to erase the central dir
2171   - $v_size = $v_central_dir['offset'];
2172   - while ($v_size != 0)
2173   - {
2174   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2175   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
2176   - $v_buffer = fread($this->zip_fd, $v_read_size);
2177   - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2178   - $v_size -= $v_read_size;
2179   - }
2180   -
2181   - // ----- Swap the file descriptor
2182   - // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2183   - // the following methods on the temporary fil and not the real archive
2184   - $v_swap = $this->zip_fd;
2185   - $this->zip_fd = $v_zip_temp_fd;
2186   - $v_zip_temp_fd = $v_swap;
2187   -
2188   - // ----- Add the files
2189   - $v_header_list = array();
2190   - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2191   - {
2192   - fclose($v_zip_temp_fd);
2193   - $this->privCloseFd();
2194   - @unlink($v_zip_temp_name);
2195   - $this->privSwapBackMagicQuotes();
2196   -
2197   - // ----- Return
2198   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2199   - return $v_result;
2200   - }
2201   -
2202   - // ----- Store the offset of the central dir
2203   - $v_offset = @ftell($this->zip_fd);
2204   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
2205   -
2206   - // ----- Copy the block of file headers from the old archive
2207   - $v_size = $v_central_dir['size'];
2208   - while ($v_size != 0)
2209   - {
2210   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2211   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
2212   - $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2213   - @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2214   - $v_size -= $v_read_size;
2215   - }
2216   -
2217   - // ----- Create the Central Dir files header
2218   - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2219   - {
2220   - // ----- Create the file header
2221   - if ($v_header_list[$i]['status'] == 'ok') {
2222   - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2223   - fclose($v_zip_temp_fd);
2224   - $this->privCloseFd();
2225   - @unlink($v_zip_temp_name);
2226   - $this->privSwapBackMagicQuotes();
2227   -
2228   - // ----- Return
2229   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2230   - return $v_result;
2231   - }
2232   - $v_count++;
2233   - }
2234   -
2235   - // ----- Transform the header to a 'usable' info
2236   - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2237   - }
2238   -
2239   - // ----- Zip file comment
2240   - $v_comment = $v_central_dir['comment'];
2241   - if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2242   - $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2243   - }
2244   - if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2245   - $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2246   - }
2247   - if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2248   - $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2249   - }
2250   -
2251   - // ----- Calculate the size of the central header
2252   - $v_size = @ftell($this->zip_fd)-$v_offset;
2253   -
2254   - // ----- Create the central dir footer
2255   - if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2256   - {
2257   - // ----- Reset the file list
2258   - unset($v_header_list);
2259   - $this->privSwapBackMagicQuotes();
2260   -
2261   - // ----- Return
2262   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2263   - return $v_result;
2264   - }
2265   -
2266   - // ----- Swap back the file descriptor
2267   - $v_swap = $this->zip_fd;
2268   - $this->zip_fd = $v_zip_temp_fd;
2269   - $v_zip_temp_fd = $v_swap;
2270   -
2271   - // ----- Close
2272   - $this->privCloseFd();
2273   -
2274   - // ----- Close the temporary file
2275   - @fclose($v_zip_temp_fd);
2276   -
2277   - // ----- Magic quotes trick
2278   - $this->privSwapBackMagicQuotes();
2279   -
2280   - // ----- Delete the zip file
2281   - // TBC : I should test the result ...
2282   - @unlink($this->zipname);
2283   -
2284   - // ----- Rename the temporary file
2285   - // TBC : I should test the result ...
2286   - //@rename($v_zip_temp_name, $this->zipname);
2287   - PclZipUtilRename($v_zip_temp_name, $this->zipname);
2288   -
2289   - // ----- Return
2290   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2291   - return $v_result;
2292   - }
2293   - // --------------------------------------------------------------------------------
2294   -
2295   - // --------------------------------------------------------------------------------
2296   - // Function : privOpenFd()
2297   - // Description :
2298   - // Parameters :
2299   - // --------------------------------------------------------------------------------
2300   - function privOpenFd($p_mode)
2301   - {
2302   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);
2303   - $v_result=1;
2304   -
2305   - // ----- Look if already open
2306   - if ($this->zip_fd != 0)
2307   - {
2308   - // ----- Error log
2309   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2310   -
2311   - // ----- Return
2312   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2313   - return PclZip::errorCode();
2314   - }
2315   -
2316   - // ----- Open the zip file
2317   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');
2318   - if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2319   - {
2320   - // ----- Error log
2321   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2322   -
2323   - // ----- Return
2324   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2325   - return PclZip::errorCode();
2326   - }
2327   -
2328   - // ----- Return
2329   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2330   - return $v_result;
2331   - }
2332   - // --------------------------------------------------------------------------------
2333   -
2334   - // --------------------------------------------------------------------------------
2335   - // Function : privCloseFd()
2336   - // Description :
2337   - // Parameters :
2338   - // --------------------------------------------------------------------------------
2339   - function privCloseFd()
2340   - {
2341   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");
2342   - $v_result=1;
2343   -
2344   - if ($this->zip_fd != 0)
2345   - @fclose($this->zip_fd);
2346   - $this->zip_fd = 0;
2347   -
2348   - // ----- Return
2349   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2350   - return $v_result;
2351   - }
2352   - // --------------------------------------------------------------------------------
2353   -
2354   - // --------------------------------------------------------------------------------
2355   - // Function : privAddList()
2356   - // Description :
2357   - // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2358   - // different from the real path of the file. This is usefull if you want to have PclTar
2359   - // running in any directory, and memorize relative path from an other directory.
2360   - // Parameters :
2361   - // $p_list : An array containing the file or directory names to add in the tar
2362   - // $p_result_list : list of added files with their properties (specially the status field)
2363   - // $p_add_dir : Path to add in the filename path archived
2364   - // $p_remove_dir : Path to remove in the filename path archived
2365   - // Return Values :
2366   - // --------------------------------------------------------------------------------
2367   -// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2368   - function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2369   - {
2370   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list");
2371   - $v_result=1;
2372   -
2373   - // ----- Add the files
2374   - $v_header_list = array();
2375   - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2376   - {
2377   - // ----- Return
2378   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2379   - return $v_result;
2380   - }
2381   -
2382   - // ----- Store the offset of the central dir
2383   - $v_offset = @ftell($this->zip_fd);
2384   -
2385   - // ----- Create the Central Dir files header
2386   - for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2387   - {
2388   - // ----- Create the file header
2389   - if ($v_header_list[$i]['status'] == 'ok') {
2390   - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2391   - // ----- Return
2392   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2393   - return $v_result;
2394   - }
2395   - $v_count++;
2396   - }
2397   -
2398   - // ----- Transform the header to a 'usable' info
2399   - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2400   - }
2401   -
2402   - // ----- Zip file comment
2403   - $v_comment = '';
2404   - if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2405   - $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2406   - }
2407   -
2408   - // ----- Calculate the size of the central header
2409   - $v_size = @ftell($this->zip_fd)-$v_offset;
2410   -
2411   - // ----- Create the central dir footer
2412   - if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2413   - {
2414   - // ----- Reset the file list
2415   - unset($v_header_list);
2416   -
2417   - // ----- Return
2418   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2419   - return $v_result;
2420   - }
2421   -
2422   - // ----- Return
2423   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2424   - return $v_result;
2425   - }
2426   - // --------------------------------------------------------------------------------
2427   -
2428   - // --------------------------------------------------------------------------------
2429   - // Function : privAddFileList()
2430   - // Description :
2431   - // Parameters :
2432   - // $p_filedescr_list : An array containing the file description
2433   - // or directory names to add in the zip
2434   - // $p_result_list : list of added files with their properties (specially the status field)
2435   - // Return Values :
2436   - // --------------------------------------------------------------------------------
2437   - function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2438   - {
2439   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "filedescr_list");
2440   - $v_result=1;
2441   - $v_header = array();
2442   -
2443   - // ----- Recuperate the current number of elt in list
2444   - $v_nb = sizeof($p_result_list);
2445   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have ".$v_nb." elements");
2446   -
2447   - // ----- Loop on the files
2448   - for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
2449   - // ----- Format the filename
2450   - $p_filedescr_list[$j]['filename']
2451   - = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
2452   -
2453   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file '".$p_filedescr_list[$j]['filename']."'");
2454   -
2455   - // ----- Skip empty file names
2456   - // TBC : Can this be possible ? not checked in DescrParseAtt ?
2457   - if ($p_filedescr_list[$j]['filename'] == "") {
2458   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
2459   - continue;
2460   - }
2461   -
2462   - // ----- Check the filename
2463   - if (!file_exists($p_filedescr_list[$j]['filename'])) {
2464   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
2465   - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
2466   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2467   - return PclZip::errorCode();
2468   - }
2469   -
2470   - // ----- Look if it is a file or a dir with no all path remove option
2471   - if ( (is_file($p_filedescr_list[$j]['filename']))
2472   - || ( is_dir($p_filedescr_list[$j]['filename'])
2473   - && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2474   - || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2475   -
2476   - // ----- Add the file
2477   - $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2478   - $p_options);
2479   - if ($v_result != 1) {
2480   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2481   - return $v_result;
2482   - }
2483   -
2484   - // ----- Store the file infos
2485   - $p_result_list[$v_nb++] = $v_header;
2486   - }
2487   - }
2488   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have ".$v_nb." elements");
2489   -
2490   - // ----- Return
2491   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2492   - return $v_result;
2493   - }
2494   - // --------------------------------------------------------------------------------
2495   -
2496   - // --------------------------------------------------------------------------------
2497   - // Function : privAddFile()
2498   - // Description :
2499   - // Parameters :
2500   - // Return Values :
2501   - // --------------------------------------------------------------------------------
2502   - function privAddFile($p_filedescr, &$p_header, &$p_options)
2503   - {
2504   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'");
2505   - $v_result=1;
2506   -
2507   - // ----- Working variable
2508   - $p_filename = $p_filedescr['filename'];
2509   -
2510   - // TBC : Already done in the fileAtt check ... ?
2511   - if ($p_filename == "") {
2512   - // ----- Error log
2513   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2514   -
2515   - // ----- Return
2516   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2517   - return PclZip::errorCode();
2518   - }
2519   -
2520   - // ----- Look for a stored different filename
2521   - if (isset($p_filedescr['stored_filename'])) {
2522   - $v_stored_filename = $p_filedescr['stored_filename'];
2523   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"');
2524   - }
2525   - else {
2526   - $v_stored_filename = $p_filedescr['stored_filename'];
2527   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same');
2528   - }
2529   -
2530   - // ----- Set the file properties
2531   - clearstatcache();
2532   - $p_header['version'] = 20;
2533   - $p_header['version_extracted'] = 10;
2534   - $p_header['flag'] = 0;
2535   - $p_header['compression'] = 0;
2536   - $p_header['mtime'] = filemtime($p_filename);
2537   - $p_header['crc'] = 0;
2538   - $p_header['compressed_size'] = 0;
2539   - $p_header['size'] = filesize($p_filename);
2540   - $p_header['filename_len'] = strlen($p_filename);
2541   - $p_header['extra_len'] = 0;
2542   - $p_header['comment_len'] = 0;
2543   - $p_header['disk'] = 0;
2544   - $p_header['internal'] = 0;
2545   -// $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
2546   - $p_header['external'] = (is_file($p_filename)?0x00000000:0x00000010);
2547   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'");
2548   - $p_header['offset'] = 0;
2549   - $p_header['filename'] = $p_filename;
2550   - $p_header['stored_filename'] = $v_stored_filename;
2551   - $p_header['extra'] = '';
2552   - $p_header['comment'] = '';
2553   - $p_header['status'] = 'ok';
2554   - $p_header['index'] = -1;
2555   -
2556   - // ----- Look for pre-add callback
2557   - if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2558   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");
2559   -
2560   - // ----- Generate a local information
2561   - $v_local_header = array();
2562   - $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2563   -
2564   - // ----- Call the callback
2565   - // Here I do not use call_user_func() because I need to send a reference to the
2566   - // header.
2567   - eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2568   - if ($v_result == 0) {
2569   - // ----- Change the file status
2570   - $p_header['status'] = "skipped";
2571   - $v_result = 1;
2572   - }
2573   -
2574   - // ----- Update the informations
2575   - // Only some fields can be modified
2576   - if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2577   - $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2578   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
2579   - }
2580   - }
2581   -
2582   - // ----- Look for empty stored filename
2583   - if ($p_header['stored_filename'] == "") {
2584   - $p_header['status'] = "filtered";
2585   - }
2586   -
2587   - // ----- Check the path length
2588   - if (strlen($p_header['stored_filename']) > 0xFF) {
2589   - $p_header['status'] = 'filename_too_long';
2590   - }
2591   -
2592   - // ----- Look if no error, or file not skipped
2593   - if ($p_header['status'] == 'ok') {
2594   -
2595   - // ----- Look for a file
2596   - if (is_file($p_filename))
2597   - {
2598   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file");
2599   - // ----- Open the source file
2600   - if (($v_file = @fopen($p_filename, "rb")) == 0) {
2601   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2602   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2603   - return PclZip::errorCode();
2604   - }
2605   -
2606   - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2607   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed");
2608   - // ----- Read the file content
2609   - $v_content_compressed = @fread($v_file, $p_header['size']);
2610   -
2611   - // ----- Calculate the CRC
2612   - $p_header['crc'] = @crc32($v_content_compressed);
2613   -
2614   - // ----- Set header parameters
2615   - $p_header['compressed_size'] = $p_header['size'];
2616   - $p_header['compression'] = 0;
2617   - }
2618   - else {
2619   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed");
2620   - // ----- Read the file content
2621   - $v_content = @fread($v_file, $p_header['size']);
2622   -
2623   - // ----- Calculate the CRC
2624   - $p_header['crc'] = @crc32($v_content);
2625   -
2626   - // ----- Compress the file
2627   - $v_content_compressed = @gzdeflate($v_content);
2628   -
2629   - // ----- Set header parameters
2630   - $p_header['compressed_size'] = strlen($v_content_compressed);
2631   - $p_header['compression'] = 8;
2632   - }
2633   -
2634   - // ----- Look for encryption
2635   - /*
2636   - if ((isset($p_options[PCLZIP_OPT_CRYPT]))
2637   - && ($p_options[PCLZIP_OPT_CRYPT] != "")) {
2638   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ....");
2639   -
2640   - // Should be a random header
2641   - $v_header = 'xxxxxxxxxxxx';
2642   - $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed,
2643   - $p_header['compressed_size'],
2644   - $v_header,
2645   - $p_header['crc'],
2646   - "test");
2647   -
2648   - $p_header['compressed_size'] += 12;
2649   - $p_header['flag'] = 1;
2650   -
2651   - // ----- Add the header to the data
2652   - $v_content_compressed = $v_header.$v_content_compressed;
2653   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed)."");
2654   - }
2655   - */
2656   -
2657   - // ----- Call the header generation
2658   - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2659   - @fclose($v_file);
2660   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2661   - return $v_result;
2662   - }
2663   -
2664   - // ----- Write the compressed (or not) content
2665   - @fwrite($this->zip_fd,
2666   - $v_content_compressed, $p_header['compressed_size']);
2667   -
2668   - // ----- Close the file
2669   - @fclose($v_file);
2670   - }
2671   -
2672   - // ----- Look for a directory
2673   - else {
2674   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder");
2675   - // ----- Look for directory last '/'
2676   - if (@substr($p_header['stored_filename'], -1) != '/') {
2677   - $p_header['stored_filename'] .= '/';
2678   - }
2679   -
2680   - // ----- Set the file properties
2681   - $p_header['size'] = 0;
2682   - //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
2683   - $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2684   -
2685   - // ----- Call the header generation
2686   - if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2687   - {
2688   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2689   - return $v_result;
2690   - }
2691   - }
2692   - }
2693   -
2694   - // ----- Look for post-add callback
2695   - if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2696   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");
2697   -
2698   - // ----- Generate a local information
2699   - $v_local_header = array();
2700   - $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2701   -
2702   - // ----- Call the callback
2703   - // Here I do not use call_user_func() because I need to send a reference to the
2704   - // header.
2705   - eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2706   - if ($v_result == 0) {
2707   - // ----- Ignored
2708   - $v_result = 1;
2709   - }
2710   -
2711   - // ----- Update the informations
2712   - // Nothing can be modified
2713   - }
2714   -
2715   - // ----- Return
2716   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2717   - return $v_result;
2718   - }
2719   - // --------------------------------------------------------------------------------
2720   -
2721   - // --------------------------------------------------------------------------------
2722   - // Function : privCalculateStoredFilename()
2723   - // Description :
2724   - // Based on file descriptor properties and global options, this method
2725   - // calculate the filename that will be stored in the archive.
2726   - // Parameters :
2727   - // Return Values :
2728   - // --------------------------------------------------------------------------------
2729   - function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2730   - {
2731   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCalculateStoredFilename", "filename='".$p_filedescr['filename']."'");
2732   - $v_result=1;
2733   -
2734   - // ----- Working variables
2735   - $p_filename = $p_filedescr['filename'];
2736   - if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2737   - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2738   - }
2739   - else {
2740   - $p_add_dir = '';
2741   - }
2742   - if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2743   - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2744   - }
2745   - else {
2746   - $p_remove_dir = '';
2747   - }
2748   - if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2749   - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2750   - }
2751   - else {
2752   - $p_remove_all_dir = 0;
2753   - }
2754   -
2755   - // ----- Look for full name change
2756   - if (isset($p_filedescr['new_full_name'])) {
2757   - $v_stored_filename = $p_filedescr['new_full_name'];
2758   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing full name of '".$p_filename."' for '".$v_stored_filename."'");
2759   - }
2760   -
2761   - // ----- Look for path and/or short name change
2762   - else {
2763   -
2764   - // ----- Look for short name change
2765   - if (isset($p_filedescr['new_short_name'])) {
2766   - $v_path_info = pathinfo($p_filename);
2767   - $v_dir = '';
2768   - if ($v_path_info['dirname'] != '') {
2769   - $v_dir = $v_path_info['dirname'].'/';
2770   - }
2771   - $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2772   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing short name of '".$p_filename."' for '".$v_stored_filename."'");
2773   - }
2774   - else {
2775   - // ----- Calculate the stored filename
2776   - $v_stored_filename = $p_filename;
2777   - }
2778   -
2779   - // ----- Look for all path to remove
2780   - if ($p_remove_all_dir) {
2781   - $v_stored_filename = basename($p_filename);
2782   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove all path selected change '".$p_filename."' for '".$v_stored_filename."'");
2783   - }
2784   - // ----- Look for partial path remove
2785   - else if ($p_remove_dir != "") {
2786   - if (substr($p_remove_dir, -1) != '/')
2787   - $p_remove_dir .= "/";
2788   -
2789   - if ( (substr($p_filename, 0, 2) == "./")
2790   - || (substr($p_remove_dir, 0, 2) == "./")) {
2791   -
2792   - if ( (substr($p_filename, 0, 2) == "./")
2793   - && (substr($p_remove_dir, 0, 2) != "./")) {
2794   - $p_remove_dir = "./".$p_remove_dir;
2795   - }
2796   - if ( (substr($p_filename, 0, 2) != "./")
2797   - && (substr($p_remove_dir, 0, 2) == "./")) {
2798   - $p_remove_dir = substr($p_remove_dir, 2);
2799   - }
2800   - }
2801   -
2802   - $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2803   - $v_stored_filename);
2804   - if ($v_compare > 0) {
2805   - if ($v_compare == 2) {
2806   - $v_stored_filename = "";
2807   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder");
2808   - }
2809   - else {
2810   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$v_stored_filename'");
2811   - $v_stored_filename = substr($v_stored_filename,
2812   - strlen($p_remove_dir));
2813   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Result is '$v_stored_filename'");
2814   - }
2815   - }
2816   - }
2817   - // ----- Look for path to add
2818   - if ($p_add_dir != "") {
2819   - if (substr($p_add_dir, -1) == "/")
2820   - $v_stored_filename = $p_add_dir.$v_stored_filename;
2821   - else
2822   - $v_stored_filename = $p_add_dir."/".$v_stored_filename;
2823   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
2824   - }
2825   - }
2826   -
2827   - // ----- Filename (reduce the path of stored name)
2828   - $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
2829   - $p_filedescr['stored_filename'] = $v_stored_filename;
2830   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename']));
2831   -
2832   - // ----- Return
2833   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2834   - return $v_result;
2835   - }
2836   - // --------------------------------------------------------------------------------
2837   -
2838   - // --------------------------------------------------------------------------------
2839   - // Function : privWriteFileHeader()
2840   - // Description :
2841   - // Parameters :
2842   - // Return Values :
2843   - // --------------------------------------------------------------------------------
2844   - function privWriteFileHeader(&$p_header)
2845   - {
2846   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
2847   - $v_result=1;
2848   -
2849   - // ----- Store the offset position of the file
2850   - $p_header['offset'] = ftell($this->zip_fd);
2851   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
2852   -
2853   - // ----- Transform UNIX mtime to DOS format mdate/mtime
2854   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
2855   - $v_date = getdate($p_header['mtime']);
2856   - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2857   - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2858   -
2859   - // ----- Packed data
2860   - $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
2861   - $p_header['version_extracted'], $p_header['flag'],
2862   - $p_header['compression'], $v_mtime, $v_mdate,
2863   - $p_header['crc'], $p_header['compressed_size'],
2864   - $p_header['size'],
2865   - strlen($p_header['stored_filename']),
2866   - $p_header['extra_len']);
2867   -
2868   - // ----- Write the first 148 bytes of the header in the archive
2869   - fputs($this->zip_fd, $v_binary_data, 30);
2870   -
2871   - // ----- Write the variable fields
2872   - if (strlen($p_header['stored_filename']) != 0)
2873   - {
2874   - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2875   - }
2876   - if ($p_header['extra_len'] != 0)
2877   - {
2878   - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2879   - }
2880   -
2881   - // ----- Return
2882   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2883   - return $v_result;
2884   - }
2885   - // --------------------------------------------------------------------------------
2886   -
2887   - // --------------------------------------------------------------------------------
2888   - // Function : privWriteCentralFileHeader()
2889   - // Description :
2890   - // Parameters :
2891   - // Return Values :
2892   - // --------------------------------------------------------------------------------
2893   - function privWriteCentralFileHeader(&$p_header)
2894   - {
2895   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
2896   - $v_result=1;
2897   -
2898   - // TBC
2899   - //for(reset($p_header); $key = key($p_header); next($p_header)) {
2900   - // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
2901   - //}
2902   -
2903   - // ----- Transform UNIX mtime to DOS format mdate/mtime
2904   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
2905   - $v_date = getdate($p_header['mtime']);
2906   - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2907   - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2908   -
2909   - // ----- Packed data
2910   - $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
2911   - $p_header['version'], $p_header['version_extracted'],
2912   - $p_header['flag'], $p_header['compression'],
2913   - $v_mtime, $v_mdate, $p_header['crc'],
2914   - $p_header['compressed_size'], $p_header['size'],
2915   - strlen($p_header['stored_filename']),
2916   - $p_header['extra_len'], $p_header['comment_len'],
2917   - $p_header['disk'], $p_header['internal'],
2918   - $p_header['external'], $p_header['offset']);
2919   -
2920   - // ----- Write the 42 bytes of the header in the zip file
2921   - fputs($this->zip_fd, $v_binary_data, 46);
2922   -
2923   - // ----- Write the variable fields
2924   - if (strlen($p_header['stored_filename']) != 0)
2925   - {
2926   - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2927   - }
2928   - if ($p_header['extra_len'] != 0)
2929   - {
2930   - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2931   - }
2932   - if ($p_header['comment_len'] != 0)
2933   - {
2934   - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
2935   - }
2936   -
2937   - // ----- Return
2938   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2939   - return $v_result;
2940   - }
2941   - // --------------------------------------------------------------------------------
2942   -
2943   - // --------------------------------------------------------------------------------
2944   - // Function : privWriteCentralHeader()
2945   - // Description :
2946   - // Parameters :
2947   - // Return Values :
2948   - // --------------------------------------------------------------------------------
2949   - function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
2950   - {
2951   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
2952   - $v_result=1;
2953   -
2954   - // ----- Packed data
2955   - $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
2956   - $p_nb_entries, $p_size,
2957   - $p_offset, strlen($p_comment));
2958   -
2959   - // ----- Write the 22 bytes of the header in the zip file
2960   - fputs($this->zip_fd, $v_binary_data, 22);
2961   -
2962   - // ----- Write the variable fields
2963   - if (strlen($p_comment) != 0)
2964   - {
2965   - fputs($this->zip_fd, $p_comment, strlen($p_comment));
2966   - }
2967   -
2968   - // ----- Return
2969   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2970   - return $v_result;
2971   - }
2972   - // --------------------------------------------------------------------------------
2973   -
2974   - // --------------------------------------------------------------------------------
2975   - // Function : privList()
2976   - // Description :
2977   - // Parameters :
2978   - // Return Values :
2979   - // --------------------------------------------------------------------------------
2980   - function privList(&$p_list)
2981   - {
2982   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
2983   - $v_result=1;
2984   -
2985   - // ----- Magic quotes trick
2986   - $this->privDisableMagicQuotes();
2987   -
2988   - // ----- Open the zip file
2989   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2990   - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
2991   - {
2992   - // ----- Magic quotes trick
2993   - $this->privSwapBackMagicQuotes();
2994   -
2995   - // ----- Error log
2996   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
2997   -
2998   - // ----- Return
2999   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3000   - return PclZip::errorCode();
3001   - }
3002   -
3003   - // ----- Read the central directory informations
3004   - $v_central_dir = array();
3005   - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3006   - {
3007   - $this->privSwapBackMagicQuotes();
3008   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3009   - return $v_result;
3010   - }
3011   -
3012   - // ----- Go to beginning of Central Dir
3013   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'");
3014   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
3015   - @rewind($this->zip_fd);
3016   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
3017   - if (@fseek($this->zip_fd, $v_central_dir['offset']))
3018   - {
3019   - $this->privSwapBackMagicQuotes();
3020   -
3021   - // ----- Error log
3022   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3023   -
3024   - // ----- Return
3025   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3026   - return PclZip::errorCode();
3027   - }
3028   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
3029   -
3030   - // ----- Read each entry
3031   - for ($i=0; $i<$v_central_dir['entries']; $i++)
3032   - {
3033   - // ----- Read the file header
3034   - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3035   - {
3036   - $this->privSwapBackMagicQuotes();
3037   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3038   - return $v_result;
3039   - }
3040   - $v_header['index'] = $i;
3041   -
3042   - // ----- Get the only interesting attributes
3043   - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
3044   - unset($v_header);
3045   - }
3046   -
3047   - // ----- Close the zip file
3048   - $this->privCloseFd();
3049   -
3050   - // ----- Magic quotes trick
3051   - $this->privSwapBackMagicQuotes();
3052   -
3053   - // ----- Return
3054   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3055   - return $v_result;
3056   - }
3057   - // --------------------------------------------------------------------------------
3058   -
3059   - // --------------------------------------------------------------------------------
3060   - // Function : privConvertHeader2FileInfo()
3061   - // Description :
3062   - // This function takes the file informations from the central directory
3063   - // entries and extract the interesting parameters that will be given back.
3064   - // The resulting file infos are set in the array $p_info
3065   - // $p_info['filename'] : Filename with full path. Given by user (add),
3066   - // extracted in the filesystem (extract).
3067   - // $p_info['stored_filename'] : Stored filename in the archive.
3068   - // $p_info['size'] = Size of the file.
3069   - // $p_info['compressed_size'] = Compressed size of the file.
3070   - // $p_info['mtime'] = Last modification date of the file.
3071   - // $p_info['comment'] = Comment associated with the file.
3072   - // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
3073   - // $p_info['status'] = status of the action on the file.
3074   - // Parameters :
3075   - // Return Values :
3076   - // --------------------------------------------------------------------------------
3077   - function privConvertHeader2FileInfo($p_header, &$p_info)
3078   - {
3079   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'");
3080   - $v_result=1;
3081   -
3082   - // ----- Get the interesting attributes
3083   - $p_info['filename'] = $p_header['filename'];
3084   - $p_info['stored_filename'] = $p_header['stored_filename'];
3085   - $p_info['size'] = $p_header['size'];
3086   - $p_info['compressed_size'] = $p_header['compressed_size'];
3087   - $p_info['mtime'] = $p_header['mtime'];
3088   - $p_info['comment'] = $p_header['comment'];
3089   - $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
3090   - $p_info['index'] = $p_header['index'];
3091   - $p_info['status'] = $p_header['status'];
3092   -
3093   - // ----- Return
3094   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3095   - return $v_result;
3096   - }
3097   - // --------------------------------------------------------------------------------
3098   -
3099   - // --------------------------------------------------------------------------------
3100   - // Function : privExtractByRule()
3101   - // Description :
3102   - // Extract a file or directory depending of rules (by index, by name, ...)
3103   - // Parameters :
3104   - // $p_file_list : An array where will be placed the properties of each
3105   - // extracted file
3106   - // $p_path : Path to add while writing the extracted files
3107   - // $p_remove_path : Path to remove (from the file memorized path) while writing the
3108   - // extracted files. If the path does not match the file path,
3109   - // the file is extracted with its memorized path.
3110   - // $p_remove_path does not apply to 'list' mode.
3111   - // $p_path and $p_remove_path are commulative.
3112   - // Return Values :
3113   - // 1 on success,0 or less on error (see error code list)
3114   - // --------------------------------------------------------------------------------
3115   - function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3116   - {
3117   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
3118   - $v_result=1;
3119   -
3120   - // ----- Magic quotes trick
3121   - $this->privDisableMagicQuotes();
3122   -
3123   - // ----- Check the path
3124   - if ( ($p_path == "")
3125   - || ( (substr($p_path, 0, 1) != "/")
3126   - && (substr($p_path, 0, 3) != "../")
3127   - && (substr($p_path,1,2)!=":/")))
3128   - $p_path = "./".$p_path;
3129   -
3130   - // ----- Reduce the path last (and duplicated) '/'
3131   - if (($p_path != "./") && ($p_path != "/"))
3132   - {
3133   - // ----- Look for the path end '/'
3134   - while (substr($p_path, -1) == "/")
3135   - {
3136   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
3137   - $p_path = substr($p_path, 0, strlen($p_path)-1);
3138   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
3139   - }
3140   - }
3141   -
3142   - // ----- Look for path to remove format (should end by /)
3143   - if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
3144   - {
3145   - $p_remove_path .= '/';
3146   - }
3147   - $p_remove_path_size = strlen($p_remove_path);
3148   -
3149   - // ----- Open the zip file
3150   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
3151   - if (($v_result = $this->privOpenFd('rb')) != 1)
3152   - {
3153   - $this->privSwapBackMagicQuotes();
3154   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3155   - return $v_result;
3156   - }
3157   -
3158   - // ----- Read the central directory informations
3159   - $v_central_dir = array();
3160   - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3161   - {
3162   - // ----- Close the zip file
3163   - $this->privCloseFd();
3164   - $this->privSwapBackMagicQuotes();
3165   -
3166   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3167   - return $v_result;
3168   - }
3169   -
3170   - // ----- Start at beginning of Central Dir
3171   - $v_pos_entry = $v_central_dir['offset'];
3172   -
3173   - // ----- Read each entry
3174   - $j_start = 0;
3175   - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3176   - {
3177   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
3178   -
3179   - // ----- Read next Central dir entry
3180   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
3181   - @rewind($this->zip_fd);
3182   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
3183   - if (@fseek($this->zip_fd, $v_pos_entry))
3184   - {
3185   - // ----- Close the zip file
3186   - $this->privCloseFd();
3187   - $this->privSwapBackMagicQuotes();
3188   -
3189   - // ----- Error log
3190   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3191   -
3192   - // ----- Return
3193   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3194   - return PclZip::errorCode();
3195   - }
3196   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
3197   -
3198   - // ----- Read the file header
3199   - $v_header = array();
3200   - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
3201   - {
3202   - // ----- Close the zip file
3203   - $this->privCloseFd();
3204   - $this->privSwapBackMagicQuotes();
3205   -
3206   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3207   - return $v_result;
3208   - }
3209   -
3210   - // ----- Store the index
3211   - $v_header['index'] = $i;
3212   -
3213   - // ----- Store the file position
3214   - $v_pos_entry = ftell($this->zip_fd);
3215   -
3216   - // ----- Look for the specific extract rules
3217   - $v_extract = false;
3218   -
3219   - // ----- Look for extract by name rule
3220   - if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
3221   - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3222   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
3223   -
3224   - // ----- Look if the filename is in the list
3225   - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
3226   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
3227   -
3228   - // ----- Look for a directory
3229   - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3230   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
3231   -
3232   - // ----- Look if the directory is in the filename path
3233   - if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3234   - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3235   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
3236   - $v_extract = true;
3237   - }
3238   - }
3239   - // ----- Look for a filename
3240   - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3241   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
3242   - $v_extract = true;
3243   - }
3244   - }
3245   - }
3246   -
3247   - // ----- Look for extract by ereg rule
3248   - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
3249   - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
3250   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
3251   -
3252   - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
3253   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
3254   - $v_extract = true;
3255   - }
3256   - }
3257   -
3258   - // ----- Look for extract by preg rule
3259   - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
3260   - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3261   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
3262   -
3263   - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
3264   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
3265   - $v_extract = true;
3266   - }
3267   - }
3268   -
3269   - // ----- Look for extract by index rule
3270   - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3271   - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3272   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
3273   -
3274   - // ----- Look if the index is in the list
3275   - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3276   - //--(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']."]");
3277   -
3278   - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3279   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
3280   - $v_extract = true;
3281   - }
3282   - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3283   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
3284   - $j_start = $j+1;
3285   - }
3286   -
3287   - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3288   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
3289   - break;
3290   - }
3291   - }
3292   - }
3293   -
3294   - // ----- Look for no rule, which means extract all the archive
3295   - else {
3296   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
3297   - $v_extract = true;
3298   - }
3299   -
3300   - // ----- Check compression method
3301   - if ( ($v_extract)
3302   - && ( ($v_header['compression'] != 8)
3303   - && ($v_header['compression'] != 0))) {
3304   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")");
3305   - $v_header['status'] = 'unsupported_compression';
3306   -
3307   - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3308   - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3309   - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3310   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3311   -
3312   - $this->privSwapBackMagicQuotes();
3313   -
3314   - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3315   - "Filename '".$v_header['stored_filename']."' is "
3316   - ."compressed by an unsupported compression "
3317   - ."method (".$v_header['compression'].") ");
3318   -
3319   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3320   - return PclZip::errorCode();
3321   - }
3322   - }
3323   -
3324   - // ----- Check encrypted files
3325   - if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3326   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption");
3327   - $v_header['status'] = 'unsupported_encryption';
3328   -
3329   - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3330   - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3331   - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3332   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3333   -
3334   - $this->privSwapBackMagicQuotes();
3335   -
3336   - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3337   - "Unsupported encryption for "
3338   - ." filename '".$v_header['stored_filename']
3339   - ."'");
3340   -
3341   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3342   - return PclZip::errorCode();
3343   - }
3344   - }
3345   -
3346   - // ----- Look for real extraction
3347   - if (($v_extract) && ($v_header['status'] != 'ok')) {
3348   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract");
3349   - $v_result = $this->privConvertHeader2FileInfo($v_header,
3350   - $p_file_list[$v_nb_extracted++]);
3351   - if ($v_result != 1) {
3352   - $this->privCloseFd();
3353   - $this->privSwapBackMagicQuotes();
3354   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3355   - return $v_result;
3356   - }
3357   -
3358   - $v_extract = false;
3359   - }
3360   -
3361   - // ----- Look for real extraction
3362   - if ($v_extract)
3363   - {
3364   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
3365   -
3366   - // ----- Go to the file position
3367   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
3368   - @rewind($this->zip_fd);
3369   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
3370   - if (@fseek($this->zip_fd, $v_header['offset']))
3371   - {
3372   - // ----- Close the zip file
3373   - $this->privCloseFd();
3374   -
3375   - $this->privSwapBackMagicQuotes();
3376   -
3377   - // ----- Error log
3378   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3379   -
3380   - // ----- Return
3381   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3382   - return PclZip::errorCode();
3383   - }
3384   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
3385   -
3386   - // ----- Look for extraction as string
3387   - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3388   -
3389   - // ----- Extracting the file
3390   - $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
3391   - if ($v_result1 < 1) {
3392   - $this->privCloseFd();
3393   - $this->privSwapBackMagicQuotes();
3394   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
3395   - return $v_result1;
3396   - }
3397   -
3398   - // ----- Get the only interesting attributes
3399   - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3400   - {
3401   - // ----- Close the zip file
3402   - $this->privCloseFd();
3403   - $this->privSwapBackMagicQuotes();
3404   -
3405   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3406   - return $v_result;
3407   - }
3408   -
3409   - // ----- Set the file content
3410   - $p_file_list[$v_nb_extracted]['content'] = $v_string;
3411   -
3412   - // ----- Next extracted file
3413   - $v_nb_extracted++;
3414   -
3415   - // ----- Look for user callback abort
3416   - if ($v_result1 == 2) {
3417   - break;
3418   - }
3419   - }
3420   - // ----- Look for extraction in standard output
3421   - elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3422   - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3423   - // ----- Extracting the file in standard output
3424   - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3425   - if ($v_result1 < 1) {
3426   - $this->privCloseFd();
3427   - $this->privSwapBackMagicQuotes();
3428   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
3429   - return $v_result1;
3430   - }
3431   -
3432   - // ----- Get the only interesting attributes
3433   - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3434   - $this->privCloseFd();
3435   - $this->privSwapBackMagicQuotes();
3436   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3437   - return $v_result;
3438   - }
3439   -
3440   - // ----- Look for user callback abort
3441   - if ($v_result1 == 2) {
3442   - break;
3443   - }
3444   - }
3445   - // ----- Look for normal extraction
3446   - else {
3447   - // ----- Extracting the file
3448   - $v_result1 = $this->privExtractFile($v_header,
3449   - $p_path, $p_remove_path,
3450   - $p_remove_all_path,
3451   - $p_options);
3452   - if ($v_result1 < 1) {
3453   - $this->privCloseFd();
3454   - $this->privSwapBackMagicQuotes();
3455   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
3456   - return $v_result1;
3457   - }
3458   -
3459   - // ----- Get the only interesting attributes
3460   - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3461   - {
3462   - // ----- Close the zip file
3463   - $this->privCloseFd();
3464   - $this->privSwapBackMagicQuotes();
3465   -
3466   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3467   - return $v_result;
3468   - }
3469   -
3470   - // ----- Look for user callback abort
3471   - if ($v_result1 == 2) {
3472   - break;
3473   - }
3474   - }
3475   - }
3476   - }
3477   -
3478   - // ----- Close the zip file
3479   - $this->privCloseFd();
3480   - $this->privSwapBackMagicQuotes();
3481   -
3482   - // ----- Return
3483   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3484   - return $v_result;
3485   - }
3486   - // --------------------------------------------------------------------------------
3487   -
3488   - // --------------------------------------------------------------------------------
3489   - // Function : privExtractFile()
3490   - // Description :
3491   - // Parameters :
3492   - // Return Values :
3493   - //
3494   - // 1 : ... ?
3495   - // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3496   - // --------------------------------------------------------------------------------
3497   - function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3498   - {
3499   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
3500   - $v_result=1;
3501   -
3502   - // ----- Read the file header
3503   - if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3504   - {
3505   - // ----- Return
3506   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3507   - return $v_result;
3508   - }
3509   -
3510   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
3511   -
3512   - // ----- Check that the file header is coherent with $p_entry info
3513   - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3514   - // TBC
3515   - }
3516   -
3517   - // ----- Look for all path to remove
3518   - if ($p_remove_all_path == true) {
3519   - // ----- Look for folder entry that not need to be extracted
3520   - if (($p_entry['external']&0x00000010)==0x00000010) {
3521   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered");
3522   -
3523   - $p_entry['status'] = "filtered";
3524   -
3525   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3526   - return $v_result;
3527   - }
3528   -
3529   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed");
3530   - // ----- Get the basename of the path
3531   - $p_entry['filename'] = basename($p_entry['filename']);
3532   - }
3533   -
3534   - // ----- Look for path to remove
3535   - else if ($p_remove_path != "")
3536   - {
3537   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove");
3538   - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3539   - {
3540   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'");
3541   -
3542   - // ----- Change the file status
3543   - $p_entry['status'] = "filtered";
3544   -
3545   - // ----- Return
3546   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3547   - return $v_result;
3548   - }
3549   -
3550   - $p_remove_path_size = strlen($p_remove_path);
3551   - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3552   - {
3553   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'");
3554   -
3555   - // ----- Remove the path
3556   - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3557   -
3558   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'");
3559   - }
3560   - }
3561   -
3562   - // ----- Add the path
3563   - if ($p_path != '') {
3564   - $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3565   - }
3566   -
3567   - // ----- Check a base_dir_restriction
3568   - if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
3569   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Check the extract directory restriction");
3570   - $v_inclusion
3571   - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
3572   - $p_entry['filename']);
3573   - if ($v_inclusion == 0) {
3574   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_EXTRACT_DIR_RESTRICTION is selected, file is outside restriction");
3575   -
3576   - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
3577   - "Filename '".$p_entry['filename']."' is "
3578   - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
3579   -
3580   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3581   - return PclZip::errorCode();
3582   - }
3583   - }
3584   -
3585   - // ----- Look for pre-extract callback
3586   - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3587   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
3588   -
3589   - // ----- Generate a local information
3590   - $v_local_header = array();
3591   - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3592   -
3593   - // ----- Call the callback
3594   - // Here I do not use call_user_func() because I need to send a reference to the
3595   - // header.
3596   - eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3597   - if ($v_result == 0) {
3598   - // ----- Change the file status
3599   - $p_entry['status'] = "skipped";
3600   - $v_result = 1;
3601   - }
3602   -
3603   - // ----- Look for abort result
3604   - if ($v_result == 2) {
3605   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3606   - // ----- This status is internal and will be changed in 'skipped'
3607   - $p_entry['status'] = "aborted";
3608   - $v_result = PCLZIP_ERR_USER_ABORTED;
3609   - }
3610   -
3611   - // ----- Update the informations
3612   - // Only some fields can be modified
3613   - $p_entry['filename'] = $v_local_header['filename'];
3614   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
3615   - }
3616   -
3617   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
3618   -
3619   - // ----- Look if extraction should be done
3620   - if ($p_entry['status'] == 'ok') {
3621   -
3622   - // ----- Look for specific actions while the file exist
3623   - if (file_exists($p_entry['filename']))
3624   - {
3625   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists");
3626   -
3627   - // ----- Look if file is a directory
3628   - if (is_dir($p_entry['filename']))
3629   - {
3630   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory");
3631   -
3632   - // ----- Change the file status
3633   - $p_entry['status'] = "already_a_directory";
3634   -
3635   - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3636   - // For historical reason first PclZip implementation does not stop
3637   - // when this kind of error occurs.
3638   - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3639   - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3640   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3641   -
3642   - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3643   - "Filename '".$p_entry['filename']."' is "
3644   - ."already used by an existing directory");
3645   -
3646   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3647   - return PclZip::errorCode();
3648   - }
3649   - }
3650   - // ----- Look if file is write protected
3651   - else if (!is_writeable($p_entry['filename']))
3652   - {
3653   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected");
3654   -
3655   - // ----- Change the file status
3656   - $p_entry['status'] = "write_protected";
3657   -
3658   - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3659   - // For historical reason first PclZip implementation does not stop
3660   - // when this kind of error occurs.
3661   - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3662   - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3663   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3664   -
3665   - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3666   - "Filename '".$p_entry['filename']."' exists "
3667   - ."and is write protected");
3668   -
3669   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3670   - return PclZip::errorCode();
3671   - }
3672   - }
3673   -
3674   - // ----- Look if the extracted file is older
3675   - else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3676   - {
3677   - //--(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']).")");
3678   - // ----- Change the file status
3679   - if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3680   - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3681   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced");
3682   - }
3683   - else {
3684   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced");
3685   - $p_entry['status'] = "newer_exist";
3686   -
3687   - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3688   - // For historical reason first PclZip implementation does not stop
3689   - // when this kind of error occurs.
3690   - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3691   - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3692   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3693   -
3694   - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3695   - "Newer version of '".$p_entry['filename']."' exists "
3696   - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3697   -
3698   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3699   - return PclZip::errorCode();
3700   - }
3701   - }
3702   - }
3703   - else {
3704   - //--(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']).")");
3705   - }
3706   - }
3707   -
3708   - // ----- Check the directory availability and create it if necessary
3709   - else {
3710   - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3711   - $v_dir_to_check = $p_entry['filename'];
3712   - else if (!strstr($p_entry['filename'], "/"))
3713   - $v_dir_to_check = "";
3714   - else
3715   - $v_dir_to_check = dirname($p_entry['filename']);
3716   -
3717   - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3718   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
3719   -
3720   - // ----- Change the file status
3721   - $p_entry['status'] = "path_creation_fail";
3722   -
3723   - // ----- Return
3724   - ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3725   - //return $v_result;
3726   - $v_result = 1;
3727   - }
3728   - }
3729   - }
3730   -
3731   - // ----- Look if extraction should be done
3732   - if ($p_entry['status'] == 'ok') {
3733   -
3734   - // ----- Do the extraction (if not a folder)
3735   - if (!(($p_entry['external']&0x00000010)==0x00000010))
3736   - {
3737   - // ----- Look for not compressed file
3738   - if ($p_entry['compression'] == 0) {
3739   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
3740   -
3741   - // ----- Opening destination file
3742   - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3743   - {
3744   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
3745   -
3746   - // ----- Change the file status
3747   - $p_entry['status'] = "write_error";
3748   -
3749   - // ----- Return
3750   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3751   - return $v_result;
3752   - }
3753   -
3754   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes");
3755   -
3756   - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3757   - $v_size = $p_entry['compressed_size'];
3758   - while ($v_size != 0)
3759   - {
3760   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3761   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes");
3762   - $v_buffer = @fread($this->zip_fd, $v_read_size);
3763   - /* Try to speed up the code
3764   - $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3765   - @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3766   - */
3767   - @fwrite($v_dest_file, $v_buffer, $v_read_size);
3768   - $v_size -= $v_read_size;
3769   - }
3770   -
3771   - // ----- Closing the destination file
3772   - fclose($v_dest_file);
3773   -
3774   - // ----- Change the file mtime
3775   - touch($p_entry['filename'], $p_entry['mtime']);
3776   -
3777   -
3778   - }
3779   - else {
3780   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")");
3781   - // ----- TBC
3782   - // Need to be finished
3783   - if (($p_entry['flag'] & 1) == 1) {
3784   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted");
3785   - /*
3786   - // ----- Read the encryption header
3787   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes");
3788   - $v_encryption_header = @fread($this->zip_fd, 12);
3789   -
3790   - // ----- Read the encrypted & compressed file in a buffer
3791   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes");
3792   - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12);
3793   -
3794   - // ----- Decrypt the buffer
3795   - $this->privDecrypt($v_encryption_header, $v_buffer,
3796   - $p_entry['compressed_size']-12, $p_entry['crc']);
3797   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'");
3798   - */
3799   - }
3800   - else {
3801   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes");
3802   - // ----- Read the compressed file in a buffer (one shot)
3803   - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3804   - }
3805   -
3806   - // ----- Decompress the file
3807   - $v_file_content = @gzinflate($v_buffer);
3808   - unset($v_buffer);
3809   - if ($v_file_content === FALSE) {
3810   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file");
3811   -
3812   - // ----- Change the file status
3813   - // TBC
3814   - $p_entry['status'] = "error";
3815   -
3816   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3817   - return $v_result;
3818   - }
3819   -
3820   - // ----- Opening destination file
3821   - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3822   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
3823   -
3824   - // ----- Change the file status
3825   - $p_entry['status'] = "write_error";
3826   -
3827   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3828   - return $v_result;
3829   - }
3830   -
3831   - // ----- Write the uncompressed data
3832   - @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3833   - unset($v_file_content);
3834   -
3835   - // ----- Closing the destination file
3836   - @fclose($v_dest_file);
3837   -
3838   - // ----- Change the file mtime
3839   - @touch($p_entry['filename'], $p_entry['mtime']);
3840   - }
3841   -
3842   - // ----- Look for chmod option
3843   - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3844   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'");
3845   -
3846   - // ----- Change the mode of the file
3847   - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3848   - }
3849   -
3850   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
3851   - }
3852   - }
3853   -
3854   - // ----- Change abort status
3855   - if ($p_entry['status'] == "aborted") {
3856   - $p_entry['status'] = "skipped";
3857   - }
3858   -
3859   - // ----- Look for post-extract callback
3860   - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3861   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
3862   -
3863   - // ----- Generate a local information
3864   - $v_local_header = array();
3865   - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3866   -
3867   - // ----- Call the callback
3868   - // Here I do not use call_user_func() because I need to send a reference to the
3869   - // header.
3870   - eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3871   -
3872   - // ----- Look for abort result
3873   - if ($v_result == 2) {
3874   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3875   - $v_result = PCLZIP_ERR_USER_ABORTED;
3876   - }
3877   - }
3878   -
3879   - // ----- Return
3880   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3881   - return $v_result;
3882   - }
3883   - // --------------------------------------------------------------------------------
3884   -
3885   - // --------------------------------------------------------------------------------
3886   - // Function : privExtractFileInOutput()
3887   - // Description :
3888   - // Parameters :
3889   - // Return Values :
3890   - // --------------------------------------------------------------------------------
3891   - function privExtractFileInOutput(&$p_entry, &$p_options)
3892   - {
3893   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', "");
3894   - $v_result=1;
3895   -
3896   - // ----- Read the file header
3897   - if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
3898   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3899   - return $v_result;
3900   - }
3901   -
3902   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
3903   -
3904   - // ----- Check that the file header is coherent with $p_entry info
3905   - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3906   - // TBC
3907   - }
3908   -
3909   - // ----- Look for pre-extract callback
3910   - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3911   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
3912   -
3913   - // ----- Generate a local information
3914   - $v_local_header = array();
3915   - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3916   -
3917   - // ----- Call the callback
3918   - // Here I do not use call_user_func() because I need to send a reference to the
3919   - // header.
3920   - eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3921   - if ($v_result == 0) {
3922   - // ----- Change the file status
3923   - $p_entry['status'] = "skipped";
3924   - $v_result = 1;
3925   - }
3926   -
3927   - // ----- Look for abort result
3928   - if ($v_result == 2) {
3929   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3930   - // ----- This status is internal and will be changed in 'skipped'
3931   - $p_entry['status'] = "aborted";
3932   - $v_result = PCLZIP_ERR_USER_ABORTED;
3933   - }
3934   -
3935   - // ----- Update the informations
3936   - // Only some fields can be modified
3937   - $p_entry['filename'] = $v_local_header['filename'];
3938   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
3939   - }
3940   -
3941   - // ----- Trace
3942   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
3943   -
3944   - // ----- Look if extraction should be done
3945   - if ($p_entry['status'] == 'ok') {
3946   -
3947   - // ----- Do the extraction (if not a folder)
3948   - if (!(($p_entry['external']&0x00000010)==0x00000010)) {
3949   - // ----- Look for not compressed file
3950   - if ($p_entry['compressed_size'] == $p_entry['size']) {
3951   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
3952   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
3953   -
3954   - // ----- Read the file in a buffer (one shot)
3955   - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3956   -
3957   - // ----- Send the file to the output
3958   - echo $v_buffer;
3959   - unset($v_buffer);
3960   - }
3961   - else {
3962   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
3963   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes");
3964   -
3965   - // ----- Read the compressed file in a buffer (one shot)
3966   - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3967   -
3968   - // ----- Decompress the file
3969   - $v_file_content = gzinflate($v_buffer);
3970   - unset($v_buffer);
3971   -
3972   - // ----- Send the file to the output
3973   - echo $v_file_content;
3974   - unset($v_file_content);
3975   - }
3976   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
3977   - }
3978   - }
3979   -
3980   - // ----- Change abort status
3981   - if ($p_entry['status'] == "aborted") {
3982   - $p_entry['status'] = "skipped";
3983   - }
3984   -
3985   - // ----- Look for post-extract callback
3986   - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3987   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
3988   -
3989   - // ----- Generate a local information
3990   - $v_local_header = array();
3991   - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3992   -
3993   - // ----- Call the callback
3994   - // Here I do not use call_user_func() because I need to send a reference to the
3995   - // header.
3996   - eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3997   -
3998   - // ----- Look for abort result
3999   - if ($v_result == 2) {
4000   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
4001   - $v_result = PCLZIP_ERR_USER_ABORTED;
4002   - }
4003   - }
4004   -
4005   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4006   - return $v_result;
4007   - }
4008   - // --------------------------------------------------------------------------------
4009   -
4010   - // --------------------------------------------------------------------------------
4011   - // Function : privExtractFileAsString()
4012   - // Description :
4013   - // Parameters :
4014   - // Return Values :
4015   - // --------------------------------------------------------------------------------
4016   - function privExtractFileAsString(&$p_entry, &$p_string)
4017   - {
4018   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'");
4019   - $v_result=1;
4020   -
4021   - // ----- Read the file header
4022   - $v_header = array();
4023   - if (($v_result = $this->privReadFileHeader($v_header)) != 1)
4024   - {
4025   - // ----- Return
4026   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4027   - return $v_result;
4028   - }
4029   -
4030   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
4031   -
4032   - // ----- Check that the file header is coherent with $p_entry info
4033   - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
4034   - // TBC
4035   - }
4036   -
4037   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
4038   -
4039   - // ----- Do the extraction (if not a folder)
4040   - if (!(($p_entry['external']&0x00000010)==0x00000010))
4041   - {
4042   - // ----- Look for not compressed file
4043   -// if ($p_entry['compressed_size'] == $p_entry['size'])
4044   - if ($p_entry['compression'] == 0) {
4045   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
4046   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
4047   -
4048   - // ----- Reading the file
4049   - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
4050   - }
4051   - else {
4052   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')");
4053   -
4054   - // ----- Reading the file
4055   - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
4056   -
4057   - // ----- Decompress the file
4058   - if (($p_string = @gzinflate($v_data)) === FALSE) {
4059   - // TBC
4060   - }
4061   - }
4062   -
4063   - // ----- Trace
4064   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
4065   - }
4066   - else {
4067   - // TBC : error : can not extract a folder in a string
4068   - }
4069   -
4070   - // ----- Return
4071   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4072   - return $v_result;
4073   - }
4074   - // --------------------------------------------------------------------------------
4075   -
4076   - // --------------------------------------------------------------------------------
4077   - // Function : privReadFileHeader()
4078   - // Description :
4079   - // Parameters :
4080   - // Return Values :
4081   - // --------------------------------------------------------------------------------
4082   - function privReadFileHeader(&$p_header)
4083   - {
4084   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", "");
4085   - $v_result=1;
4086   -
4087   - // ----- Read the 4 bytes signature
4088   - $v_binary_data = @fread($this->zip_fd, 4);
4089   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
4090   - $v_data = unpack('Vid', $v_binary_data);
4091   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
4092   -
4093   - // ----- Check signature
4094   - if ($v_data['id'] != 0x04034b50)
4095   - {
4096   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header");
4097   -
4098   - // ----- Error log
4099   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4100   -
4101   - // ----- Return
4102   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4103   - return PclZip::errorCode();
4104   - }
4105   -
4106   - // ----- Read the first 42 bytes of the header
4107   - $v_binary_data = fread($this->zip_fd, 26);
4108   -
4109   - // ----- Look for invalid block size
4110   - if (strlen($v_binary_data) != 26)
4111   - {
4112   - $p_header['filename'] = "";
4113   - $p_header['status'] = "invalid_header";
4114   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
4115   -
4116   - // ----- Error log
4117   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4118   -
4119   - // ----- Return
4120   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4121   - return PclZip::errorCode();
4122   - }
4123   -
4124   - // ----- Extract the values
4125   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
4126   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
4127   - $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
4128   -
4129   - // ----- Get filename
4130   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']);
4131   - $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
4132   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');
4133   -
4134   - // ----- Get extra_fields
4135   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']);
4136   - if ($v_data['extra_len'] != 0) {
4137   - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
4138   - }
4139   - else {
4140   - $p_header['extra'] = '';
4141   - }
4142   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\'');
4143   -
4144   - // ----- Extract properties
4145   - $p_header['version_extracted'] = $v_data['version'];
4146   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
4147   - $p_header['compression'] = $v_data['compression'];
4148   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.$p_header['compression'].'\'');
4149   - $p_header['size'] = $v_data['size'];
4150   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');
4151   - $p_header['compressed_size'] = $v_data['compressed_size'];
4152   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
4153   - $p_header['crc'] = $v_data['crc'];
4154   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
4155   - $p_header['flag'] = $v_data['flag'];
4156   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');
4157   - $p_header['filename_len'] = $v_data['filename_len'];
4158   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : \''.$p_header['filename_len'].'\'');
4159   -
4160   - // ----- Recuperate date in UNIX format
4161   - $p_header['mdate'] = $v_data['mdate'];
4162   - $p_header['mtime'] = $v_data['mtime'];
4163   - if ($p_header['mdate'] && $p_header['mtime'])
4164   - {
4165   - // ----- Extract time
4166   - $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4167   - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4168   - $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4169   -
4170   - // ----- Extract date
4171   - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4172   - $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4173   - $v_day = $p_header['mdate'] & 0x001F;
4174   -
4175   - // ----- Get UNIX date format
4176   - $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4177   -
4178   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
4179   - }
4180   - else
4181   - {
4182   - $p_header['mtime'] = time();
4183   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
4184   - }
4185   -
4186   - // TBC
4187   - //for(reset($v_data); $key = key($v_data); next($v_data)) {
4188   - // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]);
4189   - //}
4190   -
4191   - // ----- Set the stored filename
4192   - $p_header['stored_filename'] = $p_header['filename'];
4193   -
4194   - // ----- Set the status field
4195   - $p_header['status'] = "ok";
4196   -
4197   - // ----- Return
4198   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4199   - return $v_result;
4200   - }
4201   - // --------------------------------------------------------------------------------
4202   -
4203   - // --------------------------------------------------------------------------------
4204   - // Function : privReadCentralFileHeader()
4205   - // Description :
4206   - // Parameters :
4207   - // Return Values :
4208   - // --------------------------------------------------------------------------------
4209   - function privReadCentralFileHeader(&$p_header)
4210   - {
4211   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", "");
4212   - $v_result=1;
4213   -
4214   - // ----- Read the 4 bytes signature
4215   - $v_binary_data = @fread($this->zip_fd, 4);
4216   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
4217   - $v_data = unpack('Vid', $v_binary_data);
4218   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
4219   -
4220   - // ----- Check signature
4221   - if ($v_data['id'] != 0x02014b50)
4222   - {
4223   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature");
4224   -
4225   - // ----- Error log
4226   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
4227   -
4228   - // ----- Return
4229   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4230   - return PclZip::errorCode();
4231   - }
4232   -
4233   - // ----- Read the first 42 bytes of the header
4234   - $v_binary_data = fread($this->zip_fd, 42);
4235   -
4236   - // ----- Look for invalid block size
4237   - if (strlen($v_binary_data) != 42)
4238   - {
4239   - $p_header['filename'] = "";
4240   - $p_header['status'] = "invalid_header";
4241   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
4242   -
4243   - // ----- Error log
4244   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
4245   -
4246   - // ----- Return
4247   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4248   - return PclZip::errorCode();
4249   - }
4250   -
4251   - // ----- Extract the values
4252   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
4253   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
4254   - $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);
4255   -
4256   - // ----- Get filename
4257   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
4258   - if ($p_header['filename_len'] != 0)
4259   - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
4260   - else
4261   - $p_header['filename'] = '';
4262   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');
4263   -
4264   - // ----- Get extra
4265   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
4266   - if ($p_header['extra_len'] != 0)
4267   - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
4268   - else
4269   - $p_header['extra'] = '';
4270   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');
4271   -
4272   - // ----- Get comment
4273   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
4274   - if ($p_header['comment_len'] != 0)
4275   - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
4276   - else
4277   - $p_header['comment'] = '';
4278   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');
4279   -
4280   - // ----- Extract properties
4281   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');
4282   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
4283   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');
4284   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
4285   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
4286   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');
4287   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');
4288   -
4289   - // ----- Recuperate date in UNIX format
4290   - if ($p_header['mdate'] && $p_header['mtime'])
4291   - {
4292   - // ----- Extract time
4293   - $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4294   - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4295   - $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4296   -
4297   - // ----- Extract date
4298   - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4299   - $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4300   - $v_day = $p_header['mdate'] & 0x001F;
4301   -
4302   - // ----- Get UNIX date format
4303   - $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4304   -
4305   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
4306   - }
4307   - else
4308   - {
4309   - $p_header['mtime'] = time();
4310   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
4311   - }
4312   -
4313   - // ----- Set the stored filename
4314   - $p_header['stored_filename'] = $p_header['filename'];
4315   -
4316   - // ----- Set default status to ok
4317   - $p_header['status'] = 'ok';
4318   -
4319   - // ----- Look if it is a directory
4320   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
4321   - //--(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').')');
4322   - if (substr($p_header['filename'], -1) == '/') {
4323   - //$p_header['external'] = 0x41FF0010;
4324   - $p_header['external'] = 0x00000010;
4325   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.sprintf("Ox%04X", $p_header['external']).'\'');
4326   - }
4327   -
4328   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');
4329   -
4330   - // ----- Return
4331   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4332   - return $v_result;
4333   - }
4334   - // --------------------------------------------------------------------------------
4335   -
4336   - // --------------------------------------------------------------------------------
4337   - // Function : privCheckFileHeaders()
4338   - // Description :
4339   - // Parameters :
4340   - // Return Values :
4341   - // 1 on success,
4342   - // 0 on error;
4343   - // --------------------------------------------------------------------------------
4344   - function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4345   - {
4346   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", "");
4347   - $v_result=1;
4348   -
4349   - // ----- Check the static values
4350   - // TBC
4351   - if ($p_local_header['filename'] != $p_central_header['filename']) {
4352   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed');
4353   - }
4354   - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4355   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed');
4356   - }
4357   - if ($p_local_header['flag'] != $p_central_header['flag']) {
4358   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed');
4359   - }
4360   - if ($p_local_header['compression'] != $p_central_header['compression']) {
4361   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed');
4362   - }
4363   - if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4364   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed');
4365   - }
4366   - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4367   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed');
4368   - }
4369   -
4370   - // ----- Look for flag bit 3
4371   - if (($p_local_header['flag'] & 8) == 8) {
4372   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !');
4373   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header');
4374   - $p_local_header['size'] = $p_central_header['size'];
4375   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_local_header['size'].'\'');
4376   - $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4377   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_local_header['compressed_size'].'\'');
4378   - $p_local_header['crc'] = $p_central_header['crc'];
4379   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_local_header['crc']).'\'');
4380   - }
4381   -
4382   - // ----- Return
4383   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4384   - return $v_result;
4385   - }
4386   - // --------------------------------------------------------------------------------
4387   -
4388   - // --------------------------------------------------------------------------------
4389   - // Function : privReadEndCentralDir()
4390   - // Description :
4391   - // Parameters :
4392   - // Return Values :
4393   - // --------------------------------------------------------------------------------
4394   - function privReadEndCentralDir(&$p_central_dir)
4395   - {
4396   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
4397   - $v_result=1;
4398   -
4399   - // ----- Go to the end of the zip file
4400   - $v_size = filesize($this->zipname);
4401   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
4402   - @fseek($this->zip_fd, $v_size);
4403   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\'');
4404   - if (@ftell($this->zip_fd) != $v_size)
4405   - {
4406   - // ----- Error log
4407   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4408   -
4409   - // ----- Return
4410   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4411   - return PclZip::errorCode();
4412   - }
4413   -
4414   - // ----- First try : look if this is an archive with no commentaries (most of the time)
4415   - // in this case the end of central dir is at 22 bytes of the file end
4416   - $v_found = 0;
4417   - if ($v_size > 26) {
4418   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
4419   - @fseek($this->zip_fd, $v_size-22);
4420   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\'');
4421   - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4422   - {
4423   - // ----- Error log
4424   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4425   -
4426   - // ----- Return
4427   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4428   - return PclZip::errorCode();
4429   - }
4430   -
4431   - // ----- Read for bytes
4432   - $v_binary_data = @fread($this->zip_fd, 4);
4433   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
4434   - $v_data = @unpack('Vid', $v_binary_data);
4435   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
4436   -
4437   - // ----- Check signature
4438   - if ($v_data['id'] == 0x06054b50) {
4439   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
4440   - $v_found = 1;
4441   - }
4442   -
4443   - $v_pos = ftell($this->zip_fd);
4444   - }
4445   -
4446   - // ----- Go back to the maximum possible size of the Central Dir End Record
4447   - if (!$v_found) {
4448   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
4449   - $v_maximum_size = 65557; // 0xFFFF + 22;
4450   - if ($v_maximum_size > $v_size)
4451   - $v_maximum_size = $v_size;
4452   - @fseek($this->zip_fd, $v_size-$v_maximum_size);
4453   - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4454   - {
4455   - // ----- Error log
4456   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4457   -
4458   - // ----- Return
4459   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4460   - return PclZip::errorCode();
4461   - }
4462   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\'');
4463   -
4464   - // ----- Read byte per byte in order to find the signature
4465   - $v_pos = ftell($this->zip_fd);
4466   - $v_bytes = 0x00000000;
4467   - while ($v_pos < $v_size)
4468   - {
4469   - // ----- Read a byte
4470   - $v_byte = @fread($this->zip_fd, 1);
4471   -
4472   - // ----- Add the byte
4473   - $v_bytes = ($v_bytes << 8) | Ord($v_byte);
4474   -
4475   - // ----- Compare the bytes
4476   - if ($v_bytes == 0x504b0506)
4477   - {
4478   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\'');
4479   - $v_pos++;
4480   - break;
4481   - }
4482   -
4483   - $v_pos++;
4484   - }
4485   -
4486   - // ----- Look if not found end of central dir
4487   - if ($v_pos == $v_size)
4488   - {
4489   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
4490   -
4491   - // ----- Error log
4492   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4493   -
4494   - // ----- Return
4495   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4496   - return PclZip::errorCode();
4497   - }
4498   - }
4499   -
4500   - // ----- Read the first 18 bytes of the header
4501   - $v_binary_data = fread($this->zip_fd, 18);
4502   -
4503   - // ----- Look for invalid block size
4504   - if (strlen($v_binary_data) != 18)
4505   - {
4506   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4507   -
4508   - // ----- Error log
4509   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4510   -
4511   - // ----- Return
4512   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4513   - return PclZip::errorCode();
4514   - }
4515   -
4516   - // ----- Extract the values
4517   - ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
4518   - ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
4519   - $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4520   -
4521   - // ----- Check the global size
4522   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
4523   - if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4524   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive.");
4525   -
4526   - // ----- Removed in release 2.2 see readme file
4527   - // The check of the file size is a little too strict.
4528   - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4529   - // While decrypted, zip has training 0 bytes
4530   - if (0) {
4531   - // ----- Error log
4532   - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4533   - 'The central dir is not at the end of the archive.'
4534   - .' Some trailing bytes exists after the archive.');
4535   -
4536   - // ----- Return
4537   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4538   - return PclZip::errorCode();
4539   - }
4540   - }
4541   -
4542   - // ----- Get comment
4543   - if ($v_data['comment_size'] != 0)
4544   - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4545   - else
4546   - $p_central_dir['comment'] = '';
4547   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\'');
4548   -
4549   - $p_central_dir['entries'] = $v_data['entries'];
4550   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\'');
4551   - $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4552   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\'');
4553   - $p_central_dir['offset'] = $v_data['offset'];
4554   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\'');
4555   - $p_central_dir['size'] = $v_data['size'];
4556   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\'');
4557   - $p_central_dir['disk'] = $v_data['disk'];
4558   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\'');
4559   - $p_central_dir['disk_start'] = $v_data['disk_start'];
4560   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\'');
4561   -
4562   - // TBC
4563   - //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4564   - // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
4565   - //}
4566   -
4567   - // ----- Return
4568   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4569   - return $v_result;
4570   - }
4571   - // --------------------------------------------------------------------------------
4572   -
4573   - // --------------------------------------------------------------------------------
4574   - // Function : privDeleteByRule()
4575   - // Description :
4576   - // Parameters :
4577   - // Return Values :
4578   - // --------------------------------------------------------------------------------
4579   - function privDeleteByRule(&$p_result_list, &$p_options)
4580   - {
4581   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
4582   - $v_result=1;
4583   - $v_list_detail = array();
4584   -
4585   - // ----- Open the zip file
4586   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
4587   - if (($v_result=$this->privOpenFd('rb')) != 1)
4588   - {
4589   - // ----- Return
4590   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4591   - return $v_result;
4592   - }
4593   -
4594   - // ----- Read the central directory informations
4595   - $v_central_dir = array();
4596   - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4597   - {
4598   - $this->privCloseFd();
4599   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4600   - return $v_result;
4601   - }
4602   -
4603   - // ----- Go to beginning of File
4604   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
4605   - @rewind($this->zip_fd);
4606   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
4607   -
4608   - // ----- Scan all the files
4609   - // ----- Start at beginning of Central Dir
4610   - $v_pos_entry = $v_central_dir['offset'];
4611   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
4612   - @rewind($this->zip_fd);
4613   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
4614   - if (@fseek($this->zip_fd, $v_pos_entry))
4615   - {
4616   - // ----- Close the zip file
4617   - $this->privCloseFd();
4618   -
4619   - // ----- Error log
4620   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4621   -
4622   - // ----- Return
4623   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4624   - return PclZip::errorCode();
4625   - }
4626   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
4627   -
4628   - // ----- Read each entry
4629   - $v_header_list = array();
4630   - $j_start = 0;
4631   - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4632   - {
4633   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
4634   -
4635   - // ----- Read the file header
4636   - $v_header_list[$v_nb_extracted] = array();
4637   - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4638   - {
4639   - // ----- Close the zip file
4640   - $this->privCloseFd();
4641   -
4642   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4643   - return $v_result;
4644   - }
4645   -
4646   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
4647   -
4648   - // ----- Store the index
4649   - $v_header_list[$v_nb_extracted]['index'] = $i;
4650   -
4651   - // ----- Look for the specific extract rules
4652   - $v_found = false;
4653   -
4654   - // ----- Look for extract by name rule
4655   - if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
4656   - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4657   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
4658   -
4659   - // ----- Look if the filename is in the list
4660   - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4661   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
4662   -
4663   - // ----- Look for a directory
4664   - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4665   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
4666   -
4667   - // ----- Look if the directory is in the filename path
4668   - if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4669   - && (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])) {
4670   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
4671   - $v_found = true;
4672   - }
4673   - elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4674   - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4675   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
4676   - $v_found = true;
4677   - }
4678   - }
4679   - // ----- Look for a filename
4680   - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4681   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
4682   - $v_found = true;
4683   - }
4684   - }
4685   - }
4686   -
4687   - // ----- Look for extract by ereg rule
4688   - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
4689   - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4690   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
4691   -
4692   - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4693   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
4694   - $v_found = true;
4695   - }
4696   - }
4697   -
4698   - // ----- Look for extract by preg rule
4699   - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
4700   - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4701   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
4702   -
4703   - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4704   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
4705   - $v_found = true;
4706   - }
4707   - }
4708   -
4709   - // ----- Look for extract by index rule
4710   - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4711   - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4712   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
4713   -
4714   - // ----- Look if the index is in the list
4715   - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4716   - //--(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']."]");
4717   -
4718   - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4719   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
4720   - $v_found = true;
4721   - }
4722   - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4723   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
4724   - $j_start = $j+1;
4725   - }
4726   -
4727   - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4728   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
4729   - break;
4730   - }
4731   - }
4732   - }
4733   - else {
4734   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file");
4735   - $v_found = true;
4736   - }
4737   -
4738   - // ----- Look for deletion
4739   - if ($v_found)
4740   - {
4741   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
4742   - unset($v_header_list[$v_nb_extracted]);
4743   - }
4744   - else
4745   - {
4746   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
4747   - $v_nb_extracted++;
4748   - }
4749   - }
4750   -
4751   - // ----- Look if something need to be deleted
4752   - if ($v_nb_extracted > 0) {
4753   -
4754   - // ----- Creates a temporay file
4755   - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4756   -
4757   - // ----- Creates a temporary zip archive
4758   - $v_temp_zip = new PclZip($v_zip_temp_name);
4759   -
4760   - // ----- Open the temporary zip file in write mode
4761   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
4762   - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4763   - $this->privCloseFd();
4764   -
4765   - // ----- Return
4766   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4767   - return $v_result;
4768   - }
4769   -
4770   - // ----- Look which file need to be kept
4771   - for ($i=0; $i<sizeof($v_header_list); $i++) {
4772   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
4773   -
4774   - // ----- Calculate the position of the header
4775   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
4776   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
4777   - @rewind($this->zip_fd);
4778   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
4779   - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
4780   - // ----- Close the zip file
4781   - $this->privCloseFd();
4782   - $v_temp_zip->privCloseFd();
4783   - @unlink($v_zip_temp_name);
4784   -
4785   - // ----- Error log
4786   - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4787   -
4788   - // ----- Return
4789   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4790   - return PclZip::errorCode();
4791   - }
4792   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
4793   -
4794   - // ----- Read the file header
4795   - $v_local_header = array();
4796   - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4797   - // ----- Close the zip file
4798   - $this->privCloseFd();
4799   - $v_temp_zip->privCloseFd();
4800   - @unlink($v_zip_temp_name);
4801   -
4802   - // ----- Return
4803   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4804   - return $v_result;
4805   - }
4806   -
4807   - // ----- Check that local file header is same as central file header
4808   - if ($this->privCheckFileHeaders($v_local_header,
4809   - $v_header_list[$i]) != 1) {
4810   - // TBC
4811   - }
4812   - unset($v_local_header);
4813   -
4814   - // ----- Write the file header
4815   - if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4816   - // ----- Close the zip file
4817   - $this->privCloseFd();
4818   - $v_temp_zip->privCloseFd();
4819   - @unlink($v_zip_temp_name);
4820   -
4821   - // ----- Return
4822   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4823   - return $v_result;
4824   - }
4825   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
4826   -
4827   - // ----- Read/write the data block
4828   - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4829   - // ----- Close the zip file
4830   - $this->privCloseFd();
4831   - $v_temp_zip->privCloseFd();
4832   - @unlink($v_zip_temp_name);
4833   -
4834   - // ----- Return
4835   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4836   - return $v_result;
4837   - }
4838   - }
4839   -
4840   - // ----- Store the offset of the central dir
4841   - $v_offset = @ftell($v_temp_zip->zip_fd);
4842   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
4843   -
4844   - // ----- Re-Create the Central Dir files header
4845   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
4846   - for ($i=0; $i<sizeof($v_header_list); $i++) {
4847   - // ----- Create the file header
4848   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
4849   - if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4850   - $v_temp_zip->privCloseFd();
4851   - $this->privCloseFd();
4852   - @unlink($v_zip_temp_name);
4853   -
4854   - // ----- Return
4855   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4856   - return $v_result;
4857   - }
4858   -
4859   - // ----- Transform the header to a 'usable' info
4860   - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4861   - }
4862   -
4863   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
4864   -
4865   - // ----- Zip file comment
4866   - $v_comment = '';
4867   - if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4868   - $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4869   - }
4870   -
4871   - // ----- Calculate the size of the central header
4872   - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4873   -
4874   - // ----- Create the central dir footer
4875   - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4876   - // ----- Reset the file list
4877   - unset($v_header_list);
4878   - $v_temp_zip->privCloseFd();
4879   - $this->privCloseFd();
4880   - @unlink($v_zip_temp_name);
4881   -
4882   - // ----- Return
4883   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4884   - return $v_result;
4885   - }
4886   -
4887   - // ----- Close
4888   - $v_temp_zip->privCloseFd();
4889   - $this->privCloseFd();
4890   -
4891   - // ----- Delete the zip file
4892   - // TBC : I should test the result ...
4893   - @unlink($this->zipname);
4894   -
4895   - // ----- Rename the temporary file
4896   - // TBC : I should test the result ...
4897   - //@rename($v_zip_temp_name, $this->zipname);
4898   - PclZipUtilRename($v_zip_temp_name, $this->zipname);
4899   -
4900   - // ----- Destroy the temporary archive
4901   - unset($v_temp_zip);
4902   - }
4903   -
4904   - // ----- Remove every files : reset the file
4905   - else if ($v_central_dir['entries'] != 0) {
4906   - $this->privCloseFd();
4907   -
4908   - if (($v_result = $this->privOpenFd('wb')) != 1) {
4909   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4910   - return $v_result;
4911   - }
4912   -
4913   - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4914   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4915   - return $v_result;
4916   - }
4917   -
4918   - $this->privCloseFd();
4919   - }
4920   -
4921   - // ----- Return
4922   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4923   - return $v_result;
4924   - }
4925   - // --------------------------------------------------------------------------------
4926   -
4927   - // --------------------------------------------------------------------------------
4928   - // Function : privDirCheck()
4929   - // Description :
4930   - // Check if a directory exists, if not it creates it and all the parents directory
4931   - // which may be useful.
4932   - // Parameters :
4933   - // $p_dir : Directory path to check.
4934   - // Return Values :
4935   - // 1 : OK
4936   - // -1 : Unable to create directory
4937   - // --------------------------------------------------------------------------------
4938   - function privDirCheck($p_dir, $p_is_dir=false)
4939   - {
4940   - $v_result = 1;
4941   -
4942   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'");
4943   -
4944   - // ----- Remove the final '/'
4945   - if (($p_is_dir) && (substr($p_dir, -1)=='/'))
4946   - {
4947   - $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
4948   - }
4949   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'");
4950   -
4951   - // ----- Check the directory availability
4952   - if ((is_dir($p_dir)) || ($p_dir == ""))
4953   - {
4954   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
4955   - return 1;
4956   - }
4957   -
4958   - // ----- Extract parent directory
4959   - $p_parent_dir = dirname($p_dir);
4960   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
4961   -
4962   - // ----- Just a check
4963   - if ($p_parent_dir != $p_dir)
4964   - {
4965   - // ----- Look for parent directory
4966   - if ($p_parent_dir != "")
4967   - {
4968   - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
4969   - {
4970   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4971   - return $v_result;
4972   - }
4973   - }
4974   - }
4975   -
4976   - // ----- Create the directory
4977   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
4978   - if (!@mkdir($p_dir, 0777))
4979   - {
4980   - // ----- Error log
4981   - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
4982   -
4983   - // ----- Return
4984   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4985   - return PclZip::errorCode();
4986   - }
4987   -
4988   - // ----- Return
4989   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
4990   - return $v_result;
4991   - }
4992   - // --------------------------------------------------------------------------------
4993   -
4994   - // --------------------------------------------------------------------------------
4995   - // Function : privMerge()
4996   - // Description :
4997   - // If $p_archive_to_add does not exist, the function exit with a success result.
4998   - // Parameters :
4999   - // Return Values :
5000   - // --------------------------------------------------------------------------------
5001   - function privMerge(&$p_archive_to_add)
5002   - {
5003   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
5004   - $v_result=1;
5005   -
5006   - // ----- Look if the archive_to_add exists
5007   - if (!is_file($p_archive_to_add->zipname))
5008   - {
5009   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");
5010   -
5011   - // ----- Nothing to merge, so merge is a success
5012   - $v_result = 1;
5013   -
5014   - // ----- Return
5015   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5016   - return $v_result;
5017   - }
5018   -
5019   - // ----- Look if the archive exists
5020   - if (!is_file($this->zipname))
5021   - {
5022   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");
5023   -
5024   - // ----- Do a duplicate
5025   - $v_result = $this->privDuplicate($p_archive_to_add->zipname);
5026   -
5027   - // ----- Return
5028   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5029   - return $v_result;
5030   - }
5031   -
5032   - // ----- Open the zip file
5033   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
5034   - if (($v_result=$this->privOpenFd('rb')) != 1)
5035   - {
5036   - // ----- Return
5037   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5038   - return $v_result;
5039   - }
5040   -
5041   - // ----- Read the central directory informations
5042   - $v_central_dir = array();
5043   - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
5044   - {
5045   - $this->privCloseFd();
5046   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5047   - return $v_result;
5048   - }
5049   -
5050   - // ----- Go to beginning of File
5051   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
5052   - @rewind($this->zip_fd);
5053   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
5054   -
5055   - // ----- Open the archive_to_add file
5056   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
5057   - if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
5058   - {
5059   - $this->privCloseFd();
5060   -
5061   - // ----- Return
5062   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5063   - return $v_result;
5064   - }
5065   -
5066   - // ----- Read the central directory informations
5067   - $v_central_dir_to_add = array();
5068   - if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5069   - {
5070   - $this->privCloseFd();
5071   - $p_archive_to_add->privCloseFd();
5072   -
5073   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5074   - return $v_result;
5075   - }
5076   -
5077   - // ----- Go to beginning of File
5078   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
5079   - @rewind($p_archive_to_add->zip_fd);
5080   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
5081   -
5082   - // ----- Creates a temporay file
5083   - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
5084   -
5085   - // ----- Open the temporary file in write mode
5086   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
5087   - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
5088   - {
5089   - $this->privCloseFd();
5090   - $p_archive_to_add->privCloseFd();
5091   -
5092   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
5093   -
5094   - // ----- Return
5095   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
5096   - return PclZip::errorCode();
5097   - }
5098   -
5099   - // ----- Copy the files from the archive to the temporary file
5100   - // TBC : Here I should better append the file and go back to erase the central dir
5101   - $v_size = $v_central_dir['offset'];
5102   - while ($v_size != 0)
5103   - {
5104   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5105   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5106   - $v_buffer = fread($this->zip_fd, $v_read_size);
5107   - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5108   - $v_size -= $v_read_size;
5109   - }
5110   -
5111   - // ----- Copy the files from the archive_to_add into the temporary file
5112   - $v_size = $v_central_dir_to_add['offset'];
5113   - while ($v_size != 0)
5114   - {
5115   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5116   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5117   - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
5118   - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5119   - $v_size -= $v_read_size;
5120   - }
5121   -
5122   - // ----- Store the offset of the central dir
5123   - $v_offset = @ftell($v_zip_temp_fd);
5124   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
5125   -
5126   - // ----- Copy the block of file headers from the old archive
5127   - $v_size = $v_central_dir['size'];
5128   - while ($v_size != 0)
5129   - {
5130   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5131   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5132   - $v_buffer = @fread($this->zip_fd, $v_read_size);
5133   - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5134   - $v_size -= $v_read_size;
5135   - }
5136   -
5137   - // ----- Copy the block of file headers from the archive_to_add
5138   - $v_size = $v_central_dir_to_add['size'];
5139   - while ($v_size != 0)
5140   - {
5141   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5142   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5143   - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
5144   - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
5145   - $v_size -= $v_read_size;
5146   - }
5147   -
5148   - // ----- Merge the file comments
5149   - $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
5150   -
5151   - // ----- Calculate the size of the (new) central header
5152   - $v_size = @ftell($v_zip_temp_fd)-$v_offset;
5153   -
5154   - // ----- Swap the file descriptor
5155   - // Here is a trick : I swap the temporary fd with the zip fd, in order to use
5156   - // the following methods on the temporary fil and not the real archive fd
5157   - $v_swap = $this->zip_fd;
5158   - $this->zip_fd = $v_zip_temp_fd;
5159   - $v_zip_temp_fd = $v_swap;
5160   -
5161   - // ----- Create the central dir footer
5162   - if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
5163   - {
5164   - $this->privCloseFd();
5165   - $p_archive_to_add->privCloseFd();
5166   - @fclose($v_zip_temp_fd);
5167   - $this->zip_fd = null;
5168   -
5169   - // ----- Reset the file list
5170   - unset($v_header_list);
5171   -
5172   - // ----- Return
5173   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5174   - return $v_result;
5175   - }
5176   -
5177   - // ----- Swap back the file descriptor
5178   - $v_swap = $this->zip_fd;
5179   - $this->zip_fd = $v_zip_temp_fd;
5180   - $v_zip_temp_fd = $v_swap;
5181   -
5182   - // ----- Close
5183   - $this->privCloseFd();
5184   - $p_archive_to_add->privCloseFd();
5185   -
5186   - // ----- Close the temporary file
5187   - @fclose($v_zip_temp_fd);
5188   -
5189   - // ----- Delete the zip file
5190   - // TBC : I should test the result ...
5191   - @unlink($this->zipname);
5192   -
5193   - // ----- Rename the temporary file
5194   - // TBC : I should test the result ...
5195   - //@rename($v_zip_temp_name, $this->zipname);
5196   - PclZipUtilRename($v_zip_temp_name, $this->zipname);
5197   -
5198   - // ----- Return
5199   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5200   - return $v_result;
5201   - }
5202   - // --------------------------------------------------------------------------------
5203   -
5204   - // --------------------------------------------------------------------------------
5205   - // Function : privDuplicate()
5206   - // Description :
5207   - // Parameters :
5208   - // Return Values :
5209   - // --------------------------------------------------------------------------------
5210   - function privDuplicate($p_archive_filename)
5211   - {
5212   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'");
5213   - $v_result=1;
5214   -
5215   - // ----- Look if the $p_archive_filename exists
5216   - if (!is_file($p_archive_filename))
5217   - {
5218   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate.");
5219   -
5220   - // ----- Nothing to duplicate, so duplicate is a success.
5221   - $v_result = 1;
5222   -
5223   - // ----- Return
5224   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5225   - return $v_result;
5226   - }
5227   -
5228   - // ----- Open the zip file
5229   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
5230   - if (($v_result=$this->privOpenFd('wb')) != 1)
5231   - {
5232   - // ----- Return
5233   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5234   - return $v_result;
5235   - }
5236   -
5237   - // ----- Open the temporary file in write mode
5238   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
5239   - if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
5240   - {
5241   - $this->privCloseFd();
5242   -
5243   - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
5244   -
5245   - // ----- Return
5246   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
5247   - return PclZip::errorCode();
5248   - }
5249   -
5250   - // ----- Copy the files from the archive to the temporary file
5251   - // TBC : Here I should better append the file and go back to erase the central dir
5252   - $v_size = filesize($p_archive_filename);
5253   - while ($v_size != 0)
5254   - {
5255   - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
5256   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes");
5257   - $v_buffer = fread($v_zip_temp_fd, $v_read_size);
5258   - @fwrite($this->zip_fd, $v_buffer, $v_read_size);
5259   - $v_size -= $v_read_size;
5260   - }
5261   -
5262   - // ----- Close
5263   - $this->privCloseFd();
5264   -
5265   - // ----- Close the temporary file
5266   - @fclose($v_zip_temp_fd);
5267   -
5268   - // ----- Return
5269   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5270   - return $v_result;
5271   - }
5272   - // --------------------------------------------------------------------------------
5273   -
5274   - // --------------------------------------------------------------------------------
5275   - // Function : privErrorLog()
5276   - // Description :
5277   - // Parameters :
5278   - // --------------------------------------------------------------------------------
5279   - function privErrorLog($p_error_code=0, $p_error_string='')
5280   - {
5281   - if (PCLZIP_ERROR_EXTERNAL == 1) {
5282   - PclError($p_error_code, $p_error_string);
5283   - }
5284   - else {
5285   - $this->error_code = $p_error_code;
5286   - $this->error_string = $p_error_string;
5287   - }
5288   - }
5289   - // --------------------------------------------------------------------------------
5290   -
5291   - // --------------------------------------------------------------------------------
5292   - // Function : privErrorReset()
5293   - // Description :
5294   - // Parameters :
5295   - // --------------------------------------------------------------------------------
5296   - function privErrorReset()
5297   - {
5298   - if (PCLZIP_ERROR_EXTERNAL == 1) {
5299   - PclErrorReset();
5300   - }
5301   - else {
5302   - $this->error_code = 0;
5303   - $this->error_string = '';
5304   - }
5305   - }
5306   - // --------------------------------------------------------------------------------
5307   -
5308   - // --------------------------------------------------------------------------------
5309   - // Function : privDecrypt()
5310   - // Description :
5311   - // Parameters :
5312   - // Return Values :
5313   - // --------------------------------------------------------------------------------
5314   - function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc)
5315   - {
5316   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size."");
5317   - $v_result=1;
5318   -
5319   - // ----- To Be Modified ;-)
5320   - $v_pwd = "test";
5321   -
5322   - $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header,
5323   - $p_crc, $v_pwd);
5324   -
5325   - // ----- Return
5326   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5327   - return $v_result;
5328   - }
5329   - // --------------------------------------------------------------------------------
5330   -
5331   - // --------------------------------------------------------------------------------
5332   - // Function : privDisableMagicQuotes()
5333   - // Description :
5334   - // Parameters :
5335   - // Return Values :
5336   - // --------------------------------------------------------------------------------
5337   - function privDisableMagicQuotes()
5338   - {
5339   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', "");
5340   - $v_result=1;
5341   -
5342   - // ----- Look if function exists
5343   - if ( (!function_exists("get_magic_quotes_runtime"))
5344   - || (!function_exists("set_magic_quotes_runtime"))) {
5345   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
5346   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5347   - return $v_result;
5348   - }
5349   -
5350   - // ----- Look if already done
5351   - if ($this->magic_quotes_status != -1) {
5352   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled");
5353   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5354   - return $v_result;
5355   - }
5356   -
5357   - // ----- Get and memorize the magic_quote value
5358   - $this->magic_quotes_status = @get_magic_quotes_runtime();
5359   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'");
5360   -
5361   - // ----- Disable magic_quotes
5362   - if ($this->magic_quotes_status == 1) {
5363   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes");
5364   - @set_magic_quotes_runtime(0);
5365   - }
5366   -
5367   - // ----- Return
5368   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5369   - return $v_result;
5370   - }
5371   - // --------------------------------------------------------------------------------
5372   -
5373   - // --------------------------------------------------------------------------------
5374   - // Function : privSwapBackMagicQuotes()
5375   - // Description :
5376   - // Parameters :
5377   - // Return Values :
5378   - // --------------------------------------------------------------------------------
5379   - function privSwapBackMagicQuotes()
5380   - {
5381   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', "");
5382   - $v_result=1;
5383   -
5384   - // ----- Look if function exists
5385   - if ( (!function_exists("get_magic_quotes_runtime"))
5386   - || (!function_exists("set_magic_quotes_runtime"))) {
5387   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
5388   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5389   - return $v_result;
5390   - }
5391   -
5392   - // ----- Look if something to do
5393   - if ($this->magic_quotes_status != -1) {
5394   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified");
5395   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5396   - return $v_result;
5397   - }
5398   -
5399   - // ----- Swap back magic_quotes
5400   - if ($this->magic_quotes_status == 1) {
5401   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes");
5402   - @set_magic_quotes_runtime($this->magic_quotes_status);
5403   - }
5404   -
5405   - // ----- Return
5406   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5407   - return $v_result;
5408   - }
5409   - // --------------------------------------------------------------------------------
5410   -
5411   - }
5412   - // End of class
5413   - // --------------------------------------------------------------------------------
5414   -
5415   - // --------------------------------------------------------------------------------
5416   - // Function : PclZipUtilPathReduction()
5417   - // Description :
5418   - // Parameters :
5419   - // Return Values :
5420   - // --------------------------------------------------------------------------------
5421   - function PclZipUtilPathReduction($p_dir)
5422   - {
5423   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'");
5424   - $v_result = "";
5425   -
5426   - // ----- Look for not empty path
5427   - if ($p_dir != "") {
5428   - // ----- Explode path by directory names
5429   - $v_list = explode("/", $p_dir);
5430   -
5431   - // ----- Study directories from last to first
5432   - $v_skip = 0;
5433   - for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5434   - // ----- Look for current path
5435   - if ($v_list[$i] == ".") {
5436   - // ----- Ignore this directory
5437   - // Should be the first $i=0, but no check is done
5438   - }
5439   - else if ($v_list[$i] == "..") {
5440   - $v_skip++;
5441   - }
5442   - else if ($v_list[$i] == "") {
5443   - // ----- First '/' i.e. root slash
5444   - if ($i == 0) {
5445   - $v_result = "/".$v_result;
5446   - if ($v_skip > 0) {
5447   - // ----- It is an invalid path, so the path is not modified
5448   - // TBC
5449   - $v_result = $p_dir;
5450   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged");
5451   - $v_skip = 0;
5452   - }
5453   - }
5454   - // ----- Last '/' i.e. indicates a directory
5455   - else if ($i == (sizeof($v_list)-1)) {
5456   - $v_result = $v_list[$i];
5457   - }
5458   - // ----- Double '/' inside the path
5459   - else {
5460   - // ----- Ignore only the double '//' in path,
5461   - // but not the first and last '/'
5462   - }
5463   - }
5464   - else {
5465   - // ----- Look for item to skip
5466   - if ($v_skip > 0) {
5467   - $v_skip--;
5468   - }
5469   - else {
5470   - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5471   - }
5472   - }
5473   - }
5474   -
5475   - // ----- Look for skip
5476   - if ($v_skip > 0) {
5477   - while ($v_skip > 0) {
5478   - $v_result = '../'.$v_result;
5479   - $v_skip--;
5480   - }
5481   - }
5482   - }
5483   -
5484   - // ----- Return
5485   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5486   - return $v_result;
5487   - }
5488   - // --------------------------------------------------------------------------------
5489   -
5490   - // --------------------------------------------------------------------------------
5491   - // Function : PclZipUtilPathInclusion()
5492   - // Description :
5493   - // This function indicates if the path $p_path is under the $p_dir tree. Or,
5494   - // said in an other way, if the file or sub-dir $p_path is inside the dir
5495   - // $p_dir.
5496   - // The function indicates also if the path is exactly the same as the dir.
5497   - // This function supports path with duplicated '/' like '//', but does not
5498   - // support '.' or '..' statements.
5499   - // Parameters :
5500   - // Return Values :
5501   - // 0 if $p_path is not inside directory $p_dir
5502   - // 1 if $p_path is inside directory $p_dir
5503   - // 2 if $p_path is exactly the same as $p_dir
5504   - // --------------------------------------------------------------------------------
5505   - function PclZipUtilPathInclusion($p_dir, $p_path)
5506   - {
5507   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'");
5508   - $v_result = 1;
5509   -
5510   - // ----- Look for path beginning by ./
5511   - if ( ($p_dir == '.')
5512   - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
5513   - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
5514   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_dir '".$p_dir."'");
5515   - }
5516   - if ( ($p_path == '.')
5517   - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
5518   - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
5519   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Replacing ./ by full path in p_path '".$p_path."'");
5520   - }
5521   -
5522   - // ----- Explode dir and path by directory separator
5523   - $v_list_dir = explode("/", $p_dir);
5524   - $v_list_dir_size = sizeof($v_list_dir);
5525   - $v_list_path = explode("/", $p_path);
5526   - $v_list_path_size = sizeof($v_list_path);
5527   -
5528   - // ----- Study directories paths
5529   - $i = 0;
5530   - $j = 0;
5531   - while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5532   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
5533   -
5534   - // ----- Look for empty dir (path reduction)
5535   - if ($v_list_dir[$i] == '') {
5536   - $i++;
5537   - continue;
5538   - }
5539   - if ($v_list_path[$j] == '') {
5540   - $j++;
5541   - continue;
5542   - }
5543   -
5544   - // ----- Compare the items
5545   - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
5546   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different");
5547   - $v_result = 0;
5548   - }
5549   -
5550   - // ----- Next items
5551   - $i++;
5552   - $j++;
5553   - }
5554   -
5555   - // ----- Look if everything seems to be the same
5556   - if ($v_result) {
5557   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
5558   - // ----- Skip all the empty items
5559   - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5560   - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5561   - //--(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]:'')."'");
5562   -
5563   - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5564   - // ----- There are exactly the same
5565   - $v_result = 2;
5566   - }
5567   - else if ($i < $v_list_dir_size) {
5568   - // ----- The path is shorter than the dir
5569   - $v_result = 0;
5570   - }
5571   - }
5572   -
5573   - // ----- Return
5574   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5575   - return $v_result;
5576   - }
5577   - // --------------------------------------------------------------------------------
5578   -
5579   - // --------------------------------------------------------------------------------
5580   - // Function : PclZipUtilCopyBlock()
5581   - // Description :
5582   - // Parameters :
5583   - // $p_mode : read/write compression mode
5584   - // 0 : src & dest normal
5585   - // 1 : src gzip, dest normal
5586   - // 2 : src normal, dest gzip
5587   - // 3 : src & dest gzip
5588   - // Return Values :
5589   - // --------------------------------------------------------------------------------
5590   - function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5591   - {
5592   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode");
5593   - $v_result = 1;
5594   -
5595   - if ($p_mode==0)
5596   - {
5597   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src)));
5598   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest)));
5599   - while ($p_size != 0)
5600   - {
5601   - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5602   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5603   - $v_buffer = @fread($p_src, $v_read_size);
5604   - @fwrite($p_dest, $v_buffer, $v_read_size);
5605   - $p_size -= $v_read_size;
5606   - }
5607   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src)));
5608   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest)));
5609   - }
5610   - else if ($p_mode==1)
5611   - {
5612   - while ($p_size != 0)
5613   - {
5614   - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5615   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5616   - $v_buffer = @gzread($p_src, $v_read_size);
5617   - @fwrite($p_dest, $v_buffer, $v_read_size);
5618   - $p_size -= $v_read_size;
5619   - }
5620   - }
5621   - else if ($p_mode==2)
5622   - {
5623   - while ($p_size != 0)
5624   - {
5625   - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5626   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5627   - $v_buffer = @fread($p_src, $v_read_size);
5628   - @gzwrite($p_dest, $v_buffer, $v_read_size);
5629   - $p_size -= $v_read_size;
5630   - }
5631   - }
5632   - else if ($p_mode==3)
5633   - {
5634   - while ($p_size != 0)
5635   - {
5636   - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5637   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5638   - $v_buffer = @gzread($p_src, $v_read_size);
5639   - @gzwrite($p_dest, $v_buffer, $v_read_size);
5640   - $p_size -= $v_read_size;
5641   - }
5642   - }
5643   -
5644   - // ----- Return
5645   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5646   - return $v_result;
5647   - }
5648   - // --------------------------------------------------------------------------------
5649   -
5650   - // --------------------------------------------------------------------------------
5651   - // Function : PclZipUtilRename()
5652   - // Description :
5653   - // This function tries to do a simple rename() function. If it fails, it
5654   - // tries to copy the $p_src file in a new $p_dest file and then unlink the
5655   - // first one.
5656   - // Parameters :
5657   - // $p_src : Old filename
5658   - // $p_dest : New filename
5659   - // Return Values :
5660   - // 1 on success, 0 on failure.
5661   - // --------------------------------------------------------------------------------
5662   - function PclZipUtilRename($p_src, $p_dest)
5663   - {
5664   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest");
5665   - $v_result = 1;
5666   -
5667   - // ----- Try to rename the files
5668   - if (!@rename($p_src, $p_dest)) {
5669   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink");
5670   -
5671   - // ----- Try to copy & unlink the src
5672   - if (!@copy($p_src, $p_dest)) {
5673   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file");
5674   - $v_result = 0;
5675   - }
5676   - else if (!@unlink($p_src)) {
5677   - //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename");
5678   - $v_result = 0;
5679   - }
5680   - }
5681   -
5682   - // ----- Return
5683   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5684   - return $v_result;
5685   - }
5686   - // --------------------------------------------------------------------------------
5687   -
5688   - // --------------------------------------------------------------------------------
5689   - // Function : PclZipUtilOptionText()
5690   - // Description :
5691   - // Translate option value in text. Mainly for debug purpose.
5692   - // Parameters :
5693   - // $p_option : the option value.
5694   - // Return Values :
5695   - // The option text value.
5696   - // --------------------------------------------------------------------------------
5697   - function PclZipUtilOptionText($p_option)
5698   - {
5699   - //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'");
5700   -
5701   - $v_list = get_defined_constants();
5702   - for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5703   - $v_prefix = substr($v_key, 0, 10);
5704   - if (( ($v_prefix == 'PCLZIP_OPT')
5705   - || ($v_prefix == 'PCLZIP_CB_')
5706   - || ($v_prefix == 'PCLZIP_ATT'))
5707   - && ($v_list[$v_key] == $p_option)) {
5708   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key);
5709   - return $v_key;
5710   - }
5711   - }
5712   -
5713   - $v_result = 'Unknown';
5714   -
5715   - //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5716   - return $v_result;
5717   - }
5718   - // --------------------------------------------------------------------------------
5719   -
5720   - // --------------------------------------------------------------------------------
5721   - // Function : PclZipUtilTranslateWinPath()
5722   - // Description :
5723   - // Translate windows path by replacing '\' by '/' and optionally removing
5724   - // drive letter.
5725   - // Parameters :
5726   - // $p_path : path to translate.
5727   - // $p_remove_disk_letter : true | false
5728   - // Return Values :
5729   - // The path translated.
5730   - // --------------------------------------------------------------------------------
5731   - function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5732   - {
5733   - if (stristr(php_uname(), 'windows')) {
5734   - // ----- Look for potential disk letter
5735   - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
5736   - $p_path = substr($p_path, $v_position+1);
5737   - }
5738   - // ----- Change potential windows directory separator
5739   - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5740   - $p_path = strtr($p_path, '\\', '/');
5741   - }
5742   - }
5743   - return $p_path;
5744   - }
5745   - // --------------------------------------------------------------------------------
5746   -
5747   -
5748   -?>
  1 +<?php
  2 +// --------------------------------------------------------------------------------
  3 +// PhpConcept Library - Zip Module 2.8.2
  4 +// --------------------------------------------------------------------------------
  5 +// License GNU/LGPL - Vincent Blavet - August 2009
  6 +// http://www.phpconcept.net
  7 +// --------------------------------------------------------------------------------
  8 +//
  9 +// Presentation :
  10 +// PclZip is a PHP library that manage ZIP archives.
  11 +// So far tests show that archives generated by PclZip are readable by
  12 +// WinZip application and other tools.
  13 +//
  14 +// Description :
  15 +// See readme.txt and http://www.phpconcept.net
  16 +//
  17 +// Warning :
  18 +// This library and the associated files are non commercial, non professional
  19 +// work.
  20 +// It should not have unexpected results. However if any damage is caused by
  21 +// this software the author can not be responsible.
  22 +// The use of this software is at the risk of the user.
  23 +//
  24 +// --------------------------------------------------------------------------------
  25 +// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
  26 +// --------------------------------------------------------------------------------
  27 +
  28 + // ----- Constants
  29 + if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
  30 + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
  31 + }
  32 +
  33 + // ----- File list separator
  34 + // In version 1.x of PclZip, the separator for file list is a space
  35 + // (which is not a very smart choice, specifically for windows paths !).
  36 + // A better separator should be a comma (,). This constant gives you the
  37 + // abilty to change that.
  38 + // However notice that changing this value, may have impact on existing
  39 + // scripts, using space separated filenames.
  40 + // Recommanded values for compatibility with older versions :
  41 + //define( 'PCLZIP_SEPARATOR', ' ' );
  42 + // Recommanded values for smart separation of filenames.
  43 + if (!defined('PCLZIP_SEPARATOR')) {
  44 + define( 'PCLZIP_SEPARATOR', ',' );
  45 + }
  46 +
  47 + // ----- Error configuration
  48 + // 0 : PclZip Class integrated error handling
  49 + // 1 : PclError external library error handling. By enabling this
  50 + // you must ensure that you have included PclError library.
  51 + // [2,...] : reserved for futur use
  52 + if (!defined('PCLZIP_ERROR_EXTERNAL')) {
  53 + define( 'PCLZIP_ERROR_EXTERNAL', 0 );
  54 + }
  55 +
  56 + // ----- Optional static temporary directory
  57 + // By default temporary files are generated in the script current
  58 + // path.
  59 + // If defined :
  60 + // - MUST BE terminated by a '/'.
  61 + // - MUST be a valid, already created directory
  62 + // Samples :
  63 + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
  64 + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
  65 + if (!defined('PCLZIP_TEMPORARY_DIR')) {
  66 + define( 'PCLZIP_TEMPORARY_DIR', '' );
  67 + }
  68 +
  69 + // ----- Optional threshold ratio for use of temporary files
  70 + // Pclzip sense the size of the file to add/extract and decide to
  71 + // use or not temporary file. The algorythm is looking for
  72 + // memory_limit of PHP and apply a ratio.
  73 + // threshold = memory_limit * ratio.
  74 + // Recommended values are under 0.5. Default 0.47.
  75 + // Samples :
  76 + // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
  77 + if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
  78 + define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
  79 + }
  80 +
  81 +// --------------------------------------------------------------------------------
  82 +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
  83 +// --------------------------------------------------------------------------------
  84 +
  85 + // ----- Global variables
  86 + $g_pclzip_version = "2.8.2";
  87 +
  88 + // ----- Error codes
  89 + // -1 : Unable to open file in binary write mode
  90 + // -2 : Unable to open file in binary read mode
  91 + // -3 : Invalid parameters
  92 + // -4 : File does not exist
  93 + // -5 : Filename is too long (max. 255)
  94 + // -6 : Not a valid zip file
  95 + // -7 : Invalid extracted file size
  96 + // -8 : Unable to create directory
  97 + // -9 : Invalid archive extension
  98 + // -10 : Invalid archive format
  99 + // -11 : Unable to delete file (unlink)
  100 + // -12 : Unable to rename file (rename)
  101 + // -13 : Invalid header checksum
  102 + // -14 : Invalid archive size
  103 + define( 'PCLZIP_ERR_USER_ABORTED', 2 );
  104 + define( 'PCLZIP_ERR_NO_ERROR', 0 );
  105 + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
  106 + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
  107 + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
  108 + define( 'PCLZIP_ERR_MISSING_FILE', -4 );
  109 + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
  110 + define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
  111 + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
  112 + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
  113 + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
  114 + define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
  115 + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
  116 + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
  117 + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
  118 + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
  119 + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
  120 + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
  121 + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
  122 + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
  123 + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
  124 + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
  125 + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
  126 +
  127 + // ----- Options values
  128 + define( 'PCLZIP_OPT_PATH', 77001 );
  129 + define( 'PCLZIP_OPT_ADD_PATH', 77002 );
  130 + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
  131 + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
  132 + define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
  133 + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
  134 + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
  135 + define( 'PCLZIP_OPT_BY_NAME', 77008 );
  136 + define( 'PCLZIP_OPT_BY_INDEX', 77009 );
  137 + define( 'PCLZIP_OPT_BY_EREG', 77010 );
  138 + define( 'PCLZIP_OPT_BY_PREG', 77011 );
  139 + define( 'PCLZIP_OPT_COMMENT', 77012 );
  140 + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
  141 + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
  142 + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
  143 + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
  144 + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
  145 + // Having big trouble with crypt. Need to multiply 2 long int
  146 + // which is not correctly supported by PHP ...
  147 + //define( 'PCLZIP_OPT_CRYPT', 77018 );
  148 + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
  149 + define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
  150 + define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
  151 + define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
  152 + define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
  153 + define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
  154 + define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
  155 +
  156 + // ----- File description attributes
  157 + define( 'PCLZIP_ATT_FILE_NAME', 79001 );
  158 + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
  159 + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
  160 + define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
  161 + define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
  162 + define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
  163 +
  164 + // ----- Call backs values
  165 + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
  166 + define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
  167 + define( 'PCLZIP_CB_PRE_ADD', 78003 );
  168 + define( 'PCLZIP_CB_POST_ADD', 78004 );
  169 + /* For futur use
  170 + define( 'PCLZIP_CB_PRE_LIST', 78005 );
  171 + define( 'PCLZIP_CB_POST_LIST', 78006 );
  172 + define( 'PCLZIP_CB_PRE_DELETE', 78007 );
  173 + define( 'PCLZIP_CB_POST_DELETE', 78008 );
  174 + */
  175 +
  176 + // --------------------------------------------------------------------------------
  177 + // Class : PclZip
  178 + // Description :
  179 + // PclZip is the class that represent a Zip archive.
  180 + // The public methods allow the manipulation of the archive.
  181 + // Attributes :
  182 + // Attributes must not be accessed directly.
  183 + // Methods :
  184 + // PclZip() : Object creator
  185 + // create() : Creates the Zip archive
  186 + // listContent() : List the content of the Zip archive
  187 + // extract() : Extract the content of the archive
  188 + // properties() : List the properties of the archive
  189 + // --------------------------------------------------------------------------------
  190 + class PclZip
  191 + {
  192 + // ----- Filename of the zip file
  193 + var $zipname = '';
  194 +
  195 + // ----- File descriptor of the zip file
  196 + var $zip_fd = 0;
  197 +
  198 + // ----- Internal error handling
  199 + var $error_code = 1;
  200 + var $error_string = '';
  201 +
  202 + // ----- Current status of the magic_quotes_runtime
  203 + // This value store the php configuration for magic_quotes
  204 + // The class can then disable the magic_quotes and reset it after
  205 + var $magic_quotes_status;
  206 +
  207 + // --------------------------------------------------------------------------------
  208 + // Function : PclZip()
  209 + // Description :
  210 + // Creates a PclZip object and set the name of the associated Zip archive
  211 + // filename.
  212 + // Note that no real action is taken, if the archive does not exist it is not
  213 + // created. Use create() for that.
  214 + // --------------------------------------------------------------------------------
  215 + function PclZip($p_zipname)
  216 + {
  217 +
  218 + // ----- Tests the zlib
  219 + if (!function_exists('gzopen'))
  220 + {
  221 + die('Abort '.basename(__FILE__).' : Missing zlib extensions');
  222 + }
  223 +
  224 + // ----- Set the attributes
  225 + $this->zipname = $p_zipname;
  226 + $this->zip_fd = 0;
  227 + $this->magic_quotes_status = -1;
  228 +
  229 + // ----- Return
  230 + return;
  231 + }
  232 + // --------------------------------------------------------------------------------
  233 +
  234 + // --------------------------------------------------------------------------------
  235 + // Function :
  236 + // create($p_filelist, $p_add_dir="", $p_remove_dir="")
  237 + // create($p_filelist, $p_option, $p_option_value, ...)
  238 + // Description :
  239 + // This method supports two different synopsis. The first one is historical.
  240 + // This method creates a Zip Archive. The Zip file is created in the
  241 + // filesystem. The files and directories indicated in $p_filelist
  242 + // are added in the archive. See the parameters description for the
  243 + // supported format of $p_filelist.
  244 + // When a directory is in the list, the directory and its content is added
  245 + // in the archive.
  246 + // In this synopsis, the function takes an optional variable list of
  247 + // options. See bellow the supported options.
  248 + // Parameters :
  249 + // $p_filelist : An array containing file or directory names, or
  250 + // a string containing one filename or one directory name, or
  251 + // a string containing a list of filenames and/or directory
  252 + // names separated by spaces.
  253 + // $p_add_dir : A path to add before the real path of the archived file,
  254 + // in order to have it memorized in the archive.
  255 + // $p_remove_dir : A path to remove from the real path of the file to archive,
  256 + // in order to have a shorter path memorized in the archive.
  257 + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  258 + // is removed first, before $p_add_dir is added.
  259 + // Options :
  260 + // PCLZIP_OPT_ADD_PATH :
  261 + // PCLZIP_OPT_REMOVE_PATH :
  262 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  263 + // PCLZIP_OPT_COMMENT :
  264 + // PCLZIP_CB_PRE_ADD :
  265 + // PCLZIP_CB_POST_ADD :
  266 + // Return Values :
  267 + // 0 on failure,
  268 + // The list of the added files, with a status of the add action.
  269 + // (see PclZip::listContent() for list entry format)
  270 + // --------------------------------------------------------------------------------
  271 + function create($p_filelist)
  272 + {
  273 + $v_result=1;
  274 +
  275 + // ----- Reset the error handler
  276 + $this->privErrorReset();
  277 +
  278 + // ----- Set default values
  279 + $v_options = array();
  280 + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  281 +
  282 + // ----- Look for variable options arguments
  283 + $v_size = func_num_args();
  284 +
  285 + // ----- Look for arguments
  286 + if ($v_size > 1) {
  287 + // ----- Get the arguments
  288 + $v_arg_list = func_get_args();
  289 +
  290 + // ----- Remove from the options list the first argument
  291 + array_shift($v_arg_list);
  292 + $v_size--;
  293 +
  294 + // ----- Look for first arg
  295 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  296 +
  297 + // ----- Parse the options
  298 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  299 + array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  300 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  301 + PCLZIP_OPT_ADD_PATH => 'optional',
  302 + PCLZIP_CB_PRE_ADD => 'optional',
  303 + PCLZIP_CB_POST_ADD => 'optional',
  304 + PCLZIP_OPT_NO_COMPRESSION => 'optional',
  305 + PCLZIP_OPT_COMMENT => 'optional',
  306 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  307 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  308 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  309 + //, PCLZIP_OPT_CRYPT => 'optional'
  310 + ));
  311 + if ($v_result != 1) {
  312 + return 0;
  313 + }
  314 + }
  315 +
  316 + // ----- Look for 2 args
  317 + // Here we need to support the first historic synopsis of the
  318 + // method.
  319 + else {
  320 +
  321 + // ----- Get the first argument
  322 + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
  323 +
  324 + // ----- Look for the optional second argument
  325 + if ($v_size == 2) {
  326 + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
  327 + }
  328 + else if ($v_size > 2) {
  329 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  330 + "Invalid number / type of arguments");
  331 + return 0;
  332 + }
  333 + }
  334 + }
  335 +
  336 + // ----- Look for default option values
  337 + $this->privOptionDefaultThreshold($v_options);
  338 +
  339 + // ----- Init
  340 + $v_string_list = array();
  341 + $v_att_list = array();
  342 + $v_filedescr_list = array();
  343 + $p_result_list = array();
  344 +
  345 + // ----- Look if the $p_filelist is really an array
  346 + if (is_array($p_filelist)) {
  347 +
  348 + // ----- Look if the first element is also an array
  349 + // This will mean that this is a file description entry
  350 + if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
  351 + $v_att_list = $p_filelist;
  352 + }
  353 +
  354 + // ----- The list is a list of string names
  355 + else {
  356 + $v_string_list = $p_filelist;
  357 + }
  358 + }
  359 +
  360 + // ----- Look if the $p_filelist is a string
  361 + else if (is_string($p_filelist)) {
  362 + // ----- Create a list from the string
  363 + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  364 + }
  365 +
  366 + // ----- Invalid variable type for $p_filelist
  367 + else {
  368 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
  369 + return 0;
  370 + }
  371 +
  372 + // ----- Reformat the string list
  373 + if (sizeof($v_string_list) != 0) {
  374 + foreach ($v_string_list as $v_string) {
  375 + if ($v_string != '') {
  376 + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
  377 + }
  378 + else {
  379 + }
  380 + }
  381 + }
  382 +
  383 + // ----- For each file in the list check the attributes
  384 + $v_supported_attributes
  385 + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
  386 + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
  387 + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
  388 + ,PCLZIP_ATT_FILE_MTIME => 'optional'
  389 + ,PCLZIP_ATT_FILE_CONTENT => 'optional'
  390 + ,PCLZIP_ATT_FILE_COMMENT => 'optional'
  391 + );
  392 + foreach ($v_att_list as $v_entry) {
  393 + $v_result = $this->privFileDescrParseAtt($v_entry,
  394 + $v_filedescr_list[],
  395 + $v_options,
  396 + $v_supported_attributes);
  397 + if ($v_result != 1) {
  398 + return 0;
  399 + }
  400 + }
  401 +
  402 + // ----- Expand the filelist (expand directories)
  403 + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
  404 + if ($v_result != 1) {
  405 + return 0;
  406 + }
  407 +
  408 + // ----- Call the create fct
  409 + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
  410 + if ($v_result != 1) {
  411 + return 0;
  412 + }
  413 +
  414 + // ----- Return
  415 + return $p_result_list;
  416 + }
  417 + // --------------------------------------------------------------------------------
  418 +
  419 + // --------------------------------------------------------------------------------
  420 + // Function :
  421 + // add($p_filelist, $p_add_dir="", $p_remove_dir="")
  422 + // add($p_filelist, $p_option, $p_option_value, ...)
  423 + // Description :
  424 + // This method supports two synopsis. The first one is historical.
  425 + // This methods add the list of files in an existing archive.
  426 + // If a file with the same name already exists, it is added at the end of the
  427 + // archive, the first one is still present.
  428 + // If the archive does not exist, it is created.
  429 + // Parameters :
  430 + // $p_filelist : An array containing file or directory names, or
  431 + // a string containing one filename or one directory name, or
  432 + // a string containing a list of filenames and/or directory
  433 + // names separated by spaces.
  434 + // $p_add_dir : A path to add before the real path of the archived file,
  435 + // in order to have it memorized in the archive.
  436 + // $p_remove_dir : A path to remove from the real path of the file to archive,
  437 + // in order to have a shorter path memorized in the archive.
  438 + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  439 + // is removed first, before $p_add_dir is added.
  440 + // Options :
  441 + // PCLZIP_OPT_ADD_PATH :
  442 + // PCLZIP_OPT_REMOVE_PATH :
  443 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  444 + // PCLZIP_OPT_COMMENT :
  445 + // PCLZIP_OPT_ADD_COMMENT :
  446 + // PCLZIP_OPT_PREPEND_COMMENT :
  447 + // PCLZIP_CB_PRE_ADD :
  448 + // PCLZIP_CB_POST_ADD :
  449 + // Return Values :
  450 + // 0 on failure,
  451 + // The list of the added files, with a status of the add action.
  452 + // (see PclZip::listContent() for list entry format)
  453 + // --------------------------------------------------------------------------------
  454 + function add($p_filelist)
  455 + {
  456 + $v_result=1;
  457 +
  458 + // ----- Reset the error handler
  459 + $this->privErrorReset();
  460 +
  461 + // ----- Set default values
  462 + $v_options = array();
  463 + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  464 +
  465 + // ----- Look for variable options arguments
  466 + $v_size = func_num_args();
  467 +
  468 + // ----- Look for arguments
  469 + if ($v_size > 1) {
  470 + // ----- Get the arguments
  471 + $v_arg_list = func_get_args();
  472 +
  473 + // ----- Remove form the options list the first argument
  474 + array_shift($v_arg_list);
  475 + $v_size--;
  476 +
  477 + // ----- Look for first arg
  478 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  479 +
  480 + // ----- Parse the options
  481 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  482 + array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  483 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  484 + PCLZIP_OPT_ADD_PATH => 'optional',
  485 + PCLZIP_CB_PRE_ADD => 'optional',
  486 + PCLZIP_CB_POST_ADD => 'optional',
  487 + PCLZIP_OPT_NO_COMPRESSION => 'optional',
  488 + PCLZIP_OPT_COMMENT => 'optional',
  489 + PCLZIP_OPT_ADD_COMMENT => 'optional',
  490 + PCLZIP_OPT_PREPEND_COMMENT => 'optional',
  491 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  492 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  493 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  494 + //, PCLZIP_OPT_CRYPT => 'optional'
  495 + ));
  496 + if ($v_result != 1) {
  497 + return 0;
  498 + }
  499 + }
  500 +
  501 + // ----- Look for 2 args
  502 + // Here we need to support the first historic synopsis of the
  503 + // method.
  504 + else {
  505 +
  506 + // ----- Get the first argument
  507 + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
  508 +
  509 + // ----- Look for the optional second argument
  510 + if ($v_size == 2) {
  511 + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
  512 + }
  513 + else if ($v_size > 2) {
  514 + // ----- Error log
  515 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  516 +
  517 + // ----- Return
  518 + return 0;
  519 + }
  520 + }
  521 + }
  522 +
  523 + // ----- Look for default option values
  524 + $this->privOptionDefaultThreshold($v_options);
  525 +
  526 + // ----- Init
  527 + $v_string_list = array();
  528 + $v_att_list = array();
  529 + $v_filedescr_list = array();
  530 + $p_result_list = array();
  531 +
  532 + // ----- Look if the $p_filelist is really an array
  533 + if (is_array($p_filelist)) {
  534 +
  535 + // ----- Look if the first element is also an array
  536 + // This will mean that this is a file description entry
  537 + if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
  538 + $v_att_list = $p_filelist;
  539 + }
  540 +
  541 + // ----- The list is a list of string names
  542 + else {
  543 + $v_string_list = $p_filelist;
  544 + }
  545 + }
  546 +
  547 + // ----- Look if the $p_filelist is a string
  548 + else if (is_string($p_filelist)) {
  549 + // ----- Create a list from the string
  550 + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  551 + }
  552 +
  553 + // ----- Invalid variable type for $p_filelist
  554 + else {
  555 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
  556 + return 0;
  557 + }
  558 +
  559 + // ----- Reformat the string list
  560 + if (sizeof($v_string_list) != 0) {
  561 + foreach ($v_string_list as $v_string) {
  562 + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
  563 + }
  564 + }
  565 +
  566 + // ----- For each file in the list check the attributes
  567 + $v_supported_attributes
  568 + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
  569 + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
  570 + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
  571 + ,PCLZIP_ATT_FILE_MTIME => 'optional'
  572 + ,PCLZIP_ATT_FILE_CONTENT => 'optional'
  573 + ,PCLZIP_ATT_FILE_COMMENT => 'optional'
  574 + );
  575 + foreach ($v_att_list as $v_entry) {
  576 + $v_result = $this->privFileDescrParseAtt($v_entry,
  577 + $v_filedescr_list[],
  578 + $v_options,
  579 + $v_supported_attributes);
  580 + if ($v_result != 1) {
  581 + return 0;
  582 + }
  583 + }
  584 +
  585 + // ----- Expand the filelist (expand directories)
  586 + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
  587 + if ($v_result != 1) {
  588 + return 0;
  589 + }
  590 +
  591 + // ----- Call the create fct
  592 + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
  593 + if ($v_result != 1) {
  594 + return 0;
  595 + }
  596 +
  597 + // ----- Return
  598 + return $p_result_list;
  599 + }
  600 + // --------------------------------------------------------------------------------
  601 +
  602 + // --------------------------------------------------------------------------------
  603 + // Function : listContent()
  604 + // Description :
  605 + // This public method, gives the list of the files and directories, with their
  606 + // properties.
  607 + // The properties of each entries in the list are (used also in other functions) :
  608 + // filename : Name of the file. For a create or add action it is the filename
  609 + // given by the user. For an extract function it is the filename
  610 + // of the extracted file.
  611 + // stored_filename : Name of the file / directory stored in the archive.
  612 + // size : Size of the stored file.
  613 + // compressed_size : Size of the file's data compressed in the archive
  614 + // (without the headers overhead)
  615 + // mtime : Last known modification date of the file (UNIX timestamp)
  616 + // comment : Comment associated with the file
  617 + // folder : true | false
  618 + // index : index of the file in the archive
  619 + // status : status of the action (depending of the action) :
  620 + // Values are :
  621 + // ok : OK !
  622 + // filtered : the file / dir is not extracted (filtered by user)
  623 + // already_a_directory : the file can not be extracted because a
  624 + // directory with the same name already exists
  625 + // write_protected : the file can not be extracted because a file
  626 + // with the same name already exists and is
  627 + // write protected
  628 + // newer_exist : the file was not extracted because a newer file exists
  629 + // path_creation_fail : the file is not extracted because the folder
  630 + // does not exist and can not be created
  631 + // write_error : the file was not extracted because there was a
  632 + // error while writing the file
  633 + // read_error : the file was not extracted because there was a error
  634 + // while reading the file
  635 + // invalid_header : the file was not extracted because of an archive
  636 + // format error (bad file header)
  637 + // Note that each time a method can continue operating when there
  638 + // is an action error on a file, the error is only logged in the file status.
  639 + // Return Values :
  640 + // 0 on an unrecoverable failure,
  641 + // The list of the files in the archive.
  642 + // --------------------------------------------------------------------------------
  643 + function listContent()
  644 + {
  645 + $v_result=1;
  646 +
  647 + // ----- Reset the error handler
  648 + $this->privErrorReset();
  649 +
  650 + // ----- Check archive
  651 + if (!$this->privCheckFormat()) {
  652 + return(0);
  653 + }
  654 +
  655 + // ----- Call the extracting fct
  656 + $p_list = array();
  657 + if (($v_result = $this->privList($p_list)) != 1)
  658 + {
  659 + unset($p_list);
  660 + return(0);
  661 + }
  662 +
  663 + // ----- Return
  664 + return $p_list;
  665 + }
  666 + // --------------------------------------------------------------------------------
  667 +
  668 + // --------------------------------------------------------------------------------
  669 + // Function :
  670 + // extract($p_path="./", $p_remove_path="")
  671 + // extract([$p_option, $p_option_value, ...])
  672 + // Description :
  673 + // This method supports two synopsis. The first one is historical.
  674 + // This method extract all the files / directories from the archive to the
  675 + // folder indicated in $p_path.
  676 + // If you want to ignore the 'root' part of path of the memorized files
  677 + // you can indicate this in the optional $p_remove_path parameter.
  678 + // By default, if a newer file with the same name already exists, the
  679 + // file is not extracted.
  680 + //
  681 + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
  682 + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
  683 + // at the end of the path value of PCLZIP_OPT_PATH.
  684 + // Parameters :
  685 + // $p_path : Path where the files and directories are to be extracted
  686 + // $p_remove_path : First part ('root' part) of the memorized path
  687 + // (if any similar) to remove while extracting.
  688 + // Options :
  689 + // PCLZIP_OPT_PATH :
  690 + // PCLZIP_OPT_ADD_PATH :
  691 + // PCLZIP_OPT_REMOVE_PATH :
  692 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  693 + // PCLZIP_CB_PRE_EXTRACT :
  694 + // PCLZIP_CB_POST_EXTRACT :
  695 + // Return Values :
  696 + // 0 or a negative value on failure,
  697 + // The list of the extracted files, with a status of the action.
  698 + // (see PclZip::listContent() for list entry format)
  699 + // --------------------------------------------------------------------------------
  700 + function extract()
  701 + {
  702 + $v_result=1;
  703 +
  704 + // ----- Reset the error handler
  705 + $this->privErrorReset();
  706 +
  707 + // ----- Check archive
  708 + if (!$this->privCheckFormat()) {
  709 + return(0);
  710 + }
  711 +
  712 + // ----- Set default values
  713 + $v_options = array();
  714 +// $v_path = "./";
  715 + $v_path = '';
  716 + $v_remove_path = "";
  717 + $v_remove_all_path = false;
  718 +
  719 + // ----- Look for variable options arguments
  720 + $v_size = func_num_args();
  721 +
  722 + // ----- Default values for option
  723 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  724 +
  725 + // ----- Look for arguments
  726 + if ($v_size > 0) {
  727 + // ----- Get the arguments
  728 + $v_arg_list = func_get_args();
  729 +
  730 + // ----- Look for first arg
  731 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  732 +
  733 + // ----- Parse the options
  734 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  735 + array (PCLZIP_OPT_PATH => 'optional',
  736 + PCLZIP_OPT_REMOVE_PATH => 'optional',
  737 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  738 + PCLZIP_OPT_ADD_PATH => 'optional',
  739 + PCLZIP_CB_PRE_EXTRACT => 'optional',
  740 + PCLZIP_CB_POST_EXTRACT => 'optional',
  741 + PCLZIP_OPT_SET_CHMOD => 'optional',
  742 + PCLZIP_OPT_BY_NAME => 'optional',
  743 + PCLZIP_OPT_BY_EREG => 'optional',
  744 + PCLZIP_OPT_BY_PREG => 'optional',
  745 + PCLZIP_OPT_BY_INDEX => 'optional',
  746 + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  747 + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
  748 + PCLZIP_OPT_REPLACE_NEWER => 'optional'
  749 + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
  750 + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
  751 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  752 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  753 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  754 + ));
  755 + if ($v_result != 1) {
  756 + return 0;
  757 + }
  758 +
  759 + // ----- Set the arguments
  760 + if (isset($v_options[PCLZIP_OPT_PATH])) {
  761 + $v_path = $v_options[PCLZIP_OPT_PATH];
  762 + }
  763 + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  764 + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  765 + }
  766 + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  767 + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  768 + }
  769 + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  770 + // ----- Check for '/' in last path char
  771 + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  772 + $v_path .= '/';
  773 + }
  774 + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  775 + }
  776 + }
  777 +
  778 + // ----- Look for 2 args
  779 + // Here we need to support the first historic synopsis of the
  780 + // method.
  781 + else {
  782 +
  783 + // ----- Get the first argument
  784 + $v_path = $v_arg_list[0];
  785 +
  786 + // ----- Look for the optional second argument
  787 + if ($v_size == 2) {
  788 + $v_remove_path = $v_arg_list[1];
  789 + }
  790 + else if ($v_size > 2) {
  791 + // ----- Error log
  792 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  793 +
  794 + // ----- Return
  795 + return 0;
  796 + }
  797 + }
  798 + }
  799 +
  800 + // ----- Look for default option values
  801 + $this->privOptionDefaultThreshold($v_options);
  802 +
  803 + // ----- Trace
  804 +
  805 + // ----- Call the extracting fct
  806 + $p_list = array();
  807 + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
  808 + $v_remove_all_path, $v_options);
  809 + if ($v_result < 1) {
  810 + unset($p_list);
  811 + return(0);
  812 + }
  813 +
  814 + // ----- Return
  815 + return $p_list;
  816 + }
  817 + // --------------------------------------------------------------------------------
  818 +
  819 +
  820 + // --------------------------------------------------------------------------------
  821 + // Function :
  822 + // extractByIndex($p_index, $p_path="./", $p_remove_path="")
  823 + // extractByIndex($p_index, [$p_option, $p_option_value, ...])
  824 + // Description :
  825 + // This method supports two synopsis. The first one is historical.
  826 + // This method is doing a partial extract of the archive.
  827 + // The extracted files or folders are identified by their index in the
  828 + // archive (from 0 to n).
  829 + // Note that if the index identify a folder, only the folder entry is
  830 + // extracted, not all the files included in the archive.
  831 + // Parameters :
  832 + // $p_index : A single index (integer) or a string of indexes of files to
  833 + // extract. The form of the string is "0,4-6,8-12" with only numbers
  834 + // and '-' for range or ',' to separate ranges. No spaces or ';'
  835 + // are allowed.
  836 + // $p_path : Path where the files and directories are to be extracted
  837 + // $p_remove_path : First part ('root' part) of the memorized path
  838 + // (if any similar) to remove while extracting.
  839 + // Options :
  840 + // PCLZIP_OPT_PATH :
  841 + // PCLZIP_OPT_ADD_PATH :
  842 + // PCLZIP_OPT_REMOVE_PATH :
  843 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  844 + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
  845 + // not as files.
  846 + // The resulting content is in a new field 'content' in the file
  847 + // structure.
  848 + // This option must be used alone (any other options are ignored).
  849 + // PCLZIP_CB_PRE_EXTRACT :
  850 + // PCLZIP_CB_POST_EXTRACT :
  851 + // Return Values :
  852 + // 0 on failure,
  853 + // The list of the extracted files, with a status of the action.
  854 + // (see PclZip::listContent() for list entry format)
  855 + // --------------------------------------------------------------------------------
  856 + //function extractByIndex($p_index, options...)
  857 + function extractByIndex($p_index)
  858 + {
  859 + $v_result=1;
  860 +
  861 + // ----- Reset the error handler
  862 + $this->privErrorReset();
  863 +
  864 + // ----- Check archive
  865 + if (!$this->privCheckFormat()) {
  866 + return(0);
  867 + }
  868 +
  869 + // ----- Set default values
  870 + $v_options = array();
  871 +// $v_path = "./";
  872 + $v_path = '';
  873 + $v_remove_path = "";
  874 + $v_remove_all_path = false;
  875 +
  876 + // ----- Look for variable options arguments
  877 + $v_size = func_num_args();
  878 +
  879 + // ----- Default values for option
  880 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  881 +
  882 + // ----- Look for arguments
  883 + if ($v_size > 1) {
  884 + // ----- Get the arguments
  885 + $v_arg_list = func_get_args();
  886 +
  887 + // ----- Remove form the options list the first argument
  888 + array_shift($v_arg_list);
  889 + $v_size--;
  890 +
  891 + // ----- Look for first arg
  892 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  893 +
  894 + // ----- Parse the options
  895 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  896 + array (PCLZIP_OPT_PATH => 'optional',
  897 + PCLZIP_OPT_REMOVE_PATH => 'optional',
  898 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  899 + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  900 + PCLZIP_OPT_ADD_PATH => 'optional',
  901 + PCLZIP_CB_PRE_EXTRACT => 'optional',
  902 + PCLZIP_CB_POST_EXTRACT => 'optional',
  903 + PCLZIP_OPT_SET_CHMOD => 'optional',
  904 + PCLZIP_OPT_REPLACE_NEWER => 'optional'
  905 + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
  906 + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
  907 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  908 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  909 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  910 + ));
  911 + if ($v_result != 1) {
  912 + return 0;
  913 + }
  914 +
  915 + // ----- Set the arguments
  916 + if (isset($v_options[PCLZIP_OPT_PATH])) {
  917 + $v_path = $v_options[PCLZIP_OPT_PATH];
  918 + }
  919 + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  920 + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  921 + }
  922 + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  923 + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  924 + }
  925 + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  926 + // ----- Check for '/' in last path char
  927 + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  928 + $v_path .= '/';
  929 + }
  930 + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  931 + }
  932 + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
  933 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  934 + }
  935 + else {
  936 + }
  937 + }
  938 +
  939 + // ----- Look for 2 args
  940 + // Here we need to support the first historic synopsis of the
  941 + // method.
  942 + else {
  943 +
  944 + // ----- Get the first argument
  945 + $v_path = $v_arg_list[0];
  946 +
  947 + // ----- Look for the optional second argument
  948 + if ($v_size == 2) {
  949 + $v_remove_path = $v_arg_list[1];
  950 + }
  951 + else if ($v_size > 2) {
  952 + // ----- Error log
  953 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  954 +
  955 + // ----- Return
  956 + return 0;
  957 + }
  958 + }
  959 + }
  960 +
  961 + // ----- Trace
  962 +
  963 + // ----- Trick
  964 + // Here I want to reuse extractByRule(), so I need to parse the $p_index
  965 + // with privParseOptions()
  966 + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
  967 + $v_options_trick = array();
  968 + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
  969 + array (PCLZIP_OPT_BY_INDEX => 'optional' ));
  970 + if ($v_result != 1) {
  971 + return 0;
  972 + }
  973 + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
  974 +
  975 + // ----- Look for default option values
  976 + $this->privOptionDefaultThreshold($v_options);
  977 +
  978 + // ----- Call the extracting fct
  979 + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
  980 + return(0);
  981 + }
  982 +
  983 + // ----- Return
  984 + return $p_list;
  985 + }
  986 + // --------------------------------------------------------------------------------
  987 +
  988 + // --------------------------------------------------------------------------------
  989 + // Function :
  990 + // delete([$p_option, $p_option_value, ...])
  991 + // Description :
  992 + // This method removes files from the archive.
  993 + // If no parameters are given, then all the archive is emptied.
  994 + // Parameters :
  995 + // None or optional arguments.
  996 + // Options :
  997 + // PCLZIP_OPT_BY_INDEX :
  998 + // PCLZIP_OPT_BY_NAME :
  999 + // PCLZIP_OPT_BY_EREG :
  1000 + // PCLZIP_OPT_BY_PREG :
  1001 + // Return Values :
  1002 + // 0 on failure,
  1003 + // The list of the files which are still present in the archive.
  1004 + // (see PclZip::listContent() for list entry format)
  1005 + // --------------------------------------------------------------------------------
  1006 + function delete()
  1007 + {
  1008 + $v_result=1;
  1009 +
  1010 + // ----- Reset the error handler
  1011 + $this->privErrorReset();
  1012 +
  1013 + // ----- Check archive
  1014 + if (!$this->privCheckFormat()) {
  1015 + return(0);
  1016 + }
  1017 +
  1018 + // ----- Set default values
  1019 + $v_options = array();
  1020 +
  1021 + // ----- Look for variable options arguments
  1022 + $v_size = func_num_args();
  1023 +
  1024 + // ----- Look for arguments
  1025 + if ($v_size > 0) {
  1026 + // ----- Get the arguments
  1027 + $v_arg_list = func_get_args();
  1028 +
  1029 + // ----- Parse the options
  1030 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  1031 + array (PCLZIP_OPT_BY_NAME => 'optional',
  1032 + PCLZIP_OPT_BY_EREG => 'optional',
  1033 + PCLZIP_OPT_BY_PREG => 'optional',
  1034 + PCLZIP_OPT_BY_INDEX => 'optional' ));
  1035 + if ($v_result != 1) {
  1036 + return 0;
  1037 + }
  1038 + }
  1039 +
  1040 + // ----- Magic quotes trick
  1041 + $this->privDisableMagicQuotes();
  1042 +
  1043 + // ----- Call the delete fct
  1044 + $v_list = array();
  1045 + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
  1046 + $this->privSwapBackMagicQuotes();
  1047 + unset($v_list);
  1048 + return(0);
  1049 + }
  1050 +
  1051 + // ----- Magic quotes trick
  1052 + $this->privSwapBackMagicQuotes();
  1053 +
  1054 + // ----- Return
  1055 + return $v_list;
  1056 + }
  1057 + // --------------------------------------------------------------------------------
  1058 +
  1059 + // --------------------------------------------------------------------------------
  1060 + // Function : deleteByIndex()
  1061 + // Description :
  1062 + // ***** Deprecated *****
  1063 + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
  1064 + // --------------------------------------------------------------------------------
  1065 + function deleteByIndex($p_index)
  1066 + {
  1067 +
  1068 + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
  1069 +
  1070 + // ----- Return
  1071 + return $p_list;
  1072 + }
  1073 + // --------------------------------------------------------------------------------
  1074 +
  1075 + // --------------------------------------------------------------------------------
  1076 + // Function : properties()
  1077 + // Description :
  1078 + // This method gives the properties of the archive.
  1079 + // The properties are :
  1080 + // nb : Number of files in the archive
  1081 + // comment : Comment associated with the archive file
  1082 + // status : not_exist, ok
  1083 + // Parameters :
  1084 + // None
  1085 + // Return Values :
  1086 + // 0 on failure,
  1087 + // An array with the archive properties.
  1088 + // --------------------------------------------------------------------------------
  1089 + function properties()
  1090 + {
  1091 +
  1092 + // ----- Reset the error handler
  1093 + $this->privErrorReset();
  1094 +
  1095 + // ----- Magic quotes trick
  1096 + $this->privDisableMagicQuotes();
  1097 +
  1098 + // ----- Check archive
  1099 + if (!$this->privCheckFormat()) {
  1100 + $this->privSwapBackMagicQuotes();
  1101 + return(0);
  1102 + }
  1103 +
  1104 + // ----- Default properties
  1105 + $v_prop = array();
  1106 + $v_prop['comment'] = '';
  1107 + $v_prop['nb'] = 0;
  1108 + $v_prop['status'] = 'not_exist';
  1109 +
  1110 + // ----- Look if file exists
  1111 + if (@is_file($this->zipname))
  1112 + {
  1113 + // ----- Open the zip file
  1114 + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  1115 + {
  1116 + $this->privSwapBackMagicQuotes();
  1117 +
  1118 + // ----- Error log
  1119 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  1120 +
  1121 + // ----- Return
  1122 + return 0;
  1123 + }
  1124 +
  1125 + // ----- Read the central directory informations
  1126 + $v_central_dir = array();
  1127 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1128 + {
  1129 + $this->privSwapBackMagicQuotes();
  1130 + return 0;
  1131 + }
  1132 +
  1133 + // ----- Close the zip file
  1134 + $this->privCloseFd();
  1135 +
  1136 + // ----- Set the user attributes
  1137 + $v_prop['comment'] = $v_central_dir['comment'];
  1138 + $v_prop['nb'] = $v_central_dir['entries'];
  1139 + $v_prop['status'] = 'ok';
  1140 + }
  1141 +
  1142 + // ----- Magic quotes trick
  1143 + $this->privSwapBackMagicQuotes();
  1144 +
  1145 + // ----- Return
  1146 + return $v_prop;
  1147 + }
  1148 + // --------------------------------------------------------------------------------
  1149 +
  1150 + // --------------------------------------------------------------------------------
  1151 + // Function : duplicate()
  1152 + // Description :
  1153 + // This method creates an archive by copying the content of an other one. If
  1154 + // the archive already exist, it is replaced by the new one without any warning.
  1155 + // Parameters :
  1156 + // $p_archive : The filename of a valid archive, or
  1157 + // a valid PclZip object.
  1158 + // Return Values :
  1159 + // 1 on success.
  1160 + // 0 or a negative value on error (error code).
  1161 + // --------------------------------------------------------------------------------
  1162 + function duplicate($p_archive)
  1163 + {
  1164 + $v_result = 1;
  1165 +
  1166 + // ----- Reset the error handler
  1167 + $this->privErrorReset();
  1168 +
  1169 + // ----- Look if the $p_archive is a PclZip object
  1170 + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
  1171 + {
  1172 +
  1173 + // ----- Duplicate the archive
  1174 + $v_result = $this->privDuplicate($p_archive->zipname);
  1175 + }
  1176 +
  1177 + // ----- Look if the $p_archive is a string (so a filename)
  1178 + else if (is_string($p_archive))
  1179 + {
  1180 +
  1181 + // ----- Check that $p_archive is a valid zip file
  1182 + // TBC : Should also check the archive format
  1183 + if (!is_file($p_archive)) {
  1184 + // ----- Error log
  1185 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
  1186 + $v_result = PCLZIP_ERR_MISSING_FILE;
  1187 + }
  1188 + else {
  1189 + // ----- Duplicate the archive
  1190 + $v_result = $this->privDuplicate($p_archive);
  1191 + }
  1192 + }
  1193 +
  1194 + // ----- Invalid variable
  1195 + else
  1196 + {
  1197 + // ----- Error log
  1198 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1199 + $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1200 + }
  1201 +
  1202 + // ----- Return
  1203 + return $v_result;
  1204 + }
  1205 + // --------------------------------------------------------------------------------
  1206 +
  1207 + // --------------------------------------------------------------------------------
  1208 + // Function : merge()
  1209 + // Description :
  1210 + // This method merge the $p_archive_to_add archive at the end of the current
  1211 + // one ($this).
  1212 + // If the archive ($this) does not exist, the merge becomes a duplicate.
  1213 + // If the $p_archive_to_add archive does not exist, the merge is a success.
  1214 + // Parameters :
  1215 + // $p_archive_to_add : It can be directly the filename of a valid zip archive,
  1216 + // or a PclZip object archive.
  1217 + // Return Values :
  1218 + // 1 on success,
  1219 + // 0 or negative values on error (see below).
  1220 + // --------------------------------------------------------------------------------
  1221 + function merge($p_archive_to_add)
  1222 + {
  1223 + $v_result = 1;
  1224 +
  1225 + // ----- Reset the error handler
  1226 + $this->privErrorReset();
  1227 +
  1228 + // ----- Check archive
  1229 + if (!$this->privCheckFormat()) {
  1230 + return(0);
  1231 + }
  1232 +
  1233 + // ----- Look if the $p_archive_to_add is a PclZip object
  1234 + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
  1235 + {
  1236 +
  1237 + // ----- Merge the archive
  1238 + $v_result = $this->privMerge($p_archive_to_add);
  1239 + }
  1240 +
  1241 + // ----- Look if the $p_archive_to_add is a string (so a filename)
  1242 + else if (is_string($p_archive_to_add))
  1243 + {
  1244 +
  1245 + // ----- Create a temporary archive
  1246 + $v_object_archive = new PclZip($p_archive_to_add);
  1247 +
  1248 + // ----- Merge the archive
  1249 + $v_result = $this->privMerge($v_object_archive);
  1250 + }
  1251 +
  1252 + // ----- Invalid variable
  1253 + else
  1254 + {
  1255 + // ----- Error log
  1256 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1257 + $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1258 + }
  1259 +
  1260 + // ----- Return
  1261 + return $v_result;
  1262 + }
  1263 + // --------------------------------------------------------------------------------
  1264 +
  1265 +
  1266 +
  1267 + // --------------------------------------------------------------------------------
  1268 + // Function : errorCode()
  1269 + // Description :
  1270 + // Parameters :
  1271 + // --------------------------------------------------------------------------------
  1272 + function errorCode()
  1273 + {
  1274 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  1275 + return(PclErrorCode());
  1276 + }
  1277 + else {
  1278 + return($this->error_code);
  1279 + }
  1280 + }
  1281 + // --------------------------------------------------------------------------------
  1282 +
  1283 + // --------------------------------------------------------------------------------
  1284 + // Function : errorName()
  1285 + // Description :
  1286 + // Parameters :
  1287 + // --------------------------------------------------------------------------------
  1288 + function errorName($p_with_code=false)
  1289 + {
  1290 + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
  1291 + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
  1292 + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
  1293 + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
  1294 + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
  1295 + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
  1296 + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
  1297 + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
  1298 + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
  1299 + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
  1300 + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
  1301 + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
  1302 + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
  1303 + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
  1304 + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
  1305 + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
  1306 + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
  1307 + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
  1308 + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
  1309 + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
  1310 + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
  1311 + );
  1312 +
  1313 + if (isset($v_name[$this->error_code])) {
  1314 + $v_value = $v_name[$this->error_code];
  1315 + }
  1316 + else {
  1317 + $v_value = 'NoName';
  1318 + }
  1319 +
  1320 + if ($p_with_code) {
  1321 + return($v_value.' ('.$this->error_code.')');
  1322 + }
  1323 + else {
  1324 + return($v_value);
  1325 + }
  1326 + }
  1327 + // --------------------------------------------------------------------------------
  1328 +
  1329 + // --------------------------------------------------------------------------------
  1330 + // Function : errorInfo()
  1331 + // Description :
  1332 + // Parameters :
  1333 + // --------------------------------------------------------------------------------
  1334 + function errorInfo($p_full=false)
  1335 + {
  1336 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  1337 + return(PclErrorString());
  1338 + }
  1339 + else {
  1340 + if ($p_full) {
  1341 + return($this->errorName(true)." : ".$this->error_string);
  1342 + }
  1343 + else {
  1344 + return($this->error_string." [code ".$this->error_code."]");
  1345 + }
  1346 + }
  1347 + }
  1348 + // --------------------------------------------------------------------------------
  1349 +
  1350 +
  1351 +// --------------------------------------------------------------------------------
  1352 +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
  1353 +// ***** *****
  1354 +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
  1355 +// --------------------------------------------------------------------------------
  1356 +
  1357 +
  1358 +
  1359 + // --------------------------------------------------------------------------------
  1360 + // Function : privCheckFormat()
  1361 + // Description :
  1362 + // This method check that the archive exists and is a valid zip archive.
  1363 + // Several level of check exists. (futur)
  1364 + // Parameters :
  1365 + // $p_level : Level of check. Default 0.
  1366 + // 0 : Check the first bytes (magic codes) (default value))
  1367 + // 1 : 0 + Check the central directory (futur)
  1368 + // 2 : 1 + Check each file header (futur)
  1369 + // Return Values :
  1370 + // true on success,
  1371 + // false on error, the error code is set.
  1372 + // --------------------------------------------------------------------------------
  1373 + function privCheckFormat($p_level=0)
  1374 + {
  1375 + $v_result = true;
  1376 +
  1377 + // ----- Reset the file system cache
  1378 + clearstatcache();
  1379 +
  1380 + // ----- Reset the error handler
  1381 + $this->privErrorReset();
  1382 +
  1383 + // ----- Look if the file exits
  1384 + if (!is_file($this->zipname)) {
  1385 + // ----- Error log
  1386 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
  1387 + return(false);
  1388 + }
  1389 +
  1390 + // ----- Check that the file is readeable
  1391 + if (!is_readable($this->zipname)) {
  1392 + // ----- Error log
  1393 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
  1394 + return(false);
  1395 + }
  1396 +
  1397 + // ----- Check the magic code
  1398 + // TBC
  1399 +
  1400 + // ----- Check the central header
  1401 + // TBC
  1402 +
  1403 + // ----- Check each file header
  1404 + // TBC
  1405 +
  1406 + // ----- Return
  1407 + return $v_result;
  1408 + }
  1409 + // --------------------------------------------------------------------------------
  1410 +
  1411 + // --------------------------------------------------------------------------------
  1412 + // Function : privParseOptions()
  1413 + // Description :
  1414 + // This internal methods reads the variable list of arguments ($p_options_list,
  1415 + // $p_size) and generate an array with the options and values ($v_result_list).
  1416 + // $v_requested_options contains the options that can be present and those that
  1417 + // must be present.
  1418 + // $v_requested_options is an array, with the option value as key, and 'optional',
  1419 + // or 'mandatory' as value.
  1420 + // Parameters :
  1421 + // See above.
  1422 + // Return Values :
  1423 + // 1 on success.
  1424 + // 0 on failure.
  1425 + // --------------------------------------------------------------------------------
  1426 + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
  1427 + {
  1428 + $v_result=1;
  1429 +
  1430 + // ----- Read the options
  1431 + $i=0;
  1432 + while ($i<$p_size) {
  1433 +
  1434 + // ----- Check if the option is supported
  1435 + if (!isset($v_requested_options[$p_options_list[$i]])) {
  1436 + // ----- Error log
  1437 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
  1438 +
  1439 + // ----- Return
  1440 + return PclZip::errorCode();
  1441 + }
  1442 +
  1443 + // ----- Look for next option
  1444 + switch ($p_options_list[$i]) {
  1445 + // ----- Look for options that request a path value
  1446 + case PCLZIP_OPT_PATH :
  1447 + case PCLZIP_OPT_REMOVE_PATH :
  1448 + case PCLZIP_OPT_ADD_PATH :
  1449 + // ----- Check the number of parameters
  1450 + if (($i+1) >= $p_size) {
  1451 + // ----- Error log
  1452 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1453 +
  1454 + // ----- Return
  1455 + return PclZip::errorCode();
  1456 + }
  1457 +
  1458 + // ----- Get the value
  1459 + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
  1460 + $i++;
  1461 + break;
  1462 +
  1463 + case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
  1464 + // ----- Check the number of parameters
  1465 + if (($i+1) >= $p_size) {
  1466 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1467 + return PclZip::errorCode();
  1468 + }
  1469 +
  1470 + // ----- Check for incompatible options
  1471 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
  1472 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
  1473 + return PclZip::errorCode();
  1474 + }
  1475 +
  1476 + // ----- Check the value
  1477 + $v_value = $p_options_list[$i+1];
  1478 + if ((!is_integer($v_value)) || ($v_value<0)) {
  1479 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1480 + return PclZip::errorCode();
  1481 + }
  1482 +
  1483 + // ----- Get the value (and convert it in bytes)
  1484 + $v_result_list[$p_options_list[$i]] = $v_value*1048576;
  1485 + $i++;
  1486 + break;
  1487 +
  1488 + case PCLZIP_OPT_TEMP_FILE_ON :
  1489 + // ----- Check for incompatible options
  1490 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
  1491 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
  1492 + return PclZip::errorCode();
  1493 + }
  1494 +
  1495 + $v_result_list[$p_options_list[$i]] = true;
  1496 + break;
  1497 +
  1498 + case PCLZIP_OPT_TEMP_FILE_OFF :
  1499 + // ----- Check for incompatible options
  1500 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
  1501 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
  1502 + return PclZip::errorCode();
  1503 + }
  1504 + // ----- Check for incompatible options
  1505 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
  1506 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
  1507 + return PclZip::errorCode();
  1508 + }
  1509 +
  1510 + $v_result_list[$p_options_list[$i]] = true;
  1511 + break;
  1512 +
  1513 + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
  1514 + // ----- Check the number of parameters
  1515 + if (($i+1) >= $p_size) {
  1516 + // ----- Error log
  1517 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1518 +
  1519 + // ----- Return
  1520 + return PclZip::errorCode();
  1521 + }
  1522 +
  1523 + // ----- Get the value
  1524 + if ( is_string($p_options_list[$i+1])
  1525 + && ($p_options_list[$i+1] != '')) {
  1526 + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
  1527 + $i++;
  1528 + }
  1529 + else {
  1530 + }
  1531 + break;
  1532 +
  1533 + // ----- Look for options that request an array of string for value
  1534 + case PCLZIP_OPT_BY_NAME :
  1535 + // ----- Check the number of parameters
  1536 + if (($i+1) >= $p_size) {
  1537 + // ----- Error log
  1538 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1539 +
  1540 + // ----- Return
  1541 + return PclZip::errorCode();
  1542 + }
  1543 +
  1544 + // ----- Get the value
  1545 + if (is_string($p_options_list[$i+1])) {
  1546 + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
  1547 + }
  1548 + else if (is_array($p_options_list[$i+1])) {
  1549 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1550 + }
  1551 + else {
  1552 + // ----- Error log
  1553 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1554 +
  1555 + // ----- Return
  1556 + return PclZip::errorCode();
  1557 + }
  1558 + $i++;
  1559 + break;
  1560 +
  1561 + // ----- Look for options that request an EREG or PREG expression
  1562 + case PCLZIP_OPT_BY_EREG :
  1563 + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
  1564 + // to PCLZIP_OPT_BY_PREG
  1565 + $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
  1566 + case PCLZIP_OPT_BY_PREG :
  1567 + //case PCLZIP_OPT_CRYPT :
  1568 + // ----- Check the number of parameters
  1569 + if (($i+1) >= $p_size) {
  1570 + // ----- Error log
  1571 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1572 +
  1573 + // ----- Return
  1574 + return PclZip::errorCode();
  1575 + }
  1576 +
  1577 + // ----- Get the value
  1578 + if (is_string($p_options_list[$i+1])) {
  1579 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1580 + }
  1581 + else {
  1582 + // ----- Error log
  1583 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1584 +
  1585 + // ----- Return
  1586 + return PclZip::errorCode();
  1587 + }
  1588 + $i++;
  1589 + break;
  1590 +
  1591 + // ----- Look for options that takes a string
  1592 + case PCLZIP_OPT_COMMENT :
  1593 + case PCLZIP_OPT_ADD_COMMENT :
  1594 + case PCLZIP_OPT_PREPEND_COMMENT :
  1595 + // ----- Check the number of parameters
  1596 + if (($i+1) >= $p_size) {
  1597 + // ----- Error log
  1598 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
  1599 + "Missing parameter value for option '"
  1600 + .PclZipUtilOptionText($p_options_list[$i])
  1601 + ."'");
  1602 +
  1603 + // ----- Return
  1604 + return PclZip::errorCode();
  1605 + }
  1606 +
  1607 + // ----- Get the value
  1608 + if (is_string($p_options_list[$i+1])) {
  1609 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1610 + }
  1611 + else {
  1612 + // ----- Error log
  1613 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
  1614 + "Wrong parameter value for option '"
  1615 + .PclZipUtilOptionText($p_options_list[$i])
  1616 + ."'");
  1617 +
  1618 + // ----- Return
  1619 + return PclZip::errorCode();
  1620 + }
  1621 + $i++;
  1622 + break;
  1623 +
  1624 + // ----- Look for options that request an array of index
  1625 + case PCLZIP_OPT_BY_INDEX :
  1626 + // ----- Check the number of parameters
  1627 + if (($i+1) >= $p_size) {
  1628 + // ----- Error log
  1629 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1630 +
  1631 + // ----- Return
  1632 + return PclZip::errorCode();
  1633 + }
  1634 +
  1635 + // ----- Get the value
  1636 + $v_work_list = array();
  1637 + if (is_string($p_options_list[$i+1])) {
  1638 +
  1639 + // ----- Remove spaces
  1640 + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
  1641 +
  1642 + // ----- Parse items
  1643 + $v_work_list = explode(",", $p_options_list[$i+1]);
  1644 + }
  1645 + else if (is_integer($p_options_list[$i+1])) {
  1646 + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
  1647 + }
  1648 + else if (is_array($p_options_list[$i+1])) {
  1649 + $v_work_list = $p_options_list[$i+1];
  1650 + }
  1651 + else {
  1652 + // ----- Error log
  1653 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1654 +
  1655 + // ----- Return
  1656 + return PclZip::errorCode();
  1657 + }
  1658 +
  1659 + // ----- Reduce the index list
  1660 + // each index item in the list must be a couple with a start and
  1661 + // an end value : [0,3], [5-5], [8-10], ...
  1662 + // ----- Check the format of each item
  1663 + $v_sort_flag=false;
  1664 + $v_sort_value=0;
  1665 + for ($j=0; $j<sizeof($v_work_list); $j++) {
  1666 + // ----- Explode the item
  1667 + $v_item_list = explode("-", $v_work_list[$j]);
  1668 + $v_size_item_list = sizeof($v_item_list);
  1669 +
  1670 + // ----- TBC : Here we might check that each item is a
  1671 + // real integer ...
  1672 +
  1673 + // ----- Look for single value
  1674 + if ($v_size_item_list == 1) {
  1675 + // ----- Set the option value
  1676 + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1677 + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
  1678 + }
  1679 + elseif ($v_size_item_list == 2) {
  1680 + // ----- Set the option value
  1681 + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1682 + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
  1683 + }
  1684 + else {
  1685 + // ----- Error log
  1686 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1687 +
  1688 + // ----- Return
  1689 + return PclZip::errorCode();
  1690 + }
  1691 +
  1692 +
  1693 + // ----- Look for list sort
  1694 + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
  1695 + $v_sort_flag=true;
  1696 +
  1697 + // ----- TBC : An automatic sort should be writen ...
  1698 + // ----- Error log
  1699 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1700 +
  1701 + // ----- Return
  1702 + return PclZip::errorCode();
  1703 + }
  1704 + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
  1705 + }
  1706 +
  1707 + // ----- Sort the items
  1708 + if ($v_sort_flag) {
  1709 + // TBC : To Be Completed
  1710 + }
  1711 +
  1712 + // ----- Next option
  1713 + $i++;
  1714 + break;
  1715 +
  1716 + // ----- Look for options that request no value
  1717 + case PCLZIP_OPT_REMOVE_ALL_PATH :
  1718 + case PCLZIP_OPT_EXTRACT_AS_STRING :
  1719 + case PCLZIP_OPT_NO_COMPRESSION :
  1720 + case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
  1721 + case PCLZIP_OPT_REPLACE_NEWER :
  1722 + case PCLZIP_OPT_STOP_ON_ERROR :
  1723 + $v_result_list[$p_options_list[$i]] = true;
  1724 + break;
  1725 +
  1726 + // ----- Look for options that request an octal value
  1727 + case PCLZIP_OPT_SET_CHMOD :
  1728 + // ----- Check the number of parameters
  1729 + if (($i+1) >= $p_size) {
  1730 + // ----- Error log
  1731 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1732 +
  1733 + // ----- Return
  1734 + return PclZip::errorCode();
  1735 + }
  1736 +
  1737 + // ----- Get the value
  1738 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1739 + $i++;
  1740 + break;
  1741 +
  1742 + // ----- Look for options that request a call-back
  1743 + case PCLZIP_CB_PRE_EXTRACT :
  1744 + case PCLZIP_CB_POST_EXTRACT :
  1745 + case PCLZIP_CB_PRE_ADD :
  1746 + case PCLZIP_CB_POST_ADD :
  1747 + /* for futur use
  1748 + case PCLZIP_CB_PRE_DELETE :
  1749 + case PCLZIP_CB_POST_DELETE :
  1750 + case PCLZIP_CB_PRE_LIST :
  1751 + case PCLZIP_CB_POST_LIST :
  1752 + */
  1753 + // ----- Check the number of parameters
  1754 + if (($i+1) >= $p_size) {
  1755 + // ----- Error log
  1756 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1757 +
  1758 + // ----- Return
  1759 + return PclZip::errorCode();
  1760 + }
  1761 +
  1762 + // ----- Get the value
  1763 + $v_function_name = $p_options_list[$i+1];
  1764 +
  1765 + // ----- Check that the value is a valid existing function
  1766 + if (!function_exists($v_function_name)) {
  1767 + // ----- Error log
  1768 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1769 +
  1770 + // ----- Return
  1771 + return PclZip::errorCode();
  1772 + }
  1773 +
  1774 + // ----- Set the attribute
  1775 + $v_result_list[$p_options_list[$i]] = $v_function_name;
  1776 + $i++;
  1777 + break;
  1778 +
  1779 + default :
  1780 + // ----- Error log
  1781 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  1782 + "Unknown parameter '"
  1783 + .$p_options_list[$i]."'");
  1784 +
  1785 + // ----- Return
  1786 + return PclZip::errorCode();
  1787 + }
  1788 +
  1789 + // ----- Next options
  1790 + $i++;
  1791 + }
  1792 +
  1793 + // ----- Look for mandatory options
  1794 + if ($v_requested_options !== false) {
  1795 + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1796 + // ----- Look for mandatory option
  1797 + if ($v_requested_options[$key] == 'mandatory') {
  1798 + // ----- Look if present
  1799 + if (!isset($v_result_list[$key])) {
  1800 + // ----- Error log
  1801 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1802 +
  1803 + // ----- Return
  1804 + return PclZip::errorCode();
  1805 + }
  1806 + }
  1807 + }
  1808 + }
  1809 +
  1810 + // ----- Look for default values
  1811 + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
  1812 +
  1813 + }
  1814 +
  1815 + // ----- Return
  1816 + return $v_result;
  1817 + }
  1818 + // --------------------------------------------------------------------------------
  1819 +
  1820 + // --------------------------------------------------------------------------------
  1821 + // Function : privOptionDefaultThreshold()
  1822 + // Description :
  1823 + // Parameters :
  1824 + // Return Values :
  1825 + // --------------------------------------------------------------------------------
  1826 + function privOptionDefaultThreshold(&$p_options)
  1827 + {
  1828 + $v_result=1;
  1829 +
  1830 + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
  1831 + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
  1832 + return $v_result;
  1833 + }
  1834 +
  1835 + // ----- Get 'memory_limit' configuration value
  1836 + $v_memory_limit = ini_get('memory_limit');
  1837 + $v_memory_limit = trim($v_memory_limit);
  1838 + $last = strtolower(substr($v_memory_limit, -1));
  1839 +
  1840 + if($last == 'g')
  1841 + //$v_memory_limit = $v_memory_limit*1024*1024*1024;
  1842 + $v_memory_limit = $v_memory_limit*1073741824;
  1843 + if($last == 'm')
  1844 + //$v_memory_limit = $v_memory_limit*1024*1024;
  1845 + $v_memory_limit = $v_memory_limit*1048576;
  1846 + if($last == 'k')
  1847 + $v_memory_limit = $v_memory_limit*1024;
  1848 +
  1849 + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
  1850 +
  1851 +
  1852 + // ----- Sanity check : No threshold if value lower than 1M
  1853 + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
  1854 + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
  1855 + }
  1856 +
  1857 + // ----- Return
  1858 + return $v_result;
  1859 + }
  1860 + // --------------------------------------------------------------------------------
  1861 +
  1862 + // --------------------------------------------------------------------------------
  1863 + // Function : privFileDescrParseAtt()
  1864 + // Description :
  1865 + // Parameters :
  1866 + // Return Values :
  1867 + // 1 on success.
  1868 + // 0 on failure.
  1869 + // --------------------------------------------------------------------------------
  1870 + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
  1871 + {
  1872 + $v_result=1;
  1873 +
  1874 + // ----- For each file in the list check the attributes
  1875 + foreach ($p_file_list as $v_key => $v_value) {
  1876 +
  1877 + // ----- Check if the option is supported
  1878 + if (!isset($v_requested_options[$v_key])) {
  1879 + // ----- Error log
  1880 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
  1881 +
  1882 + // ----- Return
  1883 + return PclZip::errorCode();
  1884 + }
  1885 +
  1886 + // ----- Look for attribute
  1887 + switch ($v_key) {
  1888 + case PCLZIP_ATT_FILE_NAME :
  1889 + if (!is_string($v_value)) {
  1890 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1891 + return PclZip::errorCode();
  1892 + }
  1893 +
  1894 + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
  1895 +
  1896 + if ($p_filedescr['filename'] == '') {
  1897 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1898 + return PclZip::errorCode();
  1899 + }
  1900 +
  1901 + break;
  1902 +
  1903 + case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
  1904 + if (!is_string($v_value)) {
  1905 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1906 + return PclZip::errorCode();
  1907 + }
  1908 +
  1909 + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
  1910 +
  1911 + if ($p_filedescr['new_short_name'] == '') {
  1912 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1913 + return PclZip::errorCode();
  1914 + }
  1915 + break;
  1916 +
  1917 + case PCLZIP_ATT_FILE_NEW_FULL_NAME :
  1918 + if (!is_string($v_value)) {
  1919 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1920 + return PclZip::errorCode();
  1921 + }
  1922 +
  1923 + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
  1924 +
  1925 + if ($p_filedescr['new_full_name'] == '') {
  1926 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1927 + return PclZip::errorCode();
  1928 + }
  1929 + break;
  1930 +
  1931 + // ----- Look for options that takes a string
  1932 + case PCLZIP_ATT_FILE_COMMENT :
  1933 + if (!is_string($v_value)) {
  1934 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1935 + return PclZip::errorCode();
  1936 + }
  1937 +
  1938 + $p_filedescr['comment'] = $v_value;
  1939 + break;
  1940 +
  1941 + case PCLZIP_ATT_FILE_MTIME :
  1942 + if (!is_integer($v_value)) {
  1943 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1944 + return PclZip::errorCode();
  1945 + }
  1946 +
  1947 + $p_filedescr['mtime'] = $v_value;
  1948 + break;
  1949 +
  1950 + case PCLZIP_ATT_FILE_CONTENT :
  1951 + $p_filedescr['content'] = $v_value;
  1952 + break;
  1953 +
  1954 + default :
  1955 + // ----- Error log
  1956 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  1957 + "Unknown parameter '".$v_key."'");
  1958 +
  1959 + // ----- Return
  1960 + return PclZip::errorCode();
  1961 + }
  1962 +
  1963 + // ----- Look for mandatory options
  1964 + if ($v_requested_options !== false) {
  1965 + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1966 + // ----- Look for mandatory option
  1967 + if ($v_requested_options[$key] == 'mandatory') {
  1968 + // ----- Look if present
  1969 + if (!isset($p_file_list[$key])) {
  1970 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1971 + return PclZip::errorCode();
  1972 + }
  1973 + }
  1974 + }
  1975 + }
  1976 +
  1977 + // end foreach
  1978 + }
  1979 +
  1980 + // ----- Return
  1981 + return $v_result;
  1982 + }
  1983 + // --------------------------------------------------------------------------------
  1984 +
  1985 + // --------------------------------------------------------------------------------
  1986 + // Function : privFileDescrExpand()
  1987 + // Description :
  1988 + // This method look for each item of the list to see if its a file, a folder
  1989 + // or a string to be added as file. For any other type of files (link, other)
  1990 + // just ignore the item.
  1991 + // Then prepare the information that will be stored for that file.
  1992 + // When its a folder, expand the folder with all the files that are in that
  1993 + // folder (recursively).
  1994 + // Parameters :
  1995 + // Return Values :
  1996 + // 1 on success.
  1997 + // 0 on failure.
  1998 + // --------------------------------------------------------------------------------
  1999 + function privFileDescrExpand(&$p_filedescr_list, &$p_options)
  2000 + {
  2001 + $v_result=1;
  2002 +
  2003 + // ----- Create a result list
  2004 + $v_result_list = array();
  2005 +
  2006 + // ----- Look each entry
  2007 + for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
  2008 +
  2009 + // ----- Get filedescr
  2010 + $v_descr = $p_filedescr_list[$i];
  2011 +
  2012 + // ----- Reduce the filename
  2013 + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
  2014 + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
  2015 +
  2016 + // ----- Look for real file or folder
  2017 + if (file_exists($v_descr['filename'])) {
  2018 + if (@is_file($v_descr['filename'])) {
  2019 + $v_descr['type'] = 'file';
  2020 + }
  2021 + else if (@is_dir($v_descr['filename'])) {
  2022 + $v_descr['type'] = 'folder';
  2023 + }
  2024 + else if (@is_link($v_descr['filename'])) {
  2025 + // skip
  2026 + continue;
  2027 + }
  2028 + else {
  2029 + // skip
  2030 + continue;
  2031 + }
  2032 + }
  2033 +
  2034 + // ----- Look for string added as file
  2035 + else if (isset($v_descr['content'])) {
  2036 + $v_descr['type'] = 'virtual_file';
  2037 + }
  2038 +
  2039 + // ----- Missing file
  2040 + else {
  2041 + // ----- Error log
  2042 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
  2043 +
  2044 + // ----- Return
  2045 + return PclZip::errorCode();
  2046 + }
  2047 +
  2048 + // ----- Calculate the stored filename
  2049 + $this->privCalculateStoredFilename($v_descr, $p_options);
  2050 +
  2051 + // ----- Add the descriptor in result list
  2052 + $v_result_list[sizeof($v_result_list)] = $v_descr;
  2053 +
  2054 + // ----- Look for folder
  2055 + if ($v_descr['type'] == 'folder') {
  2056 + // ----- List of items in folder
  2057 + $v_dirlist_descr = array();
  2058 + $v_dirlist_nb = 0;
  2059 + if ($v_folder_handler = @opendir($v_descr['filename'])) {
  2060 + while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
  2061 +
  2062 + // ----- Skip '.' and '..'
  2063 + if (($v_item_handler == '.') || ($v_item_handler == '..')) {
  2064 + continue;
  2065 + }
  2066 +
  2067 + // ----- Compose the full filename
  2068 + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
  2069 +
  2070 + // ----- Look for different stored filename
  2071 + // Because the name of the folder was changed, the name of the
  2072 + // files/sub-folders also change
  2073 + if (($v_descr['stored_filename'] != $v_descr['filename'])
  2074 + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
  2075 + if ($v_descr['stored_filename'] != '') {
  2076 + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
  2077 + }
  2078 + else {
  2079 + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
  2080 + }
  2081 + }
  2082 +
  2083 + $v_dirlist_nb++;
  2084 + }
  2085 +
  2086 + @closedir($v_folder_handler);
  2087 + }
  2088 + else {
  2089 + // TBC : unable to open folder in read mode
  2090 + }
  2091 +
  2092 + // ----- Expand each element of the list
  2093 + if ($v_dirlist_nb != 0) {
  2094 + // ----- Expand
  2095 + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
  2096 + return $v_result;
  2097 + }
  2098 +
  2099 + // ----- Concat the resulting list
  2100 + $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
  2101 + }
  2102 + else {
  2103 + }
  2104 +
  2105 + // ----- Free local array
  2106 + unset($v_dirlist_descr);
  2107 + }
  2108 + }
  2109 +
  2110 + // ----- Get the result list
  2111 + $p_filedescr_list = $v_result_list;
  2112 +
  2113 + // ----- Return
  2114 + return $v_result;
  2115 + }
  2116 + // --------------------------------------------------------------------------------
  2117 +
  2118 + // --------------------------------------------------------------------------------
  2119 + // Function : privCreate()
  2120 + // Description :
  2121 + // Parameters :
  2122 + // Return Values :
  2123 + // --------------------------------------------------------------------------------
  2124 + function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
  2125 + {
  2126 + $v_result=1;
  2127 + $v_list_detail = array();
  2128 +
  2129 + // ----- Magic quotes trick
  2130 + $this->privDisableMagicQuotes();
  2131 +
  2132 + // ----- Open the file in write mode
  2133 + if (($v_result = $this->privOpenFd('wb')) != 1)
  2134 + {
  2135 + // ----- Return
  2136 + return $v_result;
  2137 + }
  2138 +
  2139 + // ----- Add the list of files
  2140 + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
  2141 +
  2142 + // ----- Close
  2143 + $this->privCloseFd();
  2144 +
  2145 + // ----- Magic quotes trick
  2146 + $this->privSwapBackMagicQuotes();
  2147 +
  2148 + // ----- Return
  2149 + return $v_result;
  2150 + }
  2151 + // --------------------------------------------------------------------------------
  2152 +
  2153 + // --------------------------------------------------------------------------------
  2154 + // Function : privAdd()
  2155 + // Description :
  2156 + // Parameters :
  2157 + // Return Values :
  2158 + // --------------------------------------------------------------------------------
  2159 + function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
  2160 + {
  2161 + $v_result=1;
  2162 + $v_list_detail = array();
  2163 +
  2164 + // ----- Look if the archive exists or is empty
  2165 + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
  2166 + {
  2167 +
  2168 + // ----- Do a create
  2169 + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
  2170 +
  2171 + // ----- Return
  2172 + return $v_result;
  2173 + }
  2174 + // ----- Magic quotes trick
  2175 + $this->privDisableMagicQuotes();
  2176 +
  2177 + // ----- Open the zip file
  2178 + if (($v_result=$this->privOpenFd('rb')) != 1)
  2179 + {
  2180 + // ----- Magic quotes trick
  2181 + $this->privSwapBackMagicQuotes();
  2182 +
  2183 + // ----- Return
  2184 + return $v_result;
  2185 + }
  2186 +
  2187 + // ----- Read the central directory informations
  2188 + $v_central_dir = array();
  2189 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  2190 + {
  2191 + $this->privCloseFd();
  2192 + $this->privSwapBackMagicQuotes();
  2193 + return $v_result;
  2194 + }
  2195 +
  2196 + // ----- Go to beginning of File
  2197 + @rewind($this->zip_fd);
  2198 +
  2199 + // ----- Creates a temporay file
  2200 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  2201 +
  2202 + // ----- Open the temporary file in write mode
  2203 + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  2204 + {
  2205 + $this->privCloseFd();
  2206 + $this->privSwapBackMagicQuotes();
  2207 +
  2208 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  2209 +
  2210 + // ----- Return
  2211 + return PclZip::errorCode();
  2212 + }
  2213 +
  2214 + // ----- Copy the files from the archive to the temporary file
  2215 + // TBC : Here I should better append the file and go back to erase the central dir
  2216 + $v_size = $v_central_dir['offset'];
  2217 + while ($v_size != 0)
  2218 + {
  2219 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2220 + $v_buffer = fread($this->zip_fd, $v_read_size);
  2221 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  2222 + $v_size -= $v_read_size;
  2223 + }
  2224 +
  2225 + // ----- Swap the file descriptor
  2226 + // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  2227 + // the following methods on the temporary fil and not the real archive
  2228 + $v_swap = $this->zip_fd;
  2229 + $this->zip_fd = $v_zip_temp_fd;
  2230 + $v_zip_temp_fd = $v_swap;
  2231 +
  2232 + // ----- Add the files
  2233 + $v_header_list = array();
  2234 + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
  2235 + {
  2236 + fclose($v_zip_temp_fd);
  2237 + $this->privCloseFd();
  2238 + @unlink($v_zip_temp_name);
  2239 + $this->privSwapBackMagicQuotes();
  2240 +
  2241 + // ----- Return
  2242 + return $v_result;
  2243 + }
  2244 +
  2245 + // ----- Store the offset of the central dir
  2246 + $v_offset = @ftell($this->zip_fd);
  2247 +
  2248 + // ----- Copy the block of file headers from the old archive
  2249 + $v_size = $v_central_dir['size'];
  2250 + while ($v_size != 0)
  2251 + {
  2252 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2253 + $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
  2254 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  2255 + $v_size -= $v_read_size;
  2256 + }
  2257 +
  2258 + // ----- Create the Central Dir files header
  2259 + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
  2260 + {
  2261 + // ----- Create the file header
  2262 + if ($v_header_list[$i]['status'] == 'ok') {
  2263 + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  2264 + fclose($v_zip_temp_fd);
  2265 + $this->privCloseFd();
  2266 + @unlink($v_zip_temp_name);
  2267 + $this->privSwapBackMagicQuotes();
  2268 +
  2269 + // ----- Return
  2270 + return $v_result;
  2271 + }
  2272 + $v_count++;
  2273 + }
  2274 +
  2275 + // ----- Transform the header to a 'usable' info
  2276 + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  2277 + }
  2278 +
  2279 + // ----- Zip file comment
  2280 + $v_comment = $v_central_dir['comment'];
  2281 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  2282 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  2283 + }
  2284 + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
  2285 + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
  2286 + }
  2287 + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
  2288 + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
  2289 + }
  2290 +
  2291 + // ----- Calculate the size of the central header
  2292 + $v_size = @ftell($this->zip_fd)-$v_offset;
  2293 +
  2294 + // ----- Create the central dir footer
  2295 + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
  2296 + {
  2297 + // ----- Reset the file list
  2298 + unset($v_header_list);
  2299 + $this->privSwapBackMagicQuotes();
  2300 +
  2301 + // ----- Return
  2302 + return $v_result;
  2303 + }
  2304 +
  2305 + // ----- Swap back the file descriptor
  2306 + $v_swap = $this->zip_fd;
  2307 + $this->zip_fd = $v_zip_temp_fd;
  2308 + $v_zip_temp_fd = $v_swap;
  2309 +
  2310 + // ----- Close
  2311 + $this->privCloseFd();
  2312 +
  2313 + // ----- Close the temporary file
  2314 + @fclose($v_zip_temp_fd);
  2315 +
  2316 + // ----- Magic quotes trick
  2317 + $this->privSwapBackMagicQuotes();
  2318 +
  2319 + // ----- Delete the zip file
  2320 + // TBC : I should test the result ...
  2321 + @unlink($this->zipname);
  2322 +
  2323 + // ----- Rename the temporary file
  2324 + // TBC : I should test the result ...
  2325 + //@rename($v_zip_temp_name, $this->zipname);
  2326 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  2327 +
  2328 + // ----- Return
  2329 + return $v_result;
  2330 + }
  2331 + // --------------------------------------------------------------------------------
  2332 +
  2333 + // --------------------------------------------------------------------------------
  2334 + // Function : privOpenFd()
  2335 + // Description :
  2336 + // Parameters :
  2337 + // --------------------------------------------------------------------------------
  2338 + function privOpenFd($p_mode)
  2339 + {
  2340 + $v_result=1;
  2341 +
  2342 + // ----- Look if already open
  2343 + if ($this->zip_fd != 0)
  2344 + {
  2345 + // ----- Error log
  2346 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
  2347 +
  2348 + // ----- Return
  2349 + return PclZip::errorCode();
  2350 + }
  2351 +
  2352 + // ----- Open the zip file
  2353 + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
  2354 + {
  2355 + // ----- Error log
  2356 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
  2357 +
  2358 + // ----- Return
  2359 + return PclZip::errorCode();
  2360 + }
  2361 +
  2362 + // ----- Return
  2363 + return $v_result;
  2364 + }
  2365 + // --------------------------------------------------------------------------------
  2366 +
  2367 + // --------------------------------------------------------------------------------
  2368 + // Function : privCloseFd()
  2369 + // Description :
  2370 + // Parameters :
  2371 + // --------------------------------------------------------------------------------
  2372 + function privCloseFd()
  2373 + {
  2374 + $v_result=1;
  2375 +
  2376 + if ($this->zip_fd != 0)
  2377 + @fclose($this->zip_fd);
  2378 + $this->zip_fd = 0;
  2379 +
  2380 + // ----- Return
  2381 + return $v_result;
  2382 + }
  2383 + // --------------------------------------------------------------------------------
  2384 +
  2385 + // --------------------------------------------------------------------------------
  2386 + // Function : privAddList()
  2387 + // Description :
  2388 + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  2389 + // different from the real path of the file. This is usefull if you want to have PclTar
  2390 + // running in any directory, and memorize relative path from an other directory.
  2391 + // Parameters :
  2392 + // $p_list : An array containing the file or directory names to add in the tar
  2393 + // $p_result_list : list of added files with their properties (specially the status field)
  2394 + // $p_add_dir : Path to add in the filename path archived
  2395 + // $p_remove_dir : Path to remove in the filename path archived
  2396 + // Return Values :
  2397 + // --------------------------------------------------------------------------------
  2398 +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  2399 + function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
  2400 + {
  2401 + $v_result=1;
  2402 +
  2403 + // ----- Add the files
  2404 + $v_header_list = array();
  2405 + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
  2406 + {
  2407 + // ----- Return
  2408 + return $v_result;
  2409 + }
  2410 +
  2411 + // ----- Store the offset of the central dir
  2412 + $v_offset = @ftell($this->zip_fd);
  2413 +
  2414 + // ----- Create the Central Dir files header
  2415 + for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
  2416 + {
  2417 + // ----- Create the file header
  2418 + if ($v_header_list[$i]['status'] == 'ok') {
  2419 + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  2420 + // ----- Return
  2421 + return $v_result;
  2422 + }
  2423 + $v_count++;
  2424 + }
  2425 +
  2426 + // ----- Transform the header to a 'usable' info
  2427 + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  2428 + }
  2429 +
  2430 + // ----- Zip file comment
  2431 + $v_comment = '';
  2432 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  2433 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  2434 + }
  2435 +
  2436 + // ----- Calculate the size of the central header
  2437 + $v_size = @ftell($this->zip_fd)-$v_offset;
  2438 +
  2439 + // ----- Create the central dir footer
  2440 + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
  2441 + {
  2442 + // ----- Reset the file list
  2443 + unset($v_header_list);
  2444 +
  2445 + // ----- Return
  2446 + return $v_result;
  2447 + }
  2448 +
  2449 + // ----- Return
  2450 + return $v_result;
  2451 + }
  2452 + // --------------------------------------------------------------------------------
  2453 +
  2454 + // --------------------------------------------------------------------------------
  2455 + // Function : privAddFileList()
  2456 + // Description :
  2457 + // Parameters :
  2458 + // $p_filedescr_list : An array containing the file description
  2459 + // or directory names to add in the zip
  2460 + // $p_result_list : list of added files with their properties (specially the status field)
  2461 + // Return Values :
  2462 + // --------------------------------------------------------------------------------
  2463 + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
  2464 + {
  2465 + $v_result=1;
  2466 + $v_header = array();
  2467 +
  2468 + // ----- Recuperate the current number of elt in list
  2469 + $v_nb = sizeof($p_result_list);
  2470 +
  2471 + // ----- Loop on the files
  2472 + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
  2473 + // ----- Format the filename
  2474 + $p_filedescr_list[$j]['filename']
  2475 + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
  2476 +
  2477 +
  2478 + // ----- Skip empty file names
  2479 + // TBC : Can this be possible ? not checked in DescrParseAtt ?
  2480 + if ($p_filedescr_list[$j]['filename'] == "") {
  2481 + continue;
  2482 + }
  2483 +
  2484 + // ----- Check the filename
  2485 + if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
  2486 + && (!file_exists($p_filedescr_list[$j]['filename']))) {
  2487 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
  2488 + return PclZip::errorCode();
  2489 + }
  2490 +
  2491 + // ----- Look if it is a file or a dir with no all path remove option
  2492 + // or a dir with all its path removed
  2493 +// if ( (is_file($p_filedescr_list[$j]['filename']))
  2494 +// || ( is_dir($p_filedescr_list[$j]['filename'])
  2495 + if ( ($p_filedescr_list[$j]['type'] == 'file')
  2496 + || ($p_filedescr_list[$j]['type'] == 'virtual_file')
  2497 + || ( ($p_filedescr_list[$j]['type'] == 'folder')
  2498 + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
  2499 + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
  2500 + ) {
  2501 +
  2502 + // ----- Add the file
  2503 + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
  2504 + $p_options);
  2505 + if ($v_result != 1) {
  2506 + return $v_result;
  2507 + }
  2508 +
  2509 + // ----- Store the file infos
  2510 + $p_result_list[$v_nb++] = $v_header;
  2511 + }
  2512 + }
  2513 +
  2514 + // ----- Return
  2515 + return $v_result;
  2516 + }
  2517 + // --------------------------------------------------------------------------------
  2518 +
  2519 + // --------------------------------------------------------------------------------
  2520 + // Function : privAddFile()
  2521 + // Description :
  2522 + // Parameters :
  2523 + // Return Values :
  2524 + // --------------------------------------------------------------------------------
  2525 + function privAddFile($p_filedescr, &$p_header, &$p_options)
  2526 + {
  2527 + $v_result=1;
  2528 +
  2529 + // ----- Working variable
  2530 + $p_filename = $p_filedescr['filename'];
  2531 +
  2532 + // TBC : Already done in the fileAtt check ... ?
  2533 + if ($p_filename == "") {
  2534 + // ----- Error log
  2535 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
  2536 +
  2537 + // ----- Return
  2538 + return PclZip::errorCode();
  2539 + }
  2540 +
  2541 + // ----- Look for a stored different filename
  2542 + /* TBC : Removed
  2543 + if (isset($p_filedescr['stored_filename'])) {
  2544 + $v_stored_filename = $p_filedescr['stored_filename'];
  2545 + }
  2546 + else {
  2547 + $v_stored_filename = $p_filedescr['stored_filename'];
  2548 + }
  2549 + */
  2550 +
  2551 + // ----- Set the file properties
  2552 + clearstatcache();
  2553 + $p_header['version'] = 20;
  2554 + $p_header['version_extracted'] = 10;
  2555 + $p_header['flag'] = 0;
  2556 + $p_header['compression'] = 0;
  2557 + $p_header['crc'] = 0;
  2558 + $p_header['compressed_size'] = 0;
  2559 + $p_header['filename_len'] = strlen($p_filename);
  2560 + $p_header['extra_len'] = 0;
  2561 + $p_header['disk'] = 0;
  2562 + $p_header['internal'] = 0;
  2563 + $p_header['offset'] = 0;
  2564 + $p_header['filename'] = $p_filename;
  2565 +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
  2566 + $p_header['stored_filename'] = $p_filedescr['stored_filename'];
  2567 + $p_header['extra'] = '';
  2568 + $p_header['status'] = 'ok';
  2569 + $p_header['index'] = -1;
  2570 +
  2571 + // ----- Look for regular file
  2572 + if ($p_filedescr['type']=='file') {
  2573 + $p_header['external'] = 0x00000000;
  2574 + $p_header['size'] = filesize($p_filename);
  2575 + }
  2576 +
  2577 + // ----- Look for regular folder
  2578 + else if ($p_filedescr['type']=='folder') {
  2579 + $p_header['external'] = 0x00000010;
  2580 + $p_header['mtime'] = filemtime($p_filename);
  2581 + $p_header['size'] = filesize($p_filename);
  2582 + }
  2583 +
  2584 + // ----- Look for virtual file
  2585 + else if ($p_filedescr['type'] == 'virtual_file') {
  2586 + $p_header['external'] = 0x00000000;
  2587 + $p_header['size'] = strlen($p_filedescr['content']);
  2588 + }
  2589 +
  2590 +
  2591 + // ----- Look for filetime
  2592 + if (isset($p_filedescr['mtime'])) {
  2593 + $p_header['mtime'] = $p_filedescr['mtime'];
  2594 + }
  2595 + else if ($p_filedescr['type'] == 'virtual_file') {
  2596 + $p_header['mtime'] = time();
  2597 + }
  2598 + else {
  2599 + $p_header['mtime'] = filemtime($p_filename);
  2600 + }
  2601 +
  2602 + // ------ Look for file comment
  2603 + if (isset($p_filedescr['comment'])) {
  2604 + $p_header['comment_len'] = strlen($p_filedescr['comment']);
  2605 + $p_header['comment'] = $p_filedescr['comment'];
  2606 + }
  2607 + else {
  2608 + $p_header['comment_len'] = 0;
  2609 + $p_header['comment'] = '';
  2610 + }
  2611 +
  2612 + // ----- Look for pre-add callback
  2613 + if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
  2614 +
  2615 + // ----- Generate a local information
  2616 + $v_local_header = array();
  2617 + $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2618 +
  2619 + // ----- Call the callback
  2620 + // Here I do not use call_user_func() because I need to send a reference to the
  2621 + // header.
  2622 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
  2623 + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
  2624 + if ($v_result == 0) {
  2625 + // ----- Change the file status
  2626 + $p_header['status'] = "skipped";
  2627 + $v_result = 1;
  2628 + }
  2629 +
  2630 + // ----- Update the informations
  2631 + // Only some fields can be modified
  2632 + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
  2633 + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
  2634 + }
  2635 + }
  2636 +
  2637 + // ----- Look for empty stored filename
  2638 + if ($p_header['stored_filename'] == "") {
  2639 + $p_header['status'] = "filtered";
  2640 + }
  2641 +
  2642 + // ----- Check the path length
  2643 + if (strlen($p_header['stored_filename']) > 0xFF) {
  2644 + $p_header['status'] = 'filename_too_long';
  2645 + }
  2646 +
  2647 + // ----- Look if no error, or file not skipped
  2648 + if ($p_header['status'] == 'ok') {
  2649 +
  2650 + // ----- Look for a file
  2651 + if ($p_filedescr['type'] == 'file') {
  2652 + // ----- Look for using temporary file to zip
  2653 + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
  2654 + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
  2655 + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
  2656 + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
  2657 + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
  2658 + if ($v_result < PCLZIP_ERR_NO_ERROR) {
  2659 + return $v_result;
  2660 + }
  2661 + }
  2662 +
  2663 + // ----- Use "in memory" zip algo
  2664 + else {
  2665 +
  2666 + // ----- Open the source file
  2667 + if (($v_file = @fopen($p_filename, "rb")) == 0) {
  2668 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
  2669 + return PclZip::errorCode();
  2670 + }
  2671 +
  2672 + // ----- Read the file content
  2673 + $v_content = @fread($v_file, $p_header['size']);
  2674 +
  2675 + // ----- Close the file
  2676 + @fclose($v_file);
  2677 +
  2678 + // ----- Calculate the CRC
  2679 + $p_header['crc'] = @crc32($v_content);
  2680 +
  2681 + // ----- Look for no compression
  2682 + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
  2683 + // ----- Set header parameters
  2684 + $p_header['compressed_size'] = $p_header['size'];
  2685 + $p_header['compression'] = 0;
  2686 + }
  2687 +
  2688 + // ----- Look for normal compression
  2689 + else {
  2690 + // ----- Compress the content
  2691 + $v_content = @gzdeflate($v_content);
  2692 +
  2693 + // ----- Set header parameters
  2694 + $p_header['compressed_size'] = strlen($v_content);
  2695 + $p_header['compression'] = 8;
  2696 + }
  2697 +
  2698 + // ----- Call the header generation
  2699 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2700 + @fclose($v_file);
  2701 + return $v_result;
  2702 + }
  2703 +
  2704 + // ----- Write the compressed (or not) content
  2705 + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
  2706 +
  2707 + }
  2708 +
  2709 + }
  2710 +
  2711 + // ----- Look for a virtual file (a file from string)
  2712 + else if ($p_filedescr['type'] == 'virtual_file') {
  2713 +
  2714 + $v_content = $p_filedescr['content'];
  2715 +
  2716 + // ----- Calculate the CRC
  2717 + $p_header['crc'] = @crc32($v_content);
  2718 +
  2719 + // ----- Look for no compression
  2720 + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
  2721 + // ----- Set header parameters
  2722 + $p_header['compressed_size'] = $p_header['size'];
  2723 + $p_header['compression'] = 0;
  2724 + }
  2725 +
  2726 + // ----- Look for normal compression
  2727 + else {
  2728 + // ----- Compress the content
  2729 + $v_content = @gzdeflate($v_content);
  2730 +
  2731 + // ----- Set header parameters
  2732 + $p_header['compressed_size'] = strlen($v_content);
  2733 + $p_header['compression'] = 8;
  2734 + }
  2735 +
  2736 + // ----- Call the header generation
  2737 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2738 + @fclose($v_file);
  2739 + return $v_result;
  2740 + }
  2741 +
  2742 + // ----- Write the compressed (or not) content
  2743 + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
  2744 + }
  2745 +
  2746 + // ----- Look for a directory
  2747 + else if ($p_filedescr['type'] == 'folder') {
  2748 + // ----- Look for directory last '/'
  2749 + if (@substr($p_header['stored_filename'], -1) != '/') {
  2750 + $p_header['stored_filename'] .= '/';
  2751 + }
  2752 +
  2753 + // ----- Set the file properties
  2754 + $p_header['size'] = 0;
  2755 + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
  2756 + $p_header['external'] = 0x00000010; // Value for a folder : to be checked
  2757 +
  2758 + // ----- Call the header generation
  2759 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
  2760 + {
  2761 + return $v_result;
  2762 + }
  2763 + }
  2764 + }
  2765 +
  2766 + // ----- Look for post-add callback
  2767 + if (isset($p_options[PCLZIP_CB_POST_ADD])) {
  2768 +
  2769 + // ----- Generate a local information
  2770 + $v_local_header = array();
  2771 + $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2772 +
  2773 + // ----- Call the callback
  2774 + // Here I do not use call_user_func() because I need to send a reference to the
  2775 + // header.
  2776 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
  2777 + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
  2778 + if ($v_result == 0) {
  2779 + // ----- Ignored
  2780 + $v_result = 1;
  2781 + }
  2782 +
  2783 + // ----- Update the informations
  2784 + // Nothing can be modified
  2785 + }
  2786 +
  2787 + // ----- Return
  2788 + return $v_result;
  2789 + }
  2790 + // --------------------------------------------------------------------------------
  2791 +
  2792 + // --------------------------------------------------------------------------------
  2793 + // Function : privAddFileUsingTempFile()
  2794 + // Description :
  2795 + // Parameters :
  2796 + // Return Values :
  2797 + // --------------------------------------------------------------------------------
  2798 + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
  2799 + {
  2800 + $v_result=PCLZIP_ERR_NO_ERROR;
  2801 +
  2802 + // ----- Working variable
  2803 + $p_filename = $p_filedescr['filename'];
  2804 +
  2805 +
  2806 + // ----- Open the source file
  2807 + if (($v_file = @fopen($p_filename, "rb")) == 0) {
  2808 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
  2809 + return PclZip::errorCode();
  2810 + }
  2811 +
  2812 + // ----- Creates a compressed temporary file
  2813 + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
  2814 + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
  2815 + fclose($v_file);
  2816 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
  2817 + return PclZip::errorCode();
  2818 + }
  2819 +
  2820 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  2821 + $v_size = filesize($p_filename);
  2822 + while ($v_size != 0) {
  2823 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2824 + $v_buffer = @fread($v_file, $v_read_size);
  2825 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  2826 + @gzputs($v_file_compressed, $v_buffer, $v_read_size);
  2827 + $v_size -= $v_read_size;
  2828 + }
  2829 +
  2830 + // ----- Close the file
  2831 + @fclose($v_file);
  2832 + @gzclose($v_file_compressed);
  2833 +
  2834 + // ----- Check the minimum file size
  2835 + if (filesize($v_gzip_temp_name) < 18) {
  2836 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
  2837 + return PclZip::errorCode();
  2838 + }
  2839 +
  2840 + // ----- Extract the compressed attributes
  2841 + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
  2842 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
  2843 + return PclZip::errorCode();
  2844 + }
  2845 +
  2846 + // ----- Read the gzip file header
  2847 + $v_binary_data = @fread($v_file_compressed, 10);
  2848 + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
  2849 +
  2850 + // ----- Check some parameters
  2851 + $v_data_header['os'] = bin2hex($v_data_header['os']);
  2852 +
  2853 + // ----- Read the gzip file footer
  2854 + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
  2855 + $v_binary_data = @fread($v_file_compressed, 8);
  2856 + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
  2857 +
  2858 + // ----- Set the attributes
  2859 + $p_header['compression'] = ord($v_data_header['cm']);
  2860 + //$p_header['mtime'] = $v_data_header['mtime'];
  2861 + $p_header['crc'] = $v_data_footer['crc'];
  2862 + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
  2863 +
  2864 + // ----- Close the file
  2865 + @fclose($v_file_compressed);
  2866 +
  2867 + // ----- Call the header generation
  2868 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2869 + return $v_result;
  2870 + }
  2871 +
  2872 + // ----- Add the compressed data
  2873 + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
  2874 + {
  2875 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
  2876 + return PclZip::errorCode();
  2877 + }
  2878 +
  2879 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  2880 + fseek($v_file_compressed, 10);
  2881 + $v_size = $p_header['compressed_size'];
  2882 + while ($v_size != 0)
  2883 + {
  2884 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2885 + $v_buffer = @fread($v_file_compressed, $v_read_size);
  2886 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  2887 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  2888 + $v_size -= $v_read_size;
  2889 + }
  2890 +
  2891 + // ----- Close the file
  2892 + @fclose($v_file_compressed);
  2893 +
  2894 + // ----- Unlink the temporary file
  2895 + @unlink($v_gzip_temp_name);
  2896 +
  2897 + // ----- Return
  2898 + return $v_result;
  2899 + }
  2900 + // --------------------------------------------------------------------------------
  2901 +
  2902 + // --------------------------------------------------------------------------------
  2903 + // Function : privCalculateStoredFilename()
  2904 + // Description :
  2905 + // Based on file descriptor properties and global options, this method
  2906 + // calculate the filename that will be stored in the archive.
  2907 + // Parameters :
  2908 + // Return Values :
  2909 + // --------------------------------------------------------------------------------
  2910 + function privCalculateStoredFilename(&$p_filedescr, &$p_options)
  2911 + {
  2912 + $v_result=1;
  2913 +
  2914 + // ----- Working variables
  2915 + $p_filename = $p_filedescr['filename'];
  2916 + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
  2917 + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
  2918 + }
  2919 + else {
  2920 + $p_add_dir = '';
  2921 + }
  2922 + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
  2923 + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
  2924 + }
  2925 + else {
  2926 + $p_remove_dir = '';
  2927 + }
  2928 + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  2929 + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  2930 + }
  2931 + else {
  2932 + $p_remove_all_dir = 0;
  2933 + }
  2934 +
  2935 +
  2936 + // ----- Look for full name change
  2937 + if (isset($p_filedescr['new_full_name'])) {
  2938 + // ----- Remove drive letter if any
  2939 + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
  2940 + }
  2941 +
  2942 + // ----- Look for path and/or short name change
  2943 + else {
  2944 +
  2945 + // ----- Look for short name change
  2946 + // Its when we cahnge just the filename but not the path
  2947 + if (isset($p_filedescr['new_short_name'])) {
  2948 + $v_path_info = pathinfo($p_filename);
  2949 + $v_dir = '';
  2950 + if ($v_path_info['dirname'] != '') {
  2951 + $v_dir = $v_path_info['dirname'].'/';
  2952 + }
  2953 + $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
  2954 + }
  2955 + else {
  2956 + // ----- Calculate the stored filename
  2957 + $v_stored_filename = $p_filename;
  2958 + }
  2959 +
  2960 + // ----- Look for all path to remove
  2961 + if ($p_remove_all_dir) {
  2962 + $v_stored_filename = basename($p_filename);
  2963 + }
  2964 + // ----- Look for partial path remove
  2965 + else if ($p_remove_dir != "") {
  2966 + if (substr($p_remove_dir, -1) != '/')
  2967 + $p_remove_dir .= "/";
  2968 +
  2969 + if ( (substr($p_filename, 0, 2) == "./")
  2970 + || (substr($p_remove_dir, 0, 2) == "./")) {
  2971 +
  2972 + if ( (substr($p_filename, 0, 2) == "./")
  2973 + && (substr($p_remove_dir, 0, 2) != "./")) {
  2974 + $p_remove_dir = "./".$p_remove_dir;
  2975 + }
  2976 + if ( (substr($p_filename, 0, 2) != "./")
  2977 + && (substr($p_remove_dir, 0, 2) == "./")) {
  2978 + $p_remove_dir = substr($p_remove_dir, 2);
  2979 + }
  2980 + }
  2981 +
  2982 + $v_compare = PclZipUtilPathInclusion($p_remove_dir,
  2983 + $v_stored_filename);
  2984 + if ($v_compare > 0) {
  2985 + if ($v_compare == 2) {
  2986 + $v_stored_filename = "";
  2987 + }
  2988 + else {
  2989 + $v_stored_filename = substr($v_stored_filename,
  2990 + strlen($p_remove_dir));
  2991 + }
  2992 + }
  2993 + }
  2994 +
  2995 + // ----- Remove drive letter if any
  2996 + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
  2997 +
  2998 + // ----- Look for path to add
  2999 + if ($p_add_dir != "") {
  3000 + if (substr($p_add_dir, -1) == "/")
  3001 + $v_stored_filename = $p_add_dir.$v_stored_filename;
  3002 + else
  3003 + $v_stored_filename = $p_add_dir."/".$v_stored_filename;
  3004 + }
  3005 + }
  3006 +
  3007 + // ----- Filename (reduce the path of stored name)
  3008 + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
  3009 + $p_filedescr['stored_filename'] = $v_stored_filename;
  3010 +
  3011 + // ----- Return
  3012 + return $v_result;
  3013 + }
  3014 + // --------------------------------------------------------------------------------
  3015 +
  3016 + // --------------------------------------------------------------------------------
  3017 + // Function : privWriteFileHeader()
  3018 + // Description :
  3019 + // Parameters :
  3020 + // Return Values :
  3021 + // --------------------------------------------------------------------------------
  3022 + function privWriteFileHeader(&$p_header)
  3023 + {
  3024 + $v_result=1;
  3025 +
  3026 + // ----- Store the offset position of the file
  3027 + $p_header['offset'] = ftell($this->zip_fd);
  3028 +
  3029 + // ----- Transform UNIX mtime to DOS format mdate/mtime
  3030 + $v_date = getdate($p_header['mtime']);
  3031 + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  3032 + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  3033 +
  3034 + // ----- Packed data
  3035 + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
  3036 + $p_header['version_extracted'], $p_header['flag'],
  3037 + $p_header['compression'], $v_mtime, $v_mdate,
  3038 + $p_header['crc'], $p_header['compressed_size'],
  3039 + $p_header['size'],
  3040 + strlen($p_header['stored_filename']),
  3041 + $p_header['extra_len']);
  3042 +
  3043 + // ----- Write the first 148 bytes of the header in the archive
  3044 + fputs($this->zip_fd, $v_binary_data, 30);
  3045 +
  3046 + // ----- Write the variable fields
  3047 + if (strlen($p_header['stored_filename']) != 0)
  3048 + {
  3049 + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  3050 + }
  3051 + if ($p_header['extra_len'] != 0)
  3052 + {
  3053 + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  3054 + }
  3055 +
  3056 + // ----- Return
  3057 + return $v_result;
  3058 + }
  3059 + // --------------------------------------------------------------------------------
  3060 +
  3061 + // --------------------------------------------------------------------------------
  3062 + // Function : privWriteCentralFileHeader()
  3063 + // Description :
  3064 + // Parameters :
  3065 + // Return Values :
  3066 + // --------------------------------------------------------------------------------
  3067 + function privWriteCentralFileHeader(&$p_header)
  3068 + {
  3069 + $v_result=1;
  3070 +
  3071 + // TBC
  3072 + //for(reset($p_header); $key = key($p_header); next($p_header)) {
  3073 + //}
  3074 +
  3075 + // ----- Transform UNIX mtime to DOS format mdate/mtime
  3076 + $v_date = getdate($p_header['mtime']);
  3077 + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  3078 + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  3079 +
  3080 +
  3081 + // ----- Packed data
  3082 + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
  3083 + $p_header['version'], $p_header['version_extracted'],
  3084 + $p_header['flag'], $p_header['compression'],
  3085 + $v_mtime, $v_mdate, $p_header['crc'],
  3086 + $p_header['compressed_size'], $p_header['size'],
  3087 + strlen($p_header['stored_filename']),
  3088 + $p_header['extra_len'], $p_header['comment_len'],
  3089 + $p_header['disk'], $p_header['internal'],
  3090 + $p_header['external'], $p_header['offset']);
  3091 +
  3092 + // ----- Write the 42 bytes of the header in the zip file
  3093 + fputs($this->zip_fd, $v_binary_data, 46);
  3094 +
  3095 + // ----- Write the variable fields
  3096 + if (strlen($p_header['stored_filename']) != 0)
  3097 + {
  3098 + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  3099 + }
  3100 + if ($p_header['extra_len'] != 0)
  3101 + {
  3102 + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  3103 + }
  3104 + if ($p_header['comment_len'] != 0)
  3105 + {
  3106 + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
  3107 + }
  3108 +
  3109 + // ----- Return
  3110 + return $v_result;
  3111 + }
  3112 + // --------------------------------------------------------------------------------
  3113 +
  3114 + // --------------------------------------------------------------------------------
  3115 + // Function : privWriteCentralHeader()
  3116 + // Description :
  3117 + // Parameters :
  3118 + // Return Values :
  3119 + // --------------------------------------------------------------------------------
  3120 + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
  3121 + {
  3122 + $v_result=1;
  3123 +
  3124 + // ----- Packed data
  3125 + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
  3126 + $p_nb_entries, $p_size,
  3127 + $p_offset, strlen($p_comment));
  3128 +
  3129 + // ----- Write the 22 bytes of the header in the zip file
  3130 + fputs($this->zip_fd, $v_binary_data, 22);
  3131 +
  3132 + // ----- Write the variable fields
  3133 + if (strlen($p_comment) != 0)
  3134 + {
  3135 + fputs($this->zip_fd, $p_comment, strlen($p_comment));
  3136 + }
  3137 +
  3138 + // ----- Return
  3139 + return $v_result;
  3140 + }
  3141 + // --------------------------------------------------------------------------------
  3142 +
  3143 + // --------------------------------------------------------------------------------
  3144 + // Function : privList()
  3145 + // Description :
  3146 + // Parameters :
  3147 + // Return Values :
  3148 + // --------------------------------------------------------------------------------
  3149 + function privList(&$p_list)
  3150 + {
  3151 + $v_result=1;
  3152 +
  3153 + // ----- Magic quotes trick
  3154 + $this->privDisableMagicQuotes();
  3155 +
  3156 + // ----- Open the zip file
  3157 + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  3158 + {
  3159 + // ----- Magic quotes trick
  3160 + $this->privSwapBackMagicQuotes();
  3161 +
  3162 + // ----- Error log
  3163 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  3164 +
  3165 + // ----- Return
  3166 + return PclZip::errorCode();
  3167 + }
  3168 +
  3169 + // ----- Read the central directory informations
  3170 + $v_central_dir = array();
  3171 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3172 + {
  3173 + $this->privSwapBackMagicQuotes();
  3174 + return $v_result;
  3175 + }
  3176 +
  3177 + // ----- Go to beginning of Central Dir
  3178 + @rewind($this->zip_fd);
  3179 + if (@fseek($this->zip_fd, $v_central_dir['offset']))
  3180 + {
  3181 + $this->privSwapBackMagicQuotes();
  3182 +
  3183 + // ----- Error log
  3184 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3185 +
  3186 + // ----- Return
  3187 + return PclZip::errorCode();
  3188 + }
  3189 +
  3190 + // ----- Read each entry
  3191 + for ($i=0; $i<$v_central_dir['entries']; $i++)
  3192 + {
  3193 + // ----- Read the file header
  3194 + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  3195 + {
  3196 + $this->privSwapBackMagicQuotes();
  3197 + return $v_result;
  3198 + }
  3199 + $v_header['index'] = $i;
  3200 +
  3201 + // ----- Get the only interesting attributes
  3202 + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
  3203 + unset($v_header);
  3204 + }
  3205 +
  3206 + // ----- Close the zip file
  3207 + $this->privCloseFd();
  3208 +
  3209 + // ----- Magic quotes trick
  3210 + $this->privSwapBackMagicQuotes();
  3211 +
  3212 + // ----- Return
  3213 + return $v_result;
  3214 + }
  3215 + // --------------------------------------------------------------------------------
  3216 +
  3217 + // --------------------------------------------------------------------------------
  3218 + // Function : privConvertHeader2FileInfo()
  3219 + // Description :
  3220 + // This function takes the file informations from the central directory
  3221 + // entries and extract the interesting parameters that will be given back.
  3222 + // The resulting file infos are set in the array $p_info
  3223 + // $p_info['filename'] : Filename with full path. Given by user (add),
  3224 + // extracted in the filesystem (extract).
  3225 + // $p_info['stored_filename'] : Stored filename in the archive.
  3226 + // $p_info['size'] = Size of the file.
  3227 + // $p_info['compressed_size'] = Compressed size of the file.
  3228 + // $p_info['mtime'] = Last modification date of the file.
  3229 + // $p_info['comment'] = Comment associated with the file.
  3230 + // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
  3231 + // $p_info['status'] = status of the action on the file.
  3232 + // $p_info['crc'] = CRC of the file content.
  3233 + // Parameters :
  3234 + // Return Values :
  3235 + // --------------------------------------------------------------------------------
  3236 + function privConvertHeader2FileInfo($p_header, &$p_info)
  3237 + {
  3238 + $v_result=1;
  3239 +
  3240 + // ----- Get the interesting attributes
  3241 + $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
  3242 + $p_info['filename'] = $v_temp_path;
  3243 + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
  3244 + $p_info['stored_filename'] = $v_temp_path;
  3245 + $p_info['size'] = $p_header['size'];
  3246 + $p_info['compressed_size'] = $p_header['compressed_size'];
  3247 + $p_info['mtime'] = $p_header['mtime'];
  3248 + $p_info['comment'] = $p_header['comment'];
  3249 + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
  3250 + $p_info['index'] = $p_header['index'];
  3251 + $p_info['status'] = $p_header['status'];
  3252 + $p_info['crc'] = $p_header['crc'];
  3253 +
  3254 + // ----- Return
  3255 + return $v_result;
  3256 + }
  3257 + // --------------------------------------------------------------------------------
  3258 +
  3259 + // --------------------------------------------------------------------------------
  3260 + // Function : privExtractByRule()
  3261 + // Description :
  3262 + // Extract a file or directory depending of rules (by index, by name, ...)
  3263 + // Parameters :
  3264 + // $p_file_list : An array where will be placed the properties of each
  3265 + // extracted file
  3266 + // $p_path : Path to add while writing the extracted files
  3267 + // $p_remove_path : Path to remove (from the file memorized path) while writing the
  3268 + // extracted files. If the path does not match the file path,
  3269 + // the file is extracted with its memorized path.
  3270 + // $p_remove_path does not apply to 'list' mode.
  3271 + // $p_path and $p_remove_path are commulative.
  3272 + // Return Values :
  3273 + // 1 on success,0 or less on error (see error code list)
  3274 + // --------------------------------------------------------------------------------
  3275 + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  3276 + {
  3277 + $v_result=1;
  3278 +
  3279 + // ----- Magic quotes trick
  3280 + $this->privDisableMagicQuotes();
  3281 +
  3282 + // ----- Check the path
  3283 + if ( ($p_path == "")
  3284 + || ( (substr($p_path, 0, 1) != "/")
  3285 + && (substr($p_path, 0, 3) != "../")
  3286 + && (substr($p_path,1,2)!=":/")))
  3287 + $p_path = "./".$p_path;
  3288 +
  3289 + // ----- Reduce the path last (and duplicated) '/'
  3290 + if (($p_path != "./") && ($p_path != "/"))
  3291 + {
  3292 + // ----- Look for the path end '/'
  3293 + while (substr($p_path, -1) == "/")
  3294 + {
  3295 + $p_path = substr($p_path, 0, strlen($p_path)-1);
  3296 + }
  3297 + }
  3298 +
  3299 + // ----- Look for path to remove format (should end by /)
  3300 + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  3301 + {
  3302 + $p_remove_path .= '/';
  3303 + }
  3304 + $p_remove_path_size = strlen($p_remove_path);
  3305 +
  3306 + // ----- Open the zip file
  3307 + if (($v_result = $this->privOpenFd('rb')) != 1)
  3308 + {
  3309 + $this->privSwapBackMagicQuotes();
  3310 + return $v_result;
  3311 + }
  3312 +
  3313 + // ----- Read the central directory informations
  3314 + $v_central_dir = array();
  3315 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3316 + {
  3317 + // ----- Close the zip file
  3318 + $this->privCloseFd();
  3319 + $this->privSwapBackMagicQuotes();
  3320 +
  3321 + return $v_result;
  3322 + }
  3323 +
  3324 + // ----- Start at beginning of Central Dir
  3325 + $v_pos_entry = $v_central_dir['offset'];
  3326 +
  3327 + // ----- Read each entry
  3328 + $j_start = 0;
  3329 + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  3330 + {
  3331 +
  3332 + // ----- Read next Central dir entry
  3333 + @rewind($this->zip_fd);
  3334 + if (@fseek($this->zip_fd, $v_pos_entry))
  3335 + {
  3336 + // ----- Close the zip file
  3337 + $this->privCloseFd();
  3338 + $this->privSwapBackMagicQuotes();
  3339 +
  3340 + // ----- Error log
  3341 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3342 +
  3343 + // ----- Return
  3344 + return PclZip::errorCode();
  3345 + }
  3346 +
  3347 + // ----- Read the file header
  3348 + $v_header = array();
  3349 + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  3350 + {
  3351 + // ----- Close the zip file
  3352 + $this->privCloseFd();
  3353 + $this->privSwapBackMagicQuotes();
  3354 +
  3355 + return $v_result;
  3356 + }
  3357 +
  3358 + // ----- Store the index
  3359 + $v_header['index'] = $i;
  3360 +
  3361 + // ----- Store the file position
  3362 + $v_pos_entry = ftell($this->zip_fd);
  3363 +
  3364 + // ----- Look for the specific extract rules
  3365 + $v_extract = false;
  3366 +
  3367 + // ----- Look for extract by name rule
  3368 + if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
  3369 + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  3370 +
  3371 + // ----- Look if the filename is in the list
  3372 + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
  3373 +
  3374 + // ----- Look for a directory
  3375 + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  3376 +
  3377 + // ----- Look if the directory is in the filename path
  3378 + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  3379 + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  3380 + $v_extract = true;
  3381 + }
  3382 + }
  3383 + // ----- Look for a filename
  3384 + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  3385 + $v_extract = true;
  3386 + }
  3387 + }
  3388 + }
  3389 +
  3390 + // ----- Look for extract by ereg rule
  3391 + // ereg() is deprecated with PHP 5.3
  3392 + /*
  3393 + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
  3394 + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  3395 +
  3396 + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
  3397 + $v_extract = true;
  3398 + }
  3399 + }
  3400 + */
  3401 +
  3402 + // ----- Look for extract by preg rule
  3403 + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
  3404 + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  3405 +
  3406 + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
  3407 + $v_extract = true;
  3408 + }
  3409 + }
  3410 +
  3411 + // ----- Look for extract by index rule
  3412 + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  3413 + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  3414 +
  3415 + // ----- Look if the index is in the list
  3416 + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
  3417 +
  3418 + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  3419 + $v_extract = true;
  3420 + }
  3421 + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  3422 + $j_start = $j+1;
  3423 + }
  3424 +
  3425 + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  3426 + break;
  3427 + }
  3428 + }
  3429 + }
  3430 +
  3431 + // ----- Look for no rule, which means extract all the archive
  3432 + else {
  3433 + $v_extract = true;
  3434 + }
  3435 +
  3436 + // ----- Check compression method
  3437 + if ( ($v_extract)
  3438 + && ( ($v_header['compression'] != 8)
  3439 + && ($v_header['compression'] != 0))) {
  3440 + $v_header['status'] = 'unsupported_compression';
  3441 +
  3442 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3443 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3444 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3445 +
  3446 + $this->privSwapBackMagicQuotes();
  3447 +
  3448 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
  3449 + "Filename '".$v_header['stored_filename']."' is "
  3450 + ."compressed by an unsupported compression "
  3451 + ."method (".$v_header['compression'].") ");
  3452 +
  3453 + return PclZip::errorCode();
  3454 + }
  3455 + }
  3456 +
  3457 + // ----- Check encrypted files
  3458 + if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
  3459 + $v_header['status'] = 'unsupported_encryption';
  3460 +
  3461 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3462 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3463 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3464 +
  3465 + $this->privSwapBackMagicQuotes();
  3466 +
  3467 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
  3468 + "Unsupported encryption for "
  3469 + ." filename '".$v_header['stored_filename']
  3470 + ."'");
  3471 +
  3472 + return PclZip::errorCode();
  3473 + }
  3474 + }
  3475 +
  3476 + // ----- Look for real extraction
  3477 + if (($v_extract) && ($v_header['status'] != 'ok')) {
  3478 + $v_result = $this->privConvertHeader2FileInfo($v_header,
  3479 + $p_file_list[$v_nb_extracted++]);
  3480 + if ($v_result != 1) {
  3481 + $this->privCloseFd();
  3482 + $this->privSwapBackMagicQuotes();
  3483 + return $v_result;
  3484 + }
  3485 +
  3486 + $v_extract = false;
  3487 + }
  3488 +
  3489 + // ----- Look for real extraction
  3490 + if ($v_extract)
  3491 + {
  3492 +
  3493 + // ----- Go to the file position
  3494 + @rewind($this->zip_fd);
  3495 + if (@fseek($this->zip_fd, $v_header['offset']))
  3496 + {
  3497 + // ----- Close the zip file
  3498 + $this->privCloseFd();
  3499 +
  3500 + $this->privSwapBackMagicQuotes();
  3501 +
  3502 + // ----- Error log
  3503 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3504 +
  3505 + // ----- Return
  3506 + return PclZip::errorCode();
  3507 + }
  3508 +
  3509 + // ----- Look for extraction as string
  3510 + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
  3511 +
  3512 + $v_string = '';
  3513 +
  3514 + // ----- Extracting the file
  3515 + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
  3516 + if ($v_result1 < 1) {
  3517 + $this->privCloseFd();
  3518 + $this->privSwapBackMagicQuotes();
  3519 + return $v_result1;
  3520 + }
  3521 +
  3522 + // ----- Get the only interesting attributes
  3523 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
  3524 + {
  3525 + // ----- Close the zip file
  3526 + $this->privCloseFd();
  3527 + $this->privSwapBackMagicQuotes();
  3528 +
  3529 + return $v_result;
  3530 + }
  3531 +
  3532 + // ----- Set the file content
  3533 + $p_file_list[$v_nb_extracted]['content'] = $v_string;
  3534 +
  3535 + // ----- Next extracted file
  3536 + $v_nb_extracted++;
  3537 +
  3538 + // ----- Look for user callback abort
  3539 + if ($v_result1 == 2) {
  3540 + break;
  3541 + }
  3542 + }
  3543 + // ----- Look for extraction in standard output
  3544 + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
  3545 + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
  3546 + // ----- Extracting the file in standard output
  3547 + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
  3548 + if ($v_result1 < 1) {
  3549 + $this->privCloseFd();
  3550 + $this->privSwapBackMagicQuotes();
  3551 + return $v_result1;
  3552 + }
  3553 +
  3554 + // ----- Get the only interesting attributes
  3555 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
  3556 + $this->privCloseFd();
  3557 + $this->privSwapBackMagicQuotes();
  3558 + return $v_result;
  3559 + }
  3560 +
  3561 + // ----- Look for user callback abort
  3562 + if ($v_result1 == 2) {
  3563 + break;
  3564 + }
  3565 + }
  3566 + // ----- Look for normal extraction
  3567 + else {
  3568 + // ----- Extracting the file
  3569 + $v_result1 = $this->privExtractFile($v_header,
  3570 + $p_path, $p_remove_path,
  3571 + $p_remove_all_path,
  3572 + $p_options);
  3573 + if ($v_result1 < 1) {
  3574 + $this->privCloseFd();
  3575 + $this->privSwapBackMagicQuotes();
  3576 + return $v_result1;
  3577 + }
  3578 +
  3579 + // ----- Get the only interesting attributes
  3580 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
  3581 + {
  3582 + // ----- Close the zip file
  3583 + $this->privCloseFd();
  3584 + $this->privSwapBackMagicQuotes();
  3585 +
  3586 + return $v_result;
  3587 + }
  3588 +
  3589 + // ----- Look for user callback abort
  3590 + if ($v_result1 == 2) {
  3591 + break;
  3592 + }
  3593 + }
  3594 + }
  3595 + }
  3596 +
  3597 + // ----- Close the zip file
  3598 + $this->privCloseFd();
  3599 + $this->privSwapBackMagicQuotes();
  3600 +
  3601 + // ----- Return
  3602 + return $v_result;
  3603 + }
  3604 + // --------------------------------------------------------------------------------
  3605 +
  3606 + // --------------------------------------------------------------------------------
  3607 + // Function : privExtractFile()
  3608 + // Description :
  3609 + // Parameters :
  3610 + // Return Values :
  3611 + //
  3612 + // 1 : ... ?
  3613 + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
  3614 + // --------------------------------------------------------------------------------
  3615 + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  3616 + {
  3617 + $v_result=1;
  3618 +
  3619 + // ----- Read the file header
  3620 + if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  3621 + {
  3622 + // ----- Return
  3623 + return $v_result;
  3624 + }
  3625 +
  3626 +
  3627 + // ----- Check that the file header is coherent with $p_entry info
  3628 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  3629 + // TBC
  3630 + }
  3631 +
  3632 + // ----- Look for all path to remove
  3633 + if ($p_remove_all_path == true) {
  3634 + // ----- Look for folder entry that not need to be extracted
  3635 + if (($p_entry['external']&0x00000010)==0x00000010) {
  3636 +
  3637 + $p_entry['status'] = "filtered";
  3638 +
  3639 + return $v_result;
  3640 + }
  3641 +
  3642 + // ----- Get the basename of the path
  3643 + $p_entry['filename'] = basename($p_entry['filename']);
  3644 + }
  3645 +
  3646 + // ----- Look for path to remove
  3647 + else if ($p_remove_path != "")
  3648 + {
  3649 + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
  3650 + {
  3651 +
  3652 + // ----- Change the file status
  3653 + $p_entry['status'] = "filtered";
  3654 +
  3655 + // ----- Return
  3656 + return $v_result;
  3657 + }
  3658 +
  3659 + $p_remove_path_size = strlen($p_remove_path);
  3660 + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
  3661 + {
  3662 +
  3663 + // ----- Remove the path
  3664 + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
  3665 +
  3666 + }
  3667 + }
  3668 +
  3669 + // ----- Add the path
  3670 + if ($p_path != '') {
  3671 + $p_entry['filename'] = $p_path."/".$p_entry['filename'];
  3672 + }
  3673 +
  3674 + // ----- Check a base_dir_restriction
  3675 + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
  3676 + $v_inclusion
  3677 + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
  3678 + $p_entry['filename']);
  3679 + if ($v_inclusion == 0) {
  3680 +
  3681 + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
  3682 + "Filename '".$p_entry['filename']."' is "
  3683 + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
  3684 +
  3685 + return PclZip::errorCode();
  3686 + }
  3687 + }
  3688 +
  3689 + // ----- Look for pre-extract callback
  3690 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  3691 +
  3692 + // ----- Generate a local information
  3693 + $v_local_header = array();
  3694 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3695 +
  3696 + // ----- Call the callback
  3697 + // Here I do not use call_user_func() because I need to send a reference to the
  3698 + // header.
  3699 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  3700 + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
  3701 + if ($v_result == 0) {
  3702 + // ----- Change the file status
  3703 + $p_entry['status'] = "skipped";
  3704 + $v_result = 1;
  3705 + }
  3706 +
  3707 + // ----- Look for abort result
  3708 + if ($v_result == 2) {
  3709 + // ----- This status is internal and will be changed in 'skipped'
  3710 + $p_entry['status'] = "aborted";
  3711 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3712 + }
  3713 +
  3714 + // ----- Update the informations
  3715 + // Only some fields can be modified
  3716 + $p_entry['filename'] = $v_local_header['filename'];
  3717 + }
  3718 +
  3719 +
  3720 + // ----- Look if extraction should be done
  3721 + if ($p_entry['status'] == 'ok') {
  3722 +
  3723 + // ----- Look for specific actions while the file exist
  3724 + if (file_exists($p_entry['filename']))
  3725 + {
  3726 +
  3727 + // ----- Look if file is a directory
  3728 + if (is_dir($p_entry['filename']))
  3729 + {
  3730 +
  3731 + // ----- Change the file status
  3732 + $p_entry['status'] = "already_a_directory";
  3733 +
  3734 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3735 + // For historical reason first PclZip implementation does not stop
  3736 + // when this kind of error occurs.
  3737 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3738 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3739 +
  3740 + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
  3741 + "Filename '".$p_entry['filename']."' is "
  3742 + ."already used by an existing directory");
  3743 +
  3744 + return PclZip::errorCode();
  3745 + }
  3746 + }
  3747 + // ----- Look if file is write protected
  3748 + else if (!is_writeable($p_entry['filename']))
  3749 + {
  3750 +
  3751 + // ----- Change the file status
  3752 + $p_entry['status'] = "write_protected";
  3753 +
  3754 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3755 + // For historical reason first PclZip implementation does not stop
  3756 + // when this kind of error occurs.
  3757 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3758 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3759 +
  3760 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  3761 + "Filename '".$p_entry['filename']."' exists "
  3762 + ."and is write protected");
  3763 +
  3764 + return PclZip::errorCode();
  3765 + }
  3766 + }
  3767 +
  3768 + // ----- Look if the extracted file is older
  3769 + else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
  3770 + {
  3771 + // ----- Change the file status
  3772 + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
  3773 + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
  3774 + }
  3775 + else {
  3776 + $p_entry['status'] = "newer_exist";
  3777 +
  3778 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3779 + // For historical reason first PclZip implementation does not stop
  3780 + // when this kind of error occurs.
  3781 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3782 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3783 +
  3784 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  3785 + "Newer version of '".$p_entry['filename']."' exists "
  3786 + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
  3787 +
  3788 + return PclZip::errorCode();
  3789 + }
  3790 + }
  3791 + }
  3792 + else {
  3793 + }
  3794 + }
  3795 +
  3796 + // ----- Check the directory availability and create it if necessary
  3797 + else {
  3798 + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
  3799 + $v_dir_to_check = $p_entry['filename'];
  3800 + else if (!strstr($p_entry['filename'], "/"))
  3801 + $v_dir_to_check = "";
  3802 + else
  3803 + $v_dir_to_check = dirname($p_entry['filename']);
  3804 +
  3805 + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
  3806 +
  3807 + // ----- Change the file status
  3808 + $p_entry['status'] = "path_creation_fail";
  3809 +
  3810 + // ----- Return
  3811 + //return $v_result;
  3812 + $v_result = 1;
  3813 + }
  3814 + }
  3815 + }
  3816 +
  3817 + // ----- Look if extraction should be done
  3818 + if ($p_entry['status'] == 'ok') {
  3819 +
  3820 + // ----- Do the extraction (if not a folder)
  3821 + if (!(($p_entry['external']&0x00000010)==0x00000010))
  3822 + {
  3823 + // ----- Look for not compressed file
  3824 + if ($p_entry['compression'] == 0) {
  3825 +
  3826 + // ----- Opening destination file
  3827 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
  3828 + {
  3829 +
  3830 + // ----- Change the file status
  3831 + $p_entry['status'] = "write_error";
  3832 +
  3833 + // ----- Return
  3834 + return $v_result;
  3835 + }
  3836 +
  3837 +
  3838 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  3839 + $v_size = $p_entry['compressed_size'];
  3840 + while ($v_size != 0)
  3841 + {
  3842 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  3843 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  3844 + /* Try to speed up the code
  3845 + $v_binary_data = pack('a'.$v_read_size, $v_buffer);
  3846 + @fwrite($v_dest_file, $v_binary_data, $v_read_size);
  3847 + */
  3848 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  3849 + $v_size -= $v_read_size;
  3850 + }
  3851 +
  3852 + // ----- Closing the destination file
  3853 + fclose($v_dest_file);
  3854 +
  3855 + // ----- Change the file mtime
  3856 + touch($p_entry['filename'], $p_entry['mtime']);
  3857 +
  3858 +
  3859 + }
  3860 + else {
  3861 + // ----- TBC
  3862 + // Need to be finished
  3863 + if (($p_entry['flag'] & 1) == 1) {
  3864 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
  3865 + return PclZip::errorCode();
  3866 + }
  3867 +
  3868 +
  3869 + // ----- Look for using temporary file to unzip
  3870 + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
  3871 + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
  3872 + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
  3873 + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
  3874 + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
  3875 + if ($v_result < PCLZIP_ERR_NO_ERROR) {
  3876 + return $v_result;
  3877 + }
  3878 + }
  3879 +
  3880 + // ----- Look for extract in memory
  3881 + else {
  3882 +
  3883 +
  3884 + // ----- Read the compressed file in a buffer (one shot)
  3885 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  3886 +
  3887 + // ----- Decompress the file
  3888 + $v_file_content = @gzinflate($v_buffer);
  3889 + unset($v_buffer);
  3890 + if ($v_file_content === FALSE) {
  3891 +
  3892 + // ----- Change the file status
  3893 + // TBC
  3894 + $p_entry['status'] = "error";
  3895 +
  3896 + return $v_result;
  3897 + }
  3898 +
  3899 + // ----- Opening destination file
  3900 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  3901 +
  3902 + // ----- Change the file status
  3903 + $p_entry['status'] = "write_error";
  3904 +
  3905 + return $v_result;
  3906 + }
  3907 +
  3908 + // ----- Write the uncompressed data
  3909 + @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
  3910 + unset($v_file_content);
  3911 +
  3912 + // ----- Closing the destination file
  3913 + @fclose($v_dest_file);
  3914 +
  3915 + }
  3916 +
  3917 + // ----- Change the file mtime
  3918 + @touch($p_entry['filename'], $p_entry['mtime']);
  3919 + }
  3920 +
  3921 + // ----- Look for chmod option
  3922 + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
  3923 +
  3924 + // ----- Change the mode of the file
  3925 + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
  3926 + }
  3927 +
  3928 + }
  3929 + }
  3930 +
  3931 + // ----- Change abort status
  3932 + if ($p_entry['status'] == "aborted") {
  3933 + $p_entry['status'] = "skipped";
  3934 + }
  3935 +
  3936 + // ----- Look for post-extract callback
  3937 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  3938 +
  3939 + // ----- Generate a local information
  3940 + $v_local_header = array();
  3941 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3942 +
  3943 + // ----- Call the callback
  3944 + // Here I do not use call_user_func() because I need to send a reference to the
  3945 + // header.
  3946 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  3947 + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
  3948 +
  3949 + // ----- Look for abort result
  3950 + if ($v_result == 2) {
  3951 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3952 + }
  3953 + }
  3954 +
  3955 + // ----- Return
  3956 + return $v_result;
  3957 + }
  3958 + // --------------------------------------------------------------------------------
  3959 +
  3960 + // --------------------------------------------------------------------------------
  3961 + // Function : privExtractFileUsingTempFile()
  3962 + // Description :
  3963 + // Parameters :
  3964 + // Return Values :
  3965 + // --------------------------------------------------------------------------------
  3966 + function privExtractFileUsingTempFile(&$p_entry, &$p_options)
  3967 + {
  3968 + $v_result=1;
  3969 +
  3970 + // ----- Creates a temporary file
  3971 + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
  3972 + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
  3973 + fclose($v_file);
  3974 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
  3975 + return PclZip::errorCode();
  3976 + }
  3977 +
  3978 +
  3979 + // ----- Write gz file format header
  3980 + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
  3981 + @fwrite($v_dest_file, $v_binary_data, 10);
  3982 +
  3983 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  3984 + $v_size = $p_entry['compressed_size'];
  3985 + while ($v_size != 0)
  3986 + {
  3987 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  3988 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  3989 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  3990 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  3991 + $v_size -= $v_read_size;
  3992 + }
  3993 +
  3994 + // ----- Write gz file format footer
  3995 + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
  3996 + @fwrite($v_dest_file, $v_binary_data, 8);
  3997 +
  3998 + // ----- Close the temporary file
  3999 + @fclose($v_dest_file);
  4000 +
  4001 + // ----- Opening destination file
  4002 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  4003 + $p_entry['status'] = "write_error";
  4004 + return $v_result;
  4005 + }
  4006 +
  4007 + // ----- Open the temporary gz file
  4008 + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
  4009 + @fclose($v_dest_file);
  4010 + $p_entry['status'] = "read_error";
  4011 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
  4012 + return PclZip::errorCode();
  4013 + }
  4014 +
  4015 +
  4016 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  4017 + $v_size = $p_entry['size'];
  4018 + while ($v_size != 0) {
  4019 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4020 + $v_buffer = @gzread($v_src_file, $v_read_size);
  4021 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  4022 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  4023 + $v_size -= $v_read_size;
  4024 + }
  4025 + @fclose($v_dest_file);
  4026 + @gzclose($v_src_file);
  4027 +
  4028 + // ----- Delete the temporary file
  4029 + @unlink($v_gzip_temp_name);
  4030 +
  4031 + // ----- Return
  4032 + return $v_result;
  4033 + }
  4034 + // --------------------------------------------------------------------------------
  4035 +
  4036 + // --------------------------------------------------------------------------------
  4037 + // Function : privExtractFileInOutput()
  4038 + // Description :
  4039 + // Parameters :
  4040 + // Return Values :
  4041 + // --------------------------------------------------------------------------------
  4042 + function privExtractFileInOutput(&$p_entry, &$p_options)
  4043 + {
  4044 + $v_result=1;
  4045 +
  4046 + // ----- Read the file header
  4047 + if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
  4048 + return $v_result;
  4049 + }
  4050 +
  4051 +
  4052 + // ----- Check that the file header is coherent with $p_entry info
  4053 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  4054 + // TBC
  4055 + }
  4056 +
  4057 + // ----- Look for pre-extract callback
  4058 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  4059 +
  4060 + // ----- Generate a local information
  4061 + $v_local_header = array();
  4062 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4063 +
  4064 + // ----- Call the callback
  4065 + // Here I do not use call_user_func() because I need to send a reference to the
  4066 + // header.
  4067 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  4068 + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
  4069 + if ($v_result == 0) {
  4070 + // ----- Change the file status
  4071 + $p_entry['status'] = "skipped";
  4072 + $v_result = 1;
  4073 + }
  4074 +
  4075 + // ----- Look for abort result
  4076 + if ($v_result == 2) {
  4077 + // ----- This status is internal and will be changed in 'skipped'
  4078 + $p_entry['status'] = "aborted";
  4079 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4080 + }
  4081 +
  4082 + // ----- Update the informations
  4083 + // Only some fields can be modified
  4084 + $p_entry['filename'] = $v_local_header['filename'];
  4085 + }
  4086 +
  4087 + // ----- Trace
  4088 +
  4089 + // ----- Look if extraction should be done
  4090 + if ($p_entry['status'] == 'ok') {
  4091 +
  4092 + // ----- Do the extraction (if not a folder)
  4093 + if (!(($p_entry['external']&0x00000010)==0x00000010)) {
  4094 + // ----- Look for not compressed file
  4095 + if ($p_entry['compressed_size'] == $p_entry['size']) {
  4096 +
  4097 + // ----- Read the file in a buffer (one shot)
  4098 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  4099 +
  4100 + // ----- Send the file to the output
  4101 + echo $v_buffer;
  4102 + unset($v_buffer);
  4103 + }
  4104 + else {
  4105 +
  4106 + // ----- Read the compressed file in a buffer (one shot)
  4107 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  4108 +
  4109 + // ----- Decompress the file
  4110 + $v_file_content = gzinflate($v_buffer);
  4111 + unset($v_buffer);
  4112 +
  4113 + // ----- Send the file to the output
  4114 + echo $v_file_content;
  4115 + unset($v_file_content);
  4116 + }
  4117 + }
  4118 + }
  4119 +
  4120 + // ----- Change abort status
  4121 + if ($p_entry['status'] == "aborted") {
  4122 + $p_entry['status'] = "skipped";
  4123 + }
  4124 +
  4125 + // ----- Look for post-extract callback
  4126 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  4127 +
  4128 + // ----- Generate a local information
  4129 + $v_local_header = array();
  4130 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4131 +
  4132 + // ----- Call the callback
  4133 + // Here I do not use call_user_func() because I need to send a reference to the
  4134 + // header.
  4135 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  4136 + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
  4137 +
  4138 + // ----- Look for abort result
  4139 + if ($v_result == 2) {
  4140 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4141 + }
  4142 + }
  4143 +
  4144 + return $v_result;
  4145 + }
  4146 + // --------------------------------------------------------------------------------
  4147 +
  4148 + // --------------------------------------------------------------------------------
  4149 + // Function : privExtractFileAsString()
  4150 + // Description :
  4151 + // Parameters :
  4152 + // Return Values :
  4153 + // --------------------------------------------------------------------------------
  4154 + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
  4155 + {
  4156 + $v_result=1;
  4157 +
  4158 + // ----- Read the file header
  4159 + $v_header = array();
  4160 + if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  4161 + {
  4162 + // ----- Return
  4163 + return $v_result;
  4164 + }
  4165 +
  4166 +
  4167 + // ----- Check that the file header is coherent with $p_entry info
  4168 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  4169 + // TBC
  4170 + }
  4171 +
  4172 + // ----- Look for pre-extract callback
  4173 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  4174 +
  4175 + // ----- Generate a local information
  4176 + $v_local_header = array();
  4177 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4178 +
  4179 + // ----- Call the callback
  4180 + // Here I do not use call_user_func() because I need to send a reference to the
  4181 + // header.
  4182 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  4183 + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
  4184 + if ($v_result == 0) {
  4185 + // ----- Change the file status
  4186 + $p_entry['status'] = "skipped";
  4187 + $v_result = 1;
  4188 + }
  4189 +
  4190 + // ----- Look for abort result
  4191 + if ($v_result == 2) {
  4192 + // ----- This status is internal and will be changed in 'skipped'
  4193 + $p_entry['status'] = "aborted";
  4194 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4195 + }
  4196 +
  4197 + // ----- Update the informations
  4198 + // Only some fields can be modified
  4199 + $p_entry['filename'] = $v_local_header['filename'];
  4200 + }
  4201 +
  4202 +
  4203 + // ----- Look if extraction should be done
  4204 + if ($p_entry['status'] == 'ok') {
  4205 +
  4206 + // ----- Do the extraction (if not a folder)
  4207 + if (!(($p_entry['external']&0x00000010)==0x00000010)) {
  4208 + // ----- Look for not compressed file
  4209 + // if ($p_entry['compressed_size'] == $p_entry['size'])
  4210 + if ($p_entry['compression'] == 0) {
  4211 +
  4212 + // ----- Reading the file
  4213 + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
  4214 + }
  4215 + else {
  4216 +
  4217 + // ----- Reading the file
  4218 + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
  4219 +
  4220 + // ----- Decompress the file
  4221 + if (($p_string = @gzinflate($v_data)) === FALSE) {
  4222 + // TBC
  4223 + }
  4224 + }
  4225 +
  4226 + // ----- Trace
  4227 + }
  4228 + else {
  4229 + // TBC : error : can not extract a folder in a string
  4230 + }
  4231 +
  4232 + }
  4233 +
  4234 + // ----- Change abort status
  4235 + if ($p_entry['status'] == "aborted") {
  4236 + $p_entry['status'] = "skipped";
  4237 + }
  4238 +
  4239 + // ----- Look for post-extract callback
  4240 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  4241 +
  4242 + // ----- Generate a local information
  4243 + $v_local_header = array();
  4244 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4245 +
  4246 + // ----- Swap the content to header
  4247 + $v_local_header['content'] = $p_string;
  4248 + $p_string = '';
  4249 +
  4250 + // ----- Call the callback
  4251 + // Here I do not use call_user_func() because I need to send a reference to the
  4252 + // header.
  4253 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  4254 + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
  4255 +
  4256 + // ----- Swap back the content to header
  4257 + $p_string = $v_local_header['content'];
  4258 + unset($v_local_header['content']);
  4259 +
  4260 + // ----- Look for abort result
  4261 + if ($v_result == 2) {
  4262 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4263 + }
  4264 + }
  4265 +
  4266 + // ----- Return
  4267 + return $v_result;
  4268 + }
  4269 + // --------------------------------------------------------------------------------
  4270 +
  4271 + // --------------------------------------------------------------------------------
  4272 + // Function : privReadFileHeader()
  4273 + // Description :
  4274 + // Parameters :
  4275 + // Return Values :
  4276 + // --------------------------------------------------------------------------------
  4277 + function privReadFileHeader(&$p_header)
  4278 + {
  4279 + $v_result=1;
  4280 +
  4281 + // ----- Read the 4 bytes signature
  4282 + $v_binary_data = @fread($this->zip_fd, 4);
  4283 + $v_data = unpack('Vid', $v_binary_data);
  4284 +
  4285 + // ----- Check signature
  4286 + if ($v_data['id'] != 0x04034b50)
  4287 + {
  4288 +
  4289 + // ----- Error log
  4290 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  4291 +
  4292 + // ----- Return
  4293 + return PclZip::errorCode();
  4294 + }
  4295 +
  4296 + // ----- Read the first 42 bytes of the header
  4297 + $v_binary_data = fread($this->zip_fd, 26);
  4298 +
  4299 + // ----- Look for invalid block size
  4300 + if (strlen($v_binary_data) != 26)
  4301 + {
  4302 + $p_header['filename'] = "";
  4303 + $p_header['status'] = "invalid_header";
  4304 +
  4305 + // ----- Error log
  4306 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  4307 +
  4308 + // ----- Return
  4309 + return PclZip::errorCode();
  4310 + }
  4311 +
  4312 + // ----- Extract the values
  4313 + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
  4314 +
  4315 + // ----- Get filename
  4316 + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
  4317 +
  4318 + // ----- Get extra_fields
  4319 + if ($v_data['extra_len'] != 0) {
  4320 + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
  4321 + }
  4322 + else {
  4323 + $p_header['extra'] = '';
  4324 + }
  4325 +
  4326 + // ----- Extract properties
  4327 + $p_header['version_extracted'] = $v_data['version'];
  4328 + $p_header['compression'] = $v_data['compression'];
  4329 + $p_header['size'] = $v_data['size'];
  4330 + $p_header['compressed_size'] = $v_data['compressed_size'];
  4331 + $p_header['crc'] = $v_data['crc'];
  4332 + $p_header['flag'] = $v_data['flag'];
  4333 + $p_header['filename_len'] = $v_data['filename_len'];
  4334 +
  4335 + // ----- Recuperate date in UNIX format
  4336 + $p_header['mdate'] = $v_data['mdate'];
  4337 + $p_header['mtime'] = $v_data['mtime'];
  4338 + if ($p_header['mdate'] && $p_header['mtime'])
  4339 + {
  4340 + // ----- Extract time
  4341 + $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  4342 + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  4343 + $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  4344 +
  4345 + // ----- Extract date
  4346 + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  4347 + $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  4348 + $v_day = $p_header['mdate'] & 0x001F;
  4349 +
  4350 + // ----- Get UNIX date format
  4351 + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  4352 +
  4353 + }
  4354 + else
  4355 + {
  4356 + $p_header['mtime'] = time();
  4357 + }
  4358 +
  4359 + // TBC
  4360 + //for(reset($v_data); $key = key($v_data); next($v_data)) {
  4361 + //}
  4362 +
  4363 + // ----- Set the stored filename
  4364 + $p_header['stored_filename'] = $p_header['filename'];
  4365 +
  4366 + // ----- Set the status field
  4367 + $p_header['status'] = "ok";
  4368 +
  4369 + // ----- Return
  4370 + return $v_result;
  4371 + }
  4372 + // --------------------------------------------------------------------------------
  4373 +
  4374 + // --------------------------------------------------------------------------------
  4375 + // Function : privReadCentralFileHeader()
  4376 + // Description :
  4377 + // Parameters :
  4378 + // Return Values :
  4379 + // --------------------------------------------------------------------------------
  4380 + function privReadCentralFileHeader(&$p_header)
  4381 + {
  4382 + $v_result=1;
  4383 +
  4384 + // ----- Read the 4 bytes signature
  4385 + $v_binary_data = @fread($this->zip_fd, 4);
  4386 + $v_data = unpack('Vid', $v_binary_data);
  4387 +
  4388 + // ----- Check signature
  4389 + if ($v_data['id'] != 0x02014b50)
  4390 + {
  4391 +
  4392 + // ----- Error log
  4393 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  4394 +
  4395 + // ----- Return
  4396 + return PclZip::errorCode();
  4397 + }
  4398 +
  4399 + // ----- Read the first 42 bytes of the header
  4400 + $v_binary_data = fread($this->zip_fd, 42);
  4401 +
  4402 + // ----- Look for invalid block size
  4403 + if (strlen($v_binary_data) != 42)
  4404 + {
  4405 + $p_header['filename'] = "";
  4406 + $p_header['status'] = "invalid_header";
  4407 +
  4408 + // ----- Error log
  4409 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  4410 +
  4411 + // ----- Return
  4412 + return PclZip::errorCode();
  4413 + }
  4414 +
  4415 + // ----- Extract the values
  4416 + $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);
  4417 +
  4418 + // ----- Get filename
  4419 + if ($p_header['filename_len'] != 0)
  4420 + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
  4421 + else
  4422 + $p_header['filename'] = '';
  4423 +
  4424 + // ----- Get extra
  4425 + if ($p_header['extra_len'] != 0)
  4426 + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
  4427 + else
  4428 + $p_header['extra'] = '';
  4429 +
  4430 + // ----- Get comment
  4431 + if ($p_header['comment_len'] != 0)
  4432 + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
  4433 + else
  4434 + $p_header['comment'] = '';
  4435 +
  4436 + // ----- Extract properties
  4437 +
  4438 + // ----- Recuperate date in UNIX format
  4439 + //if ($p_header['mdate'] && $p_header['mtime'])
  4440 + // TBC : bug : this was ignoring time with 0/0/0
  4441 + if (1)
  4442 + {
  4443 + // ----- Extract time
  4444 + $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  4445 + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  4446 + $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  4447 +
  4448 + // ----- Extract date
  4449 + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  4450 + $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  4451 + $v_day = $p_header['mdate'] & 0x001F;
  4452 +
  4453 + // ----- Get UNIX date format
  4454 + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  4455 +
  4456 + }
  4457 + else
  4458 + {
  4459 + $p_header['mtime'] = time();
  4460 + }
  4461 +
  4462 + // ----- Set the stored filename
  4463 + $p_header['stored_filename'] = $p_header['filename'];
  4464 +
  4465 + // ----- Set default status to ok
  4466 + $p_header['status'] = 'ok';
  4467 +
  4468 + // ----- Look if it is a directory
  4469 + if (substr($p_header['filename'], -1) == '/') {
  4470 + //$p_header['external'] = 0x41FF0010;
  4471 + $p_header['external'] = 0x00000010;
  4472 + }
  4473 +
  4474 +
  4475 + // ----- Return
  4476 + return $v_result;
  4477 + }
  4478 + // --------------------------------------------------------------------------------
  4479 +
  4480 + // --------------------------------------------------------------------------------
  4481 + // Function : privCheckFileHeaders()
  4482 + // Description :
  4483 + // Parameters :
  4484 + // Return Values :
  4485 + // 1 on success,
  4486 + // 0 on error;
  4487 + // --------------------------------------------------------------------------------
  4488 + function privCheckFileHeaders(&$p_local_header, &$p_central_header)
  4489 + {
  4490 + $v_result=1;
  4491 +
  4492 + // ----- Check the static values
  4493 + // TBC
  4494 + if ($p_local_header['filename'] != $p_central_header['filename']) {
  4495 + }
  4496 + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
  4497 + }
  4498 + if ($p_local_header['flag'] != $p_central_header['flag']) {
  4499 + }
  4500 + if ($p_local_header['compression'] != $p_central_header['compression']) {
  4501 + }
  4502 + if ($p_local_header['mtime'] != $p_central_header['mtime']) {
  4503 + }
  4504 + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
  4505 + }
  4506 +
  4507 + // ----- Look for flag bit 3
  4508 + if (($p_local_header['flag'] & 8) == 8) {
  4509 + $p_local_header['size'] = $p_central_header['size'];
  4510 + $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
  4511 + $p_local_header['crc'] = $p_central_header['crc'];
  4512 + }
  4513 +
  4514 + // ----- Return
  4515 + return $v_result;
  4516 + }
  4517 + // --------------------------------------------------------------------------------
  4518 +
  4519 + // --------------------------------------------------------------------------------
  4520 + // Function : privReadEndCentralDir()
  4521 + // Description :
  4522 + // Parameters :
  4523 + // Return Values :
  4524 + // --------------------------------------------------------------------------------
  4525 + function privReadEndCentralDir(&$p_central_dir)
  4526 + {
  4527 + $v_result=1;
  4528 +
  4529 + // ----- Go to the end of the zip file
  4530 + $v_size = filesize($this->zipname);
  4531 + @fseek($this->zip_fd, $v_size);
  4532 + if (@ftell($this->zip_fd) != $v_size)
  4533 + {
  4534 + // ----- Error log
  4535 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
  4536 +
  4537 + // ----- Return
  4538 + return PclZip::errorCode();
  4539 + }
  4540 +
  4541 + // ----- First try : look if this is an archive with no commentaries (most of the time)
  4542 + // in this case the end of central dir is at 22 bytes of the file end
  4543 + $v_found = 0;
  4544 + if ($v_size > 26) {
  4545 + @fseek($this->zip_fd, $v_size-22);
  4546 + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
  4547 + {
  4548 + // ----- Error log
  4549 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  4550 +
  4551 + // ----- Return
  4552 + return PclZip::errorCode();
  4553 + }
  4554 +
  4555 + // ----- Read for bytes
  4556 + $v_binary_data = @fread($this->zip_fd, 4);
  4557 + $v_data = @unpack('Vid', $v_binary_data);
  4558 +
  4559 + // ----- Check signature
  4560 + if ($v_data['id'] == 0x06054b50) {
  4561 + $v_found = 1;
  4562 + }
  4563 +
  4564 + $v_pos = ftell($this->zip_fd);
  4565 + }
  4566 +
  4567 + // ----- Go back to the maximum possible size of the Central Dir End Record
  4568 + if (!$v_found) {
  4569 + $v_maximum_size = 65557; // 0xFFFF + 22;
  4570 + if ($v_maximum_size > $v_size)
  4571 + $v_maximum_size = $v_size;
  4572 + @fseek($this->zip_fd, $v_size-$v_maximum_size);
  4573 + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
  4574 + {
  4575 + // ----- Error log
  4576 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  4577 +
  4578 + // ----- Return
  4579 + return PclZip::errorCode();
  4580 + }
  4581 +
  4582 + // ----- Read byte per byte in order to find the signature
  4583 + $v_pos = ftell($this->zip_fd);
  4584 + $v_bytes = 0x00000000;
  4585 + while ($v_pos < $v_size)
  4586 + {
  4587 + // ----- Read a byte
  4588 + $v_byte = @fread($this->zip_fd, 1);
  4589 +
  4590 + // ----- Add the byte
  4591 + //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
  4592 + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
  4593 + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
  4594 + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
  4595 +
  4596 + // ----- Compare the bytes
  4597 + if ($v_bytes == 0x504b0506)
  4598 + {
  4599 + $v_pos++;
  4600 + break;
  4601 + }
  4602 +
  4603 + $v_pos++;
  4604 + }
  4605 +
  4606 + // ----- Look if not found end of central dir
  4607 + if ($v_pos == $v_size)
  4608 + {
  4609 +
  4610 + // ----- Error log
  4611 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
  4612 +
  4613 + // ----- Return
  4614 + return PclZip::errorCode();
  4615 + }
  4616 + }
  4617 +
  4618 + // ----- Read the first 18 bytes of the header
  4619 + $v_binary_data = fread($this->zip_fd, 18);
  4620 +
  4621 + // ----- Look for invalid block size
  4622 + if (strlen($v_binary_data) != 18)
  4623 + {
  4624 +
  4625 + // ----- Error log
  4626 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  4627 +
  4628 + // ----- Return
  4629 + return PclZip::errorCode();
  4630 + }
  4631 +
  4632 + // ----- Extract the values
  4633 + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
  4634 +
  4635 + // ----- Check the global size
  4636 + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
  4637 +
  4638 + // ----- Removed in release 2.2 see readme file
  4639 + // The check of the file size is a little too strict.
  4640 + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
  4641 + // While decrypted, zip has training 0 bytes
  4642 + if (0) {
  4643 + // ----- Error log
  4644 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
  4645 + 'The central dir is not at the end of the archive.'
  4646 + .' Some trailing bytes exists after the archive.');
  4647 +
  4648 + // ----- Return
  4649 + return PclZip::errorCode();
  4650 + }
  4651 + }
  4652 +
  4653 + // ----- Get comment
  4654 + if ($v_data['comment_size'] != 0) {
  4655 + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
  4656 + }
  4657 + else
  4658 + $p_central_dir['comment'] = '';
  4659 +
  4660 + $p_central_dir['entries'] = $v_data['entries'];
  4661 + $p_central_dir['disk_entries'] = $v_data['disk_entries'];
  4662 + $p_central_dir['offset'] = $v_data['offset'];
  4663 + $p_central_dir['size'] = $v_data['size'];
  4664 + $p_central_dir['disk'] = $v_data['disk'];
  4665 + $p_central_dir['disk_start'] = $v_data['disk_start'];
  4666 +
  4667 + // TBC
  4668 + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
  4669 + //}
  4670 +
  4671 + // ----- Return
  4672 + return $v_result;
  4673 + }
  4674 + // --------------------------------------------------------------------------------
  4675 +
  4676 + // --------------------------------------------------------------------------------
  4677 + // Function : privDeleteByRule()
  4678 + // Description :
  4679 + // Parameters :
  4680 + // Return Values :
  4681 + // --------------------------------------------------------------------------------
  4682 + function privDeleteByRule(&$p_result_list, &$p_options)
  4683 + {
  4684 + $v_result=1;
  4685 + $v_list_detail = array();
  4686 +
  4687 + // ----- Open the zip file
  4688 + if (($v_result=$this->privOpenFd('rb')) != 1)
  4689 + {
  4690 + // ----- Return
  4691 + return $v_result;
  4692 + }
  4693 +
  4694 + // ----- Read the central directory informations
  4695 + $v_central_dir = array();
  4696 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  4697 + {
  4698 + $this->privCloseFd();
  4699 + return $v_result;
  4700 + }
  4701 +
  4702 + // ----- Go to beginning of File
  4703 + @rewind($this->zip_fd);
  4704 +
  4705 + // ----- Scan all the files
  4706 + // ----- Start at beginning of Central Dir
  4707 + $v_pos_entry = $v_central_dir['offset'];
  4708 + @rewind($this->zip_fd);
  4709 + if (@fseek($this->zip_fd, $v_pos_entry))
  4710 + {
  4711 + // ----- Close the zip file
  4712 + $this->privCloseFd();
  4713 +
  4714 + // ----- Error log
  4715 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  4716 +
  4717 + // ----- Return
  4718 + return PclZip::errorCode();
  4719 + }
  4720 +
  4721 + // ----- Read each entry
  4722 + $v_header_list = array();
  4723 + $j_start = 0;
  4724 + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  4725 + {
  4726 +
  4727 + // ----- Read the file header
  4728 + $v_header_list[$v_nb_extracted] = array();
  4729 + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
  4730 + {
  4731 + // ----- Close the zip file
  4732 + $this->privCloseFd();
  4733 +
  4734 + return $v_result;
  4735 + }
  4736 +
  4737 +
  4738 + // ----- Store the index
  4739 + $v_header_list[$v_nb_extracted]['index'] = $i;
  4740 +
  4741 + // ----- Look for the specific extract rules
  4742 + $v_found = false;
  4743 +
  4744 + // ----- Look for extract by name rule
  4745 + if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
  4746 + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  4747 +
  4748 + // ----- Look if the filename is in the list
  4749 + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
  4750 +
  4751 + // ----- Look for a directory
  4752 + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  4753 +
  4754 + // ----- Look if the directory is in the filename path
  4755 + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  4756 + && (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])) {
  4757 + $v_found = true;
  4758 + }
  4759 + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
  4760 + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  4761 + $v_found = true;
  4762 + }
  4763 + }
  4764 + // ----- Look for a filename
  4765 + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  4766 + $v_found = true;
  4767 + }
  4768 + }
  4769 + }
  4770 +
  4771 + // ----- Look for extract by ereg rule
  4772 + // ereg() is deprecated with PHP 5.3
  4773 + /*
  4774 + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
  4775 + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  4776 +
  4777 + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  4778 + $v_found = true;
  4779 + }
  4780 + }
  4781 + */
  4782 +
  4783 + // ----- Look for extract by preg rule
  4784 + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
  4785 + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  4786 +
  4787 + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  4788 + $v_found = true;
  4789 + }
  4790 + }
  4791 +
  4792 + // ----- Look for extract by index rule
  4793 + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  4794 + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  4795 +
  4796 + // ----- Look if the index is in the list
  4797 + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
  4798 +
  4799 + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  4800 + $v_found = true;
  4801 + }
  4802 + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  4803 + $j_start = $j+1;
  4804 + }
  4805 +
  4806 + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  4807 + break;
  4808 + }
  4809 + }
  4810 + }
  4811 + else {
  4812 + $v_found = true;
  4813 + }
  4814 +
  4815 + // ----- Look for deletion
  4816 + if ($v_found)
  4817 + {
  4818 + unset($v_header_list[$v_nb_extracted]);
  4819 + }
  4820 + else
  4821 + {
  4822 + $v_nb_extracted++;
  4823 + }
  4824 + }
  4825 +
  4826 + // ----- Look if something need to be deleted
  4827 + if ($v_nb_extracted > 0) {
  4828 +
  4829 + // ----- Creates a temporay file
  4830 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  4831 +
  4832 + // ----- Creates a temporary zip archive
  4833 + $v_temp_zip = new PclZip($v_zip_temp_name);
  4834 +
  4835 + // ----- Open the temporary zip file in write mode
  4836 + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
  4837 + $this->privCloseFd();
  4838 +
  4839 + // ----- Return
  4840 + return $v_result;
  4841 + }
  4842 +
  4843 + // ----- Look which file need to be kept
  4844 + for ($i=0; $i<sizeof($v_header_list); $i++) {
  4845 +
  4846 + // ----- Calculate the position of the header
  4847 + @rewind($this->zip_fd);
  4848 + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
  4849 + // ----- Close the zip file
  4850 + $this->privCloseFd();
  4851 + $v_temp_zip->privCloseFd();
  4852 + @unlink($v_zip_temp_name);
  4853 +
  4854 + // ----- Error log
  4855 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  4856 +
  4857 + // ----- Return
  4858 + return PclZip::errorCode();
  4859 + }
  4860 +
  4861 + // ----- Read the file header
  4862 + $v_local_header = array();
  4863 + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
  4864 + // ----- Close the zip file
  4865 + $this->privCloseFd();
  4866 + $v_temp_zip->privCloseFd();
  4867 + @unlink($v_zip_temp_name);
  4868 +
  4869 + // ----- Return
  4870 + return $v_result;
  4871 + }
  4872 +
  4873 + // ----- Check that local file header is same as central file header
  4874 + if ($this->privCheckFileHeaders($v_local_header,
  4875 + $v_header_list[$i]) != 1) {
  4876 + // TBC
  4877 + }
  4878 + unset($v_local_header);
  4879 +
  4880 + // ----- Write the file header
  4881 + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
  4882 + // ----- Close the zip file
  4883 + $this->privCloseFd();
  4884 + $v_temp_zip->privCloseFd();
  4885 + @unlink($v_zip_temp_name);
  4886 +
  4887 + // ----- Return
  4888 + return $v_result;
  4889 + }
  4890 +
  4891 + // ----- Read/write the data block
  4892 + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
  4893 + // ----- Close the zip file
  4894 + $this->privCloseFd();
  4895 + $v_temp_zip->privCloseFd();
  4896 + @unlink($v_zip_temp_name);
  4897 +
  4898 + // ----- Return
  4899 + return $v_result;
  4900 + }
  4901 + }
  4902 +
  4903 + // ----- Store the offset of the central dir
  4904 + $v_offset = @ftell($v_temp_zip->zip_fd);
  4905 +
  4906 + // ----- Re-Create the Central Dir files header
  4907 + for ($i=0; $i<sizeof($v_header_list); $i++) {
  4908 + // ----- Create the file header
  4909 + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  4910 + $v_temp_zip->privCloseFd();
  4911 + $this->privCloseFd();
  4912 + @unlink($v_zip_temp_name);
  4913 +
  4914 + // ----- Return
  4915 + return $v_result;
  4916 + }
  4917 +
  4918 + // ----- Transform the header to a 'usable' info
  4919 + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  4920 + }
  4921 +
  4922 +
  4923 + // ----- Zip file comment
  4924 + $v_comment = '';
  4925 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  4926 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  4927 + }
  4928 +
  4929 + // ----- Calculate the size of the central header
  4930 + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
  4931 +
  4932 + // ----- Create the central dir footer
  4933 + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
  4934 + // ----- Reset the file list
  4935 + unset($v_header_list);
  4936 + $v_temp_zip->privCloseFd();
  4937 + $this->privCloseFd();
  4938 + @unlink($v_zip_temp_name);
  4939 +
  4940 + // ----- Return
  4941 + return $v_result;
  4942 + }
  4943 +
  4944 + // ----- Close
  4945 + $v_temp_zip->privCloseFd();
  4946 + $this->privCloseFd();
  4947 +
  4948 + // ----- Delete the zip file
  4949 + // TBC : I should test the result ...
  4950 + @unlink($this->zipname);
  4951 +
  4952 + // ----- Rename the temporary file
  4953 + // TBC : I should test the result ...
  4954 + //@rename($v_zip_temp_name, $this->zipname);
  4955 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  4956 +
  4957 + // ----- Destroy the temporary archive
  4958 + unset($v_temp_zip);
  4959 + }
  4960 +
  4961 + // ----- Remove every files : reset the file
  4962 + else if ($v_central_dir['entries'] != 0) {
  4963 + $this->privCloseFd();
  4964 +
  4965 + if (($v_result = $this->privOpenFd('wb')) != 1) {
  4966 + return $v_result;
  4967 + }
  4968 +
  4969 + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
  4970 + return $v_result;
  4971 + }
  4972 +
  4973 + $this->privCloseFd();
  4974 + }
  4975 +
  4976 + // ----- Return
  4977 + return $v_result;
  4978 + }
  4979 + // --------------------------------------------------------------------------------
  4980 +
  4981 + // --------------------------------------------------------------------------------
  4982 + // Function : privDirCheck()
  4983 + // Description :
  4984 + // Check if a directory exists, if not it creates it and all the parents directory
  4985 + // which may be useful.
  4986 + // Parameters :
  4987 + // $p_dir : Directory path to check.
  4988 + // Return Values :
  4989 + // 1 : OK
  4990 + // -1 : Unable to create directory
  4991 + // --------------------------------------------------------------------------------
  4992 + function privDirCheck($p_dir, $p_is_dir=false)
  4993 + {
  4994 + $v_result = 1;
  4995 +
  4996 +
  4997 + // ----- Remove the final '/'
  4998 + if (($p_is_dir) && (substr($p_dir, -1)=='/'))
  4999 + {
  5000 + $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
  5001 + }
  5002 +
  5003 + // ----- Check the directory availability
  5004 + if ((is_dir($p_dir)) || ($p_dir == ""))
  5005 + {
  5006 + return 1;
  5007 + }
  5008 +
  5009 + // ----- Extract parent directory
  5010 + $p_parent_dir = dirname($p_dir);
  5011 +
  5012 + // ----- Just a check
  5013 + if ($p_parent_dir != $p_dir)
  5014 + {
  5015 + // ----- Look for parent directory
  5016 + if ($p_parent_dir != "")
  5017 + {
  5018 + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
  5019 + {
  5020 + return $v_result;
  5021 + }
  5022 + }
  5023 + }
  5024 +
  5025 + // ----- Create the directory
  5026 + if (!@mkdir($p_dir, 0777))
  5027 + {
  5028 + // ----- Error log
  5029 + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
  5030 +
  5031 + // ----- Return
  5032 + return PclZip::errorCode();
  5033 + }
  5034 +
  5035 + // ----- Return
  5036 + return $v_result;
  5037 + }
  5038 + // --------------------------------------------------------------------------------
  5039 +
  5040 + // --------------------------------------------------------------------------------
  5041 + // Function : privMerge()
  5042 + // Description :
  5043 + // If $p_archive_to_add does not exist, the function exit with a success result.
  5044 + // Parameters :
  5045 + // Return Values :
  5046 + // --------------------------------------------------------------------------------
  5047 + function privMerge(&$p_archive_to_add)
  5048 + {
  5049 + $v_result=1;
  5050 +
  5051 + // ----- Look if the archive_to_add exists
  5052 + if (!is_file($p_archive_to_add->zipname))
  5053 + {
  5054 +
  5055 + // ----- Nothing to merge, so merge is a success
  5056 + $v_result = 1;
  5057 +
  5058 + // ----- Return
  5059 + return $v_result;
  5060 + }
  5061 +
  5062 + // ----- Look if the archive exists
  5063 + if (!is_file($this->zipname))
  5064 + {
  5065 +
  5066 + // ----- Do a duplicate
  5067 + $v_result = $this->privDuplicate($p_archive_to_add->zipname);
  5068 +
  5069 + // ----- Return
  5070 + return $v_result;
  5071 + }
  5072 +
  5073 + // ----- Open the zip file
  5074 + if (($v_result=$this->privOpenFd('rb')) != 1)
  5075 + {
  5076 + // ----- Return
  5077 + return $v_result;
  5078 + }
  5079 +
  5080 + // ----- Read the central directory informations
  5081 + $v_central_dir = array();
  5082 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  5083 + {
  5084 + $this->privCloseFd();
  5085 + return $v_result;
  5086 + }
  5087 +
  5088 + // ----- Go to beginning of File
  5089 + @rewind($this->zip_fd);
  5090 +
  5091 + // ----- Open the archive_to_add file
  5092 + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
  5093 + {
  5094 + $this->privCloseFd();
  5095 +
  5096 + // ----- Return
  5097 + return $v_result;
  5098 + }
  5099 +
  5100 + // ----- Read the central directory informations
  5101 + $v_central_dir_to_add = array();
  5102 + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
  5103 + {
  5104 + $this->privCloseFd();
  5105 + $p_archive_to_add->privCloseFd();
  5106 +
  5107 + return $v_result;
  5108 + }
  5109 +
  5110 + // ----- Go to beginning of File
  5111 + @rewind($p_archive_to_add->zip_fd);
  5112 +
  5113 + // ----- Creates a temporay file
  5114 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  5115 +
  5116 + // ----- Open the temporary file in write mode
  5117 + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  5118 + {
  5119 + $this->privCloseFd();
  5120 + $p_archive_to_add->privCloseFd();
  5121 +
  5122 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  5123 +
  5124 + // ----- Return
  5125 + return PclZip::errorCode();
  5126 + }
  5127 +
  5128 + // ----- Copy the files from the archive to the temporary file
  5129 + // TBC : Here I should better append the file and go back to erase the central dir
  5130 + $v_size = $v_central_dir['offset'];
  5131 + while ($v_size != 0)
  5132 + {
  5133 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5134 + $v_buffer = fread($this->zip_fd, $v_read_size);
  5135 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5136 + $v_size -= $v_read_size;
  5137 + }
  5138 +
  5139 + // ----- Copy the files from the archive_to_add into the temporary file
  5140 + $v_size = $v_central_dir_to_add['offset'];
  5141 + while ($v_size != 0)
  5142 + {
  5143 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5144 + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
  5145 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5146 + $v_size -= $v_read_size;
  5147 + }
  5148 +
  5149 + // ----- Store the offset of the central dir
  5150 + $v_offset = @ftell($v_zip_temp_fd);
  5151 +
  5152 + // ----- Copy the block of file headers from the old archive
  5153 + $v_size = $v_central_dir['size'];
  5154 + while ($v_size != 0)
  5155 + {
  5156 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5157 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  5158 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5159 + $v_size -= $v_read_size;
  5160 + }
  5161 +
  5162 + // ----- Copy the block of file headers from the archive_to_add
  5163 + $v_size = $v_central_dir_to_add['size'];
  5164 + while ($v_size != 0)
  5165 + {
  5166 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5167 + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
  5168 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5169 + $v_size -= $v_read_size;
  5170 + }
  5171 +
  5172 + // ----- Merge the file comments
  5173 + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
  5174 +
  5175 + // ----- Calculate the size of the (new) central header
  5176 + $v_size = @ftell($v_zip_temp_fd)-$v_offset;
  5177 +
  5178 + // ----- Swap the file descriptor
  5179 + // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  5180 + // the following methods on the temporary fil and not the real archive fd
  5181 + $v_swap = $this->zip_fd;
  5182 + $this->zip_fd = $v_zip_temp_fd;
  5183 + $v_zip_temp_fd = $v_swap;
  5184 +
  5185 + // ----- Create the central dir footer
  5186 + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
  5187 + {
  5188 + $this->privCloseFd();
  5189 + $p_archive_to_add->privCloseFd();
  5190 + @fclose($v_zip_temp_fd);
  5191 + $this->zip_fd = null;
  5192 +
  5193 + // ----- Reset the file list
  5194 + unset($v_header_list);
  5195 +
  5196 + // ----- Return
  5197 + return $v_result;
  5198 + }
  5199 +
  5200 + // ----- Swap back the file descriptor
  5201 + $v_swap = $this->zip_fd;
  5202 + $this->zip_fd = $v_zip_temp_fd;
  5203 + $v_zip_temp_fd = $v_swap;
  5204 +
  5205 + // ----- Close
  5206 + $this->privCloseFd();
  5207 + $p_archive_to_add->privCloseFd();
  5208 +
  5209 + // ----- Close the temporary file
  5210 + @fclose($v_zip_temp_fd);
  5211 +
  5212 + // ----- Delete the zip file
  5213 + // TBC : I should test the result ...
  5214 + @unlink($this->zipname);
  5215 +
  5216 + // ----- Rename the temporary file
  5217 + // TBC : I should test the result ...
  5218 + //@rename($v_zip_temp_name, $this->zipname);
  5219 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  5220 +
  5221 + // ----- Return
  5222 + return $v_result;
  5223 + }
  5224 + // --------------------------------------------------------------------------------
  5225 +
  5226 + // --------------------------------------------------------------------------------
  5227 + // Function : privDuplicate()
  5228 + // Description :
  5229 + // Parameters :
  5230 + // Return Values :
  5231 + // --------------------------------------------------------------------------------
  5232 + function privDuplicate($p_archive_filename)
  5233 + {
  5234 + $v_result=1;
  5235 +
  5236 + // ----- Look if the $p_archive_filename exists
  5237 + if (!is_file($p_archive_filename))
  5238 + {
  5239 +
  5240 + // ----- Nothing to duplicate, so duplicate is a success.
  5241 + $v_result = 1;
  5242 +
  5243 + // ----- Return
  5244 + return $v_result;
  5245 + }
  5246 +
  5247 + // ----- Open the zip file
  5248 + if (($v_result=$this->privOpenFd('wb')) != 1)
  5249 + {
  5250 + // ----- Return
  5251 + return $v_result;
  5252 + }
  5253 +
  5254 + // ----- Open the temporary file in write mode
  5255 + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
  5256 + {
  5257 + $this->privCloseFd();
  5258 +
  5259 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
  5260 +
  5261 + // ----- Return
  5262 + return PclZip::errorCode();
  5263 + }
  5264 +
  5265 + // ----- Copy the files from the archive to the temporary file
  5266 + // TBC : Here I should better append the file and go back to erase the central dir
  5267 + $v_size = filesize($p_archive_filename);
  5268 + while ($v_size != 0)
  5269 + {
  5270 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5271 + $v_buffer = fread($v_zip_temp_fd, $v_read_size);
  5272 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  5273 + $v_size -= $v_read_size;
  5274 + }
  5275 +
  5276 + // ----- Close
  5277 + $this->privCloseFd();
  5278 +
  5279 + // ----- Close the temporary file
  5280 + @fclose($v_zip_temp_fd);
  5281 +
  5282 + // ----- Return
  5283 + return $v_result;
  5284 + }
  5285 + // --------------------------------------------------------------------------------
  5286 +
  5287 + // --------------------------------------------------------------------------------
  5288 + // Function : privErrorLog()
  5289 + // Description :
  5290 + // Parameters :
  5291 + // --------------------------------------------------------------------------------
  5292 + function privErrorLog($p_error_code=0, $p_error_string='')
  5293 + {
  5294 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  5295 + PclError($p_error_code, $p_error_string);
  5296 + }
  5297 + else {
  5298 + $this->error_code = $p_error_code;
  5299 + $this->error_string = $p_error_string;
  5300 + }
  5301 + }
  5302 + // --------------------------------------------------------------------------------
  5303 +
  5304 + // --------------------------------------------------------------------------------
  5305 + // Function : privErrorReset()
  5306 + // Description :
  5307 + // Parameters :
  5308 + // --------------------------------------------------------------------------------
  5309 + function privErrorReset()
  5310 + {
  5311 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  5312 + PclErrorReset();
  5313 + }
  5314 + else {
  5315 + $this->error_code = 0;
  5316 + $this->error_string = '';
  5317 + }
  5318 + }
  5319 + // --------------------------------------------------------------------------------
  5320 +
  5321 + // --------------------------------------------------------------------------------
  5322 + // Function : privDisableMagicQuotes()
  5323 + // Description :
  5324 + // Parameters :
  5325 + // Return Values :
  5326 + // --------------------------------------------------------------------------------
  5327 + function privDisableMagicQuotes()
  5328 + {
  5329 + $v_result=1;
  5330 +
  5331 + // ----- Look if function exists
  5332 + if ( (!function_exists("get_magic_quotes_runtime"))
  5333 + || (!function_exists("set_magic_quotes_runtime"))) {
  5334 + return $v_result;
  5335 + }
  5336 +
  5337 + // ----- Look if already done
  5338 + if ($this->magic_quotes_status != -1) {
  5339 + return $v_result;
  5340 + }
  5341 +
  5342 + // ----- Get and memorize the magic_quote value
  5343 + $this->magic_quotes_status = @get_magic_quotes_runtime();
  5344 +
  5345 + // ----- Disable magic_quotes
  5346 + if ($this->magic_quotes_status == 1) {
  5347 + @set_magic_quotes_runtime(0);
  5348 + }
  5349 +
  5350 + // ----- Return
  5351 + return $v_result;
  5352 + }
  5353 + // --------------------------------------------------------------------------------
  5354 +
  5355 + // --------------------------------------------------------------------------------
  5356 + // Function : privSwapBackMagicQuotes()
  5357 + // Description :
  5358 + // Parameters :
  5359 + // Return Values :
  5360 + // --------------------------------------------------------------------------------
  5361 + function privSwapBackMagicQuotes()
  5362 + {
  5363 + $v_result=1;
  5364 +
  5365 + // ----- Look if function exists
  5366 + if ( (!function_exists("get_magic_quotes_runtime"))
  5367 + || (!function_exists("set_magic_quotes_runtime"))) {
  5368 + return $v_result;
  5369 + }
  5370 +
  5371 + // ----- Look if something to do
  5372 + if ($this->magic_quotes_status != -1) {
  5373 + return $v_result;
  5374 + }
  5375 +
  5376 + // ----- Swap back magic_quotes
  5377 + if ($this->magic_quotes_status == 1) {
  5378 + @set_magic_quotes_runtime($this->magic_quotes_status);
  5379 + }
  5380 +
  5381 + // ----- Return
  5382 + return $v_result;
  5383 + }
  5384 + // --------------------------------------------------------------------------------
  5385 +
  5386 + }
  5387 + // End of class
  5388 + // --------------------------------------------------------------------------------
  5389 +
  5390 + // --------------------------------------------------------------------------------
  5391 + // Function : PclZipUtilPathReduction()
  5392 + // Description :
  5393 + // Parameters :
  5394 + // Return Values :
  5395 + // --------------------------------------------------------------------------------
  5396 + function PclZipUtilPathReduction($p_dir)
  5397 + {
  5398 + $v_result = "";
  5399 +
  5400 + // ----- Look for not empty path
  5401 + if ($p_dir != "") {
  5402 + // ----- Explode path by directory names
  5403 + $v_list = explode("/", $p_dir);
  5404 +
  5405 + // ----- Study directories from last to first
  5406 + $v_skip = 0;
  5407 + for ($i=sizeof($v_list)-1; $i>=0; $i--) {
  5408 + // ----- Look for current path
  5409 + if ($v_list[$i] == ".") {
  5410 + // ----- Ignore this directory
  5411 + // Should be the first $i=0, but no check is done
  5412 + }
  5413 + else if ($v_list[$i] == "..") {
  5414 + $v_skip++;
  5415 + }
  5416 + else if ($v_list[$i] == "") {
  5417 + // ----- First '/' i.e. root slash
  5418 + if ($i == 0) {
  5419 + $v_result = "/".$v_result;
  5420 + if ($v_skip > 0) {
  5421 + // ----- It is an invalid path, so the path is not modified
  5422 + // TBC
  5423 + $v_result = $p_dir;
  5424 + $v_skip = 0;
  5425 + }
  5426 + }
  5427 + // ----- Last '/' i.e. indicates a directory
  5428 + else if ($i == (sizeof($v_list)-1)) {
  5429 + $v_result = $v_list[$i];
  5430 + }
  5431 + // ----- Double '/' inside the path
  5432 + else {
  5433 + // ----- Ignore only the double '//' in path,
  5434 + // but not the first and last '/'
  5435 + }
  5436 + }
  5437 + else {
  5438 + // ----- Look for item to skip
  5439 + if ($v_skip > 0) {
  5440 + $v_skip--;
  5441 + }
  5442 + else {
  5443 + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
  5444 + }
  5445 + }
  5446 + }
  5447 +
  5448 + // ----- Look for skip
  5449 + if ($v_skip > 0) {
  5450 + while ($v_skip > 0) {
  5451 + $v_result = '../'.$v_result;
  5452 + $v_skip--;
  5453 + }
  5454 + }
  5455 + }
  5456 +
  5457 + // ----- Return
  5458 + return $v_result;
  5459 + }
  5460 + // --------------------------------------------------------------------------------
  5461 +
  5462 + // --------------------------------------------------------------------------------
  5463 + // Function : PclZipUtilPathInclusion()
  5464 + // Description :
  5465 + // This function indicates if the path $p_path is under the $p_dir tree. Or,
  5466 + // said in an other way, if the file or sub-dir $p_path is inside the dir
  5467 + // $p_dir.
  5468 + // The function indicates also if the path is exactly the same as the dir.
  5469 + // This function supports path with duplicated '/' like '//', but does not
  5470 + // support '.' or '..' statements.
  5471 + // Parameters :
  5472 + // Return Values :
  5473 + // 0 if $p_path is not inside directory $p_dir
  5474 + // 1 if $p_path is inside directory $p_dir
  5475 + // 2 if $p_path is exactly the same as $p_dir
  5476 + // --------------------------------------------------------------------------------
  5477 + function PclZipUtilPathInclusion($p_dir, $p_path)
  5478 + {
  5479 + $v_result = 1;
  5480 +
  5481 + // ----- Look for path beginning by ./
  5482 + if ( ($p_dir == '.')
  5483 + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
  5484 + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
  5485 + }
  5486 + if ( ($p_path == '.')
  5487 + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
  5488 + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
  5489 + }
  5490 +
  5491 + // ----- Explode dir and path by directory separator
  5492 + $v_list_dir = explode("/", $p_dir);
  5493 + $v_list_dir_size = sizeof($v_list_dir);
  5494 + $v_list_path = explode("/", $p_path);
  5495 + $v_list_path_size = sizeof($v_list_path);
  5496 +
  5497 + // ----- Study directories paths
  5498 + $i = 0;
  5499 + $j = 0;
  5500 + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
  5501 +
  5502 + // ----- Look for empty dir (path reduction)
  5503 + if ($v_list_dir[$i] == '') {
  5504 + $i++;
  5505 + continue;
  5506 + }
  5507 + if ($v_list_path[$j] == '') {
  5508 + $j++;
  5509 + continue;
  5510 + }
  5511 +
  5512 + // ----- Compare the items
  5513 + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
  5514 + $v_result = 0;
  5515 + }
  5516 +
  5517 + // ----- Next items
  5518 + $i++;
  5519 + $j++;
  5520 + }
  5521 +
  5522 + // ----- Look if everything seems to be the same
  5523 + if ($v_result) {
  5524 + // ----- Skip all the empty items
  5525 + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
  5526 + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
  5527 +
  5528 + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
  5529 + // ----- There are exactly the same
  5530 + $v_result = 2;
  5531 + }
  5532 + else if ($i < $v_list_dir_size) {
  5533 + // ----- The path is shorter than the dir
  5534 + $v_result = 0;
  5535 + }
  5536 + }
  5537 +
  5538 + // ----- Return
  5539 + return $v_result;
  5540 + }
  5541 + // --------------------------------------------------------------------------------
  5542 +
  5543 + // --------------------------------------------------------------------------------
  5544 + // Function : PclZipUtilCopyBlock()
  5545 + // Description :
  5546 + // Parameters :
  5547 + // $p_mode : read/write compression mode
  5548 + // 0 : src & dest normal
  5549 + // 1 : src gzip, dest normal
  5550 + // 2 : src normal, dest gzip
  5551 + // 3 : src & dest gzip
  5552 + // Return Values :
  5553 + // --------------------------------------------------------------------------------
  5554 + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
  5555 + {
  5556 + $v_result = 1;
  5557 +
  5558 + if ($p_mode==0)
  5559 + {
  5560 + while ($p_size != 0)
  5561 + {
  5562 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5563 + $v_buffer = @fread($p_src, $v_read_size);
  5564 + @fwrite($p_dest, $v_buffer, $v_read_size);
  5565 + $p_size -= $v_read_size;
  5566 + }
  5567 + }
  5568 + else if ($p_mode==1)
  5569 + {
  5570 + while ($p_size != 0)
  5571 + {
  5572 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5573 + $v_buffer = @gzread($p_src, $v_read_size);
  5574 + @fwrite($p_dest, $v_buffer, $v_read_size);
  5575 + $p_size -= $v_read_size;
  5576 + }
  5577 + }
  5578 + else if ($p_mode==2)
  5579 + {
  5580 + while ($p_size != 0)
  5581 + {
  5582 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5583 + $v_buffer = @fread($p_src, $v_read_size);
  5584 + @gzwrite($p_dest, $v_buffer, $v_read_size);
  5585 + $p_size -= $v_read_size;
  5586 + }
  5587 + }
  5588 + else if ($p_mode==3)
  5589 + {
  5590 + while ($p_size != 0)
  5591 + {
  5592 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5593 + $v_buffer = @gzread($p_src, $v_read_size);
  5594 + @gzwrite($p_dest, $v_buffer, $v_read_size);
  5595 + $p_size -= $v_read_size;
  5596 + }
  5597 + }
  5598 +
  5599 + // ----- Return
  5600 + return $v_result;
  5601 + }
  5602 + // --------------------------------------------------------------------------------
  5603 +
  5604 + // --------------------------------------------------------------------------------
  5605 + // Function : PclZipUtilRename()
  5606 + // Description :
  5607 + // This function tries to do a simple rename() function. If it fails, it
  5608 + // tries to copy the $p_src file in a new $p_dest file and then unlink the
  5609 + // first one.
  5610 + // Parameters :
  5611 + // $p_src : Old filename
  5612 + // $p_dest : New filename
  5613 + // Return Values :
  5614 + // 1 on success, 0 on failure.
  5615 + // --------------------------------------------------------------------------------
  5616 + function PclZipUtilRename($p_src, $p_dest)
  5617 + {
  5618 + $v_result = 1;
  5619 +
  5620 + // ----- Try to rename the files
  5621 + if (!@rename($p_src, $p_dest)) {
  5622 +
  5623 + // ----- Try to copy & unlink the src
  5624 + if (!@copy($p_src, $p_dest)) {
  5625 + $v_result = 0;
  5626 + }
  5627 + else if (!@unlink($p_src)) {
  5628 + $v_result = 0;
  5629 + }
  5630 + }
  5631 +
  5632 + // ----- Return
  5633 + return $v_result;
  5634 + }
  5635 + // --------------------------------------------------------------------------------
  5636 +
  5637 + // --------------------------------------------------------------------------------
  5638 + // Function : PclZipUtilOptionText()
  5639 + // Description :
  5640 + // Translate option value in text. Mainly for debug purpose.
  5641 + // Parameters :
  5642 + // $p_option : the option value.
  5643 + // Return Values :
  5644 + // The option text value.
  5645 + // --------------------------------------------------------------------------------
  5646 + function PclZipUtilOptionText($p_option)
  5647 + {
  5648 +
  5649 + $v_list = get_defined_constants();
  5650 + for (reset($v_list); $v_key = key($v_list); next($v_list)) {
  5651 + $v_prefix = substr($v_key, 0, 10);
  5652 + if (( ($v_prefix == 'PCLZIP_OPT')
  5653 + || ($v_prefix == 'PCLZIP_CB_')
  5654 + || ($v_prefix == 'PCLZIP_ATT'))
  5655 + && ($v_list[$v_key] == $p_option)) {
  5656 + return $v_key;
  5657 + }
  5658 + }
  5659 +
  5660 + $v_result = 'Unknown';
  5661 +
  5662 + return $v_result;
  5663 + }
  5664 + // --------------------------------------------------------------------------------
  5665 +
  5666 + // --------------------------------------------------------------------------------
  5667 + // Function : PclZipUtilTranslateWinPath()
  5668 + // Description :
  5669 + // Translate windows path by replacing '\' by '/' and optionally removing
  5670 + // drive letter.
  5671 + // Parameters :
  5672 + // $p_path : path to translate.
  5673 + // $p_remove_disk_letter : true | false
  5674 + // Return Values :
  5675 + // The path translated.
  5676 + // --------------------------------------------------------------------------------
  5677 + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
  5678 + {
  5679 + if (stristr(php_uname(), 'windows')) {
  5680 + // ----- Look for potential disk letter
  5681 + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
  5682 + $p_path = substr($p_path, $v_position+1);
  5683 + }
  5684 + // ----- Change potential windows directory separator
  5685 + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
  5686 + $p_path = strtr($p_path, '\\', '/');
  5687 + }
  5688 + }
  5689 + return $p_path;
  5690 + }
  5691 + // --------------------------------------------------------------------------------
  5692 +
  5693 +
  5694 +?>
... ...