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