5 Modification information for LGPL compliance
7 r56990 - 2010-06-16 13:05:36 -0700 (Wed, 16 Jun 2010) - kjing - snapshot "Mango" svn branch to a new one for GitHub sync
9 r56989 - 2010-06-16 13:01:33 -0700 (Wed, 16 Jun 2010) - kjing - defunt "Mango" svn dev branch before github cutover
11 r55980 - 2010-04-19 13:31:28 -0700 (Mon, 19 Apr 2010) - kjing - create Mango (6.1) based on windex
13 r51719 - 2009-10-22 10:18:00 -0700 (Thu, 22 Oct 2009) - mitani - Converted to Build 3 tags and updated the build system
15 r51634 - 2009-10-19 13:32:22 -0700 (Mon, 19 Oct 2009) - mitani - Windex is the branch for Sugar Sales 1.0 development
17 r51443 - 2009-10-12 13:34:36 -0700 (Mon, 12 Oct 2009) - jmertic - Bug 33332 - Made application PHP 5.3 compliant with E_DEPRECATED warnings on by:
18 - Changing all ereg function to either preg or simple string based ones
19 - No more references to magic quotes.
20 - Change all the session_unregister() functions to just unset() the correct session variable instead.
22 r50375 - 2009-08-24 18:07:43 -0700 (Mon, 24 Aug 2009) - dwong - branch kobe2 from tokyo r50372
24 r46791 - 2009-05-03 17:06:15 -0700 (Sun, 03 May 2009) - wdong - 28603, merge from maint520_hermosa
26 r42807 - 2008-12-29 11:16:59 -0800 (Mon, 29 Dec 2008) - dwong - Branch from trunk/sugarcrm r42806 to branches/tokyo/sugarcrm
28 r38213 - 2008-07-24 12:50:06 -0700 (Thu, 24 Jul 2008) - Collin Lee - Bug:22608
29 Modified pclzip.lib.php files in both portal and server code base to not use call by reference for func_get_args in the extract method.
30 Modified (server and portal side):
31 include/pclzip/pclzip.lib.php
33 r36478 - 2008-06-10 09:23:49 -0700 (Tue, 10 Jun 2008) - Collin Lee - Fix for 22608
34 Marked as fixed in 5.1.0 GA. Changed the method call in pclzip.lib.php to use a call by reference.
36 include/pclzip/pclzip.lib.php
38 r15812 - 2006-08-10 17:05:31 -0700 (Thu, 10 Aug 2006) - chris - fixing calltime-pass-by-reference error
40 r14739 - 2006-07-17 21:27:19 -0700 (Mon, 17 Jul 2006) - majed - revert pclzip
42 r14367 - 2006-06-29 14:20:41 -0700 (Thu, 29 Jun 2006) - chris - updating PCLZip library to current latest 2.5 (security fixes)
44 r11996 - 2006-03-09 14:16:53 -0800 (Thu, 09 Mar 2006) - sadek - Updated pclzip library from 2.3 to 2.4. There was a bug in PCLZIP 2.3 that caused my diag tool to break in certain environments
46 r7861 - 2005-09-20 15:40:25 -0700 (Tue, 20 Sep 2005) - majed - & fix for 3.5.1
48 r5573 - 2005-06-03 16:32:18 -0700 (Fri, 03 Jun 2005) - bob - checking in chosen [un]zip utility
54 // --------------------------------------------------------------------------------
55 // PhpConcept Library - Zip Module 2.4
56 // --------------------------------------------------------------------------------
57 // License GNU/LGPL - Vincent Blavet - November 2004
58 // http://www.phpconcept.net
59 // --------------------------------------------------------------------------------
62 // PclZip is a PHP library that manage ZIP archives.
63 // So far tests show that archives generated by PclZip are readable by
64 // WinZip application and other tools.
67 // See readme.txt and http://www.phpconcept.net
70 // This library and the associated files are non commercial, non professional
72 // It should not have unexpected results. However if any damage is caused by
73 // this software the author can not be responsible.
74 // The use of this software is at the risk of the user.
76 // --------------------------------------------------------------------------------
78 // --------------------------------------------------------------------------------
81 define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
83 // ----- File list separator
84 // In version 1.x of PclZip, the separator for file list is a space
85 // (which is not a very smart choice, specifically for windows paths !).
86 // A better separator should be a comma (,). This constant gives you the
87 // abilty to change that.
88 // However notice that changing this value, may have impact on existing
89 // scripts, using space separated filenames.
90 // Recommanded values for compatibility with older versions :
91 //define( 'PCLZIP_SEPARATOR', ' ' );
92 // Recommanded values for smart separation of filenames.
93 define( 'PCLZIP_SEPARATOR', ',' );
95 // ----- Error configuration
96 // 0 : PclZip Class integrated error handling
97 // 1 : PclError external library error handling. By enabling this
98 // you must ensure that you have included PclError library.
99 // [2,...] : reserved for futur use
100 define( 'PCLZIP_ERROR_EXTERNAL', 0 );
102 // ----- Optional static temporary directory
103 // By default temporary files are generated in the script current
106 // - MUST BE terminated by a '/'.
107 // - MUST be a valid, already created directory
109 // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
110 // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
111 define( 'PCLZIP_TEMPORARY_DIR', '' );
113 // --------------------------------------------------------------------------------
114 // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
115 // --------------------------------------------------------------------------------
117 // ----- Global variables
118 $g_pclzip_version = "2.4";
121 // -1 : Unable to open file in binary write mode
122 // -2 : Unable to open file in binary read mode
123 // -3 : Invalid parameters
124 // -4 : File does not exist
125 // -5 : Filename is too long (max. 255)
126 // -6 : Not a valid zip file
127 // -7 : Invalid extracted file size
128 // -8 : Unable to create directory
129 // -9 : Invalid archive extension
130 // -10 : Invalid archive format
131 // -11 : Unable to delete file (unlink)
132 // -12 : Unable to rename file (rename)
133 // -13 : Invalid header checksum
134 // -14 : Invalid archive size
135 define( 'PCLZIP_ERR_USER_ABORTED', 2 );
136 define( 'PCLZIP_ERR_NO_ERROR', 0 );
137 define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
138 define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
139 define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
140 define( 'PCLZIP_ERR_MISSING_FILE', -4 );
141 define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
142 define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
143 define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
144 define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
145 define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
146 define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
147 define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
148 define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
149 define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
150 define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
151 define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
152 define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
153 define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
154 define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
155 define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
157 // ----- Options values
158 define( 'PCLZIP_OPT_PATH', 77001 );
159 define( 'PCLZIP_OPT_ADD_PATH', 77002 );
160 define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
161 define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
162 define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
163 define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
164 define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
165 define( 'PCLZIP_OPT_BY_NAME', 77008 );
166 define( 'PCLZIP_OPT_BY_INDEX', 77009 );
167 define( 'PCLZIP_OPT_BY_EREG', 77010 );
168 define( 'PCLZIP_OPT_BY_PREG', 77011 );
169 define( 'PCLZIP_OPT_COMMENT', 77012 );
170 define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
171 define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
172 define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
173 define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
174 define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
175 // Having big trouble with crypt. Need to multiply 2 long int
176 // which is not correctly supported by PHP ...
177 //define( 'PCLZIP_OPT_CRYPT', 77018 );
179 // ----- Call backs values
180 define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
181 define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
182 define( 'PCLZIP_CB_PRE_ADD', 78003 );
183 define( 'PCLZIP_CB_POST_ADD', 78004 );
185 define( 'PCLZIP_CB_PRE_LIST', 78005 );
186 define( 'PCLZIP_CB_POST_LIST', 78006 );
187 define( 'PCLZIP_CB_PRE_DELETE', 78007 );
188 define( 'PCLZIP_CB_POST_DELETE', 78008 );
191 // --------------------------------------------------------------------------------
194 // PclZip is the class that represent a Zip archive.
195 // The public methods allow the manipulation of the archive.
197 // Attributes must not be accessed directly.
199 // PclZip() : Object creator
200 // create() : Creates the Zip archive
201 // listContent() : List the content of the Zip archive
202 // extract() : Extract the content of the archive
203 // properties() : List the properties of the archive
204 // --------------------------------------------------------------------------------
207 // ----- Filename of the zip file
210 // ----- File descriptor of the zip file
213 // ----- Internal error handling
215 var $error_string = '';
217 // ----- Current status of the magic_quotes_runtime
218 // This value store the php configuration for magic_quotes
219 // The class can then disable the magic_quotes and reset it after
220 var $magic_quotes_status;
222 // --------------------------------------------------------------------------------
223 // Function : PclZip()
225 // Creates a PclZip object and set the name of the associated Zip archive
227 // Note that no real action is taken, if the archive does not exist it is not
228 // created. Use create() for that.
229 // --------------------------------------------------------------------------------
230 function PclZip($p_zipname)
232 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");
234 // ----- Tests the zlib
235 if (!function_exists('gzopen'))
237 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");
238 die('Abort '.basename(__FILE__).' : Missing zlib extensions');
241 // ----- Set the attributes
242 $this->zipname = $p_zipname;
244 $this->magic_quotes_status = -1;
247 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);
250 // --------------------------------------------------------------------------------
252 // --------------------------------------------------------------------------------
254 // create($p_filelist, $p_add_dir="", $p_remove_dir="")
255 // create($p_filelist, $p_option, $p_option_value, ...)
257 // This method supports two different synopsis. The first one is historical.
258 // This method creates a Zip Archive. The Zip file is created in the
259 // filesystem. The files and directories indicated in $p_filelist
260 // are added in the archive. See the parameters description for the
261 // supported format of $p_filelist.
262 // When a directory is in the list, the directory and its content is added
264 // In this synopsis, the function takes an optional variable list of
265 // options. See bellow the supported options.
267 // $p_filelist : An array containing file or directory names, or
268 // a string containing one filename or one directory name, or
269 // a string containing a list of filenames and/or directory
270 // names separated by spaces.
271 // $p_add_dir : A path to add before the real path of the archived file,
272 // in order to have it memorized in the archive.
273 // $p_remove_dir : A path to remove from the real path of the file to archive,
274 // in order to have a shorter path memorized in the archive.
275 // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
276 // is removed first, before $p_add_dir is added.
278 // PCLZIP_OPT_ADD_PATH :
279 // PCLZIP_OPT_REMOVE_PATH :
280 // PCLZIP_OPT_REMOVE_ALL_PATH :
281 // PCLZIP_OPT_COMMENT :
282 // PCLZIP_CB_PRE_ADD :
283 // PCLZIP_CB_POST_ADD :
286 // The list of the added files, with a status of the add action.
287 // (see PclZip::listContent() for list entry format)
288 // --------------------------------------------------------------------------------
289 // function create($p_filelist, $p_add_dir="", $p_remove_dir="")
290 function create($p_filelist /*, options */)
292 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");
295 // ----- Reset the error handler
296 $this->privErrorReset();
298 // ----- Set default values
299 $v_options = array();
302 $v_remove_all_path = false;
303 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
305 // ----- Look for variable options arguments
306 $v_size = func_num_args();
307 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
309 // ----- Look for arguments
311 // ----- Get the arguments
312 $v_arg_list = func_get_args();
314 // ----- Remove form the options list the first argument
315 array_shift($v_arg_list);
318 // ----- Look for first arg
319 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
320 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
322 // ----- Parse the options
323 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
324 array (PCLZIP_OPT_REMOVE_PATH => 'optional',
325 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
326 PCLZIP_OPT_ADD_PATH => 'optional',
327 PCLZIP_CB_PRE_ADD => 'optional',
328 PCLZIP_CB_POST_ADD => 'optional',
329 PCLZIP_OPT_NO_COMPRESSION => 'optional',
330 PCLZIP_OPT_COMMENT => 'optional'
331 //, PCLZIP_OPT_CRYPT => 'optional'
333 if ($v_result != 1) {
334 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
338 // ----- Set the arguments
339 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
340 $v_add_path = $v_options[PCLZIP_OPT_ADD_PATH];
342 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
343 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
345 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
346 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
350 // ----- Look for 2 args
351 // Here we need to support the first historic synopsis of the
354 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
356 // ----- Get the first argument
357 $v_add_path = $v_arg_list[0];
359 // ----- Look for the optional second argument
361 $v_remove_path = $v_arg_list[1];
363 else if ($v_size > 2) {
365 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
366 "Invalid number / type of arguments");
369 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
376 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "add_path='$v_add_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_all_path?'true':'false')."'");
378 // ----- Look if the $p_filelist is really an array
379 $p_result_list = array();
380 if (is_array($p_filelist))
382 // ----- Call the create fct
383 $v_result = $this->privCreate($p_filelist, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
386 // ----- Look if the $p_filelist is a string
387 else if (is_string($p_filelist))
389 // ----- Create a list with the elements from the string
390 $v_list = explode(PCLZIP_SEPARATOR, $p_filelist);
392 // ----- Call the create fct
393 $v_result = $this->privCreate($v_list, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
396 // ----- Invalid variable
400 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
401 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
407 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
412 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
413 return $p_result_list;
415 // --------------------------------------------------------------------------------
417 // --------------------------------------------------------------------------------
419 // add($p_filelist, $p_add_dir="", $p_remove_dir="")
420 // add($p_filelist, $p_option, $p_option_value, ...)
422 // This method supports two synopsis. The first one is historical.
423 // This methods add the list of files in an existing archive.
424 // If a file with the same name already exists, it is added at the end of the
425 // archive, the first one is still present.
426 // If the archive does not exist, it is created.
428 // $p_filelist : An array containing file or directory names, or
429 // a string containing one filename or one directory name, or
430 // a string containing a list of filenames and/or directory
431 // names separated by spaces.
432 // $p_add_dir : A path to add before the real path of the archived file,
433 // in order to have it memorized in the archive.
434 // $p_remove_dir : A path to remove from the real path of the file to archive,
435 // in order to have a shorter path memorized in the archive.
436 // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
437 // is removed first, before $p_add_dir is added.
439 // PCLZIP_OPT_ADD_PATH :
440 // PCLZIP_OPT_REMOVE_PATH :
441 // PCLZIP_OPT_REMOVE_ALL_PATH :
442 // PCLZIP_OPT_COMMENT :
443 // PCLZIP_OPT_ADD_COMMENT :
444 // PCLZIP_OPT_PREPEND_COMMENT :
445 // PCLZIP_CB_PRE_ADD :
446 // PCLZIP_CB_POST_ADD :
449 // The list of the added files, with a status of the add action.
450 // (see PclZip::listContent() for list entry format)
451 // --------------------------------------------------------------------------------
452 // function add($p_filelist, $p_add_dir="", $p_remove_dir="")
453 function add($p_filelist /* options */)
455 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");
458 // ----- Reset the error handler
459 $this->privErrorReset();
461 // ----- Set default values
462 $v_options = array();
465 $v_remove_all_path = false;
466 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
468 // ----- Look for variable options arguments
469 $v_size = func_num_args();
470 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
472 // ----- Look for arguments
474 // ----- Get the arguments
475 $v_arg_list = &func_get_args();
477 // ----- Remove form the options list the first argument
478 array_shift($v_arg_list);
481 // ----- Look for first arg
482 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
483 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
485 // ----- Parse the options
486 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
487 array (PCLZIP_OPT_REMOVE_PATH => 'optional',
488 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
489 PCLZIP_OPT_ADD_PATH => 'optional',
490 PCLZIP_CB_PRE_ADD => 'optional',
491 PCLZIP_CB_POST_ADD => 'optional',
492 PCLZIP_OPT_NO_COMPRESSION => 'optional',
493 PCLZIP_OPT_COMMENT => 'optional',
494 PCLZIP_OPT_ADD_COMMENT => 'optional',
495 PCLZIP_OPT_PREPEND_COMMENT => 'optional'
496 //, PCLZIP_OPT_CRYPT => 'optional'
498 if ($v_result != 1) {
499 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
503 // ----- Set the arguments
504 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
505 $v_add_path = $v_options[PCLZIP_OPT_ADD_PATH];
507 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
508 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
510 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
511 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
515 // ----- Look for 2 args
516 // Here we need to support the first historic synopsis of the
519 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
521 // ----- Get the first argument
522 $v_add_path = $v_arg_list[0];
524 // ----- Look for the optional second argument
526 $v_remove_path = $v_arg_list[1];
528 else if ($v_size > 2) {
530 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
533 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
540 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "add_path='$v_add_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_all_path?'true':'false')."'");
542 // ----- Look if the $p_filelist is really an array
543 $p_result_list = array();
544 if (is_array($p_filelist))
546 // ----- Call the create fct
547 $v_result = $this->privAdd($p_filelist, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
550 // ----- Look if the $p_filelist is a string
551 else if (is_string($p_filelist))
553 // ----- Create a list with the elements from the string
554 $v_list = explode(PCLZIP_SEPARATOR, $p_filelist);
556 // ----- Call the create fct
557 $v_result = $this->privAdd($v_list, $p_result_list, $v_add_path, $v_remove_path, $v_remove_all_path, $v_options);
560 // ----- Invalid variable
564 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
565 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
571 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
576 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
577 return $p_result_list;
579 // --------------------------------------------------------------------------------
581 // --------------------------------------------------------------------------------
582 // Function : listContent()
584 // This public method, gives the list of the files and directories, with their
586 // The properties of each entries in the list are (used also in other functions) :
587 // filename : Name of the file. For a create or add action it is the filename
588 // given by the user. For an extract function it is the filename
589 // of the extracted file.
590 // stored_filename : Name of the file / directory stored in the archive.
591 // size : Size of the stored file.
592 // compressed_size : Size of the file's data compressed in the archive
593 // (without the headers overhead)
594 // mtime : Last known modification date of the file (UNIX timestamp)
595 // comment : Comment associated with the file
596 // folder : true | false
597 // index : index of the file in the archive
598 // status : status of the action (depending of the action) :
601 // filtered : the file / dir is not extracted (filtered by user)
602 // already_a_directory : the file can not be extracted because a
603 // directory with the same name already exists
604 // write_protected : the file can not be extracted because a file
605 // with the same name already exists and is
607 // newer_exist : the file was not extracted because a newer file exists
608 // path_creation_fail : the file is not extracted because the folder
609 // does not exists and can not be created
610 // write_error : the file was not extracted because there was a
611 // error while writing the file
612 // read_error : the file was not extracted because there was a error
613 // while reading the file
614 // invalid_header : the file was not extracted because of an archive
615 // format error (bad file header)
616 // Note that each time a method can continue operating when there
617 // is an action error on a file, the error is only logged in the file status.
619 // 0 on an unrecoverable failure,
620 // The list of the files in the archive.
621 // --------------------------------------------------------------------------------
622 function listContent()
624 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");
627 // ----- Reset the error handler
628 $this->privErrorReset();
630 // ----- Check archive
631 if (!$this->privCheckFormat()) {
632 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
636 // ----- Call the extracting fct
638 if (($v_result = $this->privList($p_list)) != 1)
641 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
646 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
649 // --------------------------------------------------------------------------------
651 // --------------------------------------------------------------------------------
653 // extract($p_path="./", $p_remove_path="")
654 // extract([$p_option, $p_option_value, ...])
656 // This method supports two synopsis. The first one is historical.
657 // This method extract all the files / directories from the archive to the
658 // folder indicated in $p_path.
659 // If you want to ignore the 'root' part of path of the memorized files
660 // you can indicate this in the optional $p_remove_path parameter.
661 // By default, if a newer file with the same name already exists, the
662 // file is not extracted.
664 // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
665 // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
666 // at the end of the path value of PCLZIP_OPT_PATH.
668 // $p_path : Path where the files and directories are to be extracted
669 // $p_remove_path : First part ('root' part) of the memorized path
670 // (if any similar) to remove while extracting.
673 // PCLZIP_OPT_ADD_PATH :
674 // PCLZIP_OPT_REMOVE_PATH :
675 // PCLZIP_OPT_REMOVE_ALL_PATH :
676 // PCLZIP_CB_PRE_EXTRACT :
677 // PCLZIP_CB_POST_EXTRACT :
679 // 0 or a negative value on failure,
680 // The list of the extracted files, with a status of the action.
681 // (see PclZip::listContent() for list entry format)
682 // --------------------------------------------------------------------------------
683 //function extract($p_path="./", $p_remove_path="")
684 function extract(/* options */)
686 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
689 // ----- Reset the error handler
690 $this->privErrorReset();
692 // ----- Check archive
693 if (!$this->privCheckFormat()) {
694 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
698 // ----- Set default values
699 $v_options = array();
703 $v_remove_all_path = false;
705 // ----- Look for variable options arguments
706 $v_size = func_num_args();
707 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
709 // ----- Default values for option
710 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
712 // ----- Look for arguments
714 // ----- Get the arguments
715 $v_arg_list = &func_get_args();
717 // ----- Look for first arg
718 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
719 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
721 // ----- Parse the options
722 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
723 array (PCLZIP_OPT_PATH => 'optional',
724 PCLZIP_OPT_REMOVE_PATH => 'optional',
725 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
726 PCLZIP_OPT_ADD_PATH => 'optional',
727 PCLZIP_CB_PRE_EXTRACT => 'optional',
728 PCLZIP_CB_POST_EXTRACT => 'optional',
729 PCLZIP_OPT_SET_CHMOD => 'optional',
730 PCLZIP_OPT_BY_NAME => 'optional',
731 PCLZIP_OPT_BY_EREG => 'optional',
732 PCLZIP_OPT_BY_PREG => 'optional',
733 PCLZIP_OPT_BY_INDEX => 'optional',
734 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
735 PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
736 PCLZIP_OPT_REPLACE_NEWER => 'optional'
737 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
739 if ($v_result != 1) {
740 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
744 // ----- Set the arguments
745 if (isset($v_options[PCLZIP_OPT_PATH])) {
746 $v_path = $v_options[PCLZIP_OPT_PATH];
748 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
749 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
751 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
752 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
754 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
755 // ----- Check for '/' in last path char
756 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
759 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
763 // ----- Look for 2 args
764 // Here we need to support the first historic synopsis of the
767 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
769 // ----- Get the first argument
770 $v_path = $v_arg_list[0];
772 // ----- Look for the optional second argument
774 $v_remove_path = $v_arg_list[1];
776 else if ($v_size > 2) {
778 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
781 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
788 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
790 // ----- Call the extracting fct
792 $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
793 $v_remove_all_path, $v_options);
796 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
801 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
804 // --------------------------------------------------------------------------------
807 // --------------------------------------------------------------------------------
809 // extractByIndex($p_index, $p_path="./", $p_remove_path="")
810 // extractByIndex($p_index, [$p_option, $p_option_value, ...])
812 // This method supports two synopsis. The first one is historical.
813 // This method is doing a partial extract of the archive.
814 // The extracted files or folders are identified by their index in the
815 // archive (from 0 to n).
816 // Note that if the index identify a folder, only the folder entry is
817 // extracted, not all the files included in the archive.
819 // $p_index : A single index (integer) or a string of indexes of files to
820 // extract. The form of the string is "0,4-6,8-12" with only numbers
821 // and '-' for range or ',' to separate ranges. No spaces or ';'
823 // $p_path : Path where the files and directories are to be extracted
824 // $p_remove_path : First part ('root' part) of the memorized path
825 // (if any similar) to remove while extracting.
828 // PCLZIP_OPT_ADD_PATH :
829 // PCLZIP_OPT_REMOVE_PATH :
830 // PCLZIP_OPT_REMOVE_ALL_PATH :
831 // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
833 // The resulting content is in a new field 'content' in the file
835 // This option must be used alone (any other options are ignored).
836 // PCLZIP_CB_PRE_EXTRACT :
837 // PCLZIP_CB_POST_EXTRACT :
840 // The list of the extracted files, with a status of the action.
841 // (see PclZip::listContent() for list entry format)
842 // --------------------------------------------------------------------------------
843 function extractByIndex($p_index /* $options */)
845 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");
848 // ----- Reset the error handler
849 $this->privErrorReset();
851 // ----- Check archive
852 if (!$this->privCheckFormat()) {
853 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
857 // ----- Set default values
858 $v_options = array();
862 $v_remove_all_path = false;
864 // ----- Look for variable options arguments
865 $v_size = func_num_args();
866 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
868 // ----- Default values for option
869 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
871 // ----- Look for arguments
873 // ----- Get the arguments
874 $v_arg_list = &func_get_args();
876 // ----- Remove form the options list the first argument
877 array_shift($v_arg_list);
880 // ----- Look for first arg
881 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
882 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
884 // ----- Parse the options
885 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
886 array (PCLZIP_OPT_PATH => 'optional',
887 PCLZIP_OPT_REMOVE_PATH => 'optional',
888 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
889 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
890 PCLZIP_OPT_ADD_PATH => 'optional',
891 PCLZIP_CB_PRE_EXTRACT => 'optional',
892 PCLZIP_CB_POST_EXTRACT => 'optional',
893 PCLZIP_OPT_SET_CHMOD => 'optional',
894 PCLZIP_OPT_REPLACE_NEWER => 'optional'
895 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
897 if ($v_result != 1) {
898 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
902 // ----- Set the arguments
903 if (isset($v_options[PCLZIP_OPT_PATH])) {
904 $v_path = $v_options[PCLZIP_OPT_PATH];
906 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
907 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
909 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
910 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
912 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
913 // ----- Check for '/' in last path char
914 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
917 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
919 if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
920 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
921 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");
924 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");
928 // ----- Look for 2 args
929 // Here we need to support the first historic synopsis of the
932 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
934 // ----- Get the first argument
935 $v_path = $v_arg_list[0];
937 // ----- Look for the optional second argument
939 $v_remove_path = $v_arg_list[1];
941 else if ($v_size > 2) {
943 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
946 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
953 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
956 // Here I want to reuse extractByRule(), so I need to parse the $p_index
957 // with privParseOptions()
958 $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
959 $v_options_trick = array();
960 $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
961 array (PCLZIP_OPT_BY_INDEX => 'optional' ));
962 if ($v_result != 1) {
963 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
966 $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
968 // ----- Call the extracting fct
969 if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
970 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
975 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
978 // --------------------------------------------------------------------------------
980 // --------------------------------------------------------------------------------
982 // delete([$p_option, $p_option_value, ...])
984 // This method removes files from the archive.
985 // If no parameters are given, then all the archive is emptied.
987 // None or optional arguments.
989 // PCLZIP_OPT_BY_INDEX :
990 // PCLZIP_OPT_BY_NAME :
991 // PCLZIP_OPT_BY_EREG :
992 // PCLZIP_OPT_BY_PREG :
995 // The list of the files which are still present in the archive.
996 // (see PclZip::listContent() for list entry format)
997 // --------------------------------------------------------------------------------
998 function delete(/* options */)
1000 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
1003 // ----- Reset the error handler
1004 $this->privErrorReset();
1006 // ----- Check archive
1007 if (!$this->privCheckFormat()) {
1008 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1012 // ----- Set default values
1013 $v_options = array();
1015 // ----- Look for variable options arguments
1016 $v_size = func_num_args();
1017 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
1019 // ----- Look for arguments
1021 // ----- Get the arguments
1022 $v_arg_list = &func_get_args();
1024 // ----- Parse the options
1025 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1026 array (PCLZIP_OPT_BY_NAME => 'optional',
1027 PCLZIP_OPT_BY_EREG => 'optional',
1028 PCLZIP_OPT_BY_PREG => 'optional',
1029 PCLZIP_OPT_BY_INDEX => 'optional' ));
1030 if ($v_result != 1) {
1031 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1036 // ----- Magic quotes trick
1037 $this->privDisableMagicQuotes();
1039 // ----- Call the delete fct
1041 if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1042 $this->privSwapBackMagicQuotes();
1044 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
1048 // ----- Magic quotes trick
1049 $this->privSwapBackMagicQuotes();
1052 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
1055 // --------------------------------------------------------------------------------
1057 // --------------------------------------------------------------------------------
1058 // Function : deleteByIndex()
1060 // ***** Deprecated *****
1061 // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1062 // --------------------------------------------------------------------------------
1063 function deleteByIndex($p_index)
1065 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
1067 $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1070 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
1073 // --------------------------------------------------------------------------------
1075 // --------------------------------------------------------------------------------
1076 // Function : properties()
1078 // This method gives the properties of the archive.
1079 // The properties are :
1080 // nb : Number of files in the archive
1081 // comment : Comment associated with the archive file
1082 // status : not_exist, ok
1087 // An array with the archive properties.
1088 // --------------------------------------------------------------------------------
1089 function properties()
1091 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");
1093 // ----- Reset the error handler
1094 $this->privErrorReset();
1096 // ----- Magic quotes trick
1097 $this->privDisableMagicQuotes();
1099 // ----- Check archive
1100 if (!$this->privCheckFormat()) {
1101 $this->privSwapBackMagicQuotes();
1102 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1106 // ----- Default properties
1108 $v_prop['comment'] = '';
1110 $v_prop['status'] = 'not_exist';
1112 // ----- Look if file exists
1113 if (@is_file($this->zipname))
1115 // ----- Open the zip file
1116 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
1117 if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1119 $this->privSwapBackMagicQuotes();
1122 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1125 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);
1129 // ----- Read the central directory informations
1130 $v_central_dir = array();
1131 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1133 $this->privSwapBackMagicQuotes();
1134 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1138 // ----- Close the zip file
1139 $this->privCloseFd();
1141 // ----- Set the user attributes
1142 $v_prop['comment'] = $v_central_dir['comment'];
1143 $v_prop['nb'] = $v_central_dir['entries'];
1144 $v_prop['status'] = 'ok';
1147 // ----- Magic quotes trick
1148 $this->privSwapBackMagicQuotes();
1151 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);
1154 // --------------------------------------------------------------------------------
1156 // --------------------------------------------------------------------------------
1157 // Function : duplicate()
1159 // This method creates an archive by copying the content of an other one. If
1160 // the archive already exist, it is replaced by the new one without any warning.
1162 // $p_archive : The filename of a valid archive, or
1163 // a valid PclZip object.
1166 // 0 or a negative value on error (error code).
1167 // --------------------------------------------------------------------------------
1168 function duplicate($p_archive)
1170 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");
1173 // ----- Reset the error handler
1174 $this->privErrorReset();
1176 // ----- Look if the $p_archive is a PclZip object
1177 if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1179 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");
1181 // ----- Duplicate the archive
1182 $v_result = $this->privDuplicate($p_archive->zipname);
1185 // ----- Look if the $p_archive is a string (so a filename)
1186 else if (is_string($p_archive))
1188 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");
1190 // ----- Check that $p_archive is a valid zip file
1191 // TBC : Should also check the archive format
1192 if (!is_file($p_archive)) {
1194 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1195 $v_result = PCLZIP_ERR_MISSING_FILE;
1198 // ----- Duplicate the archive
1199 $v_result = $this->privDuplicate($p_archive);
1203 // ----- Invalid variable
1207 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1208 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1212 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1215 // --------------------------------------------------------------------------------
1217 // --------------------------------------------------------------------------------
1218 // Function : merge()
1220 // This method merge the $p_archive_to_add archive at the end of the current
1222 // If the archive ($this) does not exist, the merge becomes a duplicate.
1223 // If the $p_archive_to_add archive does not exist, the merge is a success.
1225 // $p_archive_to_add : It can be directly the filename of a valid zip archive,
1226 // or a PclZip object archive.
1229 // 0 or negative values on error (see below).
1230 // --------------------------------------------------------------------------------
1231 function merge($p_archive_to_add)
1233 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");
1236 // ----- Reset the error handler
1237 $this->privErrorReset();
1239 // ----- Check archive
1240 if (!$this->privCheckFormat()) {
1241 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1245 // ----- Look if the $p_archive_to_add is a PclZip object
1246 if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1248 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");
1250 // ----- Merge the archive
1251 $v_result = $this->privMerge($p_archive_to_add);
1254 // ----- Look if the $p_archive_to_add is a string (so a filename)
1255 else if (is_string($p_archive_to_add))
1257 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");
1259 // ----- Create a temporary archive
1260 $v_object_archive = new PclZip($p_archive_to_add);
1262 // ----- Merge the archive
1263 $v_result = $this->privMerge($v_object_archive);
1266 // ----- Invalid variable
1270 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1271 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1275 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1278 // --------------------------------------------------------------------------------
1282 // --------------------------------------------------------------------------------
1283 // Function : errorCode()
1286 // --------------------------------------------------------------------------------
1287 function errorCode()
1289 if (PCLZIP_ERROR_EXTERNAL == 1) {
1290 return(PclErrorCode());
1293 return($this->error_code);
1296 // --------------------------------------------------------------------------------
1298 // --------------------------------------------------------------------------------
1299 // Function : errorName()
1302 // --------------------------------------------------------------------------------
1303 function errorName($p_with_code=false)
1305 $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1306 PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1307 PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1308 PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1309 PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1310 PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1311 PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1312 PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1313 PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1314 PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1315 PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1316 PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1317 PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1318 PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1319 PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1320 PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1321 PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1322 PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1323 PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION' );
1325 if (isset($v_name[$this->error_code])) {
1326 $v_value = $v_name[$this->error_code];
1329 $v_value = 'NoName';
1333 return($v_value.' ('.$this->error_code.')');
1339 // --------------------------------------------------------------------------------
1341 // --------------------------------------------------------------------------------
1342 // Function : errorInfo()
1345 // --------------------------------------------------------------------------------
1346 function errorInfo($p_full=false)
1348 if (PCLZIP_ERROR_EXTERNAL == 1) {
1349 return(PclErrorString());
1353 return($this->errorName(true)." : ".$this->error_string);
1356 return($this->error_string." [code ".$this->error_code."]");
1360 // --------------------------------------------------------------------------------
1363 // --------------------------------------------------------------------------------
1364 // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1366 // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1367 // --------------------------------------------------------------------------------
1371 // --------------------------------------------------------------------------------
1372 // Function : privCheckFormat()
1374 // This method check that the archive exists and is a valid zip archive.
1375 // Several level of check exists. (futur)
1377 // $p_level : Level of check. Default 0.
1378 // 0 : Check the first bytes (magic codes) (default value))
1379 // 1 : 0 + Check the central directory (futur)
1380 // 2 : 1 + Check each file header (futur)
1383 // false on error, the error code is set.
1384 // --------------------------------------------------------------------------------
1385 function privCheckFormat($p_level=0)
1387 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");
1390 // ----- Reset the file system cache
1393 // ----- Reset the error handler
1394 $this->privErrorReset();
1396 // ----- Look if the file exits
1397 if (!is_file($this->zipname)) {
1399 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1400 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
1404 // ----- Check that the file is readeable
1405 if (!is_readable($this->zipname)) {
1407 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1408 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
1412 // ----- Check the magic code
1415 // ----- Check the central header
1418 // ----- Check each file header
1422 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1425 // --------------------------------------------------------------------------------
1427 // --------------------------------------------------------------------------------
1428 // Function : privParseOptions()
1430 // This internal methods reads the variable list of arguments ($p_options_list,
1431 // $p_size) and generate an array with the options and values ($v_result_list).
1432 // $v_requested_options contains the options that can be present and those that
1434 // $v_requested_options is an array, with the option value as key, and 'optional',
1435 // or 'mandatory' as value.
1441 // --------------------------------------------------------------------------------
1442 function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1444 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");
1447 // ----- Read the options
1449 while ($i<$p_size) {
1450 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");
1452 // ----- Check if the option is requested
1453 if (!isset($v_requested_options[$p_options_list[$i]])) {
1455 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1458 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1459 return PclZip::errorCode();
1462 // ----- Look for next option
1463 switch ($p_options_list[$i]) {
1464 // ----- Look for options that request a path value
1465 case PCLZIP_OPT_PATH :
1466 case PCLZIP_OPT_REMOVE_PATH :
1467 case PCLZIP_OPT_ADD_PATH :
1468 // ----- Check the number of parameters
1469 if (($i+1) >= $p_size) {
1471 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1474 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1475 return PclZip::errorCode();
1478 // ----- Get the value
1479 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1480 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1484 // ----- Look for options that request an array of string for value
1485 case PCLZIP_OPT_BY_NAME :
1486 // ----- Check the number of parameters
1487 if (($i+1) >= $p_size) {
1489 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1492 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1493 return PclZip::errorCode();
1496 // ----- Get the value
1497 if (is_string($p_options_list[$i+1])) {
1498 $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1500 else if (is_array($p_options_list[$i+1])) {
1501 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1505 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1508 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1509 return PclZip::errorCode();
1511 ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1515 // ----- Look for options that request an EREG or PREG expression
1516 case PCLZIP_OPT_BY_EREG :
1517 case PCLZIP_OPT_BY_PREG :
1518 //case PCLZIP_OPT_CRYPT :
1519 // ----- Check the number of parameters
1520 if (($i+1) >= $p_size) {
1522 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1525 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1526 return PclZip::errorCode();
1529 // ----- Get the value
1530 if (is_string($p_options_list[$i+1])) {
1531 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1535 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1538 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1539 return PclZip::errorCode();
1541 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1545 // ----- Look for options that takes a string
1546 case PCLZIP_OPT_COMMENT :
1547 case PCLZIP_OPT_ADD_COMMENT :
1548 case PCLZIP_OPT_PREPEND_COMMENT :
1549 // ----- Check the number of parameters
1550 if (($i+1) >= $p_size) {
1552 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1553 "Missing parameter value for option '"
1554 .PclZipUtilOptionText($p_options_list[$i])
1558 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1559 return PclZip::errorCode();
1562 // ----- Get the value
1563 if (is_string($p_options_list[$i+1])) {
1564 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1568 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1569 "Wrong parameter value for option '"
1570 .PclZipUtilOptionText($p_options_list[$i])
1574 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1575 return PclZip::errorCode();
1577 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1581 // ----- Look for options that request an array of index
1582 case PCLZIP_OPT_BY_INDEX :
1583 // ----- Check the number of parameters
1584 if (($i+1) >= $p_size) {
1586 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1589 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1590 return PclZip::errorCode();
1593 // ----- Get the value
1594 $v_work_list = array();
1595 if (is_string($p_options_list[$i+1])) {
1596 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
1598 // ----- Remove spaces
1599 $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1601 // ----- Parse items
1602 $v_work_list = explode(",", $p_options_list[$i+1]);
1604 else if (is_integer($p_options_list[$i+1])) {
1605 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
1606 $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1608 else if (is_array($p_options_list[$i+1])) {
1609 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
1610 $v_work_list = $p_options_list[$i+1];
1614 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1617 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1618 return PclZip::errorCode();
1621 // ----- Reduce the index list
1622 // each index item in the list must be a couple with a start and
1623 // an end value : [0,3], [5-5], [8-10], ...
1624 // ----- Check the format of each item
1627 for ($j=0; $j<sizeof($v_work_list); $j++) {
1628 // ----- Explode the item
1629 $v_item_list = explode("-", $v_work_list[$j]);
1630 $v_size_item_list = sizeof($v_item_list);
1632 // ----- TBC : Here we might check that each item is a
1635 // ----- Look for single value
1636 if ($v_size_item_list == 1) {
1637 // ----- Set the option value
1638 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1639 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1641 elseif ($v_size_item_list == 2) {
1642 // ----- Set the option value
1643 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1644 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1648 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1651 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1652 return PclZip::errorCode();
1655 //--(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']."]");
1657 // ----- Look for list sort
1658 if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1659 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
1662 // ----- TBC : An automatic sort should be writen ...
1664 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1667 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1668 return PclZip::errorCode();
1670 $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1673 // ----- Sort the items
1675 // TBC : To Be Completed
1676 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
1679 // ----- Next option
1683 // ----- Look for options that request no value
1684 case PCLZIP_OPT_REMOVE_ALL_PATH :
1685 case PCLZIP_OPT_EXTRACT_AS_STRING :
1686 case PCLZIP_OPT_NO_COMPRESSION :
1687 case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1688 case PCLZIP_OPT_REPLACE_NEWER :
1689 case PCLZIP_OPT_STOP_ON_ERROR :
1690 $v_result_list[$p_options_list[$i]] = true;
1691 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1694 // ----- Look for options that request an octal value
1695 case PCLZIP_OPT_SET_CHMOD :
1696 // ----- Check the number of parameters
1697 if (($i+1) >= $p_size) {
1699 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1702 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1703 return PclZip::errorCode();
1706 // ----- Get the value
1707 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1708 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1712 // ----- Look for options that request a call-back
1713 case PCLZIP_CB_PRE_EXTRACT :
1714 case PCLZIP_CB_POST_EXTRACT :
1715 case PCLZIP_CB_PRE_ADD :
1716 case PCLZIP_CB_POST_ADD :
1718 case PCLZIP_CB_PRE_DELETE :
1719 case PCLZIP_CB_POST_DELETE :
1720 case PCLZIP_CB_PRE_LIST :
1721 case PCLZIP_CB_POST_LIST :
1723 // ----- Check the number of parameters
1724 if (($i+1) >= $p_size) {
1726 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1729 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1730 return PclZip::errorCode();
1733 // ----- Get the value
1734 $v_function_name = $p_options_list[$i+1];
1735 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");
1737 // ----- Check that the value is a valid existing function
1738 if (!function_exists($v_function_name)) {
1740 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1743 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1744 return PclZip::errorCode();
1747 // ----- Set the attribute
1748 $v_result_list[$p_options_list[$i]] = $v_function_name;
1754 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1755 "Unknown parameter '"
1756 .$p_options_list[$i]."'");
1759 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1760 return PclZip::errorCode();
1763 // ----- Next options
1767 // ----- Look for mandatory options
1768 if ($v_requested_options !== false) {
1769 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1770 // ----- Look for mandatory option
1771 if ($v_requested_options[$key] == 'mandatory') {
1772 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
1773 // ----- Look if present
1774 if (!isset($v_result_list[$key])) {
1776 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1779 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1780 return PclZip::errorCode();
1787 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1790 // --------------------------------------------------------------------------------
1792 // --------------------------------------------------------------------------------
1793 // Function : privCreate()
1797 // --------------------------------------------------------------------------------
1798 function privCreate($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
1800 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list, result_list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1802 $v_list_detail = array();
1804 // ----- Magic quotes trick
1805 $this->privDisableMagicQuotes();
1807 // ----- Open the file in write mode
1808 if (($v_result = $this->privOpenFd('wb')) != 1)
1811 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1815 // ----- Add the list of files
1816 $v_result = $this->privAddList($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);
1819 $this->privCloseFd();
1821 // ----- Magic quotes trick
1822 $this->privSwapBackMagicQuotes();
1825 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1828 // --------------------------------------------------------------------------------
1830 // --------------------------------------------------------------------------------
1831 // Function : privAdd()
1835 // --------------------------------------------------------------------------------
1836 function privAdd($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
1838 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list, result_list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
1840 $v_list_detail = array();
1842 // ----- Look if the archive exists or is empty
1843 if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
1845 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
1847 // ----- Do a create
1848 $v_result = $this->privCreate($p_list, $p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options);
1851 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1854 // ----- Magic quotes trick
1855 $this->privDisableMagicQuotes();
1857 // ----- Open the zip file
1858 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
1859 if (($v_result=$this->privOpenFd('rb')) != 1)
1861 // ----- Magic quotes trick
1862 $this->privSwapBackMagicQuotes();
1865 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1869 // ----- Read the central directory informations
1870 $v_central_dir = array();
1871 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1873 $this->privCloseFd();
1874 $this->privSwapBackMagicQuotes();
1875 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1879 // ----- Go to beginning of File
1880 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
1881 @rewind($this->zip_fd);
1882 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
1884 // ----- Creates a temporay file
1885 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
1887 // ----- Open the temporary file in write mode
1888 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
1889 if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
1891 $this->privCloseFd();
1892 $this->privSwapBackMagicQuotes();
1894 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
1897 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1898 return PclZip::errorCode();
1901 // ----- Copy the files from the archive to the temporary file
1902 // TBC : Here I should better append the file and go back to erase the central dir
1903 $v_size = $v_central_dir['offset'];
1904 while ($v_size != 0)
1906 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1907 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
1908 $v_buffer = fread($this->zip_fd, $v_read_size);
1909 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
1910 $v_size -= $v_read_size;
1913 // ----- Swap the file descriptor
1914 // Here is a trick : I swap the temporary fd with the zip fd, in order to use
1915 // the following methods on the temporary fil and not the real archive
1916 $v_swap = $this->zip_fd;
1917 $this->zip_fd = $v_zip_temp_fd;
1918 $v_zip_temp_fd = $v_swap;
1920 // ----- Add the files
1921 $v_header_list = array();
1922 if (($v_result = $this->privAddFileList($p_list, $v_header_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
1924 fclose($v_zip_temp_fd);
1925 $this->privCloseFd();
1926 @unlink($v_zip_temp_name);
1927 $this->privSwapBackMagicQuotes();
1930 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1934 // ----- Store the offset of the central dir
1935 $v_offset = @ftell($this->zip_fd);
1936 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
1938 // ----- Copy the block of file headers from the old archive
1939 $v_size = $v_central_dir['size'];
1940 while ($v_size != 0)
1942 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1943 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
1944 $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
1945 @fwrite($this->zip_fd, $v_buffer, $v_read_size);
1946 $v_size -= $v_read_size;
1949 // ----- Create the Central Dir files header
1950 for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
1952 // ----- Create the file header
1953 if ($v_header_list[$i]['status'] == 'ok') {
1954 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
1955 fclose($v_zip_temp_fd);
1956 $this->privCloseFd();
1957 @unlink($v_zip_temp_name);
1958 $this->privSwapBackMagicQuotes();
1961 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1967 // ----- Transform the header to a 'usable' info
1968 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
1971 // ----- Zip file comment
1972 $v_comment = $v_central_dir['comment'];
1973 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
1974 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
1976 if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
1977 $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
1979 if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
1980 $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
1983 // ----- Calculate the size of the central header
1984 $v_size = @ftell($this->zip_fd)-$v_offset;
1986 // ----- Create the central dir footer
1987 if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
1989 // ----- Reset the file list
1990 unset($v_header_list);
1991 $this->privSwapBackMagicQuotes();
1994 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1998 // ----- Swap back the file descriptor
1999 $v_swap = $this->zip_fd;
2000 $this->zip_fd = $v_zip_temp_fd;
2001 $v_zip_temp_fd = $v_swap;
2004 $this->privCloseFd();
2006 // ----- Close the temporary file
2007 @fclose($v_zip_temp_fd);
2009 // ----- Magic quotes trick
2010 $this->privSwapBackMagicQuotes();
2012 // ----- Delete the zip file
2013 // TBC : I should test the result ...
2014 @unlink($this->zipname);
2016 // ----- Rename the temporary file
2017 // TBC : I should test the result ...
2018 //@rename($v_zip_temp_name, $this->zipname);
2019 PclZipUtilRename($v_zip_temp_name, $this->zipname);
2022 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2025 // --------------------------------------------------------------------------------
2027 // --------------------------------------------------------------------------------
2028 // Function : privOpenFd()
2031 // --------------------------------------------------------------------------------
2032 function privOpenFd($p_mode)
2034 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);
2037 // ----- Look if already open
2038 if ($this->zip_fd != 0)
2041 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2044 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2045 return PclZip::errorCode();
2048 // ----- Open the zip file
2049 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');
2050 if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2053 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2056 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2057 return PclZip::errorCode();
2061 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2064 // --------------------------------------------------------------------------------
2066 // --------------------------------------------------------------------------------
2067 // Function : privCloseFd()
2070 // --------------------------------------------------------------------------------
2071 function privCloseFd()
2073 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");
2076 if ($this->zip_fd != 0)
2077 @fclose($this->zip_fd);
2081 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2084 // --------------------------------------------------------------------------------
2086 // --------------------------------------------------------------------------------
2087 // Function : privAddList()
2089 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2090 // different from the real path of the file. This is usefull if you want to have PclTar
2091 // running in any directory, and memorize relative path from an other directory.
2093 // $p_list : An array containing the file or directory names to add in the tar
2094 // $p_result_list : list of added files with their properties (specially the status field)
2095 // $p_add_dir : Path to add in the filename path archived
2096 // $p_remove_dir : Path to remove in the filename path archived
2098 // --------------------------------------------------------------------------------
2099 function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2101 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
2104 // ----- Add the files
2105 $v_header_list = array();
2106 if (($v_result = $this->privAddFileList($p_list, $v_header_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
2109 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2113 // ----- Store the offset of the central dir
2114 $v_offset = @ftell($this->zip_fd);
2116 // ----- Create the Central Dir files header
2117 for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2119 // ----- Create the file header
2120 if ($v_header_list[$i]['status'] == 'ok') {
2121 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2123 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2129 // ----- Transform the header to a 'usable' info
2130 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2133 // ----- Zip file comment
2135 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2136 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2139 // ----- Calculate the size of the central header
2140 $v_size = @ftell($this->zip_fd)-$v_offset;
2142 // ----- Create the central dir footer
2143 if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2145 // ----- Reset the file list
2146 unset($v_header_list);
2149 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2154 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2157 // --------------------------------------------------------------------------------
2159 // --------------------------------------------------------------------------------
2160 // Function : privAddFileList()
2162 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2163 // different from the real path of the file. This is usefull if you want to
2164 // run the lib in any directory, and memorize relative path from an other directory.
2166 // $p_list : An array containing the file or directory names to add in the tar
2167 // $p_result_list : list of added files with their properties (specially the status field)
2168 // $p_add_dir : Path to add in the filename path archived
2169 // $p_remove_dir : Path to remove in the filename path archived
2171 // --------------------------------------------------------------------------------
2172 function privAddFileList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2174 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "list, add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
2176 $v_header = array();
2178 // ----- Recuperate the current number of elt in list
2179 $v_nb = sizeof($p_result_list);
2180 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have $v_nb elements");
2182 // ----- Loop on the files
2183 for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++) {
2184 // ----- Recuperate the filename
2185 $p_filename = PclZipUtilTranslateWinPath($p_list[$j], false);
2187 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file [$p_filename]");
2189 // ----- Skip empty file names
2190 if ($p_filename == "") {
2191 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
2195 // ----- Check the filename
2196 if (!file_exists($p_filename)) {
2198 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '$p_filename' does not exists");
2199 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '$p_filename' does not exists");
2202 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2203 return PclZip::errorCode();
2206 // ----- Look if it is a file or a dir with no all pathnre move
2207 if ((is_file($p_filename)) || ((is_dir($p_filename)) && !$p_remove_all_dir)) {
2208 // ----- Add the file
2209 if (($v_result = $this->privAddFile($p_filename, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1)
2211 // ----- Return status
2212 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2216 // ----- Store the file infos
2217 $p_result_list[$v_nb++] = $v_header;
2220 // ----- Look for directory
2221 if (@is_dir($p_filename))
2223 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "$p_filename is a directory");
2225 // ----- Look for path
2226 if ($p_filename != ".")
2227 $v_path = $p_filename."/";
2231 // ----- Read the directory for files and sub-directories
2232 if ($p_hdir = @opendir($p_filename)) {
2233 // $p_hitem = @readdir($p_hdir); // '.' directory
2234 // $p_hitem = @readdir($p_hdir); // '..' directory
2235 while (($p_hitem = @readdir($p_hdir)) !== false) {
2236 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for $p_hitem in the directory");
2238 // ----- Skip '.' and '..'
2239 if (($p_hitem == '.') || ($p_hitem == '..')) {
2243 // ----- Look for a file
2244 if (@is_file($v_path.$p_hitem)) {
2245 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Add the file '".$v_path.$p_hitem."'");
2247 // ----- Add the file
2248 if (($v_result = $this->privAddFile($v_path.$p_hitem, $v_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, $p_options)) != 1) {
2249 // ----- Return status
2250 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2254 // ----- Store the file infos
2255 $p_result_list[$v_nb++] = $v_header;
2258 // ----- Recursive call to privAddFileList()
2259 else if (@is_dir($v_path.$p_hitem)) {
2260 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Add the directory '".$v_path.$p_hitem."'");
2262 // ----- Need an array as parameter
2263 $p_temp_list[0] = $v_path.$p_hitem;
2264 $v_result = $this->privAddFileList($p_temp_list, $p_result_list,
2265 $p_add_dir, $p_remove_dir,
2266 $p_remove_all_dir, $p_options);
2268 // ----- Update the number of elements of the list
2269 $v_nb = sizeof($p_result_list);
2272 // ----- Unsupported file types
2274 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Unsupported file type");
2280 // ----- Free memory for the recursive loop
2281 unset($p_temp_list);
2286 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have $v_nb elements");
2289 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2292 // --------------------------------------------------------------------------------
2294 // --------------------------------------------------------------------------------
2295 // Function : privAddFile()
2299 // --------------------------------------------------------------------------------
2300 function privAddFile($p_filename, &$p_header, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2302 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='$p_filename', add_dir='$p_add_dir', remove_dir='$p_remove_dir'");
2305 if ($p_filename == "")
2308 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2311 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2312 return PclZip::errorCode();
2315 // ----- Calculate the stored filename
2316 $v_stored_filename = $p_filename;
2318 // ----- Look for all path to remove
2319 if ($p_remove_all_dir) {
2320 $v_stored_filename = basename($p_filename);
2322 // ----- Look for partial path remove
2323 else if ($p_remove_dir != "")
2325 if (substr($p_remove_dir, -1) != '/')
2326 $p_remove_dir .= "/";
2328 if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./"))
2330 if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./"))
2331 $p_remove_dir = "./".$p_remove_dir;
2332 if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./"))
2333 $p_remove_dir = substr($p_remove_dir, 2);
2336 $v_compare = PclZipUtilPathInclusion($p_remove_dir, $p_filename);
2338 // if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir)
2341 if ($v_compare == 2) {
2342 $v_stored_filename = "";
2343 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder");
2346 $v_stored_filename = substr($p_filename, strlen($p_remove_dir));
2347 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'");
2351 // ----- Look for path to add
2352 if ($p_add_dir != "")
2354 if (substr($p_add_dir, -1) == "/")
2355 $v_stored_filename = $p_add_dir.$v_stored_filename;
2357 $v_stored_filename = $p_add_dir."/".$v_stored_filename;
2358 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
2361 // ----- Filename (reduce the path of stored name)
2362 $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
2364 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Filename (reduced) '$v_stored_filename', strlen ".strlen($v_stored_filename));
2366 // ----- Set the file properties
2368 $p_header['version'] = 20;
2369 $p_header['version_extracted'] = 10;
2370 $p_header['flag'] = 0;
2371 $p_header['compression'] = 0;
2372 $p_header['mtime'] = filemtime($p_filename);
2373 $p_header['crc'] = 0;
2374 $p_header['compressed_size'] = 0;
2375 $p_header['size'] = filesize($p_filename);
2376 $p_header['filename_len'] = strlen($p_filename);
2377 $p_header['extra_len'] = 0;
2378 $p_header['comment_len'] = 0;
2379 $p_header['disk'] = 0;
2380 $p_header['internal'] = 0;
2381 // $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
2382 $p_header['external'] = (is_file($p_filename)?0x00000000:0x00000010);
2383 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'");
2384 $p_header['offset'] = 0;
2385 $p_header['filename'] = $p_filename;
2386 $p_header['stored_filename'] = $v_stored_filename;
2387 $p_header['extra'] = '';
2388 $p_header['comment'] = '';
2389 $p_header['status'] = 'ok';
2390 $p_header['index'] = -1;
2393 // ----- Look for pre-add callback
2394 if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2395 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");
2397 // ----- Generate a local information
2398 $v_local_header = array();
2399 $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2401 // ----- Call the callback
2402 // Here I do not use call_user_func() because I need to send a reference to the
2404 eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2405 if ($v_result == 0) {
2406 // ----- Change the file status
2407 $p_header['status'] = "skipped";
2411 // ----- Update the informations
2412 // Only some fields can be modified
2413 if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2414 $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2415 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
2419 // ----- Look for empty stored filename
2420 if ($p_header['stored_filename'] == "") {
2421 $p_header['status'] = "filtered";
2424 // ----- Check the path length
2425 if (strlen($p_header['stored_filename']) > 0xFF) {
2426 $p_header['status'] = 'filename_too_long';
2429 // ----- Look if no error, or file not skipped
2430 if ($p_header['status'] == 'ok') {
2432 // ----- Look for a file
2433 if (is_file($p_filename))
2435 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file");
2436 // ----- Open the source file
2437 if (($v_file = @fopen($p_filename, "rb")) == 0) {
2438 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2439 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2440 return PclZip::errorCode();
2443 if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2444 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed");
2445 // ----- Read the file content
2446 $v_content_compressed = @fread($v_file, $p_header['size']);
2448 // ----- Calculate the CRC
2449 $p_header['crc'] = @crc32($v_content_compressed);
2451 // ----- Set header parameters
2452 $p_header['compressed_size'] = $p_header['size'];
2453 $p_header['compression'] = 0;
2456 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed");
2457 // ----- Read the file content
2458 $v_content = @fread($v_file, $p_header['size']);
2460 // ----- Calculate the CRC
2461 $p_header['crc'] = @crc32($v_content);
2463 // ----- Compress the file
2464 $v_content_compressed = @gzdeflate($v_content);
2466 // ----- Set header parameters
2467 $p_header['compressed_size'] = strlen($v_content_compressed);
2468 $p_header['compression'] = 8;
2471 // ----- Look for encryption
2473 if ((isset($p_options[PCLZIP_OPT_CRYPT]))
2474 && ($p_options[PCLZIP_OPT_CRYPT] != "")) {
2475 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ....");
2477 // Should be a random header
2478 $v_header = 'xxxxxxxxxxxx';
2479 $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed,
2480 $p_header['compressed_size'],
2485 $p_header['compressed_size'] += 12;
2486 $p_header['flag'] = 1;
2488 // ----- Add the header to the data
2489 $v_content_compressed = $v_header.$v_content_compressed;
2490 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed)."");
2494 // ----- Call the header generation
2495 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2497 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2501 // ----- Write the compressed (or not) content
2502 /* Try to speed up the code
2503 $v_binary_data = pack('a'.$p_header['compressed_size'],
2504 $v_content_compressed);
2505 @fwrite($this->zip_fd, $v_binary_data, $p_header['compressed_size']);
2507 @fwrite($this->zip_fd,
2508 $v_content_compressed, $p_header['compressed_size']);
2510 // ----- Close the file
2514 // ----- Look for a directory
2516 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder");
2517 // ----- Look for directory last '/'
2518 if (@substr($p_header['stored_filename'], -1) != '/') {
2519 $p_header['stored_filename'] .= '/';
2522 // ----- Set the file properties
2523 $p_header['size'] = 0;
2524 //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
2525 $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2527 // ----- Call the header generation
2528 if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2530 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2536 // ----- Look for pre-add callback
2537 if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2538 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");
2540 // ----- Generate a local information
2541 $v_local_header = array();
2542 $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2544 // ----- Call the callback
2545 // Here I do not use call_user_func() because I need to send a reference to the
2547 eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2548 if ($v_result == 0) {
2553 // ----- Update the informations
2554 // Nothing can be modified
2558 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2561 // --------------------------------------------------------------------------------
2563 // --------------------------------------------------------------------------------
2564 // Function : privWriteFileHeader()
2568 // --------------------------------------------------------------------------------
2569 function privWriteFileHeader(&$p_header)
2571 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
2575 //for(reset($p_header); $key = key($p_header); next($p_header)) {
2576 // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
2579 // ----- Store the offset position of the file
2580 $p_header['offset'] = ftell($this->zip_fd);
2581 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
2583 // ----- Transform UNIX mtime to DOS format mdate/mtime
2584 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
2585 $v_date = getdate($p_header['mtime']);
2586 $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2587 $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2589 // ----- Packed data
2590 $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
2591 $p_header['version_extracted'], $p_header['flag'],
2592 $p_header['compression'], $v_mtime, $v_mdate,
2593 $p_header['crc'], $p_header['compressed_size'],
2595 strlen($p_header['stored_filename']),
2596 $p_header['extra_len']);
2598 // ----- Write the first 148 bytes of the header in the archive
2599 fputs($this->zip_fd, $v_binary_data, 30);
2601 // ----- Write the variable fields
2602 if (strlen($p_header['stored_filename']) != 0)
2604 fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2606 if ($p_header['extra_len'] != 0)
2608 fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2612 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2615 // --------------------------------------------------------------------------------
2617 // --------------------------------------------------------------------------------
2618 // Function : privWriteCentralFileHeader()
2622 // --------------------------------------------------------------------------------
2623 function privWriteCentralFileHeader(&$p_header)
2625 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
2629 //for(reset($p_header); $key = key($p_header); next($p_header)) {
2630 // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
2633 // ----- Transform UNIX mtime to DOS format mdate/mtime
2634 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
2635 $v_date = getdate($p_header['mtime']);
2636 $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2637 $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2639 // ----- Packed data
2640 $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
2641 $p_header['version'], $p_header['version_extracted'],
2642 $p_header['flag'], $p_header['compression'],
2643 $v_mtime, $v_mdate, $p_header['crc'],
2644 $p_header['compressed_size'], $p_header['size'],
2645 strlen($p_header['stored_filename']),
2646 $p_header['extra_len'], $p_header['comment_len'],
2647 $p_header['disk'], $p_header['internal'],
2648 $p_header['external'], $p_header['offset']);
2650 // ----- Write the 42 bytes of the header in the zip file
2651 fputs($this->zip_fd, $v_binary_data, 46);
2653 // ----- Write the variable fields
2654 if (strlen($p_header['stored_filename']) != 0)
2656 fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2658 if ($p_header['extra_len'] != 0)
2660 fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2662 if ($p_header['comment_len'] != 0)
2664 fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
2668 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2671 // --------------------------------------------------------------------------------
2673 // --------------------------------------------------------------------------------
2674 // Function : privWriteCentralHeader()
2678 // --------------------------------------------------------------------------------
2679 function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
2681 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
2684 // ----- Packed data
2685 $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
2686 $p_nb_entries, $p_size,
2687 $p_offset, strlen($p_comment));
2689 // ----- Write the 22 bytes of the header in the zip file
2690 fputs($this->zip_fd, $v_binary_data, 22);
2692 // ----- Write the variable fields
2693 if (strlen($p_comment) != 0)
2695 fputs($this->zip_fd, $p_comment, strlen($p_comment));
2699 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2702 // --------------------------------------------------------------------------------
2704 // --------------------------------------------------------------------------------
2705 // Function : privList()
2709 // --------------------------------------------------------------------------------
2710 function privList(&$p_list)
2712 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
2715 // ----- Magic quotes trick
2716 $this->privDisableMagicQuotes();
2718 // ----- Open the zip file
2719 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2720 if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
2722 // ----- Magic quotes trick
2723 $this->privSwapBackMagicQuotes();
2726 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
2729 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2730 return PclZip::errorCode();
2733 // ----- Read the central directory informations
2734 $v_central_dir = array();
2735 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2737 $this->privSwapBackMagicQuotes();
2738 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2742 // ----- Go to beginning of Central Dir
2743 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Offset : ".$v_central_dir['offset']."'");
2744 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
2745 @rewind($this->zip_fd);
2746 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
2747 if (@fseek($this->zip_fd, $v_central_dir['offset']))
2749 $this->privSwapBackMagicQuotes();
2752 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
2755 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2756 return PclZip::errorCode();
2758 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position in file : ".ftell($this->zip_fd)."'");
2760 // ----- Read each entry
2761 for ($i=0; $i<$v_central_dir['entries']; $i++)
2763 // ----- Read the file header
2764 if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
2766 $this->privSwapBackMagicQuotes();
2767 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2770 $v_header['index'] = $i;
2772 // ----- Get the only interesting attributes
2773 $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
2777 // ----- Close the zip file
2778 $this->privCloseFd();
2780 // ----- Magic quotes trick
2781 $this->privSwapBackMagicQuotes();
2784 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2787 // --------------------------------------------------------------------------------
2789 // --------------------------------------------------------------------------------
2790 // Function : privConvertHeader2FileInfo()
2792 // This function takes the file informations from the central directory
2793 // entries and extract the interesting parameters that will be given back.
2794 // The resulting file infos are set in the array $p_info
2795 // $p_info['filename'] : Filename with full path. Given by user (add),
2796 // extracted in the filesystem (extract).
2797 // $p_info['stored_filename'] : Stored filename in the archive.
2798 // $p_info['size'] = Size of the file.
2799 // $p_info['compressed_size'] = Compressed size of the file.
2800 // $p_info['mtime'] = Last modification date of the file.
2801 // $p_info['comment'] = Comment associated with the file.
2802 // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
2803 // $p_info['status'] = status of the action on the file.
2806 // --------------------------------------------------------------------------------
2807 function privConvertHeader2FileInfo($p_header, &$p_info)
2809 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privConvertHeader2FileInfo", "Filename='".$p_header['filename']."'");
2812 // ----- Get the interesting attributes
2813 $p_info['filename'] = $p_header['filename'];
2814 $p_info['stored_filename'] = $p_header['stored_filename'];
2815 $p_info['size'] = $p_header['size'];
2816 $p_info['compressed_size'] = $p_header['compressed_size'];
2817 $p_info['mtime'] = $p_header['mtime'];
2818 $p_info['comment'] = $p_header['comment'];
2819 $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
2820 $p_info['index'] = $p_header['index'];
2821 $p_info['status'] = $p_header['status'];
2824 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2827 // --------------------------------------------------------------------------------
2829 // --------------------------------------------------------------------------------
2830 // Function : privExtractByRule()
2832 // Extract a file or directory depending of rules (by index, by name, ...)
2834 // $p_file_list : An array where will be placed the properties of each
2836 // $p_path : Path to add while writing the extracted files
2837 // $p_remove_path : Path to remove (from the file memorized path) while writing the
2838 // extracted files. If the path does not match the file path,
2839 // the file is extracted with its memorized path.
2840 // $p_remove_path does not apply to 'list' mode.
2841 // $p_path and $p_remove_path are commulative.
2843 // 1 on success,0 or less on error (see error code list)
2844 // --------------------------------------------------------------------------------
2845 function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
2847 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privExtractByRule", "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
2850 // ----- Magic quotes trick
2851 $this->privDisableMagicQuotes();
2853 // ----- Check the path
2854 if ( ($p_path == "")
2855 || ( (substr($p_path, 0, 1) != "/")
2856 && (substr($p_path, 0, 3) != "../")
2857 && (substr($p_path,1,2)!=":/")))
2858 $p_path = "./".$p_path;
2860 // ----- Reduce the path last (and duplicated) '/'
2861 if (($p_path != "./") && ($p_path != "/"))
2863 // ----- Look for the path end '/'
2864 while (substr($p_path, -1) == "/")
2866 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'");
2867 $p_path = substr($p_path, 0, strlen($p_path)-1);
2868 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]");
2872 // ----- Look for path to remove format (should end by /)
2873 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
2875 $p_remove_path .= '/';
2877 $p_remove_path_size = strlen($p_remove_path);
2879 // ----- Open the zip file
2880 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2881 if (($v_result = $this->privOpenFd('rb')) != 1)
2883 $this->privSwapBackMagicQuotes();
2884 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2888 // ----- Read the central directory informations
2889 $v_central_dir = array();
2890 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2892 // ----- Close the zip file
2893 $this->privCloseFd();
2894 $this->privSwapBackMagicQuotes();
2896 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2900 // ----- Start at beginning of Central Dir
2901 $v_pos_entry = $v_central_dir['offset'];
2903 // ----- Read each entry
2905 for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
2907 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry : '$i'");
2909 // ----- Read next Central dir entry
2910 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position before rewind : ".ftell($this->zip_fd)."'");
2911 @rewind($this->zip_fd);
2912 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Position after rewind : ".ftell($this->zip_fd)."'");
2913 if (@fseek($this->zip_fd, $v_pos_entry))
2915 // ----- Close the zip file
2916 $this->privCloseFd();
2917 $this->privSwapBackMagicQuotes();
2920 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
2923 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2924 return PclZip::errorCode();
2926 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Position after fseek : ".ftell($this->zip_fd)."'");
2928 // ----- Read the file header
2929 $v_header = array();
2930 if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
2932 // ----- Close the zip file
2933 $this->privCloseFd();
2934 $this->privSwapBackMagicQuotes();
2936 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2940 // ----- Store the index
2941 $v_header['index'] = $i;
2943 // ----- Store the file position
2944 $v_pos_entry = ftell($this->zip_fd);
2946 // ----- Look for the specific extract rules
2949 // ----- Look for extract by name rule
2950 if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
2951 && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
2952 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
2954 // ----- Look if the filename is in the list
2955 for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
2956 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
2958 // ----- Look for a directory
2959 if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
2960 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
2962 // ----- Look if the directory is in the filename path
2963 if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
2964 && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
2965 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
2969 // ----- Look for a filename
2970 elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
2971 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
2977 // ----- Look for extract by ereg rule
2978 else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
2979 && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
2980 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
2982 if (preg_match('/'.$p_options[PCLZIP_OPT_BY_EREG].'/', $v_header['stored_filename'])) {
2983 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
2988 // ----- Look for extract by preg rule
2989 else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
2990 && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
2991 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
2993 if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
2994 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
2999 // ----- Look for extract by index rule
3000 else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3001 && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3002 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
3004 // ----- Look if the index is in the list
3005 for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
3006 //--(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']."]");
3008 if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3009 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
3012 if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3013 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
3017 if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3018 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
3024 // ----- Look for no rule, which means extract all the archive
3026 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with no rule (extract all)");
3030 // ----- Check compression method
3032 && ( ($v_header['compression'] != 8)
3033 && ($v_header['compression'] != 0))) {
3034 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported compression method (".$v_header['compression'].")");
3035 $v_header['status'] = 'unsupported_compression';
3037 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3038 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3039 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3040 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3042 $this->privSwapBackMagicQuotes();
3044 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
3045 "Filename '".$v_header['stored_filename']."' is "
3046 ."compressed by an unsupported compression "
3047 ."method (".$v_header['compression'].") ");
3049 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3050 return PclZip::errorCode();
3054 // ----- Check encrypted files
3055 if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
3056 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unsupported file encryption");
3057 $v_header['status'] = 'unsupported_encryption';
3059 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3060 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3061 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3062 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3064 $this->privSwapBackMagicQuotes();
3066 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
3067 "Unsupported encryption for "
3068 ." filename '".$v_header['stored_filename']
3071 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3072 return PclZip::errorCode();
3076 // ----- Look for real extraction
3077 if (($v_extract) && ($v_header['status'] != 'ok')) {
3078 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "No need for extract");
3079 $v_result = $this->privConvertHeader2FileInfo($v_header,
3080 $p_file_list[$v_nb_extracted++]);
3081 if ($v_result != 1) {
3082 $this->privCloseFd();
3083 $this->privSwapBackMagicQuotes();
3084 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3091 // ----- Look for real extraction
3094 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file '".$v_header['filename']."', index '$i'");
3096 // ----- Go to the file position
3097 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
3098 @rewind($this->zip_fd);
3099 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
3100 if (@fseek($this->zip_fd, $v_header['offset']))
3102 // ----- Close the zip file
3103 $this->privCloseFd();
3105 $this->privSwapBackMagicQuotes();
3108 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3111 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3112 return PclZip::errorCode();
3114 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
3116 // ----- Look for extraction as string
3117 if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
3119 // ----- Extracting the file
3120 $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
3121 if ($v_result1 < 1) {
3122 $this->privCloseFd();
3123 $this->privSwapBackMagicQuotes();
3124 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
3128 // ----- Get the only interesting attributes
3129 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
3131 // ----- Close the zip file
3132 $this->privCloseFd();
3133 $this->privSwapBackMagicQuotes();
3135 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3139 // ----- Set the file content
3140 $p_file_list[$v_nb_extracted]['content'] = $v_string;
3142 // ----- Next extracted file
3145 // ----- Look for user callback abort
3146 if ($v_result1 == 2) {
3150 // ----- Look for extraction in standard output
3151 elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
3152 && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
3153 // ----- Extracting the file in standard output
3154 $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
3155 if ($v_result1 < 1) {
3156 $this->privCloseFd();
3157 $this->privSwapBackMagicQuotes();
3158 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
3162 // ----- Get the only interesting attributes
3163 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
3164 $this->privCloseFd();
3165 $this->privSwapBackMagicQuotes();
3166 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3170 // ----- Look for user callback abort
3171 if ($v_result1 == 2) {
3175 // ----- Look for normal extraction
3177 // ----- Extracting the file
3178 $v_result1 = $this->privExtractFile($v_header,
3179 $p_path, $p_remove_path,
3182 if ($v_result1 < 1) {
3183 $this->privCloseFd();
3184 $this->privSwapBackMagicQuotes();
3185 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result1);
3189 // ----- Get the only interesting attributes
3190 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
3192 // ----- Close the zip file
3193 $this->privCloseFd();
3194 $this->privSwapBackMagicQuotes();
3196 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3200 // ----- Look for user callback abort
3201 if ($v_result1 == 2) {
3208 // ----- Close the zip file
3209 $this->privCloseFd();
3210 $this->privSwapBackMagicQuotes();
3213 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3216 // --------------------------------------------------------------------------------
3218 // --------------------------------------------------------------------------------
3219 // Function : privExtractFile()
3225 // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
3226 // --------------------------------------------------------------------------------
3227 function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
3229 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFile', "path='$p_path', remove_path='$p_remove_path', remove_all_path='".($p_remove_all_path?'true':'false')."'");
3232 // ----- Read the file header
3233 if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3236 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3240 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
3242 // ----- Check that the file header is coherent with $p_entry info
3243 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3247 // ----- Look for all path to remove
3248 if ($p_remove_all_path == true) {
3249 // ----- Look for folder entry that not need to be extracted
3250 if (($p_entry['external']&0x00000010)==0x00000010) {
3251 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The entry is a folder : need to be filtered");
3253 $p_entry['status'] = "filtered";
3255 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3259 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "All path is removed");
3260 // ----- Get the basename of the path
3261 $p_entry['filename'] = basename($p_entry['filename']);
3264 // ----- Look for path to remove
3265 else if ($p_remove_path != "")
3267 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Look for some path to remove");
3268 if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
3270 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The folder is the same as the removed path '".$p_entry['filename']."'");
3272 // ----- Change the file status
3273 $p_entry['status'] = "filtered";
3276 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3280 $p_remove_path_size = strlen($p_remove_path);
3281 if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
3283 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '".$p_entry['filename']."'");
3285 // ----- Remove the path
3286 $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
3288 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Resulting file is '".$p_entry['filename']."'");
3292 // ----- Add the path
3295 $p_entry['filename'] = $p_path."/".$p_entry['filename'];
3298 // ----- Look for pre-extract callback
3299 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3300 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
3302 // ----- Generate a local information
3303 $v_local_header = array();
3304 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3306 // ----- Call the callback
3307 // Here I do not use call_user_func() because I need to send a reference to the
3309 eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3310 if ($v_result == 0) {
3311 // ----- Change the file status
3312 $p_entry['status'] = "skipped";
3316 // ----- Look for abort result
3317 if ($v_result == 2) {
3318 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3319 // ----- This status is internal and will be changed in 'skipped'
3320 $p_entry['status'] = "aborted";
3321 $v_result = PCLZIP_ERR_USER_ABORTED;
3324 // ----- Update the informations
3325 // Only some fields can be modified
3326 $p_entry['filename'] = $v_local_header['filename'];
3327 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
3330 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
3332 // ----- Look if extraction should be done
3333 if ($p_entry['status'] == 'ok') {
3335 // ----- Look for specific actions while the file exist
3336 if (file_exists($p_entry['filename']))
3338 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_entry['filename']."' already exists");
3340 // ----- Look if file is a directory
3341 if (is_dir($p_entry['filename']))
3343 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is a directory");
3345 // ----- Change the file status
3346 $p_entry['status'] = "already_a_directory";
3348 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3349 // For historical reason first PclZip implementation does not stop
3350 // when this kind of error occurs.
3351 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3352 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3353 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3355 PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
3356 "Filename '".$p_entry['filename']."' is "
3357 ."already used by an existing directory");
3359 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3360 return PclZip::errorCode();
3363 // ----- Look if file is write protected
3364 else if (!is_writeable($p_entry['filename']))
3366 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Existing file '".$p_entry['filename']."' is write protected");
3368 // ----- Change the file status
3369 $p_entry['status'] = "write_protected";
3371 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3372 // For historical reason first PclZip implementation does not stop
3373 // when this kind of error occurs.
3374 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3375 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3376 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3378 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3379 "Filename '".$p_entry['filename']."' exists "
3380 ."and is write protected");
3382 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3383 return PclZip::errorCode();
3387 // ----- Look if the extracted file is older
3388 else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
3390 //--(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']).")");
3391 // ----- Change the file status
3392 if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
3393 && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
3394 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_REPLACE_NEWER is selected, file will be replaced");
3397 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be replaced");
3398 $p_entry['status'] = "newer_exist";
3400 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
3401 // For historical reason first PclZip implementation does not stop
3402 // when this kind of error occurs.
3403 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
3404 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
3405 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "PCLZIP_OPT_STOP_ON_ERROR is selected, extraction will be stopped");
3407 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
3408 "Newer version of '".$p_entry['filename']."' exists "
3409 ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
3411 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3412 return PclZip::errorCode();
3417 //--(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']).")");
3421 // ----- Check the directory availability and create it if necessary
3423 if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
3424 $v_dir_to_check = $p_entry['filename'];
3425 else if (!strstr($p_entry['filename'], "/"))
3426 $v_dir_to_check = "";
3428 $v_dir_to_check = dirname($p_entry['filename']);
3430 if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
3431 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '".$p_entry['filename']."'");
3433 // ----- Change the file status
3434 $p_entry['status'] = "path_creation_fail";
3437 ////--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3444 // ----- Look if extraction should be done
3445 if ($p_entry['status'] == 'ok') {
3447 // ----- Do the extraction (if not a folder)
3448 if (!(($p_entry['external']&0x00000010)==0x00000010))
3450 // ----- Look for not compressed file
3451 if ($p_entry['compression'] == 0) {
3452 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
3454 // ----- Opening destination file
3455 if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
3457 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
3459 // ----- Change the file status
3460 $p_entry['status'] = "write_error";
3463 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3467 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read '".$p_entry['size']."' bytes");
3469 // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
3470 $v_size = $p_entry['compressed_size'];
3471 while ($v_size != 0)
3473 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3474 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Read $v_read_size bytes");
3475 $v_buffer = @fread($this->zip_fd, $v_read_size);
3476 /* Try to speed up the code
3477 $v_binary_data = pack('a'.$v_read_size, $v_buffer);
3478 @fwrite($v_dest_file, $v_binary_data, $v_read_size);
3480 @fwrite($v_dest_file, $v_buffer, $v_read_size);
3481 $v_size -= $v_read_size;
3484 // ----- Closing the destination file
3485 fclose($v_dest_file);
3487 // ----- Change the file mtime
3488 touch($p_entry['filename'], $p_entry['mtime']);
3493 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (Compression method ".$p_entry['compression'].")");
3495 // Need to be finished
3496 if (($p_entry['flag'] & 1) == 1) {
3497 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File is encrypted");
3499 // ----- Read the encryption header
3500 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read 12 encryption header bytes");
3501 $v_encryption_header = @fread($this->zip_fd, 12);
3503 // ----- Read the encrypted & compressed file in a buffer
3504 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".($p_entry['compressed_size']-12)."' compressed & encrypted bytes");
3505 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']-12);
3507 // ----- Decrypt the buffer
3508 $this->privDecrypt($v_encryption_header, $v_buffer,
3509 $p_entry['compressed_size']-12, $p_entry['crc']);
3510 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Buffer is '".$v_buffer."'");
3514 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read '".$p_entry['compressed_size']."' compressed bytes");
3515 // ----- Read the compressed file in a buffer (one shot)
3516 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3519 // ----- Decompress the file
3520 $v_file_content = @gzinflate($v_buffer);
3522 if ($v_file_content === FALSE) {
3523 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to inflate compressed file");
3525 // ----- Change the file status
3527 $p_entry['status'] = "error";
3529 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3533 // ----- Opening destination file
3534 if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
3535 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Error while opening '".$p_entry['filename']."' in write binary mode");
3537 // ----- Change the file status
3538 $p_entry['status'] = "write_error";
3540 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3544 // ----- Write the uncompressed data
3545 @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
3546 unset($v_file_content);
3548 // ----- Closing the destination file
3549 @fclose($v_dest_file);
3551 // ----- Change the file mtime
3552 @touch($p_entry['filename'], $p_entry['mtime']);
3555 // ----- Look for chmod option
3556 if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
3557 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "chmod option activated '".$p_options[PCLZIP_OPT_SET_CHMOD]."'");
3559 // ----- Change the mode of the file
3560 @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
3563 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
3567 // ----- Change abort status
3568 if ($p_entry['status'] == "aborted") {
3569 $p_entry['status'] = "skipped";
3572 // ----- Look for post-extract callback
3573 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3574 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
3576 // ----- Generate a local information
3577 $v_local_header = array();
3578 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3580 // ----- Call the callback
3581 // Here I do not use call_user_func() because I need to send a reference to the
3583 eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3585 // ----- Look for abort result
3586 if ($v_result == 2) {
3587 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3588 $v_result = PCLZIP_ERR_USER_ABORTED;
3593 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3596 // --------------------------------------------------------------------------------
3598 // --------------------------------------------------------------------------------
3599 // Function : privExtractFileInOutput()
3603 // --------------------------------------------------------------------------------
3604 function privExtractFileInOutput(&$p_entry, &$p_options)
3606 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileInOutput', "");
3609 // ----- Read the file header
3610 if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
3611 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3615 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
3617 // ----- Check that the file header is coherent with $p_entry info
3618 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3622 // ----- Look for pre-extract callback
3623 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
3624 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_EXTRACT]."()') is defined for the extraction");
3626 // ----- Generate a local information
3627 $v_local_header = array();
3628 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3630 // ----- Call the callback
3631 // Here I do not use call_user_func() because I need to send a reference to the
3633 eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
3634 if ($v_result == 0) {
3635 // ----- Change the file status
3636 $p_entry['status'] = "skipped";
3640 // ----- Look for abort result
3641 if ($v_result == 2) {
3642 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3643 // ----- This status is internal and will be changed in 'skipped'
3644 $p_entry['status'] = "aborted";
3645 $v_result = PCLZIP_ERR_USER_ABORTED;
3648 // ----- Update the informations
3649 // Only some fields can be modified
3650 $p_entry['filename'] = $v_local_header['filename'];
3651 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New filename is '".$p_entry['filename']."'");
3655 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '".$p_entry['filename']."', size '$v_header[size]'");
3657 // ----- Look if extraction should be done
3658 if ($p_entry['status'] == 'ok') {
3660 // ----- Do the extraction (if not a folder)
3661 if (!(($p_entry['external']&0x00000010)==0x00000010)) {
3662 // ----- Look for not compressed file
3663 if ($p_entry['compressed_size'] == $p_entry['size']) {
3664 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
3665 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
3667 // ----- Read the file in a buffer (one shot)
3668 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3670 // ----- Send the file to the output
3675 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file");
3676 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Reading '".$p_entry['size']."' bytes");
3678 // ----- Read the compressed file in a buffer (one shot)
3679 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
3681 // ----- Decompress the file
3682 $v_file_content = gzinflate($v_buffer);
3685 // ----- Send the file to the output
3686 echo $v_file_content;
3687 unset($v_file_content);
3689 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
3693 // ----- Change abort status
3694 if ($p_entry['status'] == "aborted") {
3695 $p_entry['status'] = "skipped";
3698 // ----- Look for post-extract callback
3699 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
3700 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_EXTRACT]."()') is defined for the extraction");
3702 // ----- Generate a local information
3703 $v_local_header = array();
3704 $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
3706 // ----- Call the callback
3707 // Here I do not use call_user_func() because I need to send a reference to the
3709 eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
3711 // ----- Look for abort result
3712 if ($v_result == 2) {
3713 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "User callback abort the extraction");
3714 $v_result = PCLZIP_ERR_USER_ABORTED;
3718 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3721 // --------------------------------------------------------------------------------
3723 // --------------------------------------------------------------------------------
3724 // Function : privExtractFileAsString()
3728 // --------------------------------------------------------------------------------
3729 function privExtractFileAsString(&$p_entry, &$p_string)
3731 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privExtractFileAsString', "p_entry['filename']='".$p_entry['filename']."'");
3734 // ----- Read the file header
3735 $v_header = array();
3736 if (($v_result = $this->privReadFileHeader($v_header)) != 1)
3739 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3743 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found file '".$v_header['filename']."', size '".$v_header['size']."'");
3745 // ----- Check that the file header is coherent with $p_entry info
3746 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
3750 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting file in string (with path) '".$p_entry['filename']."', size '$v_header[size]'");
3752 // ----- Do the extraction (if not a folder)
3753 if (!(($p_entry['external']&0x00000010)==0x00000010))
3755 // ----- Look for not compressed file
3756 // if ($p_entry['compressed_size'] == $p_entry['size'])
3757 if ($p_entry['compression'] == 0) {
3758 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting an un-compressed file");
3759 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Reading '".$p_entry['size']."' bytes");
3761 // ----- Reading the file
3762 $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
3765 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extracting a compressed file (compression method '".$p_entry['compression']."')");
3767 // ----- Reading the file
3768 $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
3770 // ----- Decompress the file
3771 if (($p_string = @gzinflate($v_data)) === FALSE) {
3777 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Extraction done");
3780 // TBC : error : can not extract a folder in a string
3784 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3787 // --------------------------------------------------------------------------------
3789 // --------------------------------------------------------------------------------
3790 // Function : privReadFileHeader()
3794 // --------------------------------------------------------------------------------
3795 function privReadFileHeader(&$p_header)
3797 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadFileHeader", "");
3800 // ----- Read the 4 bytes signature
3801 $v_binary_data = @fread($this->zip_fd, 4);
3802 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
3803 $v_data = unpack('Vid', $v_binary_data);
3804 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
3806 // ----- Check signature
3807 if ($v_data['id'] != 0x04034b50)
3809 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid File header");
3812 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
3815 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3816 return PclZip::errorCode();
3819 // ----- Read the first 42 bytes of the header
3820 $v_binary_data = fread($this->zip_fd, 26);
3822 // ----- Look for invalid block size
3823 if (mb_strlen($v_binary_data,'iso-8859-1') != 26)
3825 $p_header['filename'] = "";
3826 $p_header['status'] = "invalid_header";
3827 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
3830 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".mb_strlen($v_binary_data,'iso-8859-1'));
3833 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3834 return PclZip::errorCode();
3837 // ----- Extract the values
3838 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header : '".$v_binary_data."'");
3839 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Header (Hex) : '".bin2hex($v_binary_data)."'");
3840 $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
3842 // ----- Get filename
3843 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "File name length : ".$v_data['filename_len']);
3844 $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
3845 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename : \''.$p_header['filename'].'\'');
3847 // ----- Get extra_fields
3848 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extra field length : ".$v_data['extra_len']);
3849 if ($v_data['extra_len'] != 0) {
3850 $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
3853 $p_header['extra'] = '';
3855 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Extra field : \''.bin2hex($p_header['extra']).'\'');
3857 // ----- Extract properties
3858 $p_header['version_extracted'] = $v_data['version'];
3859 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : ('.$p_header['version_extracted'].') \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
3860 $p_header['compression'] = $v_data['compression'];
3861 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compression method : \''.$p_header['compression'].'\'');
3862 $p_header['size'] = $v_data['size'];
3863 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_header['size'].'\'');
3864 $p_header['compressed_size'] = $v_data['compressed_size'];
3865 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
3866 $p_header['crc'] = $v_data['crc'];
3867 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
3868 $p_header['flag'] = $v_data['flag'];
3869 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Flag : \''.$p_header['flag'].'\'');
3870 $p_header['filename_len'] = $v_data['filename_len'];
3871 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Filename_len : \''.$p_header['filename_len'].'\'');
3873 // ----- Recuperate date in UNIX format
3874 $p_header['mdate'] = $v_data['mdate'];
3875 $p_header['mtime'] = $v_data['mtime'];
3876 if ($p_header['mdate'] && $p_header['mtime'])
3878 // ----- Extract time
3879 $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
3880 $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
3881 $v_seconde = ($p_header['mtime'] & 0x001F)*2;
3883 // ----- Extract date
3884 $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
3885 $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
3886 $v_day = $p_header['mdate'] & 0x001F;
3888 // ----- Get UNIX date format
3889 $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
3891 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
3895 $p_header['mtime'] = time();
3896 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
3900 //for(reset($v_data); $key = key($v_data); next($v_data)) {
3901 // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Attribut[$key] = ".$v_data[$key]);
3904 // ----- Set the stored filename
3905 $p_header['stored_filename'] = $p_header['filename'];
3907 // ----- Set the status field
3908 $p_header['status'] = "ok";
3911 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
3914 // --------------------------------------------------------------------------------
3916 // --------------------------------------------------------------------------------
3917 // Function : privReadCentralFileHeader()
3921 // --------------------------------------------------------------------------------
3922 function privReadCentralFileHeader(&$p_header)
3924 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadCentralFileHeader", "");
3927 // ----- Read the 4 bytes signature
3928 $v_binary_data = @fread($this->zip_fd, 4);
3929 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
3930 $v_data = unpack('Vid', $v_binary_data);
3931 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
3933 // ----- Check signature
3934 if ($v_data['id'] != 0x02014b50)
3936 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid Central Dir File signature");
3939 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
3942 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3943 return PclZip::errorCode();
3946 // ----- Read the first 42 bytes of the header
3947 $v_binary_data = fread($this->zip_fd, 42);
3949 // ----- Look for invalid block size
3950 if (mb_strlen($v_binary_data,'iso-8859-1') != 42)
3952 $p_header['filename'] = "";
3953 $p_header['status'] = "invalid_header";
3954 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data));
3957 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".mb_strlen($v_binary_data,'iso-8859-1'));
3960 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
3961 return PclZip::errorCode();
3964 // ----- Extract the values
3965 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header : '".$v_binary_data."'");
3966 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header (Hex) : '".bin2hex($v_binary_data)."'");
3967 $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);
3969 // ----- Get filename
3970 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "File name length : ".$p_header['filename_len']);
3971 if ($p_header['filename_len'] != 0)
3972 $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
3974 $p_header['filename'] = '';
3975 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Filename : \''.$p_header['filename'].'\'');
3978 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Extra length : ".$p_header['extra_len']);
3979 if ($p_header['extra_len'] != 0)
3980 $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
3982 $p_header['extra'] = '';
3983 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Extra : \''.$p_header['extra'].'\'');
3985 // ----- Get comment
3986 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Comment length : ".$p_header['comment_len']);
3987 if ($p_header['comment_len'] != 0)
3988 $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
3990 $p_header['comment'] = '';
3991 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Comment : \''.$p_header['comment'].'\'');
3993 // ----- Extract properties
3994 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version : \''.($p_header['version']/10).'.'.($p_header['version']%10).'\'');
3995 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Version need to extract : \''.($p_header['version_extracted']/10).'.'.($p_header['version_extracted']%10).'\'');
3996 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Size : \''.$p_header['size'].'\'');
3997 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Compressed Size : \''.$p_header['compressed_size'].'\'');
3998 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'CRC : \''.sprintf("0x%X", $p_header['crc']).'\'');
3999 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Flag : \''.$p_header['flag'].'\'');
4000 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Offset : \''.$p_header['offset'].'\'');
4002 // ----- Recuperate date in UNIX format
4003 if ($p_header['mdate'] && $p_header['mtime'])
4005 // ----- Extract time
4006 $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
4007 $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
4008 $v_seconde = ($p_header['mtime'] & 0x001F)*2;
4010 // ----- Extract date
4011 $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
4012 $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
4013 $v_day = $p_header['mdate'] & 0x001F;
4015 // ----- Get UNIX date format
4016 $p_header['mtime'] = mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
4018 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
4022 $p_header['mtime'] = time();
4023 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Date is actual : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
4026 // ----- Set the stored filename
4027 $p_header['stored_filename'] = $p_header['filename'];
4029 // ----- Set default status to ok
4030 $p_header['status'] = 'ok';
4032 // ----- Look if it is a directory
4033 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Internal (Hex) : '".sprintf("Ox%04X", $p_header['internal'])."'");
4034 //--(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').')');
4035 if (substr($p_header['filename'], -1) == '/') {
4036 //$p_header['external'] = 0x41FF0010;
4037 $p_header['external'] = 0x00000010;
4038 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Force folder external : \''.sprintf("Ox%04X", $p_header['external']).'\'');
4041 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Header of filename : \''.$p_header['filename'].'\'');
4044 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4047 // --------------------------------------------------------------------------------
4049 // --------------------------------------------------------------------------------
4050 // Function : privCheckFileHeaders()
4056 // --------------------------------------------------------------------------------
4057 function privCheckFileHeaders(&$p_local_header, &$p_central_header)
4059 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFileHeaders", "");
4062 // ----- Check the static values
4064 if ($p_local_header['filename'] != $p_central_header['filename']) {
4065 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename" : TBC To Be Completed');
4067 if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
4068 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "version_extracted" : TBC To Be Completed');
4070 if ($p_local_header['flag'] != $p_central_header['flag']) {
4071 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "flag" : TBC To Be Completed');
4073 if ($p_local_header['compression'] != $p_central_header['compression']) {
4074 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "compression" : TBC To Be Completed');
4076 if ($p_local_header['mtime'] != $p_central_header['mtime']) {
4077 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "mtime" : TBC To Be Completed');
4079 if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
4080 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Bad check "filename_len" : TBC To Be Completed');
4083 // ----- Look for flag bit 3
4084 if (($p_local_header['flag'] & 8) == 8) {
4085 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Purpose bit flag bit 3 set !');
4086 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'File size, compression size and crc found in central header');
4087 $p_local_header['size'] = $p_central_header['size'];
4088 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size : \''.$p_local_header['size'].'\'');
4089 $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
4090 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Compressed Size : \''.$p_local_header['compressed_size'].'\'');
4091 $p_local_header['crc'] = $p_central_header['crc'];
4092 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'CRC : \''.sprintf("0x%X", $p_local_header['crc']).'\'');
4096 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4099 // --------------------------------------------------------------------------------
4101 // --------------------------------------------------------------------------------
4102 // Function : privReadEndCentralDir()
4106 // --------------------------------------------------------------------------------
4107 function privReadEndCentralDir(&$p_central_dir)
4109 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privReadEndCentralDir", "");
4112 // ----- Go to the end of the zip file
4113 $v_size = filesize($this->zipname);
4114 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size of the file :$v_size");
4115 @fseek($this->zip_fd, $v_size);
4116 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position at end of zip file : \''.ftell($this->zip_fd).'\'');
4117 if (@ftell($this->zip_fd) != $v_size)
4120 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
4123 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4124 return PclZip::errorCode();
4127 // ----- First try : look if this is an archive with no commentaries (most of the time)
4128 // in this case the end of central dir is at 22 bytes of the file end
4131 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Look for central dir with no comment');
4132 @fseek($this->zip_fd, $v_size-22);
4133 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after min central position : \''.ftell($this->zip_fd).'\'');
4134 if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4137 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4140 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4141 return PclZip::errorCode();
4144 // ----- Read for bytes
4145 $v_binary_data = @fread($this->zip_fd, 4);
4146 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Binary data is : '".sprintf("%08x", $v_binary_data)."'");
4147 $v_data = @unpack('Vid', $v_binary_data);
4148 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Binary signature is : '".sprintf("0x%08x", $v_data['id'])."'");
4150 // ----- Check signature
4151 if ($v_data['id'] == 0x06054b50) {
4152 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Found central dir at the default position.");
4156 $v_pos = ftell($this->zip_fd);
4159 // ----- Go back to the maximum possible size of the Central Dir End Record
4161 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Start extended search of end central dir');
4162 $v_maximum_size = 65557; // 0xFFFF + 22;
4163 if ($v_maximum_size > $v_size)
4164 $v_maximum_size = $v_size;
4165 @fseek($this->zip_fd, $v_size-$v_maximum_size);
4166 if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4169 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
4172 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4173 return PclZip::errorCode();
4175 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Position after max central position : \''.ftell($this->zip_fd).'\'');
4177 // ----- Read byte per byte in order to find the signature
4178 $v_pos = ftell($this->zip_fd);
4179 $v_bytes = 0x00000000;
4180 while ($v_pos < $v_size)
4182 // ----- Read a byte
4183 $v_byte = @fread($this->zip_fd, 1);
4185 // ----- Add the byte
4186 $v_bytes = ($v_bytes << 8) | Ord($v_byte);
4188 // ----- Compare the bytes
4189 if ($v_bytes == 0x504b0506)
4191 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, 'Found End Central Dir signature at position : \''.ftell($this->zip_fd).'\'');
4199 // ----- Look if not found end of central dir
4200 if ($v_pos == $v_size)
4202 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to find End of Central Dir Record signature");
4205 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
4208 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4209 return PclZip::errorCode();
4213 // ----- Read the first 18 bytes of the header
4214 $v_binary_data = fread($this->zip_fd, 18);
4216 // ----- Look for invalid block size
4217 if (mb_strlen($v_binary_data,'iso-8859-1') != 18)
4219 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
4222 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".mb_strlen($v_binary_data,'iso-8859-1'));
4225 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4226 return PclZip::errorCode();
4229 // ----- Extract the values
4230 ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record : '".$v_binary_data."'");
4231 ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Central Dir Record (Hex) : '".bin2hex($v_binary_data)."'");
4232 $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4234 // ----- Check the global size
4235 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Comment length : ".$v_data['comment_size']);
4236 if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
4237 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The central dir is not at the end of the archive. Some trailing bytes exists after the archive.");
4239 // ----- Removed in release 2.2 see readme file
4240 // The check of the file size is a little too strict.
4241 // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
4242 // While decrypted, zip has training 0 bytes
4245 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
4246 'The central dir is not at the end of the archive.'
4247 .' Some trailing bytes exists after the archive.');
4250 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4251 return PclZip::errorCode();
4255 // ----- Get comment
4256 if ($v_data['comment_size'] != 0)
4257 $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
4259 $p_central_dir['comment'] = '';
4260 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Comment : \''.$p_central_dir['comment'].'\'');
4262 $p_central_dir['entries'] = $v_data['entries'];
4263 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries : \''.$p_central_dir['entries'].'\'');
4264 $p_central_dir['disk_entries'] = $v_data['disk_entries'];
4265 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Nb of entries for this disk : \''.$p_central_dir['disk_entries'].'\'');
4266 $p_central_dir['offset'] = $v_data['offset'];
4267 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Offset of Central Dir : \''.$p_central_dir['offset'].'\'');
4268 $p_central_dir['size'] = $v_data['size'];
4269 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Size of Central Dir : \''.$p_central_dir['size'].'\'');
4270 $p_central_dir['disk'] = $v_data['disk'];
4271 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Disk number : \''.$p_central_dir['disk'].'\'');
4272 $p_central_dir['disk_start'] = $v_data['disk_start'];
4273 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Start disk number : \''.$p_central_dir['disk_start'].'\'');
4276 //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
4277 // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "central_dir[$key] = ".$p_central_dir[$key]);
4281 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4284 // --------------------------------------------------------------------------------
4286 // --------------------------------------------------------------------------------
4287 // Function : privDeleteByRule()
4291 // --------------------------------------------------------------------------------
4292 function privDeleteByRule(&$p_result_list, &$p_options)
4294 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDeleteByRule", "");
4296 $v_list_detail = array();
4298 // ----- Open the zip file
4299 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
4300 if (($v_result=$this->privOpenFd('rb')) != 1)
4303 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4307 // ----- Read the central directory informations
4308 $v_central_dir = array();
4309 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4311 $this->privCloseFd();
4312 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4316 // ----- Go to beginning of File
4317 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
4318 @rewind($this->zip_fd);
4319 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
4321 // ----- Scan all the files
4322 // ----- Start at beginning of Central Dir
4323 $v_pos_entry = $v_central_dir['offset'];
4324 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
4325 @rewind($this->zip_fd);
4326 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
4327 if (@fseek($this->zip_fd, $v_pos_entry))
4329 // ----- Close the zip file
4330 $this->privCloseFd();
4333 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4336 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4337 return PclZip::errorCode();
4339 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
4341 // ----- Read each entry
4342 $v_header_list = array();
4344 for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
4346 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Read next file header entry (index '$i')");
4348 // ----- Read the file header
4349 $v_header_list[$v_nb_extracted] = array();
4350 if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
4352 // ----- Close the zip file
4353 $this->privCloseFd();
4355 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4359 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename (index '$i') : '".$v_header_list[$v_nb_extracted]['stored_filename']."'");
4361 // ----- Store the index
4362 $v_header_list[$v_nb_extracted]['index'] = $i;
4364 // ----- Look for the specific extract rules
4367 // ----- Look for extract by name rule
4368 if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
4369 && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4370 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByName'");
4372 // ----- Look if the filename is in the list
4373 for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
4374 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Compare with file '".$p_options[PCLZIP_OPT_BY_NAME][$j]."'");
4376 // ----- Look for a directory
4377 if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
4378 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The searched item is a directory");
4380 // ----- Look if the directory is in the filename path
4381 if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4382 && (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])) {
4383 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The directory is in the file path");
4386 elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
4387 && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4388 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The entry is the searched directory");
4392 // ----- Look for a filename
4393 elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4394 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The file is the right one.");
4400 // ----- Look for extract by ereg rule
4401 else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
4402 && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
4403 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract by ereg '".$p_options[PCLZIP_OPT_BY_EREG]."'");
4405 if (preg_match('/'.$p_options[PCLZIP_OPT_BY_EREG].'/', $v_header_list[$v_nb_extracted]['stored_filename'])) {
4406 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
4411 // ----- Look for extract by preg rule
4412 else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
4413 && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
4414 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByEreg'");
4416 if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
4417 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filename match the regular expression");
4422 // ----- Look for extract by index rule
4423 else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
4424 && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4425 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extract with rule 'ByIndex'");
4427 // ----- Look if the index is in the list
4428 for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
4429 //--(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']."]");
4431 if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
4432 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Found as part of an index range");
4435 if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
4436 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Do not look this index range for next loop");
4440 if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
4441 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Index range is greater than index, stop loop");
4447 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "No argument mean remove all file");
4451 // ----- Look for deletion
4454 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' need to be deleted");
4455 unset($v_header_list[$v_nb_extracted]);
4459 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_header_list[$v_nb_extracted]['stored_filename']."', index '$i' will not be deleted");
4464 // ----- Look if something need to be deleted
4465 if ($v_nb_extracted > 0) {
4467 // ----- Creates a temporay file
4468 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4470 // ----- Creates a temporary zip archive
4471 $v_temp_zip = new PclZip($v_zip_temp_name);
4473 // ----- Open the temporary zip file in write mode
4474 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary write mode");
4475 if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
4476 $this->privCloseFd();
4479 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4483 // ----- Look which file need to be kept
4484 for ($i=0; $i<sizeof($v_header_list); $i++) {
4485 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Keep entry index '$i' : '".$v_header_list[$i]['filename']."'");
4487 // ----- Calculate the position of the header
4488 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset='". $v_header_list[$i]['offset']."'");
4489 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position before rewind : ".ftell($this->zip_fd)."'");
4490 @rewind($this->zip_fd);
4491 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after rewind : ".ftell($this->zip_fd)."'");
4492 if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
4493 // ----- Close the zip file
4494 $this->privCloseFd();
4495 $v_temp_zip->privCloseFd();
4496 @unlink($v_zip_temp_name);
4499 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
4502 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4503 return PclZip::errorCode();
4505 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position after fseek : ".ftell($this->zip_fd)."'");
4507 // ----- Read the file header
4508 $v_local_header = array();
4509 if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
4510 // ----- Close the zip file
4511 $this->privCloseFd();
4512 $v_temp_zip->privCloseFd();
4513 @unlink($v_zip_temp_name);
4516 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4520 // ----- Check that local file header is same as central file header
4521 if ($this->privCheckFileHeaders($v_local_header,
4522 $v_header_list[$i]) != 1) {
4525 unset($v_local_header);
4527 // ----- Write the file header
4528 if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4529 // ----- Close the zip file
4530 $this->privCloseFd();
4531 $v_temp_zip->privCloseFd();
4532 @unlink($v_zip_temp_name);
4535 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4538 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset for this file is '".$v_header_list[$i]['offset']."'");
4540 // ----- Read/write the data block
4541 if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
4542 // ----- Close the zip file
4543 $this->privCloseFd();
4544 $v_temp_zip->privCloseFd();
4545 @unlink($v_zip_temp_name);
4548 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4553 // ----- Store the offset of the central dir
4554 $v_offset = @ftell($v_temp_zip->zip_fd);
4555 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "New offset of central dir : $v_offset");
4557 // ----- Re-Create the Central Dir files header
4558 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the new central directory");
4559 for ($i=0; $i<sizeof($v_header_list); $i++) {
4560 // ----- Create the file header
4561 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Offset of file : ".$v_header_list[$i]['offset']);
4562 if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4563 $v_temp_zip->privCloseFd();
4564 $this->privCloseFd();
4565 @unlink($v_zip_temp_name);
4568 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4572 // ----- Transform the header to a 'usable' info
4573 $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4576 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Creates the central directory footer");
4578 // ----- Zip file comment
4580 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
4581 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
4584 // ----- Calculate the size of the central header
4585 $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4587 // ----- Create the central dir footer
4588 if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4589 // ----- Reset the file list
4590 unset($v_header_list);
4591 $v_temp_zip->privCloseFd();
4592 $this->privCloseFd();
4593 @unlink($v_zip_temp_name);
4596 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4601 $v_temp_zip->privCloseFd();
4602 $this->privCloseFd();
4604 // ----- Delete the zip file
4605 // TBC : I should test the result ...
4606 @unlink($this->zipname);
4608 // ----- Rename the temporary file
4609 // TBC : I should test the result ...
4610 //@rename($v_zip_temp_name, $this->zipname);
4611 PclZipUtilRename($v_zip_temp_name, $this->zipname);
4613 // ----- Destroy the temporary archive
4617 // ----- Remove every files : reset the file
4618 else if ($v_central_dir['entries'] != 0) {
4619 $this->privCloseFd();
4621 if (($v_result = $this->privOpenFd('wb')) != 1) {
4622 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4626 if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
4627 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4631 $this->privCloseFd();
4635 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4638 // --------------------------------------------------------------------------------
4640 // --------------------------------------------------------------------------------
4641 // Function : privDirCheck()
4643 // Check if a directory exists, if not it creates it and all the parents directory
4644 // which may be useful.
4646 // $p_dir : Directory path to check.
4649 // -1 : Unable to create directory
4650 // --------------------------------------------------------------------------------
4651 function privDirCheck($p_dir, $p_is_dir=false)
4655 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDirCheck", "entry='$p_dir', is_dir='".($p_is_dir?"true":"false")."'");
4657 // ----- Remove the final '/'
4658 if (($p_is_dir) && (substr($p_dir, -1)=='/'))
4660 $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
4662 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Looking for entry '$p_dir'");
4664 // ----- Check the directory availability
4665 if ((is_dir($p_dir)) || ($p_dir == ""))
4667 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory");
4671 // ----- Extract parent directory
4672 $p_parent_dir = dirname($p_dir);
4673 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'");
4675 // ----- Just a check
4676 if ($p_parent_dir != $p_dir)
4678 // ----- Look for parent directory
4679 if ($p_parent_dir != "")
4681 if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
4683 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4689 // ----- Create the directory
4690 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'");
4691 if (!@mkdir($p_dir, 0777))
4694 PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
4697 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4698 return PclZip::errorCode();
4702 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created");
4705 // --------------------------------------------------------------------------------
4707 // --------------------------------------------------------------------------------
4708 // Function : privMerge()
4710 // If $p_archive_to_add does not exist, the function exit with a success result.
4713 // --------------------------------------------------------------------------------
4714 function privMerge(&$p_archive_to_add)
4716 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privMerge", "archive='".$p_archive_to_add->zipname."'");
4719 // ----- Look if the archive_to_add exists
4720 if (!is_file($p_archive_to_add->zipname))
4722 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to add does not exist. End of merge.");
4724 // ----- Nothing to merge, so merge is a success
4728 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4732 // ----- Look if the archive exists
4733 if (!is_file($this->zipname))
4735 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, duplicate the archive_to_add.");
4737 // ----- Do a duplicate
4738 $v_result = $this->privDuplicate($p_archive_to_add->zipname);
4741 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4745 // ----- Open the zip file
4746 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
4747 if (($v_result=$this->privOpenFd('rb')) != 1)
4750 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4754 // ----- Read the central directory informations
4755 $v_central_dir = array();
4756 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
4758 $this->privCloseFd();
4759 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4763 // ----- Go to beginning of File
4764 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
4765 @rewind($this->zip_fd);
4766 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in zip : ".ftell($this->zip_fd)."'");
4768 // ----- Open the archive_to_add file
4769 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open archive_to_add in binary read mode");
4770 if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
4772 $this->privCloseFd();
4775 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4779 // ----- Read the central directory informations
4780 $v_central_dir_to_add = array();
4781 if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
4783 $this->privCloseFd();
4784 $p_archive_to_add->privCloseFd();
4786 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4790 // ----- Go to beginning of File
4791 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
4792 @rewind($p_archive_to_add->zip_fd);
4793 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in archive_to_add : ".ftell($p_archive_to_add->zip_fd)."'");
4795 // ----- Creates a temporay file
4796 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
4798 // ----- Open the temporary file in write mode
4799 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
4800 if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
4802 $this->privCloseFd();
4803 $p_archive_to_add->privCloseFd();
4805 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
4808 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4809 return PclZip::errorCode();
4812 // ----- Copy the files from the archive to the temporary file
4813 // TBC : Here I should better append the file and go back to erase the central dir
4814 $v_size = $v_central_dir['offset'];
4815 while ($v_size != 0)
4817 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4818 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
4819 $v_buffer = fread($this->zip_fd, $v_read_size);
4820 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
4821 $v_size -= $v_read_size;
4824 // ----- Copy the files from the archive_to_add into the temporary file
4825 $v_size = $v_central_dir_to_add['offset'];
4826 while ($v_size != 0)
4828 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4829 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
4830 $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
4831 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
4832 $v_size -= $v_read_size;
4835 // ----- Store the offset of the central dir
4836 $v_offset = @ftell($v_zip_temp_fd);
4837 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
4839 // ----- Copy the block of file headers from the old archive
4840 $v_size = $v_central_dir['size'];
4841 while ($v_size != 0)
4843 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4844 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
4845 $v_buffer = @fread($this->zip_fd, $v_read_size);
4846 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
4847 $v_size -= $v_read_size;
4850 // ----- Copy the block of file headers from the archive_to_add
4851 $v_size = $v_central_dir_to_add['size'];
4852 while ($v_size != 0)
4854 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4855 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
4856 $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
4857 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
4858 $v_size -= $v_read_size;
4861 // ----- Merge the file comments
4862 $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
4864 // ----- Calculate the size of the (new) central header
4865 $v_size = @ftell($v_zip_temp_fd)-$v_offset;
4867 // ----- Swap the file descriptor
4868 // Here is a trick : I swap the temporary fd with the zip fd, in order to use
4869 // the following methods on the temporary fil and not the real archive fd
4870 $v_swap = $this->zip_fd;
4871 $this->zip_fd = $v_zip_temp_fd;
4872 $v_zip_temp_fd = $v_swap;
4874 // ----- Create the central dir footer
4875 if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
4877 $this->privCloseFd();
4878 $p_archive_to_add->privCloseFd();
4879 @fclose($v_zip_temp_fd);
4880 $this->zip_fd = null;
4882 // ----- Reset the file list
4883 unset($v_header_list);
4886 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4890 // ----- Swap back the file descriptor
4891 $v_swap = $this->zip_fd;
4892 $this->zip_fd = $v_zip_temp_fd;
4893 $v_zip_temp_fd = $v_swap;
4896 $this->privCloseFd();
4897 $p_archive_to_add->privCloseFd();
4899 // ----- Close the temporary file
4900 @fclose($v_zip_temp_fd);
4902 // ----- Delete the zip file
4903 // TBC : I should test the result ...
4904 @unlink($this->zipname);
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);
4912 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4915 // --------------------------------------------------------------------------------
4917 // --------------------------------------------------------------------------------
4918 // Function : privDuplicate()
4922 // --------------------------------------------------------------------------------
4923 function privDuplicate($p_archive_filename)
4925 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privDuplicate", "archive_filename='$p_archive_filename'");
4928 // ----- Look if the $p_archive_filename exists
4929 if (!is_file($p_archive_filename))
4931 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive to duplicate does not exist. End of duplicate.");
4933 // ----- Nothing to duplicate, so duplicate is a success.
4937 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4941 // ----- Open the zip file
4942 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
4943 if (($v_result=$this->privOpenFd('wb')) != 1)
4946 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4950 // ----- Open the temporary file in write mode
4951 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
4952 if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
4954 $this->privCloseFd();
4956 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
4959 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
4960 return PclZip::errorCode();
4963 // ----- Copy the files from the archive to the temporary file
4964 // TBC : Here I should better append the file and go back to erase the central dir
4965 $v_size = filesize($p_archive_filename);
4966 while ($v_size != 0)
4968 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
4969 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Read $v_read_size bytes");
4970 $v_buffer = fread($v_zip_temp_fd, $v_read_size);
4971 @fwrite($this->zip_fd, $v_buffer, $v_read_size);
4972 $v_size -= $v_read_size;
4976 $this->privCloseFd();
4978 // ----- Close the temporary file
4979 @fclose($v_zip_temp_fd);
4982 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
4985 // --------------------------------------------------------------------------------
4987 // --------------------------------------------------------------------------------
4988 // Function : privErrorLog()
4991 // --------------------------------------------------------------------------------
4992 function privErrorLog($p_error_code=0, $p_error_string='')
4994 if (PCLZIP_ERROR_EXTERNAL == 1) {
4995 PclError($p_error_code, $p_error_string);
4998 $this->error_code = $p_error_code;
4999 $this->error_string = $p_error_string;
5002 // --------------------------------------------------------------------------------
5004 // --------------------------------------------------------------------------------
5005 // Function : privErrorReset()
5008 // --------------------------------------------------------------------------------
5009 function privErrorReset()
5011 if (PCLZIP_ERROR_EXTERNAL == 1) {
5015 $this->error_code = 0;
5016 $this->error_string = '';
5019 // --------------------------------------------------------------------------------
5021 // --------------------------------------------------------------------------------
5022 // Function : privDecrypt()
5026 // --------------------------------------------------------------------------------
5027 function privDecrypt($p_encryption_header, &$p_buffer, $p_size, $p_crc)
5029 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDecrypt', "size=".$p_size."");
5032 // ----- To Be Modified ;-)
5035 $p_buffer = PclZipUtilZipDecrypt($p_buffer, $p_size, $p_encryption_header,
5039 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5042 // --------------------------------------------------------------------------------
5044 // --------------------------------------------------------------------------------
5045 // Function : privDisableMagicQuotes()
5049 // --------------------------------------------------------------------------------
5050 function privDisableMagicQuotes()
5052 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privDisableMagicQuotes', "");
5055 // ----- Look if function exists
5056 if ( (!function_exists("get_magic_quotes_runtime"))
5057 || (!function_exists("set_magic_quotes_runtime"))) {
5058 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
5059 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5063 // ----- Look if already done
5064 if ($this->magic_quotes_status != -1) {
5065 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote already disabled");
5066 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5070 // ----- Get and memorize the magic_quote value
5071 $this->magic_quotes_status = @get_magic_quotes_runtime();
5072 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Current magic_quotes_runtime status is '".($this->magic_quotes_status==0?'disable':'enable')."'");
5074 // ----- Disable magic_quotes
5075 if ($this->magic_quotes_status == 1) {
5076 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Disable magic_quotes");
5077 //@set_magic_quotes_runtime(0);
5081 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5084 // --------------------------------------------------------------------------------
5086 // --------------------------------------------------------------------------------
5087 // Function : privSwapBackMagicQuotes()
5091 // --------------------------------------------------------------------------------
5092 function privSwapBackMagicQuotes()
5094 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::privSwapBackMagicQuotes', "");
5097 // ----- Look if function exists
5098 if ( (!function_exists("get_magic_quotes_runtime"))
5099 || (!function_exists("set_magic_quotes_runtime"))) {
5100 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Functions *et_magic_quotes_runtime are not supported");
5101 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5105 // ----- Look if something to do
5106 if ($this->magic_quotes_status != -1) {
5107 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "magic_quote not modified");
5108 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5112 // ----- Swap back magic_quotes
5113 if ($this->magic_quotes_status == 1) {
5114 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Enable back magic_quotes");
5115 //@set_magic_quotes_runtime($this->magic_quotes_status);
5119 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5122 // --------------------------------------------------------------------------------
5126 // --------------------------------------------------------------------------------
5128 // --------------------------------------------------------------------------------
5129 // Function : PclZipUtilPathReduction()
5133 // --------------------------------------------------------------------------------
5134 function PclZipUtilPathReduction($p_dir)
5136 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathReduction", "dir='$p_dir'");
5139 // ----- Look for not empty path
5141 // ----- Explode path by directory names
5142 $v_list = explode("/", $p_dir);
5144 // ----- Study directories from last to first
5146 for ($i=sizeof($v_list)-1; $i>=0; $i--) {
5147 // ----- Look for current path
5148 if ($v_list[$i] == ".") {
5149 // ----- Ignore this directory
5150 // Should be the first $i=0, but no check is done
5152 else if ($v_list[$i] == "..") {
5155 else if ($v_list[$i] == "") {
5156 // ----- First '/' i.e. root slash
5158 $v_result = "/".$v_result;
5160 // ----- It is an invalid path, so the path is not modified
5163 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Invalid path is unchanged");
5167 // ----- Last '/' i.e. indicates a directory
5168 else if ($i == (sizeof($v_list)-1)) {
5169 $v_result = $v_list[$i];
5171 // ----- Double '/' inside the path
5173 // ----- Ignore only the double '//' in path,
5174 // but not the first and last '/'
5178 // ----- Look for item to skip
5183 $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
5188 // ----- Look for skip
5190 while ($v_skip > 0) {
5191 $v_result = '../'.$v_result;
5198 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5201 // --------------------------------------------------------------------------------
5203 // --------------------------------------------------------------------------------
5204 // Function : PclZipUtilPathInclusion()
5206 // This function indicates if the path $p_path is under the $p_dir tree. Or,
5207 // said in an other way, if the file or sub-dir $p_path is inside the dir
5209 // The function indicates also if the path is exactly the same as the dir.
5210 // This function supports path with duplicated '/' like '//', but does not
5211 // support '.' or '..' statements.
5214 // 0 if $p_path is not inside directory $p_dir
5215 // 1 if $p_path is inside directory $p_dir
5216 // 2 if $p_path is exactly the same as $p_dir
5217 // --------------------------------------------------------------------------------
5218 function PclZipUtilPathInclusion($p_dir, $p_path)
5220 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilPathInclusion", "dir='$p_dir', path='$p_path'");
5223 // ----- Explode dir and path by directory separator
5224 $v_list_dir = explode("/", $p_dir);
5225 $v_list_dir_size = sizeof($v_list_dir);
5226 $v_list_path = explode("/", $p_path);
5227 $v_list_path_size = sizeof($v_list_path);
5229 // ----- Study directories paths
5232 while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5233 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Working on dir($i)='".$v_list_dir[$i]."' and path($j)='".$v_list_path[$j]."'");
5235 // ----- Look for empty dir (path reduction)
5236 if ($v_list_dir[$i] == '') {
5240 if ($v_list_path[$j] == '') {
5245 // ----- Compare the items
5246 if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
5247 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Items ($i,$j) are different");
5256 // ----- Look if everything seems to be the same
5258 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Look for tie break");
5259 // ----- Skip all the empty items
5260 while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
5261 while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
5262 //--(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]:'')."'");
5264 if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5265 // ----- There are exactly the same
5268 else if ($i < $v_list_dir_size) {
5269 // ----- The path is shorter than the dir
5275 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5278 // --------------------------------------------------------------------------------
5280 // --------------------------------------------------------------------------------
5281 // Function : PclZipUtilCopyBlock()
5284 // $p_mode : read/write compression mode
5285 // 0 : src & dest normal
5286 // 1 : src gzip, dest normal
5287 // 2 : src normal, dest gzip
5288 // 3 : src & dest gzip
5290 // --------------------------------------------------------------------------------
5291 function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
5293 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilCopyBlock", "size=$p_size, mode=$p_mode");
5298 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset before read :".(@ftell($p_src)));
5299 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset before write :".(@ftell($p_dest)));
5300 while ($p_size != 0)
5302 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5303 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5304 $v_buffer = @fread($p_src, $v_read_size);
5305 @fwrite($p_dest, $v_buffer, $v_read_size);
5306 $p_size -= $v_read_size;
5308 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Src offset after read :".(@ftell($p_src)));
5309 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Dest offset after write :".(@ftell($p_dest)));
5311 else if ($p_mode==1)
5313 while ($p_size != 0)
5315 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5316 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5317 $v_buffer = @gzread($p_src, $v_read_size);
5318 @fwrite($p_dest, $v_buffer, $v_read_size);
5319 $p_size -= $v_read_size;
5322 else if ($p_mode==2)
5324 while ($p_size != 0)
5326 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5327 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5328 $v_buffer = @fread($p_src, $v_read_size);
5329 @gzwrite($p_dest, $v_buffer, $v_read_size);
5330 $p_size -= $v_read_size;
5333 else if ($p_mode==3)
5335 while ($p_size != 0)
5337 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5338 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
5339 $v_buffer = @gzread($p_src, $v_read_size);
5340 @gzwrite($p_dest, $v_buffer, $v_read_size);
5341 $p_size -= $v_read_size;
5346 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5349 // --------------------------------------------------------------------------------
5351 // --------------------------------------------------------------------------------
5352 // Function : PclZipUtilRename()
5354 // This function tries to do a simple rename() function. If it fails, it
5355 // tries to copy the $p_src file in a new $p_dest file and then unlink the
5358 // $p_src : Old filename
5359 // $p_dest : New filename
5361 // 1 on success, 0 on failure.
5362 // --------------------------------------------------------------------------------
5363 function PclZipUtilRename($p_src, $p_dest)
5365 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilRename", "source=$p_src, destination=$p_dest");
5368 // ----- Try to rename the files
5369 if (!@rename($p_src, $p_dest)) {
5370 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to rename file, try copy+unlink");
5372 // ----- Try to copy & unlink the src
5373 if (!@copy($p_src, $p_dest)) {
5374 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to copy file");
5377 else if (!@unlink($p_src)) {
5378 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Fail to unlink old filename");
5384 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5387 // --------------------------------------------------------------------------------
5389 // --------------------------------------------------------------------------------
5390 // Function : PclZipUtilOptionText()
5392 // Translate option value in text. Mainly for debug purpose.
5394 // $p_option : the option value.
5396 // The option text value.
5397 // --------------------------------------------------------------------------------
5398 function PclZipUtilOptionText($p_option)
5400 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZipUtilOptionText", "option='".$p_option."'");
5402 $v_list = get_defined_constants();
5403 for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5404 $v_prefix = substr($v_key, 0, 10);
5405 if ((($v_prefix == 'PCLZIP_OPT') || ($v_prefix == 'PCLZIP_CB_'))
5406 && ($v_list[$v_key] == $p_option)) {
5407 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_key);
5412 $v_result = 'Unknown';
5414 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
5417 // --------------------------------------------------------------------------------
5419 // --------------------------------------------------------------------------------
5420 // Function : PclZipUtilTranslateWinPath()
5422 // Translate windows path by replacing '\' by '/' and optionally removing
5425 // $p_path : path to translate.
5426 // $p_remove_disk_letter : true | false
5428 // The path translated.
5429 // --------------------------------------------------------------------------------
5430 function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
5432 if (stristr(php_uname(), 'windows')) {
5433 // ----- Look for potential disk letter
5434 if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
5435 $p_path = substr($p_path, $v_position+1);
5437 // ----- Change potential windows directory separator
5438 if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
5439 $p_path = strtr($p_path, '\\', '/');
5444 // --------------------------------------------------------------------------------