Commit 7d6b4102adb81a99d735c27c4cf3a53acc08c287

Authored by Paul Barrett
1 parent 69d4d330

CRLF replaced by LF in thirdparty/peclzip/pclzip.lib.php.

Committed by: Paul Barrett
Showing 1 changed file with 5694 additions and 5694 deletions
thirdparty/peclzip/pclzip.lib.php
1 -<?php  
2 -// --------------------------------------------------------------------------------  
3 -// PhpConcept Library - Zip Module 2.8.2  
4 -// --------------------------------------------------------------------------------  
5 -// License GNU/LGPL - Vincent Blavet - August 2009  
6 -// http://www.phpconcept.net  
7 -// --------------------------------------------------------------------------------  
8 -//  
9 -// Presentation :  
10 -// PclZip is a PHP library that manage ZIP archives.  
11 -// So far tests show that archives generated by PclZip are readable by  
12 -// WinZip application and other tools.  
13 -//  
14 -// Description :  
15 -// See readme.txt and http://www.phpconcept.net  
16 -//  
17 -// Warning :  
18 -// This library and the associated files are non commercial, non professional  
19 -// work.  
20 -// It should not have unexpected results. However if any damage is caused by  
21 -// this software the author can not be responsible.  
22 -// The use of this software is at the risk of the user.  
23 -//  
24 -// --------------------------------------------------------------------------------  
25 -// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $  
26 -// --------------------------------------------------------------------------------  
27 -  
28 - // ----- Constants  
29 - if (!defined('PCLZIP_READ_BLOCK_SIZE')) {  
30 - define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );  
31 - }  
32 -  
33 - // ----- File list separator  
34 - // In version 1.x of PclZip, the separator for file list is a space  
35 - // (which is not a very smart choice, specifically for windows paths !).  
36 - // A better separator should be a comma (,). This constant gives you the  
37 - // abilty to change that.  
38 - // However notice that changing this value, may have impact on existing  
39 - // scripts, using space separated filenames.  
40 - // Recommanded values for compatibility with older versions :  
41 - //define( 'PCLZIP_SEPARATOR', ' ' );  
42 - // Recommanded values for smart separation of filenames.  
43 - if (!defined('PCLZIP_SEPARATOR')) {  
44 - define( 'PCLZIP_SEPARATOR', ',' );  
45 - }  
46 -  
47 - // ----- Error configuration  
48 - // 0 : PclZip Class integrated error handling  
49 - // 1 : PclError external library error handling. By enabling this  
50 - // you must ensure that you have included PclError library.  
51 - // [2,...] : reserved for futur use  
52 - if (!defined('PCLZIP_ERROR_EXTERNAL')) {  
53 - define( 'PCLZIP_ERROR_EXTERNAL', 0 );  
54 - }  
55 -  
56 - // ----- Optional static temporary directory  
57 - // By default temporary files are generated in the script current  
58 - // path.  
59 - // If defined :  
60 - // - MUST BE terminated by a '/'.  
61 - // - MUST be a valid, already created directory  
62 - // Samples :  
63 - // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );  
64 - // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );  
65 - if (!defined('PCLZIP_TEMPORARY_DIR')) {  
66 - define( 'PCLZIP_TEMPORARY_DIR', '' );  
67 - }  
68 -  
69 - // ----- Optional threshold ratio for use of temporary files  
70 - // Pclzip sense the size of the file to add/extract and decide to  
71 - // use or not temporary file. The algorythm is looking for  
72 - // memory_limit of PHP and apply a ratio.  
73 - // threshold = memory_limit * ratio.  
74 - // Recommended values are under 0.5. Default 0.47.  
75 - // Samples :  
76 - // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );  
77 - if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {  
78 - define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );  
79 - }  
80 -  
81 -// --------------------------------------------------------------------------------  
82 -// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****  
83 -// --------------------------------------------------------------------------------  
84 -  
85 - // ----- Global variables  
86 - $g_pclzip_version = "2.8.2";  
87 -  
88 - // ----- Error codes  
89 - // -1 : Unable to open file in binary write mode  
90 - // -2 : Unable to open file in binary read mode  
91 - // -3 : Invalid parameters  
92 - // -4 : File does not exist  
93 - // -5 : Filename is too long (max. 255)  
94 - // -6 : Not a valid zip file  
95 - // -7 : Invalid extracted file size  
96 - // -8 : Unable to create directory  
97 - // -9 : Invalid archive extension  
98 - // -10 : Invalid archive format  
99 - // -11 : Unable to delete file (unlink)  
100 - // -12 : Unable to rename file (rename)  
101 - // -13 : Invalid header checksum  
102 - // -14 : Invalid archive size  
103 - define( 'PCLZIP_ERR_USER_ABORTED', 2 );  
104 - define( 'PCLZIP_ERR_NO_ERROR', 0 );  
105 - define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );  
106 - define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );  
107 - define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );  
108 - define( 'PCLZIP_ERR_MISSING_FILE', -4 );  
109 - define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );  
110 - define( 'PCLZIP_ERR_INVALID_ZIP', -6 );  
111 - define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );  
112 - define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );  
113 - define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );  
114 - define( 'PCLZIP_ERR_BAD_FORMAT', -10 );  
115 - define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );  
116 - define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );  
117 - define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );  
118 - define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );  
119 - define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );  
120 - define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );  
121 - define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );  
122 - define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );  
123 - define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );  
124 - define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );  
125 - define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );  
126 -  
127 - // ----- Options values  
128 - define( 'PCLZIP_OPT_PATH', 77001 );  
129 - define( 'PCLZIP_OPT_ADD_PATH', 77002 );  
130 - define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );  
131 - define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );  
132 - define( 'PCLZIP_OPT_SET_CHMOD', 77005 );  
133 - define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );  
134 - define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );  
135 - define( 'PCLZIP_OPT_BY_NAME', 77008 );  
136 - define( 'PCLZIP_OPT_BY_INDEX', 77009 );  
137 - define( 'PCLZIP_OPT_BY_EREG', 77010 );  
138 - define( 'PCLZIP_OPT_BY_PREG', 77011 );  
139 - define( 'PCLZIP_OPT_COMMENT', 77012 );  
140 - define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );  
141 - define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );  
142 - define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );  
143 - define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );  
144 - define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );  
145 - // Having big trouble with crypt. Need to multiply 2 long int  
146 - // which is not correctly supported by PHP ...  
147 - //define( 'PCLZIP_OPT_CRYPT', 77018 );  
148 - define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );  
149 - define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );  
150 - define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias  
151 - define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );  
152 - define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias  
153 - define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );  
154 - define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias  
155 -  
156 - // ----- File description attributes  
157 - define( 'PCLZIP_ATT_FILE_NAME', 79001 );  
158 - define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );  
159 - define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );  
160 - define( 'PCLZIP_ATT_FILE_MTIME', 79004 );  
161 - define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );  
162 - define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );  
163 -  
164 - // ----- Call backs values  
165 - define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );  
166 - define( 'PCLZIP_CB_POST_EXTRACT', 78002 );  
167 - define( 'PCLZIP_CB_PRE_ADD', 78003 );  
168 - define( 'PCLZIP_CB_POST_ADD', 78004 );  
169 - /* For futur use  
170 - define( 'PCLZIP_CB_PRE_LIST', 78005 );  
171 - define( 'PCLZIP_CB_POST_LIST', 78006 );  
172 - define( 'PCLZIP_CB_PRE_DELETE', 78007 );  
173 - define( 'PCLZIP_CB_POST_DELETE', 78008 );  
174 - */  
175 -  
176 - // --------------------------------------------------------------------------------  
177 - // Class : PclZip  
178 - // Description :  
179 - // PclZip is the class that represent a Zip archive.  
180 - // The public methods allow the manipulation of the archive.  
181 - // Attributes :  
182 - // Attributes must not be accessed directly.  
183 - // Methods :  
184 - // PclZip() : Object creator  
185 - // create() : Creates the Zip archive  
186 - // listContent() : List the content of the Zip archive  
187 - // extract() : Extract the content of the archive  
188 - // properties() : List the properties of the archive  
189 - // --------------------------------------------------------------------------------  
190 - class PclZip  
191 - {  
192 - // ----- Filename of the zip file  
193 - var $zipname = '';  
194 -  
195 - // ----- File descriptor of the zip file  
196 - var $zip_fd = 0;  
197 -  
198 - // ----- Internal error handling  
199 - var $error_code = 1;  
200 - var $error_string = '';  
201 -  
202 - // ----- Current status of the magic_quotes_runtime  
203 - // This value store the php configuration for magic_quotes  
204 - // The class can then disable the magic_quotes and reset it after  
205 - var $magic_quotes_status;  
206 -  
207 - // --------------------------------------------------------------------------------  
208 - // Function : PclZip()  
209 - // Description :  
210 - // Creates a PclZip object and set the name of the associated Zip archive  
211 - // filename.  
212 - // Note that no real action is taken, if the archive does not exist it is not  
213 - // created. Use create() for that.  
214 - // --------------------------------------------------------------------------------  
215 - function PclZip($p_zipname)  
216 - {  
217 -  
218 - // ----- Tests the zlib  
219 - if (!function_exists('gzopen'))  
220 - {  
221 - die('Abort '.basename(__FILE__).' : Missing zlib extensions');  
222 - }  
223 -  
224 - // ----- Set the attributes  
225 - $this->zipname = $p_zipname;  
226 - $this->zip_fd = 0;  
227 - $this->magic_quotes_status = -1;  
228 -  
229 - // ----- Return  
230 - return;  
231 - }  
232 - // --------------------------------------------------------------------------------  
233 -  
234 - // --------------------------------------------------------------------------------  
235 - // Function :  
236 - // create($p_filelist, $p_add_dir="", $p_remove_dir="")  
237 - // create($p_filelist, $p_option, $p_option_value, ...)  
238 - // Description :  
239 - // This method supports two different synopsis. The first one is historical.  
240 - // This method creates a Zip Archive. The Zip file is created in the  
241 - // filesystem. The files and directories indicated in $p_filelist  
242 - // are added in the archive. See the parameters description for the  
243 - // supported format of $p_filelist.  
244 - // When a directory is in the list, the directory and its content is added  
245 - // in the archive.  
246 - // In this synopsis, the function takes an optional variable list of  
247 - // options. See bellow the supported options.  
248 - // Parameters :  
249 - // $p_filelist : An array containing file or directory names, or  
250 - // a string containing one filename or one directory name, or  
251 - // a string containing a list of filenames and/or directory  
252 - // names separated by spaces.  
253 - // $p_add_dir : A path to add before the real path of the archived file,  
254 - // in order to have it memorized in the archive.  
255 - // $p_remove_dir : A path to remove from the real path of the file to archive,  
256 - // in order to have a shorter path memorized in the archive.  
257 - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir  
258 - // is removed first, before $p_add_dir is added.  
259 - // Options :  
260 - // PCLZIP_OPT_ADD_PATH :  
261 - // PCLZIP_OPT_REMOVE_PATH :  
262 - // PCLZIP_OPT_REMOVE_ALL_PATH :  
263 - // PCLZIP_OPT_COMMENT :  
264 - // PCLZIP_CB_PRE_ADD :  
265 - // PCLZIP_CB_POST_ADD :  
266 - // Return Values :  
267 - // 0 on failure,  
268 - // The list of the added files, with a status of the add action.  
269 - // (see PclZip::listContent() for list entry format)  
270 - // --------------------------------------------------------------------------------  
271 - function create($p_filelist)  
272 - {  
273 - $v_result=1;  
274 -  
275 - // ----- Reset the error handler  
276 - $this->privErrorReset();  
277 -  
278 - // ----- Set default values  
279 - $v_options = array();  
280 - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;  
281 -  
282 - // ----- Look for variable options arguments  
283 - $v_size = func_num_args();  
284 -  
285 - // ----- Look for arguments  
286 - if ($v_size > 1) {  
287 - // ----- Get the arguments  
288 - $v_arg_list = func_get_args();  
289 -  
290 - // ----- Remove from the options list the first argument  
291 - array_shift($v_arg_list);  
292 - $v_size--;  
293 -  
294 - // ----- Look for first arg  
295 - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {  
296 -  
297 - // ----- Parse the options  
298 - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
299 - array (PCLZIP_OPT_REMOVE_PATH => 'optional',  
300 - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
301 - PCLZIP_OPT_ADD_PATH => 'optional',  
302 - PCLZIP_CB_PRE_ADD => 'optional',  
303 - PCLZIP_CB_POST_ADD => 'optional',  
304 - PCLZIP_OPT_NO_COMPRESSION => 'optional',  
305 - PCLZIP_OPT_COMMENT => 'optional',  
306 - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
307 - PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
308 - PCLZIP_OPT_TEMP_FILE_OFF => 'optional'  
309 - //, PCLZIP_OPT_CRYPT => 'optional'  
310 - ));  
311 - if ($v_result != 1) {  
312 - return 0;  
313 - }  
314 - }  
315 -  
316 - // ----- Look for 2 args  
317 - // Here we need to support the first historic synopsis of the  
318 - // method.  
319 - else {  
320 -  
321 - // ----- Get the first argument  
322 - $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];  
323 -  
324 - // ----- Look for the optional second argument  
325 - if ($v_size == 2) {  
326 - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];  
327 - }  
328 - else if ($v_size > 2) {  
329 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
330 - "Invalid number / type of arguments");  
331 - return 0;  
332 - }  
333 - }  
334 - }  
335 -  
336 - // ----- Look for default option values  
337 - $this->privOptionDefaultThreshold($v_options);  
338 -  
339 - // ----- Init  
340 - $v_string_list = array();  
341 - $v_att_list = array();  
342 - $v_filedescr_list = array();  
343 - $p_result_list = array();  
344 -  
345 - // ----- Look if the $p_filelist is really an array  
346 - if (is_array($p_filelist)) {  
347 -  
348 - // ----- Look if the first element is also an array  
349 - // This will mean that this is a file description entry  
350 - if (isset($p_filelist[0]) && is_array($p_filelist[0])) {  
351 - $v_att_list = $p_filelist;  
352 - }  
353 -  
354 - // ----- The list is a list of string names  
355 - else {  
356 - $v_string_list = $p_filelist;  
357 - }  
358 - }  
359 -  
360 - // ----- Look if the $p_filelist is a string  
361 - else if (is_string($p_filelist)) {  
362 - // ----- Create a list from the string  
363 - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);  
364 - }  
365 -  
366 - // ----- Invalid variable type for $p_filelist  
367 - else {  
368 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");  
369 - return 0;  
370 - }  
371 -  
372 - // ----- Reformat the string list  
373 - if (sizeof($v_string_list) != 0) {  
374 - foreach ($v_string_list as $v_string) {  
375 - if ($v_string != '') {  
376 - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;  
377 - }  
378 - else {  
379 - }  
380 - }  
381 - }  
382 -  
383 - // ----- For each file in the list check the attributes  
384 - $v_supported_attributes  
385 - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'  
386 - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'  
387 - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'  
388 - ,PCLZIP_ATT_FILE_MTIME => 'optional'  
389 - ,PCLZIP_ATT_FILE_CONTENT => 'optional'  
390 - ,PCLZIP_ATT_FILE_COMMENT => 'optional'  
391 - );  
392 - foreach ($v_att_list as $v_entry) {  
393 - $v_result = $this->privFileDescrParseAtt($v_entry,  
394 - $v_filedescr_list[],  
395 - $v_options,  
396 - $v_supported_attributes);  
397 - if ($v_result != 1) {  
398 - return 0;  
399 - }  
400 - }  
401 -  
402 - // ----- Expand the filelist (expand directories)  
403 - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);  
404 - if ($v_result != 1) {  
405 - return 0;  
406 - }  
407 -  
408 - // ----- Call the create fct  
409 - $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);  
410 - if ($v_result != 1) {  
411 - return 0;  
412 - }  
413 -  
414 - // ----- Return  
415 - return $p_result_list;  
416 - }  
417 - // --------------------------------------------------------------------------------  
418 -  
419 - // --------------------------------------------------------------------------------  
420 - // Function :  
421 - // add($p_filelist, $p_add_dir="", $p_remove_dir="")  
422 - // add($p_filelist, $p_option, $p_option_value, ...)  
423 - // Description :  
424 - // This method supports two synopsis. The first one is historical.  
425 - // This methods add the list of files in an existing archive.  
426 - // If a file with the same name already exists, it is added at the end of the  
427 - // archive, the first one is still present.  
428 - // If the archive does not exist, it is created.  
429 - // Parameters :  
430 - // $p_filelist : An array containing file or directory names, or  
431 - // a string containing one filename or one directory name, or  
432 - // a string containing a list of filenames and/or directory  
433 - // names separated by spaces.  
434 - // $p_add_dir : A path to add before the real path of the archived file,  
435 - // in order to have it memorized in the archive.  
436 - // $p_remove_dir : A path to remove from the real path of the file to archive,  
437 - // in order to have a shorter path memorized in the archive.  
438 - // When $p_add_dir and $p_remove_dir are set, $p_remove_dir  
439 - // is removed first, before $p_add_dir is added.  
440 - // Options :  
441 - // PCLZIP_OPT_ADD_PATH :  
442 - // PCLZIP_OPT_REMOVE_PATH :  
443 - // PCLZIP_OPT_REMOVE_ALL_PATH :  
444 - // PCLZIP_OPT_COMMENT :  
445 - // PCLZIP_OPT_ADD_COMMENT :  
446 - // PCLZIP_OPT_PREPEND_COMMENT :  
447 - // PCLZIP_CB_PRE_ADD :  
448 - // PCLZIP_CB_POST_ADD :  
449 - // Return Values :  
450 - // 0 on failure,  
451 - // The list of the added files, with a status of the add action.  
452 - // (see PclZip::listContent() for list entry format)  
453 - // --------------------------------------------------------------------------------  
454 - function add($p_filelist)  
455 - {  
456 - $v_result=1;  
457 -  
458 - // ----- Reset the error handler  
459 - $this->privErrorReset();  
460 -  
461 - // ----- Set default values  
462 - $v_options = array();  
463 - $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;  
464 -  
465 - // ----- Look for variable options arguments  
466 - $v_size = func_num_args();  
467 -  
468 - // ----- Look for arguments  
469 - if ($v_size > 1) {  
470 - // ----- Get the arguments  
471 - $v_arg_list = func_get_args();  
472 -  
473 - // ----- Remove form the options list the first argument  
474 - array_shift($v_arg_list);  
475 - $v_size--;  
476 -  
477 - // ----- Look for first arg  
478 - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {  
479 -  
480 - // ----- Parse the options  
481 - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
482 - array (PCLZIP_OPT_REMOVE_PATH => 'optional',  
483 - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
484 - PCLZIP_OPT_ADD_PATH => 'optional',  
485 - PCLZIP_CB_PRE_ADD => 'optional',  
486 - PCLZIP_CB_POST_ADD => 'optional',  
487 - PCLZIP_OPT_NO_COMPRESSION => 'optional',  
488 - PCLZIP_OPT_COMMENT => 'optional',  
489 - PCLZIP_OPT_ADD_COMMENT => 'optional',  
490 - PCLZIP_OPT_PREPEND_COMMENT => 'optional',  
491 - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
492 - PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
493 - PCLZIP_OPT_TEMP_FILE_OFF => 'optional'  
494 - //, PCLZIP_OPT_CRYPT => 'optional'  
495 - ));  
496 - if ($v_result != 1) {  
497 - return 0;  
498 - }  
499 - }  
500 -  
501 - // ----- Look for 2 args  
502 - // Here we need to support the first historic synopsis of the  
503 - // method.  
504 - else {  
505 -  
506 - // ----- Get the first argument  
507 - $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];  
508 -  
509 - // ----- Look for the optional second argument  
510 - if ($v_size == 2) {  
511 - $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];  
512 - }  
513 - else if ($v_size > 2) {  
514 - // ----- Error log  
515 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");  
516 -  
517 - // ----- Return  
518 - return 0;  
519 - }  
520 - }  
521 - }  
522 -  
523 - // ----- Look for default option values  
524 - $this->privOptionDefaultThreshold($v_options);  
525 -  
526 - // ----- Init  
527 - $v_string_list = array();  
528 - $v_att_list = array();  
529 - $v_filedescr_list = array();  
530 - $p_result_list = array();  
531 -  
532 - // ----- Look if the $p_filelist is really an array  
533 - if (is_array($p_filelist)) {  
534 -  
535 - // ----- Look if the first element is also an array  
536 - // This will mean that this is a file description entry  
537 - if (isset($p_filelist[0]) && is_array($p_filelist[0])) {  
538 - $v_att_list = $p_filelist;  
539 - }  
540 -  
541 - // ----- The list is a list of string names  
542 - else {  
543 - $v_string_list = $p_filelist;  
544 - }  
545 - }  
546 -  
547 - // ----- Look if the $p_filelist is a string  
548 - else if (is_string($p_filelist)) {  
549 - // ----- Create a list from the string  
550 - $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);  
551 - }  
552 -  
553 - // ----- Invalid variable type for $p_filelist  
554 - else {  
555 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");  
556 - return 0;  
557 - }  
558 -  
559 - // ----- Reformat the string list  
560 - if (sizeof($v_string_list) != 0) {  
561 - foreach ($v_string_list as $v_string) {  
562 - $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;  
563 - }  
564 - }  
565 -  
566 - // ----- For each file in the list check the attributes  
567 - $v_supported_attributes  
568 - = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'  
569 - ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'  
570 - ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'  
571 - ,PCLZIP_ATT_FILE_MTIME => 'optional'  
572 - ,PCLZIP_ATT_FILE_CONTENT => 'optional'  
573 - ,PCLZIP_ATT_FILE_COMMENT => 'optional'  
574 - );  
575 - foreach ($v_att_list as $v_entry) {  
576 - $v_result = $this->privFileDescrParseAtt($v_entry,  
577 - $v_filedescr_list[],  
578 - $v_options,  
579 - $v_supported_attributes);  
580 - if ($v_result != 1) {  
581 - return 0;  
582 - }  
583 - }  
584 -  
585 - // ----- Expand the filelist (expand directories)  
586 - $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);  
587 - if ($v_result != 1) {  
588 - return 0;  
589 - }  
590 -  
591 - // ----- Call the create fct  
592 - $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);  
593 - if ($v_result != 1) {  
594 - return 0;  
595 - }  
596 -  
597 - // ----- Return  
598 - return $p_result_list;  
599 - }  
600 - // --------------------------------------------------------------------------------  
601 -  
602 - // --------------------------------------------------------------------------------  
603 - // Function : listContent()  
604 - // Description :  
605 - // This public method, gives the list of the files and directories, with their  
606 - // properties.  
607 - // The properties of each entries in the list are (used also in other functions) :  
608 - // filename : Name of the file. For a create or add action it is the filename  
609 - // given by the user. For an extract function it is the filename  
610 - // of the extracted file.  
611 - // stored_filename : Name of the file / directory stored in the archive.  
612 - // size : Size of the stored file.  
613 - // compressed_size : Size of the file's data compressed in the archive  
614 - // (without the headers overhead)  
615 - // mtime : Last known modification date of the file (UNIX timestamp)  
616 - // comment : Comment associated with the file  
617 - // folder : true | false  
618 - // index : index of the file in the archive  
619 - // status : status of the action (depending of the action) :  
620 - // Values are :  
621 - // ok : OK !  
622 - // filtered : the file / dir is not extracted (filtered by user)  
623 - // already_a_directory : the file can not be extracted because a  
624 - // directory with the same name already exists  
625 - // write_protected : the file can not be extracted because a file  
626 - // with the same name already exists and is  
627 - // write protected  
628 - // newer_exist : the file was not extracted because a newer file exists  
629 - // path_creation_fail : the file is not extracted because the folder  
630 - // does not exist and can not be created  
631 - // write_error : the file was not extracted because there was a  
632 - // error while writing the file  
633 - // read_error : the file was not extracted because there was a error  
634 - // while reading the file  
635 - // invalid_header : the file was not extracted because of an archive  
636 - // format error (bad file header)  
637 - // Note that each time a method can continue operating when there  
638 - // is an action error on a file, the error is only logged in the file status.  
639 - // Return Values :  
640 - // 0 on an unrecoverable failure,  
641 - // The list of the files in the archive.  
642 - // --------------------------------------------------------------------------------  
643 - function listContent()  
644 - {  
645 - $v_result=1;  
646 -  
647 - // ----- Reset the error handler  
648 - $this->privErrorReset();  
649 -  
650 - // ----- Check archive  
651 - if (!$this->privCheckFormat()) {  
652 - return(0);  
653 - }  
654 -  
655 - // ----- Call the extracting fct  
656 - $p_list = array();  
657 - if (($v_result = $this->privList($p_list)) != 1)  
658 - {  
659 - unset($p_list);  
660 - return(0);  
661 - }  
662 -  
663 - // ----- Return  
664 - return $p_list;  
665 - }  
666 - // --------------------------------------------------------------------------------  
667 -  
668 - // --------------------------------------------------------------------------------  
669 - // Function :  
670 - // extract($p_path="./", $p_remove_path="")  
671 - // extract([$p_option, $p_option_value, ...])  
672 - // Description :  
673 - // This method supports two synopsis. The first one is historical.  
674 - // This method extract all the files / directories from the archive to the  
675 - // folder indicated in $p_path.  
676 - // If you want to ignore the 'root' part of path of the memorized files  
677 - // you can indicate this in the optional $p_remove_path parameter.  
678 - // By default, if a newer file with the same name already exists, the  
679 - // file is not extracted.  
680 - //  
681 - // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions  
682 - // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append  
683 - // at the end of the path value of PCLZIP_OPT_PATH.  
684 - // Parameters :  
685 - // $p_path : Path where the files and directories are to be extracted  
686 - // $p_remove_path : First part ('root' part) of the memorized path  
687 - // (if any similar) to remove while extracting.  
688 - // Options :  
689 - // PCLZIP_OPT_PATH :  
690 - // PCLZIP_OPT_ADD_PATH :  
691 - // PCLZIP_OPT_REMOVE_PATH :  
692 - // PCLZIP_OPT_REMOVE_ALL_PATH :  
693 - // PCLZIP_CB_PRE_EXTRACT :  
694 - // PCLZIP_CB_POST_EXTRACT :  
695 - // Return Values :  
696 - // 0 or a negative value on failure,  
697 - // The list of the extracted files, with a status of the action.  
698 - // (see PclZip::listContent() for list entry format)  
699 - // --------------------------------------------------------------------------------  
700 - function extract()  
701 - {  
702 - $v_result=1;  
703 -  
704 - // ----- Reset the error handler  
705 - $this->privErrorReset();  
706 -  
707 - // ----- Check archive  
708 - if (!$this->privCheckFormat()) {  
709 - return(0);  
710 - }  
711 -  
712 - // ----- Set default values  
713 - $v_options = array();  
714 -// $v_path = "./";  
715 - $v_path = '';  
716 - $v_remove_path = "";  
717 - $v_remove_all_path = false;  
718 -  
719 - // ----- Look for variable options arguments  
720 - $v_size = func_num_args();  
721 -  
722 - // ----- Default values for option  
723 - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;  
724 -  
725 - // ----- Look for arguments  
726 - if ($v_size > 0) {  
727 - // ----- Get the arguments  
728 - $v_arg_list = func_get_args();  
729 -  
730 - // ----- Look for first arg  
731 - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {  
732 -  
733 - // ----- Parse the options  
734 - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
735 - array (PCLZIP_OPT_PATH => 'optional',  
736 - PCLZIP_OPT_REMOVE_PATH => 'optional',  
737 - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
738 - PCLZIP_OPT_ADD_PATH => 'optional',  
739 - PCLZIP_CB_PRE_EXTRACT => 'optional',  
740 - PCLZIP_CB_POST_EXTRACT => 'optional',  
741 - PCLZIP_OPT_SET_CHMOD => 'optional',  
742 - PCLZIP_OPT_BY_NAME => 'optional',  
743 - PCLZIP_OPT_BY_EREG => 'optional',  
744 - PCLZIP_OPT_BY_PREG => 'optional',  
745 - PCLZIP_OPT_BY_INDEX => 'optional',  
746 - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',  
747 - PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',  
748 - PCLZIP_OPT_REPLACE_NEWER => 'optional'  
749 - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'  
750 - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',  
751 - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
752 - PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
753 - PCLZIP_OPT_TEMP_FILE_OFF => 'optional'  
754 - ));  
755 - if ($v_result != 1) {  
756 - return 0;  
757 - }  
758 -  
759 - // ----- Set the arguments  
760 - if (isset($v_options[PCLZIP_OPT_PATH])) {  
761 - $v_path = $v_options[PCLZIP_OPT_PATH];  
762 - }  
763 - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {  
764 - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];  
765 - }  
766 - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {  
767 - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];  
768 - }  
769 - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {  
770 - // ----- Check for '/' in last path char  
771 - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {  
772 - $v_path .= '/';  
773 - }  
774 - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];  
775 - }  
776 - }  
777 -  
778 - // ----- Look for 2 args  
779 - // Here we need to support the first historic synopsis of the  
780 - // method.  
781 - else {  
782 -  
783 - // ----- Get the first argument  
784 - $v_path = $v_arg_list[0];  
785 -  
786 - // ----- Look for the optional second argument  
787 - if ($v_size == 2) {  
788 - $v_remove_path = $v_arg_list[1];  
789 - }  
790 - else if ($v_size > 2) {  
791 - // ----- Error log  
792 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");  
793 -  
794 - // ----- Return  
795 - return 0;  
796 - }  
797 - }  
798 - }  
799 -  
800 - // ----- Look for default option values  
801 - $this->privOptionDefaultThreshold($v_options);  
802 -  
803 - // ----- Trace  
804 -  
805 - // ----- Call the extracting fct  
806 - $p_list = array();  
807 - $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,  
808 - $v_remove_all_path, $v_options);  
809 - if ($v_result < 1) {  
810 - unset($p_list);  
811 - return(0);  
812 - }  
813 -  
814 - // ----- Return  
815 - return $p_list;  
816 - }  
817 - // --------------------------------------------------------------------------------  
818 -  
819 -  
820 - // --------------------------------------------------------------------------------  
821 - // Function :  
822 - // extractByIndex($p_index, $p_path="./", $p_remove_path="")  
823 - // extractByIndex($p_index, [$p_option, $p_option_value, ...])  
824 - // Description :  
825 - // This method supports two synopsis. The first one is historical.  
826 - // This method is doing a partial extract of the archive.  
827 - // The extracted files or folders are identified by their index in the  
828 - // archive (from 0 to n).  
829 - // Note that if the index identify a folder, only the folder entry is  
830 - // extracted, not all the files included in the archive.  
831 - // Parameters :  
832 - // $p_index : A single index (integer) or a string of indexes of files to  
833 - // extract. The form of the string is "0,4-6,8-12" with only numbers  
834 - // and '-' for range or ',' to separate ranges. No spaces or ';'  
835 - // are allowed.  
836 - // $p_path : Path where the files and directories are to be extracted  
837 - // $p_remove_path : First part ('root' part) of the memorized path  
838 - // (if any similar) to remove while extracting.  
839 - // Options :  
840 - // PCLZIP_OPT_PATH :  
841 - // PCLZIP_OPT_ADD_PATH :  
842 - // PCLZIP_OPT_REMOVE_PATH :  
843 - // PCLZIP_OPT_REMOVE_ALL_PATH :  
844 - // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and  
845 - // not as files.  
846 - // The resulting content is in a new field 'content' in the file  
847 - // structure.  
848 - // This option must be used alone (any other options are ignored).  
849 - // PCLZIP_CB_PRE_EXTRACT :  
850 - // PCLZIP_CB_POST_EXTRACT :  
851 - // Return Values :  
852 - // 0 on failure,  
853 - // The list of the extracted files, with a status of the action.  
854 - // (see PclZip::listContent() for list entry format)  
855 - // --------------------------------------------------------------------------------  
856 - //function extractByIndex($p_index, options...)  
857 - function extractByIndex($p_index)  
858 - {  
859 - $v_result=1;  
860 -  
861 - // ----- Reset the error handler  
862 - $this->privErrorReset();  
863 -  
864 - // ----- Check archive  
865 - if (!$this->privCheckFormat()) {  
866 - return(0);  
867 - }  
868 -  
869 - // ----- Set default values  
870 - $v_options = array();  
871 -// $v_path = "./";  
872 - $v_path = '';  
873 - $v_remove_path = "";  
874 - $v_remove_all_path = false;  
875 -  
876 - // ----- Look for variable options arguments  
877 - $v_size = func_num_args();  
878 -  
879 - // ----- Default values for option  
880 - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;  
881 -  
882 - // ----- Look for arguments  
883 - if ($v_size > 1) {  
884 - // ----- Get the arguments  
885 - $v_arg_list = func_get_args();  
886 -  
887 - // ----- Remove form the options list the first argument  
888 - array_shift($v_arg_list);  
889 - $v_size--;  
890 -  
891 - // ----- Look for first arg  
892 - if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {  
893 -  
894 - // ----- Parse the options  
895 - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
896 - array (PCLZIP_OPT_PATH => 'optional',  
897 - PCLZIP_OPT_REMOVE_PATH => 'optional',  
898 - PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',  
899 - PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',  
900 - PCLZIP_OPT_ADD_PATH => 'optional',  
901 - PCLZIP_CB_PRE_EXTRACT => 'optional',  
902 - PCLZIP_CB_POST_EXTRACT => 'optional',  
903 - PCLZIP_OPT_SET_CHMOD => 'optional',  
904 - PCLZIP_OPT_REPLACE_NEWER => 'optional'  
905 - ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'  
906 - ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',  
907 - PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',  
908 - PCLZIP_OPT_TEMP_FILE_ON => 'optional',  
909 - PCLZIP_OPT_TEMP_FILE_OFF => 'optional'  
910 - ));  
911 - if ($v_result != 1) {  
912 - return 0;  
913 - }  
914 -  
915 - // ----- Set the arguments  
916 - if (isset($v_options[PCLZIP_OPT_PATH])) {  
917 - $v_path = $v_options[PCLZIP_OPT_PATH];  
918 - }  
919 - if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {  
920 - $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];  
921 - }  
922 - if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {  
923 - $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];  
924 - }  
925 - if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {  
926 - // ----- Check for '/' in last path char  
927 - if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {  
928 - $v_path .= '/';  
929 - }  
930 - $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];  
931 - }  
932 - if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {  
933 - $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;  
934 - }  
935 - else {  
936 - }  
937 - }  
938 -  
939 - // ----- Look for 2 args  
940 - // Here we need to support the first historic synopsis of the  
941 - // method.  
942 - else {  
943 -  
944 - // ----- Get the first argument  
945 - $v_path = $v_arg_list[0];  
946 -  
947 - // ----- Look for the optional second argument  
948 - if ($v_size == 2) {  
949 - $v_remove_path = $v_arg_list[1];  
950 - }  
951 - else if ($v_size > 2) {  
952 - // ----- Error log  
953 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");  
954 -  
955 - // ----- Return  
956 - return 0;  
957 - }  
958 - }  
959 - }  
960 -  
961 - // ----- Trace  
962 -  
963 - // ----- Trick  
964 - // Here I want to reuse extractByRule(), so I need to parse the $p_index  
965 - // with privParseOptions()  
966 - $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);  
967 - $v_options_trick = array();  
968 - $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,  
969 - array (PCLZIP_OPT_BY_INDEX => 'optional' ));  
970 - if ($v_result != 1) {  
971 - return 0;  
972 - }  
973 - $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];  
974 -  
975 - // ----- Look for default option values  
976 - $this->privOptionDefaultThreshold($v_options);  
977 -  
978 - // ----- Call the extracting fct  
979 - if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {  
980 - return(0);  
981 - }  
982 -  
983 - // ----- Return  
984 - return $p_list;  
985 - }  
986 - // --------------------------------------------------------------------------------  
987 -  
988 - // --------------------------------------------------------------------------------  
989 - // Function :  
990 - // delete([$p_option, $p_option_value, ...])  
991 - // Description :  
992 - // This method removes files from the archive.  
993 - // If no parameters are given, then all the archive is emptied.  
994 - // Parameters :  
995 - // None or optional arguments.  
996 - // Options :  
997 - // PCLZIP_OPT_BY_INDEX :  
998 - // PCLZIP_OPT_BY_NAME :  
999 - // PCLZIP_OPT_BY_EREG :  
1000 - // PCLZIP_OPT_BY_PREG :  
1001 - // Return Values :  
1002 - // 0 on failure,  
1003 - // The list of the files which are still present in the archive.  
1004 - // (see PclZip::listContent() for list entry format)  
1005 - // --------------------------------------------------------------------------------  
1006 - function delete()  
1007 - {  
1008 - $v_result=1;  
1009 -  
1010 - // ----- Reset the error handler  
1011 - $this->privErrorReset();  
1012 -  
1013 - // ----- Check archive  
1014 - if (!$this->privCheckFormat()) {  
1015 - return(0);  
1016 - }  
1017 -  
1018 - // ----- Set default values  
1019 - $v_options = array();  
1020 -  
1021 - // ----- Look for variable options arguments  
1022 - $v_size = func_num_args();  
1023 -  
1024 - // ----- Look for arguments  
1025 - if ($v_size > 0) {  
1026 - // ----- Get the arguments  
1027 - $v_arg_list = func_get_args();  
1028 -  
1029 - // ----- Parse the options  
1030 - $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,  
1031 - array (PCLZIP_OPT_BY_NAME => 'optional',  
1032 - PCLZIP_OPT_BY_EREG => 'optional',  
1033 - PCLZIP_OPT_BY_PREG => 'optional',  
1034 - PCLZIP_OPT_BY_INDEX => 'optional' ));  
1035 - if ($v_result != 1) {  
1036 - return 0;  
1037 - }  
1038 - }  
1039 -  
1040 - // ----- Magic quotes trick  
1041 - $this->privDisableMagicQuotes();  
1042 -  
1043 - // ----- Call the delete fct  
1044 - $v_list = array();  
1045 - if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {  
1046 - $this->privSwapBackMagicQuotes();  
1047 - unset($v_list);  
1048 - return(0);  
1049 - }  
1050 -  
1051 - // ----- Magic quotes trick  
1052 - $this->privSwapBackMagicQuotes();  
1053 -  
1054 - // ----- Return  
1055 - return $v_list;  
1056 - }  
1057 - // --------------------------------------------------------------------------------  
1058 -  
1059 - // --------------------------------------------------------------------------------  
1060 - // Function : deleteByIndex()  
1061 - // Description :  
1062 - // ***** Deprecated *****  
1063 - // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.  
1064 - // --------------------------------------------------------------------------------  
1065 - function deleteByIndex($p_index)  
1066 - {  
1067 -  
1068 - $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);  
1069 -  
1070 - // ----- Return  
1071 - return $p_list;  
1072 - }  
1073 - // --------------------------------------------------------------------------------  
1074 -  
1075 - // --------------------------------------------------------------------------------  
1076 - // Function : properties()  
1077 - // Description :  
1078 - // This method gives the properties of the archive.  
1079 - // The properties are :  
1080 - // nb : Number of files in the archive  
1081 - // comment : Comment associated with the archive file  
1082 - // status : not_exist, ok  
1083 - // Parameters :  
1084 - // None  
1085 - // Return Values :  
1086 - // 0 on failure,  
1087 - // An array with the archive properties.  
1088 - // --------------------------------------------------------------------------------  
1089 - function properties()  
1090 - {  
1091 -  
1092 - // ----- Reset the error handler  
1093 - $this->privErrorReset();  
1094 -  
1095 - // ----- Magic quotes trick  
1096 - $this->privDisableMagicQuotes();  
1097 -  
1098 - // ----- Check archive  
1099 - if (!$this->privCheckFormat()) {  
1100 - $this->privSwapBackMagicQuotes();  
1101 - return(0);  
1102 - }  
1103 -  
1104 - // ----- Default properties  
1105 - $v_prop = array();  
1106 - $v_prop['comment'] = '';  
1107 - $v_prop['nb'] = 0;  
1108 - $v_prop['status'] = 'not_exist';  
1109 -  
1110 - // ----- Look if file exists  
1111 - if (@is_file($this->zipname))  
1112 - {  
1113 - // ----- Open the zip file  
1114 - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)  
1115 - {  
1116 - $this->privSwapBackMagicQuotes();  
1117 -  
1118 - // ----- Error log  
1119 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');  
1120 -  
1121 - // ----- Return  
1122 - return 0;  
1123 - }  
1124 -  
1125 - // ----- Read the central directory informations  
1126 - $v_central_dir = array();  
1127 - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)  
1128 - {  
1129 - $this->privSwapBackMagicQuotes();  
1130 - return 0;  
1131 - }  
1132 -  
1133 - // ----- Close the zip file  
1134 - $this->privCloseFd();  
1135 -  
1136 - // ----- Set the user attributes  
1137 - $v_prop['comment'] = $v_central_dir['comment'];  
1138 - $v_prop['nb'] = $v_central_dir['entries'];  
1139 - $v_prop['status'] = 'ok';  
1140 - }  
1141 -  
1142 - // ----- Magic quotes trick  
1143 - $this->privSwapBackMagicQuotes();  
1144 -  
1145 - // ----- Return  
1146 - return $v_prop;  
1147 - }  
1148 - // --------------------------------------------------------------------------------  
1149 -  
1150 - // --------------------------------------------------------------------------------  
1151 - // Function : duplicate()  
1152 - // Description :  
1153 - // This method creates an archive by copying the content of an other one. If  
1154 - // the archive already exist, it is replaced by the new one without any warning.  
1155 - // Parameters :  
1156 - // $p_archive : The filename of a valid archive, or  
1157 - // a valid PclZip object.  
1158 - // Return Values :  
1159 - // 1 on success.  
1160 - // 0 or a negative value on error (error code).  
1161 - // --------------------------------------------------------------------------------  
1162 - function duplicate($p_archive)  
1163 - {  
1164 - $v_result = 1;  
1165 -  
1166 - // ----- Reset the error handler  
1167 - $this->privErrorReset();  
1168 -  
1169 - // ----- Look if the $p_archive is a PclZip object  
1170 - if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))  
1171 - {  
1172 -  
1173 - // ----- Duplicate the archive  
1174 - $v_result = $this->privDuplicate($p_archive->zipname);  
1175 - }  
1176 -  
1177 - // ----- Look if the $p_archive is a string (so a filename)  
1178 - else if (is_string($p_archive))  
1179 - {  
1180 -  
1181 - // ----- Check that $p_archive is a valid zip file  
1182 - // TBC : Should also check the archive format  
1183 - if (!is_file($p_archive)) {  
1184 - // ----- Error log  
1185 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");  
1186 - $v_result = PCLZIP_ERR_MISSING_FILE;  
1187 - }  
1188 - else {  
1189 - // ----- Duplicate the archive  
1190 - $v_result = $this->privDuplicate($p_archive);  
1191 - }  
1192 - }  
1193 -  
1194 - // ----- Invalid variable  
1195 - else  
1196 - {  
1197 - // ----- Error log  
1198 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");  
1199 - $v_result = PCLZIP_ERR_INVALID_PARAMETER;  
1200 - }  
1201 -  
1202 - // ----- Return  
1203 - return $v_result;  
1204 - }  
1205 - // --------------------------------------------------------------------------------  
1206 -  
1207 - // --------------------------------------------------------------------------------  
1208 - // Function : merge()  
1209 - // Description :  
1210 - // This method merge the $p_archive_to_add archive at the end of the current  
1211 - // one ($this).  
1212 - // If the archive ($this) does not exist, the merge becomes a duplicate.  
1213 - // If the $p_archive_to_add archive does not exist, the merge is a success.  
1214 - // Parameters :  
1215 - // $p_archive_to_add : It can be directly the filename of a valid zip archive,  
1216 - // or a PclZip object archive.  
1217 - // Return Values :  
1218 - // 1 on success,  
1219 - // 0 or negative values on error (see below).  
1220 - // --------------------------------------------------------------------------------  
1221 - function merge($p_archive_to_add)  
1222 - {  
1223 - $v_result = 1;  
1224 -  
1225 - // ----- Reset the error handler  
1226 - $this->privErrorReset();  
1227 -  
1228 - // ----- Check archive  
1229 - if (!$this->privCheckFormat()) {  
1230 - return(0);  
1231 - }  
1232 -  
1233 - // ----- Look if the $p_archive_to_add is a PclZip object  
1234 - if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))  
1235 - {  
1236 -  
1237 - // ----- Merge the archive  
1238 - $v_result = $this->privMerge($p_archive_to_add);  
1239 - }  
1240 -  
1241 - // ----- Look if the $p_archive_to_add is a string (so a filename)  
1242 - else if (is_string($p_archive_to_add))  
1243 - {  
1244 -  
1245 - // ----- Create a temporary archive  
1246 - $v_object_archive = new PclZip($p_archive_to_add);  
1247 -  
1248 - // ----- Merge the archive  
1249 - $v_result = $this->privMerge($v_object_archive);  
1250 - }  
1251 -  
1252 - // ----- Invalid variable  
1253 - else  
1254 - {  
1255 - // ----- Error log  
1256 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");  
1257 - $v_result = PCLZIP_ERR_INVALID_PARAMETER;  
1258 - }  
1259 -  
1260 - // ----- Return  
1261 - return $v_result;  
1262 - }  
1263 - // --------------------------------------------------------------------------------  
1264 -  
1265 -  
1266 -  
1267 - // --------------------------------------------------------------------------------  
1268 - // Function : errorCode()  
1269 - // Description :  
1270 - // Parameters :  
1271 - // --------------------------------------------------------------------------------  
1272 - function errorCode()  
1273 - {  
1274 - if (PCLZIP_ERROR_EXTERNAL == 1) {  
1275 - return(PclErrorCode());  
1276 - }  
1277 - else {  
1278 - return($this->error_code);  
1279 - }  
1280 - }  
1281 - // --------------------------------------------------------------------------------  
1282 -  
1283 - // --------------------------------------------------------------------------------  
1284 - // Function : errorName()  
1285 - // Description :  
1286 - // Parameters :  
1287 - // --------------------------------------------------------------------------------  
1288 - function errorName($p_with_code=false)  
1289 - {  
1290 - $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',  
1291 - PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',  
1292 - PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',  
1293 - PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',  
1294 - PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',  
1295 - PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',  
1296 - PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',  
1297 - PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',  
1298 - PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',  
1299 - PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',  
1300 - PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',  
1301 - PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',  
1302 - PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',  
1303 - PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',  
1304 - PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',  
1305 - PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',  
1306 - PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',  
1307 - PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',  
1308 - PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'  
1309 - ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'  
1310 - ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'  
1311 - );  
1312 -  
1313 - if (isset($v_name[$this->error_code])) {  
1314 - $v_value = $v_name[$this->error_code];  
1315 - }  
1316 - else {  
1317 - $v_value = 'NoName';  
1318 - }  
1319 -  
1320 - if ($p_with_code) {  
1321 - return($v_value.' ('.$this->error_code.')');  
1322 - }  
1323 - else {  
1324 - return($v_value);  
1325 - }  
1326 - }  
1327 - // --------------------------------------------------------------------------------  
1328 -  
1329 - // --------------------------------------------------------------------------------  
1330 - // Function : errorInfo()  
1331 - // Description :  
1332 - // Parameters :  
1333 - // --------------------------------------------------------------------------------  
1334 - function errorInfo($p_full=false)  
1335 - {  
1336 - if (PCLZIP_ERROR_EXTERNAL == 1) {  
1337 - return(PclErrorString());  
1338 - }  
1339 - else {  
1340 - if ($p_full) {  
1341 - return($this->errorName(true)." : ".$this->error_string);  
1342 - }  
1343 - else {  
1344 - return($this->error_string." [code ".$this->error_code."]");  
1345 - }  
1346 - }  
1347 - }  
1348 - // --------------------------------------------------------------------------------  
1349 -  
1350 -  
1351 -// --------------------------------------------------------------------------------  
1352 -// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****  
1353 -// ***** *****  
1354 -// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****  
1355 -// --------------------------------------------------------------------------------  
1356 -  
1357 -  
1358 -  
1359 - // --------------------------------------------------------------------------------  
1360 - // Function : privCheckFormat()  
1361 - // Description :  
1362 - // This method check that the archive exists and is a valid zip archive.  
1363 - // Several level of check exists. (futur)  
1364 - // Parameters :  
1365 - // $p_level : Level of check. Default 0.  
1366 - // 0 : Check the first bytes (magic codes) (default value))  
1367 - // 1 : 0 + Check the central directory (futur)  
1368 - // 2 : 1 + Check each file header (futur)  
1369 - // Return Values :  
1370 - // true on success,  
1371 - // false on error, the error code is set.  
1372 - // --------------------------------------------------------------------------------  
1373 - function privCheckFormat($p_level=0)  
1374 - {  
1375 - $v_result = true;  
1376 -  
1377 - // ----- Reset the file system cache  
1378 - clearstatcache();  
1379 -  
1380 - // ----- Reset the error handler  
1381 - $this->privErrorReset();  
1382 -  
1383 - // ----- Look if the file exits  
1384 - if (!is_file($this->zipname)) {  
1385 - // ----- Error log  
1386 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");  
1387 - return(false);  
1388 - }  
1389 -  
1390 - // ----- Check that the file is readeable  
1391 - if (!is_readable($this->zipname)) {  
1392 - // ----- Error log  
1393 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");  
1394 - return(false);  
1395 - }  
1396 -  
1397 - // ----- Check the magic code  
1398 - // TBC  
1399 -  
1400 - // ----- Check the central header  
1401 - // TBC  
1402 -  
1403 - // ----- Check each file header  
1404 - // TBC  
1405 -  
1406 - // ----- Return  
1407 - return $v_result;  
1408 - }  
1409 - // --------------------------------------------------------------------------------  
1410 -  
1411 - // --------------------------------------------------------------------------------  
1412 - // Function : privParseOptions()  
1413 - // Description :  
1414 - // This internal methods reads the variable list of arguments ($p_options_list,  
1415 - // $p_size) and generate an array with the options and values ($v_result_list).  
1416 - // $v_requested_options contains the options that can be present and those that  
1417 - // must be present.  
1418 - // $v_requested_options is an array, with the option value as key, and 'optional',  
1419 - // or 'mandatory' as value.  
1420 - // Parameters :  
1421 - // See above.  
1422 - // Return Values :  
1423 - // 1 on success.  
1424 - // 0 on failure.  
1425 - // --------------------------------------------------------------------------------  
1426 - function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)  
1427 - {  
1428 - $v_result=1;  
1429 -  
1430 - // ----- Read the options  
1431 - $i=0;  
1432 - while ($i<$p_size) {  
1433 -  
1434 - // ----- Check if the option is supported  
1435 - if (!isset($v_requested_options[$p_options_list[$i]])) {  
1436 - // ----- Error log  
1437 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");  
1438 -  
1439 - // ----- Return  
1440 - return PclZip::errorCode();  
1441 - }  
1442 -  
1443 - // ----- Look for next option  
1444 - switch ($p_options_list[$i]) {  
1445 - // ----- Look for options that request a path value  
1446 - case PCLZIP_OPT_PATH :  
1447 - case PCLZIP_OPT_REMOVE_PATH :  
1448 - case PCLZIP_OPT_ADD_PATH :  
1449 - // ----- Check the number of parameters  
1450 - if (($i+1) >= $p_size) {  
1451 - // ----- Error log  
1452 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1453 -  
1454 - // ----- Return  
1455 - return PclZip::errorCode();  
1456 - }  
1457 -  
1458 - // ----- Get the value  
1459 - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);  
1460 - $i++;  
1461 - break;  
1462 -  
1463 - case PCLZIP_OPT_TEMP_FILE_THRESHOLD :  
1464 - // ----- Check the number of parameters  
1465 - if (($i+1) >= $p_size) {  
1466 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1467 - return PclZip::errorCode();  
1468 - }  
1469 -  
1470 - // ----- Check for incompatible options  
1471 - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {  
1472 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");  
1473 - return PclZip::errorCode();  
1474 - }  
1475 -  
1476 - // ----- Check the value  
1477 - $v_value = $p_options_list[$i+1];  
1478 - if ((!is_integer($v_value)) || ($v_value<0)) {  
1479 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1480 - return PclZip::errorCode();  
1481 - }  
1482 -  
1483 - // ----- Get the value (and convert it in bytes)  
1484 - $v_result_list[$p_options_list[$i]] = $v_value*1048576;  
1485 - $i++;  
1486 - break;  
1487 -  
1488 - case PCLZIP_OPT_TEMP_FILE_ON :  
1489 - // ----- Check for incompatible options  
1490 - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {  
1491 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");  
1492 - return PclZip::errorCode();  
1493 - }  
1494 -  
1495 - $v_result_list[$p_options_list[$i]] = true;  
1496 - break;  
1497 -  
1498 - case PCLZIP_OPT_TEMP_FILE_OFF :  
1499 - // ----- Check for incompatible options  
1500 - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {  
1501 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");  
1502 - return PclZip::errorCode();  
1503 - }  
1504 - // ----- Check for incompatible options  
1505 - if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {  
1506 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");  
1507 - return PclZip::errorCode();  
1508 - }  
1509 -  
1510 - $v_result_list[$p_options_list[$i]] = true;  
1511 - break;  
1512 -  
1513 - case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :  
1514 - // ----- Check the number of parameters  
1515 - if (($i+1) >= $p_size) {  
1516 - // ----- Error log  
1517 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1518 -  
1519 - // ----- Return  
1520 - return PclZip::errorCode();  
1521 - }  
1522 -  
1523 - // ----- Get the value  
1524 - if ( is_string($p_options_list[$i+1])  
1525 - && ($p_options_list[$i+1] != '')) {  
1526 - $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);  
1527 - $i++;  
1528 - }  
1529 - else {  
1530 - }  
1531 - break;  
1532 -  
1533 - // ----- Look for options that request an array of string for value  
1534 - case PCLZIP_OPT_BY_NAME :  
1535 - // ----- Check the number of parameters  
1536 - if (($i+1) >= $p_size) {  
1537 - // ----- Error log  
1538 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1539 -  
1540 - // ----- Return  
1541 - return PclZip::errorCode();  
1542 - }  
1543 -  
1544 - // ----- Get the value  
1545 - if (is_string($p_options_list[$i+1])) {  
1546 - $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];  
1547 - }  
1548 - else if (is_array($p_options_list[$i+1])) {  
1549 - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];  
1550 - }  
1551 - else {  
1552 - // ----- Error log  
1553 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1554 -  
1555 - // ----- Return  
1556 - return PclZip::errorCode();  
1557 - }  
1558 - $i++;  
1559 - break;  
1560 -  
1561 - // ----- Look for options that request an EREG or PREG expression  
1562 - case PCLZIP_OPT_BY_EREG :  
1563 - // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG  
1564 - // to PCLZIP_OPT_BY_PREG  
1565 - $p_options_list[$i] = PCLZIP_OPT_BY_PREG;  
1566 - case PCLZIP_OPT_BY_PREG :  
1567 - //case PCLZIP_OPT_CRYPT :  
1568 - // ----- Check the number of parameters  
1569 - if (($i+1) >= $p_size) {  
1570 - // ----- Error log  
1571 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1572 -  
1573 - // ----- Return  
1574 - return PclZip::errorCode();  
1575 - }  
1576 -  
1577 - // ----- Get the value  
1578 - if (is_string($p_options_list[$i+1])) {  
1579 - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];  
1580 - }  
1581 - else {  
1582 - // ----- Error log  
1583 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1584 -  
1585 - // ----- Return  
1586 - return PclZip::errorCode();  
1587 - }  
1588 - $i++;  
1589 - break;  
1590 -  
1591 - // ----- Look for options that takes a string  
1592 - case PCLZIP_OPT_COMMENT :  
1593 - case PCLZIP_OPT_ADD_COMMENT :  
1594 - case PCLZIP_OPT_PREPEND_COMMENT :  
1595 - // ----- Check the number of parameters  
1596 - if (($i+1) >= $p_size) {  
1597 - // ----- Error log  
1598 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,  
1599 - "Missing parameter value for option '"  
1600 - .PclZipUtilOptionText($p_options_list[$i])  
1601 - ."'");  
1602 -  
1603 - // ----- Return  
1604 - return PclZip::errorCode();  
1605 - }  
1606 -  
1607 - // ----- Get the value  
1608 - if (is_string($p_options_list[$i+1])) {  
1609 - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];  
1610 - }  
1611 - else {  
1612 - // ----- Error log  
1613 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,  
1614 - "Wrong parameter value for option '"  
1615 - .PclZipUtilOptionText($p_options_list[$i])  
1616 - ."'");  
1617 -  
1618 - // ----- Return  
1619 - return PclZip::errorCode();  
1620 - }  
1621 - $i++;  
1622 - break;  
1623 -  
1624 - // ----- Look for options that request an array of index  
1625 - case PCLZIP_OPT_BY_INDEX :  
1626 - // ----- Check the number of parameters  
1627 - if (($i+1) >= $p_size) {  
1628 - // ----- Error log  
1629 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1630 -  
1631 - // ----- Return  
1632 - return PclZip::errorCode();  
1633 - }  
1634 -  
1635 - // ----- Get the value  
1636 - $v_work_list = array();  
1637 - if (is_string($p_options_list[$i+1])) {  
1638 -  
1639 - // ----- Remove spaces  
1640 - $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');  
1641 -  
1642 - // ----- Parse items  
1643 - $v_work_list = explode(",", $p_options_list[$i+1]);  
1644 - }  
1645 - else if (is_integer($p_options_list[$i+1])) {  
1646 - $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];  
1647 - }  
1648 - else if (is_array($p_options_list[$i+1])) {  
1649 - $v_work_list = $p_options_list[$i+1];  
1650 - }  
1651 - else {  
1652 - // ----- Error log  
1653 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1654 -  
1655 - // ----- Return  
1656 - return PclZip::errorCode();  
1657 - }  
1658 -  
1659 - // ----- Reduce the index list  
1660 - // each index item in the list must be a couple with a start and  
1661 - // an end value : [0,3], [5-5], [8-10], ...  
1662 - // ----- Check the format of each item  
1663 - $v_sort_flag=false;  
1664 - $v_sort_value=0;  
1665 - for ($j=0; $j<sizeof($v_work_list); $j++) {  
1666 - // ----- Explode the item  
1667 - $v_item_list = explode("-", $v_work_list[$j]);  
1668 - $v_size_item_list = sizeof($v_item_list);  
1669 -  
1670 - // ----- TBC : Here we might check that each item is a  
1671 - // real integer ...  
1672 -  
1673 - // ----- Look for single value  
1674 - if ($v_size_item_list == 1) {  
1675 - // ----- Set the option value  
1676 - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];  
1677 - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];  
1678 - }  
1679 - elseif ($v_size_item_list == 2) {  
1680 - // ----- Set the option value  
1681 - $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];  
1682 - $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];  
1683 - }  
1684 - else {  
1685 - // ----- Error log  
1686 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1687 -  
1688 - // ----- Return  
1689 - return PclZip::errorCode();  
1690 - }  
1691 -  
1692 -  
1693 - // ----- Look for list sort  
1694 - if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {  
1695 - $v_sort_flag=true;  
1696 -  
1697 - // ----- TBC : An automatic sort should be writen ...  
1698 - // ----- Error log  
1699 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1700 -  
1701 - // ----- Return  
1702 - return PclZip::errorCode();  
1703 - }  
1704 - $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];  
1705 - }  
1706 -  
1707 - // ----- Sort the items  
1708 - if ($v_sort_flag) {  
1709 - // TBC : To Be Completed  
1710 - }  
1711 -  
1712 - // ----- Next option  
1713 - $i++;  
1714 - break;  
1715 -  
1716 - // ----- Look for options that request no value  
1717 - case PCLZIP_OPT_REMOVE_ALL_PATH :  
1718 - case PCLZIP_OPT_EXTRACT_AS_STRING :  
1719 - case PCLZIP_OPT_NO_COMPRESSION :  
1720 - case PCLZIP_OPT_EXTRACT_IN_OUTPUT :  
1721 - case PCLZIP_OPT_REPLACE_NEWER :  
1722 - case PCLZIP_OPT_STOP_ON_ERROR :  
1723 - $v_result_list[$p_options_list[$i]] = true;  
1724 - break;  
1725 -  
1726 - // ----- Look for options that request an octal value  
1727 - case PCLZIP_OPT_SET_CHMOD :  
1728 - // ----- Check the number of parameters  
1729 - if (($i+1) >= $p_size) {  
1730 - // ----- Error log  
1731 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1732 -  
1733 - // ----- Return  
1734 - return PclZip::errorCode();  
1735 - }  
1736 -  
1737 - // ----- Get the value  
1738 - $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];  
1739 - $i++;  
1740 - break;  
1741 -  
1742 - // ----- Look for options that request a call-back  
1743 - case PCLZIP_CB_PRE_EXTRACT :  
1744 - case PCLZIP_CB_POST_EXTRACT :  
1745 - case PCLZIP_CB_PRE_ADD :  
1746 - case PCLZIP_CB_POST_ADD :  
1747 - /* for futur use  
1748 - case PCLZIP_CB_PRE_DELETE :  
1749 - case PCLZIP_CB_POST_DELETE :  
1750 - case PCLZIP_CB_PRE_LIST :  
1751 - case PCLZIP_CB_POST_LIST :  
1752 - */  
1753 - // ----- Check the number of parameters  
1754 - if (($i+1) >= $p_size) {  
1755 - // ----- Error log  
1756 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1757 -  
1758 - // ----- Return  
1759 - return PclZip::errorCode();  
1760 - }  
1761 -  
1762 - // ----- Get the value  
1763 - $v_function_name = $p_options_list[$i+1];  
1764 -  
1765 - // ----- Check that the value is a valid existing function  
1766 - if (!function_exists($v_function_name)) {  
1767 - // ----- Error log  
1768 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");  
1769 -  
1770 - // ----- Return  
1771 - return PclZip::errorCode();  
1772 - }  
1773 -  
1774 - // ----- Set the attribute  
1775 - $v_result_list[$p_options_list[$i]] = $v_function_name;  
1776 - $i++;  
1777 - break;  
1778 -  
1779 - default :  
1780 - // ----- Error log  
1781 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
1782 - "Unknown parameter '"  
1783 - .$p_options_list[$i]."'");  
1784 -  
1785 - // ----- Return  
1786 - return PclZip::errorCode();  
1787 - }  
1788 -  
1789 - // ----- Next options  
1790 - $i++;  
1791 - }  
1792 -  
1793 - // ----- Look for mandatory options  
1794 - if ($v_requested_options !== false) {  
1795 - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {  
1796 - // ----- Look for mandatory option  
1797 - if ($v_requested_options[$key] == 'mandatory') {  
1798 - // ----- Look if present  
1799 - if (!isset($v_result_list[$key])) {  
1800 - // ----- Error log  
1801 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");  
1802 -  
1803 - // ----- Return  
1804 - return PclZip::errorCode();  
1805 - }  
1806 - }  
1807 - }  
1808 - }  
1809 -  
1810 - // ----- Look for default values  
1811 - if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {  
1812 -  
1813 - }  
1814 -  
1815 - // ----- Return  
1816 - return $v_result;  
1817 - }  
1818 - // --------------------------------------------------------------------------------  
1819 -  
1820 - // --------------------------------------------------------------------------------  
1821 - // Function : privOptionDefaultThreshold()  
1822 - // Description :  
1823 - // Parameters :  
1824 - // Return Values :  
1825 - // --------------------------------------------------------------------------------  
1826 - function privOptionDefaultThreshold(&$p_options)  
1827 - {  
1828 - $v_result=1;  
1829 -  
1830 - if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])  
1831 - || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {  
1832 - return $v_result;  
1833 - }  
1834 -  
1835 - // ----- Get 'memory_limit' configuration value  
1836 - $v_memory_limit = ini_get('memory_limit');  
1837 - $v_memory_limit = trim($v_memory_limit);  
1838 - $last = strtolower(substr($v_memory_limit, -1));  
1839 -  
1840 - if($last == 'g')  
1841 - //$v_memory_limit = $v_memory_limit*1024*1024*1024;  
1842 - $v_memory_limit = $v_memory_limit*1073741824;  
1843 - if($last == 'm')  
1844 - //$v_memory_limit = $v_memory_limit*1024*1024;  
1845 - $v_memory_limit = $v_memory_limit*1048576;  
1846 - if($last == 'k')  
1847 - $v_memory_limit = $v_memory_limit*1024;  
1848 -  
1849 - $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);  
1850 -  
1851 -  
1852 - // ----- Sanity check : No threshold if value lower than 1M  
1853 - if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {  
1854 - unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);  
1855 - }  
1856 -  
1857 - // ----- Return  
1858 - return $v_result;  
1859 - }  
1860 - // --------------------------------------------------------------------------------  
1861 -  
1862 - // --------------------------------------------------------------------------------  
1863 - // Function : privFileDescrParseAtt()  
1864 - // Description :  
1865 - // Parameters :  
1866 - // Return Values :  
1867 - // 1 on success.  
1868 - // 0 on failure.  
1869 - // --------------------------------------------------------------------------------  
1870 - function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)  
1871 - {  
1872 - $v_result=1;  
1873 -  
1874 - // ----- For each file in the list check the attributes  
1875 - foreach ($p_file_list as $v_key => $v_value) {  
1876 -  
1877 - // ----- Check if the option is supported  
1878 - if (!isset($v_requested_options[$v_key])) {  
1879 - // ----- Error log  
1880 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");  
1881 -  
1882 - // ----- Return  
1883 - return PclZip::errorCode();  
1884 - }  
1885 -  
1886 - // ----- Look for attribute  
1887 - switch ($v_key) {  
1888 - case PCLZIP_ATT_FILE_NAME :  
1889 - if (!is_string($v_value)) {  
1890 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");  
1891 - return PclZip::errorCode();  
1892 - }  
1893 -  
1894 - $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);  
1895 -  
1896 - if ($p_filedescr['filename'] == '') {  
1897 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");  
1898 - return PclZip::errorCode();  
1899 - }  
1900 -  
1901 - break;  
1902 -  
1903 - case PCLZIP_ATT_FILE_NEW_SHORT_NAME :  
1904 - if (!is_string($v_value)) {  
1905 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");  
1906 - return PclZip::errorCode();  
1907 - }  
1908 -  
1909 - $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);  
1910 -  
1911 - if ($p_filedescr['new_short_name'] == '') {  
1912 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");  
1913 - return PclZip::errorCode();  
1914 - }  
1915 - break;  
1916 -  
1917 - case PCLZIP_ATT_FILE_NEW_FULL_NAME :  
1918 - if (!is_string($v_value)) {  
1919 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");  
1920 - return PclZip::errorCode();  
1921 - }  
1922 -  
1923 - $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);  
1924 -  
1925 - if ($p_filedescr['new_full_name'] == '') {  
1926 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");  
1927 - return PclZip::errorCode();  
1928 - }  
1929 - break;  
1930 -  
1931 - // ----- Look for options that takes a string  
1932 - case PCLZIP_ATT_FILE_COMMENT :  
1933 - if (!is_string($v_value)) {  
1934 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");  
1935 - return PclZip::errorCode();  
1936 - }  
1937 -  
1938 - $p_filedescr['comment'] = $v_value;  
1939 - break;  
1940 -  
1941 - case PCLZIP_ATT_FILE_MTIME :  
1942 - if (!is_integer($v_value)) {  
1943 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");  
1944 - return PclZip::errorCode();  
1945 - }  
1946 -  
1947 - $p_filedescr['mtime'] = $v_value;  
1948 - break;  
1949 -  
1950 - case PCLZIP_ATT_FILE_CONTENT :  
1951 - $p_filedescr['content'] = $v_value;  
1952 - break;  
1953 -  
1954 - default :  
1955 - // ----- Error log  
1956 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,  
1957 - "Unknown parameter '".$v_key."'");  
1958 -  
1959 - // ----- Return  
1960 - return PclZip::errorCode();  
1961 - }  
1962 -  
1963 - // ----- Look for mandatory options  
1964 - if ($v_requested_options !== false) {  
1965 - for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {  
1966 - // ----- Look for mandatory option  
1967 - if ($v_requested_options[$key] == 'mandatory') {  
1968 - // ----- Look if present  
1969 - if (!isset($p_file_list[$key])) {  
1970 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");  
1971 - return PclZip::errorCode();  
1972 - }  
1973 - }  
1974 - }  
1975 - }  
1976 -  
1977 - // end foreach  
1978 - }  
1979 -  
1980 - // ----- Return  
1981 - return $v_result;  
1982 - }  
1983 - // --------------------------------------------------------------------------------  
1984 -  
1985 - // --------------------------------------------------------------------------------  
1986 - // Function : privFileDescrExpand()  
1987 - // Description :  
1988 - // This method look for each item of the list to see if its a file, a folder  
1989 - // or a string to be added as file. For any other type of files (link, other)  
1990 - // just ignore the item.  
1991 - // Then prepare the information that will be stored for that file.  
1992 - // When its a folder, expand the folder with all the files that are in that  
1993 - // folder (recursively).  
1994 - // Parameters :  
1995 - // Return Values :  
1996 - // 1 on success.  
1997 - // 0 on failure.  
1998 - // --------------------------------------------------------------------------------  
1999 - function privFileDescrExpand(&$p_filedescr_list, &$p_options)  
2000 - {  
2001 - $v_result=1;  
2002 -  
2003 - // ----- Create a result list  
2004 - $v_result_list = array();  
2005 -  
2006 - // ----- Look each entry  
2007 - for ($i=0; $i<sizeof($p_filedescr_list); $i++) {  
2008 -  
2009 - // ----- Get filedescr  
2010 - $v_descr = $p_filedescr_list[$i];  
2011 -  
2012 - // ----- Reduce the filename  
2013 - $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);  
2014 - $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);  
2015 -  
2016 - // ----- Look for real file or folder  
2017 - if (file_exists($v_descr['filename'])) {  
2018 - if (@is_file($v_descr['filename'])) {  
2019 - $v_descr['type'] = 'file';  
2020 - }  
2021 - else if (@is_dir($v_descr['filename'])) {  
2022 - $v_descr['type'] = 'folder';  
2023 - }  
2024 - else if (@is_link($v_descr['filename'])) {  
2025 - // skip  
2026 - continue;  
2027 - }  
2028 - else {  
2029 - // skip  
2030 - continue;  
2031 - }  
2032 - }  
2033 -  
2034 - // ----- Look for string added as file  
2035 - else if (isset($v_descr['content'])) {  
2036 - $v_descr['type'] = 'virtual_file';  
2037 - }  
2038 -  
2039 - // ----- Missing file  
2040 - else {  
2041 - // ----- Error log  
2042 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");  
2043 -  
2044 - // ----- Return  
2045 - return PclZip::errorCode();  
2046 - }  
2047 -  
2048 - // ----- Calculate the stored filename  
2049 - $this->privCalculateStoredFilename($v_descr, $p_options);  
2050 -  
2051 - // ----- Add the descriptor in result list  
2052 - $v_result_list[sizeof($v_result_list)] = $v_descr;  
2053 -  
2054 - // ----- Look for folder  
2055 - if ($v_descr['type'] == 'folder') {  
2056 - // ----- List of items in folder  
2057 - $v_dirlist_descr = array();  
2058 - $v_dirlist_nb = 0;  
2059 - if ($v_folder_handler = @opendir($v_descr['filename'])) {  
2060 - while (($v_item_handler = @readdir($v_folder_handler)) !== false) {  
2061 -  
2062 - // ----- Skip '.' and '..'  
2063 - if (($v_item_handler == '.') || ($v_item_handler == '..')) {  
2064 - continue;  
2065 - }  
2066 -  
2067 - // ----- Compose the full filename  
2068 - $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;  
2069 -  
2070 - // ----- Look for different stored filename  
2071 - // Because the name of the folder was changed, the name of the  
2072 - // files/sub-folders also change  
2073 - if (($v_descr['stored_filename'] != $v_descr['filename'])  
2074 - && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {  
2075 - if ($v_descr['stored_filename'] != '') {  
2076 - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;  
2077 - }  
2078 - else {  
2079 - $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;  
2080 - }  
2081 - }  
2082 -  
2083 - $v_dirlist_nb++;  
2084 - }  
2085 -  
2086 - @closedir($v_folder_handler);  
2087 - }  
2088 - else {  
2089 - // TBC : unable to open folder in read mode  
2090 - }  
2091 -  
2092 - // ----- Expand each element of the list  
2093 - if ($v_dirlist_nb != 0) {  
2094 - // ----- Expand  
2095 - if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {  
2096 - return $v_result;  
2097 - }  
2098 -  
2099 - // ----- Concat the resulting list  
2100 - $v_result_list = array_merge($v_result_list, $v_dirlist_descr);  
2101 - }  
2102 - else {  
2103 - }  
2104 -  
2105 - // ----- Free local array  
2106 - unset($v_dirlist_descr);  
2107 - }  
2108 - }  
2109 -  
2110 - // ----- Get the result list  
2111 - $p_filedescr_list = $v_result_list;  
2112 -  
2113 - // ----- Return  
2114 - return $v_result;  
2115 - }  
2116 - // --------------------------------------------------------------------------------  
2117 -  
2118 - // --------------------------------------------------------------------------------  
2119 - // Function : privCreate()  
2120 - // Description :  
2121 - // Parameters :  
2122 - // Return Values :  
2123 - // --------------------------------------------------------------------------------  
2124 - function privCreate($p_filedescr_list, &$p_result_list, &$p_options)  
2125 - {  
2126 - $v_result=1;  
2127 - $v_list_detail = array();  
2128 -  
2129 - // ----- Magic quotes trick  
2130 - $this->privDisableMagicQuotes();  
2131 -  
2132 - // ----- Open the file in write mode  
2133 - if (($v_result = $this->privOpenFd('wb')) != 1)  
2134 - {  
2135 - // ----- Return  
2136 - return $v_result;  
2137 - }  
2138 -  
2139 - // ----- Add the list of files  
2140 - $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);  
2141 -  
2142 - // ----- Close  
2143 - $this->privCloseFd();  
2144 -  
2145 - // ----- Magic quotes trick  
2146 - $this->privSwapBackMagicQuotes();  
2147 -  
2148 - // ----- Return  
2149 - return $v_result;  
2150 - }  
2151 - // --------------------------------------------------------------------------------  
2152 -  
2153 - // --------------------------------------------------------------------------------  
2154 - // Function : privAdd()  
2155 - // Description :  
2156 - // Parameters :  
2157 - // Return Values :  
2158 - // --------------------------------------------------------------------------------  
2159 - function privAdd($p_filedescr_list, &$p_result_list, &$p_options)  
2160 - {  
2161 - $v_result=1;  
2162 - $v_list_detail = array();  
2163 -  
2164 - // ----- Look if the archive exists or is empty  
2165 - if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))  
2166 - {  
2167 -  
2168 - // ----- Do a create  
2169 - $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);  
2170 -  
2171 - // ----- Return  
2172 - return $v_result;  
2173 - }  
2174 - // ----- Magic quotes trick  
2175 - $this->privDisableMagicQuotes();  
2176 -  
2177 - // ----- Open the zip file  
2178 - if (($v_result=$this->privOpenFd('rb')) != 1)  
2179 - {  
2180 - // ----- Magic quotes trick  
2181 - $this->privSwapBackMagicQuotes();  
2182 -  
2183 - // ----- Return  
2184 - return $v_result;  
2185 - }  
2186 -  
2187 - // ----- Read the central directory informations  
2188 - $v_central_dir = array();  
2189 - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)  
2190 - {  
2191 - $this->privCloseFd();  
2192 - $this->privSwapBackMagicQuotes();  
2193 - return $v_result;  
2194 - }  
2195 -  
2196 - // ----- Go to beginning of File  
2197 - @rewind($this->zip_fd);  
2198 -  
2199 - // ----- Creates a temporay file  
2200 - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';  
2201 -  
2202 - // ----- Open the temporary file in write mode  
2203 - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)  
2204 - {  
2205 - $this->privCloseFd();  
2206 - $this->privSwapBackMagicQuotes();  
2207 -  
2208 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');  
2209 -  
2210 - // ----- Return  
2211 - return PclZip::errorCode();  
2212 - }  
2213 -  
2214 - // ----- Copy the files from the archive to the temporary file  
2215 - // TBC : Here I should better append the file and go back to erase the central dir  
2216 - $v_size = $v_central_dir['offset'];  
2217 - while ($v_size != 0)  
2218 - {  
2219 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
2220 - $v_buffer = fread($this->zip_fd, $v_read_size);  
2221 - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);  
2222 - $v_size -= $v_read_size;  
2223 - }  
2224 -  
2225 - // ----- Swap the file descriptor  
2226 - // Here is a trick : I swap the temporary fd with the zip fd, in order to use  
2227 - // the following methods on the temporary fil and not the real archive  
2228 - $v_swap = $this->zip_fd;  
2229 - $this->zip_fd = $v_zip_temp_fd;  
2230 - $v_zip_temp_fd = $v_swap;  
2231 -  
2232 - // ----- Add the files  
2233 - $v_header_list = array();  
2234 - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)  
2235 - {  
2236 - fclose($v_zip_temp_fd);  
2237 - $this->privCloseFd();  
2238 - @unlink($v_zip_temp_name);  
2239 - $this->privSwapBackMagicQuotes();  
2240 -  
2241 - // ----- Return  
2242 - return $v_result;  
2243 - }  
2244 -  
2245 - // ----- Store the offset of the central dir  
2246 - $v_offset = @ftell($this->zip_fd);  
2247 -  
2248 - // ----- Copy the block of file headers from the old archive  
2249 - $v_size = $v_central_dir['size'];  
2250 - while ($v_size != 0)  
2251 - {  
2252 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
2253 - $v_buffer = @fread($v_zip_temp_fd, $v_read_size);  
2254 - @fwrite($this->zip_fd, $v_buffer, $v_read_size);  
2255 - $v_size -= $v_read_size;  
2256 - }  
2257 -  
2258 - // ----- Create the Central Dir files header  
2259 - for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)  
2260 - {  
2261 - // ----- Create the file header  
2262 - if ($v_header_list[$i]['status'] == 'ok') {  
2263 - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {  
2264 - fclose($v_zip_temp_fd);  
2265 - $this->privCloseFd();  
2266 - @unlink($v_zip_temp_name);  
2267 - $this->privSwapBackMagicQuotes();  
2268 -  
2269 - // ----- Return  
2270 - return $v_result;  
2271 - }  
2272 - $v_count++;  
2273 - }  
2274 -  
2275 - // ----- Transform the header to a 'usable' info  
2276 - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);  
2277 - }  
2278 -  
2279 - // ----- Zip file comment  
2280 - $v_comment = $v_central_dir['comment'];  
2281 - if (isset($p_options[PCLZIP_OPT_COMMENT])) {  
2282 - $v_comment = $p_options[PCLZIP_OPT_COMMENT];  
2283 - }  
2284 - if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {  
2285 - $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];  
2286 - }  
2287 - if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {  
2288 - $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;  
2289 - }  
2290 -  
2291 - // ----- Calculate the size of the central header  
2292 - $v_size = @ftell($this->zip_fd)-$v_offset;  
2293 -  
2294 - // ----- Create the central dir footer  
2295 - if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)  
2296 - {  
2297 - // ----- Reset the file list  
2298 - unset($v_header_list);  
2299 - $this->privSwapBackMagicQuotes();  
2300 -  
2301 - // ----- Return  
2302 - return $v_result;  
2303 - }  
2304 -  
2305 - // ----- Swap back the file descriptor  
2306 - $v_swap = $this->zip_fd;  
2307 - $this->zip_fd = $v_zip_temp_fd;  
2308 - $v_zip_temp_fd = $v_swap;  
2309 -  
2310 - // ----- Close  
2311 - $this->privCloseFd();  
2312 -  
2313 - // ----- Close the temporary file  
2314 - @fclose($v_zip_temp_fd);  
2315 -  
2316 - // ----- Magic quotes trick  
2317 - $this->privSwapBackMagicQuotes();  
2318 -  
2319 - // ----- Delete the zip file  
2320 - // TBC : I should test the result ...  
2321 - @unlink($this->zipname);  
2322 -  
2323 - // ----- Rename the temporary file  
2324 - // TBC : I should test the result ...  
2325 - //@rename($v_zip_temp_name, $this->zipname);  
2326 - PclZipUtilRename($v_zip_temp_name, $this->zipname);  
2327 -  
2328 - // ----- Return  
2329 - return $v_result;  
2330 - }  
2331 - // --------------------------------------------------------------------------------  
2332 -  
2333 - // --------------------------------------------------------------------------------  
2334 - // Function : privOpenFd()  
2335 - // Description :  
2336 - // Parameters :  
2337 - // --------------------------------------------------------------------------------  
2338 - function privOpenFd($p_mode)  
2339 - {  
2340 - $v_result=1;  
2341 -  
2342 - // ----- Look if already open  
2343 - if ($this->zip_fd != 0)  
2344 - {  
2345 - // ----- Error log  
2346 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');  
2347 -  
2348 - // ----- Return  
2349 - return PclZip::errorCode();  
2350 - }  
2351 -  
2352 - // ----- Open the zip file  
2353 - if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)  
2354 - {  
2355 - // ----- Error log  
2356 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');  
2357 -  
2358 - // ----- Return  
2359 - return PclZip::errorCode();  
2360 - }  
2361 -  
2362 - // ----- Return  
2363 - return $v_result;  
2364 - }  
2365 - // --------------------------------------------------------------------------------  
2366 -  
2367 - // --------------------------------------------------------------------------------  
2368 - // Function : privCloseFd()  
2369 - // Description :  
2370 - // Parameters :  
2371 - // --------------------------------------------------------------------------------  
2372 - function privCloseFd()  
2373 - {  
2374 - $v_result=1;  
2375 -  
2376 - if ($this->zip_fd != 0)  
2377 - @fclose($this->zip_fd);  
2378 - $this->zip_fd = 0;  
2379 -  
2380 - // ----- Return  
2381 - return $v_result;  
2382 - }  
2383 - // --------------------------------------------------------------------------------  
2384 -  
2385 - // --------------------------------------------------------------------------------  
2386 - // Function : privAddList()  
2387 - // Description :  
2388 - // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is  
2389 - // different from the real path of the file. This is usefull if you want to have PclTar  
2390 - // running in any directory, and memorize relative path from an other directory.  
2391 - // Parameters :  
2392 - // $p_list : An array containing the file or directory names to add in the tar  
2393 - // $p_result_list : list of added files with their properties (specially the status field)  
2394 - // $p_add_dir : Path to add in the filename path archived  
2395 - // $p_remove_dir : Path to remove in the filename path archived  
2396 - // Return Values :  
2397 - // --------------------------------------------------------------------------------  
2398 -// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)  
2399 - function privAddList($p_filedescr_list, &$p_result_list, &$p_options)  
2400 - {  
2401 - $v_result=1;  
2402 -  
2403 - // ----- Add the files  
2404 - $v_header_list = array();  
2405 - if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)  
2406 - {  
2407 - // ----- Return  
2408 - return $v_result;  
2409 - }  
2410 -  
2411 - // ----- Store the offset of the central dir  
2412 - $v_offset = @ftell($this->zip_fd);  
2413 -  
2414 - // ----- Create the Central Dir files header  
2415 - for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)  
2416 - {  
2417 - // ----- Create the file header  
2418 - if ($v_header_list[$i]['status'] == 'ok') {  
2419 - if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {  
2420 - // ----- Return  
2421 - return $v_result;  
2422 - }  
2423 - $v_count++;  
2424 - }  
2425 -  
2426 - // ----- Transform the header to a 'usable' info  
2427 - $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);  
2428 - }  
2429 -  
2430 - // ----- Zip file comment  
2431 - $v_comment = '';  
2432 - if (isset($p_options[PCLZIP_OPT_COMMENT])) {  
2433 - $v_comment = $p_options[PCLZIP_OPT_COMMENT];  
2434 - }  
2435 -  
2436 - // ----- Calculate the size of the central header  
2437 - $v_size = @ftell($this->zip_fd)-$v_offset;  
2438 -  
2439 - // ----- Create the central dir footer  
2440 - if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)  
2441 - {  
2442 - // ----- Reset the file list  
2443 - unset($v_header_list);  
2444 -  
2445 - // ----- Return  
2446 - return $v_result;  
2447 - }  
2448 -  
2449 - // ----- Return  
2450 - return $v_result;  
2451 - }  
2452 - // --------------------------------------------------------------------------------  
2453 -  
2454 - // --------------------------------------------------------------------------------  
2455 - // Function : privAddFileList()  
2456 - // Description :  
2457 - // Parameters :  
2458 - // $p_filedescr_list : An array containing the file description  
2459 - // or directory names to add in the zip  
2460 - // $p_result_list : list of added files with their properties (specially the status field)  
2461 - // Return Values :  
2462 - // --------------------------------------------------------------------------------  
2463 - function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)  
2464 - {  
2465 - $v_result=1;  
2466 - $v_header = array();  
2467 -  
2468 - // ----- Recuperate the current number of elt in list  
2469 - $v_nb = sizeof($p_result_list);  
2470 -  
2471 - // ----- Loop on the files  
2472 - for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {  
2473 - // ----- Format the filename  
2474 - $p_filedescr_list[$j]['filename']  
2475 - = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);  
2476 -  
2477 -  
2478 - // ----- Skip empty file names  
2479 - // TBC : Can this be possible ? not checked in DescrParseAtt ?  
2480 - if ($p_filedescr_list[$j]['filename'] == "") {  
2481 - continue;  
2482 - }  
2483 -  
2484 - // ----- Check the filename  
2485 - if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')  
2486 - && (!file_exists($p_filedescr_list[$j]['filename']))) {  
2487 - PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");  
2488 - return PclZip::errorCode();  
2489 - }  
2490 -  
2491 - // ----- Look if it is a file or a dir with no all path remove option  
2492 - // or a dir with all its path removed  
2493 -// if ( (is_file($p_filedescr_list[$j]['filename']))  
2494 -// || ( is_dir($p_filedescr_list[$j]['filename'])  
2495 - if ( ($p_filedescr_list[$j]['type'] == 'file')  
2496 - || ($p_filedescr_list[$j]['type'] == 'virtual_file')  
2497 - || ( ($p_filedescr_list[$j]['type'] == 'folder')  
2498 - && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])  
2499 - || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))  
2500 - ) {  
2501 -  
2502 - // ----- Add the file  
2503 - $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,  
2504 - $p_options);  
2505 - if ($v_result != 1) {  
2506 - return $v_result;  
2507 - }  
2508 -  
2509 - // ----- Store the file infos  
2510 - $p_result_list[$v_nb++] = $v_header;  
2511 - }  
2512 - }  
2513 -  
2514 - // ----- Return  
2515 - return $v_result;  
2516 - }  
2517 - // --------------------------------------------------------------------------------  
2518 -  
2519 - // --------------------------------------------------------------------------------  
2520 - // Function : privAddFile()  
2521 - // Description :  
2522 - // Parameters :  
2523 - // Return Values :  
2524 - // --------------------------------------------------------------------------------  
2525 - function privAddFile($p_filedescr, &$p_header, &$p_options)  
2526 - {  
2527 - $v_result=1;  
2528 -  
2529 - // ----- Working variable  
2530 - $p_filename = $p_filedescr['filename'];  
2531 -  
2532 - // TBC : Already done in the fileAtt check ... ?  
2533 - if ($p_filename == "") {  
2534 - // ----- Error log  
2535 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");  
2536 -  
2537 - // ----- Return  
2538 - return PclZip::errorCode();  
2539 - }  
2540 -  
2541 - // ----- Look for a stored different filename  
2542 - /* TBC : Removed  
2543 - if (isset($p_filedescr['stored_filename'])) {  
2544 - $v_stored_filename = $p_filedescr['stored_filename'];  
2545 - }  
2546 - else {  
2547 - $v_stored_filename = $p_filedescr['stored_filename'];  
2548 - }  
2549 - */  
2550 -  
2551 - // ----- Set the file properties  
2552 - clearstatcache();  
2553 - $p_header['version'] = 20;  
2554 - $p_header['version_extracted'] = 10;  
2555 - $p_header['flag'] = 0;  
2556 - $p_header['compression'] = 0;  
2557 - $p_header['crc'] = 0;  
2558 - $p_header['compressed_size'] = 0;  
2559 - $p_header['filename_len'] = strlen($p_filename);  
2560 - $p_header['extra_len'] = 0;  
2561 - $p_header['disk'] = 0;  
2562 - $p_header['internal'] = 0;  
2563 - $p_header['offset'] = 0;  
2564 - $p_header['filename'] = $p_filename;  
2565 -// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;  
2566 - $p_header['stored_filename'] = $p_filedescr['stored_filename'];  
2567 - $p_header['extra'] = '';  
2568 - $p_header['status'] = 'ok';  
2569 - $p_header['index'] = -1;  
2570 -  
2571 - // ----- Look for regular file  
2572 - if ($p_filedescr['type']=='file') {  
2573 - $p_header['external'] = 0x00000000;  
2574 - $p_header['size'] = filesize($p_filename);  
2575 - }  
2576 -  
2577 - // ----- Look for regular folder  
2578 - else if ($p_filedescr['type']=='folder') {  
2579 - $p_header['external'] = 0x00000010;  
2580 - $p_header['mtime'] = filemtime($p_filename);  
2581 - $p_header['size'] = filesize($p_filename);  
2582 - }  
2583 -  
2584 - // ----- Look for virtual file  
2585 - else if ($p_filedescr['type'] == 'virtual_file') {  
2586 - $p_header['external'] = 0x00000000;  
2587 - $p_header['size'] = strlen($p_filedescr['content']);  
2588 - }  
2589 -  
2590 -  
2591 - // ----- Look for filetime  
2592 - if (isset($p_filedescr['mtime'])) {  
2593 - $p_header['mtime'] = $p_filedescr['mtime'];  
2594 - }  
2595 - else if ($p_filedescr['type'] == 'virtual_file') {  
2596 - $p_header['mtime'] = time();  
2597 - }  
2598 - else {  
2599 - $p_header['mtime'] = filemtime($p_filename);  
2600 - }  
2601 -  
2602 - // ------ Look for file comment  
2603 - if (isset($p_filedescr['comment'])) {  
2604 - $p_header['comment_len'] = strlen($p_filedescr['comment']);  
2605 - $p_header['comment'] = $p_filedescr['comment'];  
2606 - }  
2607 - else {  
2608 - $p_header['comment_len'] = 0;  
2609 - $p_header['comment'] = '';  
2610 - }  
2611 -  
2612 - // ----- Look for pre-add callback  
2613 - if (isset($p_options[PCLZIP_CB_PRE_ADD])) {  
2614 -  
2615 - // ----- Generate a local information  
2616 - $v_local_header = array();  
2617 - $this->privConvertHeader2FileInfo($p_header, $v_local_header);  
2618 -  
2619 - // ----- Call the callback  
2620 - // Here I do not use call_user_func() because I need to send a reference to the  
2621 - // header.  
2622 -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');  
2623 - $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);  
2624 - if ($v_result == 0) {  
2625 - // ----- Change the file status  
2626 - $p_header['status'] = "skipped";  
2627 - $v_result = 1;  
2628 - }  
2629 -  
2630 - // ----- Update the informations  
2631 - // Only some fields can be modified  
2632 - if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {  
2633 - $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);  
2634 - }  
2635 - }  
2636 -  
2637 - // ----- Look for empty stored filename  
2638 - if ($p_header['stored_filename'] == "") {  
2639 - $p_header['status'] = "filtered";  
2640 - }  
2641 -  
2642 - // ----- Check the path length  
2643 - if (strlen($p_header['stored_filename']) > 0xFF) {  
2644 - $p_header['status'] = 'filename_too_long';  
2645 - }  
2646 -  
2647 - // ----- Look if no error, or file not skipped  
2648 - if ($p_header['status'] == 'ok') {  
2649 -  
2650 - // ----- Look for a file  
2651 - if ($p_filedescr['type'] == 'file') {  
2652 - // ----- Look for using temporary file to zip  
2653 - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))  
2654 - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])  
2655 - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])  
2656 - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {  
2657 - $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);  
2658 - if ($v_result < PCLZIP_ERR_NO_ERROR) {  
2659 - return $v_result;  
2660 - }  
2661 - }  
2662 -  
2663 - // ----- Use "in memory" zip algo  
2664 - else {  
2665 -  
2666 - // ----- Open the source file  
2667 - if (($v_file = @fopen($p_filename, "rb")) == 0) {  
2668 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");  
2669 - return PclZip::errorCode();  
2670 - }  
2671 -  
2672 - // ----- Read the file content  
2673 - $v_content = @fread($v_file, $p_header['size']);  
2674 -  
2675 - // ----- Close the file  
2676 - @fclose($v_file);  
2677 -  
2678 - // ----- Calculate the CRC  
2679 - $p_header['crc'] = @crc32($v_content);  
2680 -  
2681 - // ----- Look for no compression  
2682 - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {  
2683 - // ----- Set header parameters  
2684 - $p_header['compressed_size'] = $p_header['size'];  
2685 - $p_header['compression'] = 0;  
2686 - }  
2687 -  
2688 - // ----- Look for normal compression  
2689 - else {  
2690 - // ----- Compress the content  
2691 - $v_content = @gzdeflate($v_content);  
2692 -  
2693 - // ----- Set header parameters  
2694 - $p_header['compressed_size'] = strlen($v_content);  
2695 - $p_header['compression'] = 8;  
2696 - }  
2697 -  
2698 - // ----- Call the header generation  
2699 - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {  
2700 - @fclose($v_file);  
2701 - return $v_result;  
2702 - }  
2703 -  
2704 - // ----- Write the compressed (or not) content  
2705 - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);  
2706 -  
2707 - }  
2708 -  
2709 - }  
2710 -  
2711 - // ----- Look for a virtual file (a file from string)  
2712 - else if ($p_filedescr['type'] == 'virtual_file') {  
2713 -  
2714 - $v_content = $p_filedescr['content'];  
2715 -  
2716 - // ----- Calculate the CRC  
2717 - $p_header['crc'] = @crc32($v_content);  
2718 -  
2719 - // ----- Look for no compression  
2720 - if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {  
2721 - // ----- Set header parameters  
2722 - $p_header['compressed_size'] = $p_header['size'];  
2723 - $p_header['compression'] = 0;  
2724 - }  
2725 -  
2726 - // ----- Look for normal compression  
2727 - else {  
2728 - // ----- Compress the content  
2729 - $v_content = @gzdeflate($v_content);  
2730 -  
2731 - // ----- Set header parameters  
2732 - $p_header['compressed_size'] = strlen($v_content);  
2733 - $p_header['compression'] = 8;  
2734 - }  
2735 -  
2736 - // ----- Call the header generation  
2737 - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {  
2738 - @fclose($v_file);  
2739 - return $v_result;  
2740 - }  
2741 -  
2742 - // ----- Write the compressed (or not) content  
2743 - @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);  
2744 - }  
2745 -  
2746 - // ----- Look for a directory  
2747 - else if ($p_filedescr['type'] == 'folder') {  
2748 - // ----- Look for directory last '/'  
2749 - if (@substr($p_header['stored_filename'], -1) != '/') {  
2750 - $p_header['stored_filename'] .= '/';  
2751 - }  
2752 -  
2753 - // ----- Set the file properties  
2754 - $p_header['size'] = 0;  
2755 - //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked  
2756 - $p_header['external'] = 0x00000010; // Value for a folder : to be checked  
2757 -  
2758 - // ----- Call the header generation  
2759 - if (($v_result = $this->privWriteFileHeader($p_header)) != 1)  
2760 - {  
2761 - return $v_result;  
2762 - }  
2763 - }  
2764 - }  
2765 -  
2766 - // ----- Look for post-add callback  
2767 - if (isset($p_options[PCLZIP_CB_POST_ADD])) {  
2768 -  
2769 - // ----- Generate a local information  
2770 - $v_local_header = array();  
2771 - $this->privConvertHeader2FileInfo($p_header, $v_local_header);  
2772 -  
2773 - // ----- Call the callback  
2774 - // Here I do not use call_user_func() because I need to send a reference to the  
2775 - // header.  
2776 -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');  
2777 - $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);  
2778 - if ($v_result == 0) {  
2779 - // ----- Ignored  
2780 - $v_result = 1;  
2781 - }  
2782 -  
2783 - // ----- Update the informations  
2784 - // Nothing can be modified  
2785 - }  
2786 -  
2787 - // ----- Return  
2788 - return $v_result;  
2789 - }  
2790 - // --------------------------------------------------------------------------------  
2791 -  
2792 - // --------------------------------------------------------------------------------  
2793 - // Function : privAddFileUsingTempFile()  
2794 - // Description :  
2795 - // Parameters :  
2796 - // Return Values :  
2797 - // --------------------------------------------------------------------------------  
2798 - function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)  
2799 - {  
2800 - $v_result=PCLZIP_ERR_NO_ERROR;  
2801 -  
2802 - // ----- Working variable  
2803 - $p_filename = $p_filedescr['filename'];  
2804 -  
2805 -  
2806 - // ----- Open the source file  
2807 - if (($v_file = @fopen($p_filename, "rb")) == 0) {  
2808 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");  
2809 - return PclZip::errorCode();  
2810 - }  
2811 -  
2812 - // ----- Creates a compressed temporary file  
2813 - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';  
2814 - if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {  
2815 - fclose($v_file);  
2816 - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');  
2817 - return PclZip::errorCode();  
2818 - }  
2819 -  
2820 - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks  
2821 - $v_size = filesize($p_filename);  
2822 - while ($v_size != 0) {  
2823 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
2824 - $v_buffer = @fread($v_file, $v_read_size);  
2825 - //$v_binary_data = pack('a'.$v_read_size, $v_buffer);  
2826 - @gzputs($v_file_compressed, $v_buffer, $v_read_size);  
2827 - $v_size -= $v_read_size;  
2828 - }  
2829 -  
2830 - // ----- Close the file  
2831 - @fclose($v_file);  
2832 - @gzclose($v_file_compressed);  
2833 -  
2834 - // ----- Check the minimum file size  
2835 - if (filesize($v_gzip_temp_name) < 18) {  
2836 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');  
2837 - return PclZip::errorCode();  
2838 - }  
2839 -  
2840 - // ----- Extract the compressed attributes  
2841 - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {  
2842 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');  
2843 - return PclZip::errorCode();  
2844 - }  
2845 -  
2846 - // ----- Read the gzip file header  
2847 - $v_binary_data = @fread($v_file_compressed, 10);  
2848 - $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);  
2849 -  
2850 - // ----- Check some parameters  
2851 - $v_data_header['os'] = bin2hex($v_data_header['os']);  
2852 -  
2853 - // ----- Read the gzip file footer  
2854 - @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);  
2855 - $v_binary_data = @fread($v_file_compressed, 8);  
2856 - $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);  
2857 -  
2858 - // ----- Set the attributes  
2859 - $p_header['compression'] = ord($v_data_header['cm']);  
2860 - //$p_header['mtime'] = $v_data_header['mtime'];  
2861 - $p_header['crc'] = $v_data_footer['crc'];  
2862 - $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;  
2863 -  
2864 - // ----- Close the file  
2865 - @fclose($v_file_compressed);  
2866 -  
2867 - // ----- Call the header generation  
2868 - if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {  
2869 - return $v_result;  
2870 - }  
2871 -  
2872 - // ----- Add the compressed data  
2873 - if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)  
2874 - {  
2875 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');  
2876 - return PclZip::errorCode();  
2877 - }  
2878 -  
2879 - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks  
2880 - fseek($v_file_compressed, 10);  
2881 - $v_size = $p_header['compressed_size'];  
2882 - while ($v_size != 0)  
2883 - {  
2884 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
2885 - $v_buffer = @fread($v_file_compressed, $v_read_size);  
2886 - //$v_binary_data = pack('a'.$v_read_size, $v_buffer);  
2887 - @fwrite($this->zip_fd, $v_buffer, $v_read_size);  
2888 - $v_size -= $v_read_size;  
2889 - }  
2890 -  
2891 - // ----- Close the file  
2892 - @fclose($v_file_compressed);  
2893 -  
2894 - // ----- Unlink the temporary file  
2895 - @unlink($v_gzip_temp_name);  
2896 -  
2897 - // ----- Return  
2898 - return $v_result;  
2899 - }  
2900 - // --------------------------------------------------------------------------------  
2901 -  
2902 - // --------------------------------------------------------------------------------  
2903 - // Function : privCalculateStoredFilename()  
2904 - // Description :  
2905 - // Based on file descriptor properties and global options, this method  
2906 - // calculate the filename that will be stored in the archive.  
2907 - // Parameters :  
2908 - // Return Values :  
2909 - // --------------------------------------------------------------------------------  
2910 - function privCalculateStoredFilename(&$p_filedescr, &$p_options)  
2911 - {  
2912 - $v_result=1;  
2913 -  
2914 - // ----- Working variables  
2915 - $p_filename = $p_filedescr['filename'];  
2916 - if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {  
2917 - $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];  
2918 - }  
2919 - else {  
2920 - $p_add_dir = '';  
2921 - }  
2922 - if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {  
2923 - $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];  
2924 - }  
2925 - else {  
2926 - $p_remove_dir = '';  
2927 - }  
2928 - if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {  
2929 - $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];  
2930 - }  
2931 - else {  
2932 - $p_remove_all_dir = 0;  
2933 - }  
2934 -  
2935 -  
2936 - // ----- Look for full name change  
2937 - if (isset($p_filedescr['new_full_name'])) {  
2938 - // ----- Remove drive letter if any  
2939 - $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);  
2940 - }  
2941 -  
2942 - // ----- Look for path and/or short name change  
2943 - else {  
2944 -  
2945 - // ----- Look for short name change  
2946 - // Its when we cahnge just the filename but not the path  
2947 - if (isset($p_filedescr['new_short_name'])) {  
2948 - $v_path_info = pathinfo($p_filename);  
2949 - $v_dir = '';  
2950 - if ($v_path_info['dirname'] != '') {  
2951 - $v_dir = $v_path_info['dirname'].'/';  
2952 - }  
2953 - $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];  
2954 - }  
2955 - else {  
2956 - // ----- Calculate the stored filename  
2957 - $v_stored_filename = $p_filename;  
2958 - }  
2959 -  
2960 - // ----- Look for all path to remove  
2961 - if ($p_remove_all_dir) {  
2962 - $v_stored_filename = basename($p_filename);  
2963 - }  
2964 - // ----- Look for partial path remove  
2965 - else if ($p_remove_dir != "") {  
2966 - if (substr($p_remove_dir, -1) != '/')  
2967 - $p_remove_dir .= "/";  
2968 -  
2969 - if ( (substr($p_filename, 0, 2) == "./")  
2970 - || (substr($p_remove_dir, 0, 2) == "./")) {  
2971 -  
2972 - if ( (substr($p_filename, 0, 2) == "./")  
2973 - && (substr($p_remove_dir, 0, 2) != "./")) {  
2974 - $p_remove_dir = "./".$p_remove_dir;  
2975 - }  
2976 - if ( (substr($p_filename, 0, 2) != "./")  
2977 - && (substr($p_remove_dir, 0, 2) == "./")) {  
2978 - $p_remove_dir = substr($p_remove_dir, 2);  
2979 - }  
2980 - }  
2981 -  
2982 - $v_compare = PclZipUtilPathInclusion($p_remove_dir,  
2983 - $v_stored_filename);  
2984 - if ($v_compare > 0) {  
2985 - if ($v_compare == 2) {  
2986 - $v_stored_filename = "";  
2987 - }  
2988 - else {  
2989 - $v_stored_filename = substr($v_stored_filename,  
2990 - strlen($p_remove_dir));  
2991 - }  
2992 - }  
2993 - }  
2994 -  
2995 - // ----- Remove drive letter if any  
2996 - $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);  
2997 -  
2998 - // ----- Look for path to add  
2999 - if ($p_add_dir != "") {  
3000 - if (substr($p_add_dir, -1) == "/")  
3001 - $v_stored_filename = $p_add_dir.$v_stored_filename;  
3002 - else  
3003 - $v_stored_filename = $p_add_dir."/".$v_stored_filename;  
3004 - }  
3005 - }  
3006 -  
3007 - // ----- Filename (reduce the path of stored name)  
3008 - $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);  
3009 - $p_filedescr['stored_filename'] = $v_stored_filename;  
3010 -  
3011 - // ----- Return  
3012 - return $v_result;  
3013 - }  
3014 - // --------------------------------------------------------------------------------  
3015 -  
3016 - // --------------------------------------------------------------------------------  
3017 - // Function : privWriteFileHeader()  
3018 - // Description :  
3019 - // Parameters :  
3020 - // Return Values :  
3021 - // --------------------------------------------------------------------------------  
3022 - function privWriteFileHeader(&$p_header)  
3023 - {  
3024 - $v_result=1;  
3025 -  
3026 - // ----- Store the offset position of the file  
3027 - $p_header['offset'] = ftell($this->zip_fd);  
3028 -  
3029 - // ----- Transform UNIX mtime to DOS format mdate/mtime  
3030 - $v_date = getdate($p_header['mtime']);  
3031 - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;  
3032 - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];  
3033 -  
3034 - // ----- Packed data  
3035 - $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,  
3036 - $p_header['version_extracted'], $p_header['flag'],  
3037 - $p_header['compression'], $v_mtime, $v_mdate,  
3038 - $p_header['crc'], $p_header['compressed_size'],  
3039 - $p_header['size'],  
3040 - strlen($p_header['stored_filename']),  
3041 - $p_header['extra_len']);  
3042 -  
3043 - // ----- Write the first 148 bytes of the header in the archive  
3044 - fputs($this->zip_fd, $v_binary_data, 30);  
3045 -  
3046 - // ----- Write the variable fields  
3047 - if (strlen($p_header['stored_filename']) != 0)  
3048 - {  
3049 - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));  
3050 - }  
3051 - if ($p_header['extra_len'] != 0)  
3052 - {  
3053 - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);  
3054 - }  
3055 -  
3056 - // ----- Return  
3057 - return $v_result;  
3058 - }  
3059 - // --------------------------------------------------------------------------------  
3060 -  
3061 - // --------------------------------------------------------------------------------  
3062 - // Function : privWriteCentralFileHeader()  
3063 - // Description :  
3064 - // Parameters :  
3065 - // Return Values :  
3066 - // --------------------------------------------------------------------------------  
3067 - function privWriteCentralFileHeader(&$p_header)  
3068 - {  
3069 - $v_result=1;  
3070 -  
3071 - // TBC  
3072 - //for(reset($p_header); $key = key($p_header); next($p_header)) {  
3073 - //}  
3074 -  
3075 - // ----- Transform UNIX mtime to DOS format mdate/mtime  
3076 - $v_date = getdate($p_header['mtime']);  
3077 - $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;  
3078 - $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];  
3079 -  
3080 -  
3081 - // ----- Packed data  
3082 - $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,  
3083 - $p_header['version'], $p_header['version_extracted'],  
3084 - $p_header['flag'], $p_header['compression'],  
3085 - $v_mtime, $v_mdate, $p_header['crc'],  
3086 - $p_header['compressed_size'], $p_header['size'],  
3087 - strlen($p_header['stored_filename']),  
3088 - $p_header['extra_len'], $p_header['comment_len'],  
3089 - $p_header['disk'], $p_header['internal'],  
3090 - $p_header['external'], $p_header['offset']);  
3091 -  
3092 - // ----- Write the 42 bytes of the header in the zip file  
3093 - fputs($this->zip_fd, $v_binary_data, 46);  
3094 -  
3095 - // ----- Write the variable fields  
3096 - if (strlen($p_header['stored_filename']) != 0)  
3097 - {  
3098 - fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));  
3099 - }  
3100 - if ($p_header['extra_len'] != 0)  
3101 - {  
3102 - fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);  
3103 - }  
3104 - if ($p_header['comment_len'] != 0)  
3105 - {  
3106 - fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);  
3107 - }  
3108 -  
3109 - // ----- Return  
3110 - return $v_result;  
3111 - }  
3112 - // --------------------------------------------------------------------------------  
3113 -  
3114 - // --------------------------------------------------------------------------------  
3115 - // Function : privWriteCentralHeader()  
3116 - // Description :  
3117 - // Parameters :  
3118 - // Return Values :  
3119 - // --------------------------------------------------------------------------------  
3120 - function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)  
3121 - {  
3122 - $v_result=1;  
3123 -  
3124 - // ----- Packed data  
3125 - $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,  
3126 - $p_nb_entries, $p_size,  
3127 - $p_offset, strlen($p_comment));  
3128 -  
3129 - // ----- Write the 22 bytes of the header in the zip file  
3130 - fputs($this->zip_fd, $v_binary_data, 22);  
3131 -  
3132 - // ----- Write the variable fields  
3133 - if (strlen($p_comment) != 0)  
3134 - {  
3135 - fputs($this->zip_fd, $p_comment, strlen($p_comment));  
3136 - }  
3137 -  
3138 - // ----- Return  
3139 - return $v_result;  
3140 - }  
3141 - // --------------------------------------------------------------------------------  
3142 -  
3143 - // --------------------------------------------------------------------------------  
3144 - // Function : privList()  
3145 - // Description :  
3146 - // Parameters :  
3147 - // Return Values :  
3148 - // --------------------------------------------------------------------------------  
3149 - function privList(&$p_list)  
3150 - {  
3151 - $v_result=1;  
3152 -  
3153 - // ----- Magic quotes trick  
3154 - $this->privDisableMagicQuotes();  
3155 -  
3156 - // ----- Open the zip file  
3157 - if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)  
3158 - {  
3159 - // ----- Magic quotes trick  
3160 - $this->privSwapBackMagicQuotes();  
3161 -  
3162 - // ----- Error log  
3163 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');  
3164 -  
3165 - // ----- Return  
3166 - return PclZip::errorCode();  
3167 - }  
3168 -  
3169 - // ----- Read the central directory informations  
3170 - $v_central_dir = array();  
3171 - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)  
3172 - {  
3173 - $this->privSwapBackMagicQuotes();  
3174 - return $v_result;  
3175 - }  
3176 -  
3177 - // ----- Go to beginning of Central Dir  
3178 - @rewind($this->zip_fd);  
3179 - if (@fseek($this->zip_fd, $v_central_dir['offset']))  
3180 - {  
3181 - $this->privSwapBackMagicQuotes();  
3182 -  
3183 - // ----- Error log  
3184 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');  
3185 -  
3186 - // ----- Return  
3187 - return PclZip::errorCode();  
3188 - }  
3189 -  
3190 - // ----- Read each entry  
3191 - for ($i=0; $i<$v_central_dir['entries']; $i++)  
3192 - {  
3193 - // ----- Read the file header  
3194 - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)  
3195 - {  
3196 - $this->privSwapBackMagicQuotes();  
3197 - return $v_result;  
3198 - }  
3199 - $v_header['index'] = $i;  
3200 -  
3201 - // ----- Get the only interesting attributes  
3202 - $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);  
3203 - unset($v_header);  
3204 - }  
3205 -  
3206 - // ----- Close the zip file  
3207 - $this->privCloseFd();  
3208 -  
3209 - // ----- Magic quotes trick  
3210 - $this->privSwapBackMagicQuotes();  
3211 -  
3212 - // ----- Return  
3213 - return $v_result;  
3214 - }  
3215 - // --------------------------------------------------------------------------------  
3216 -  
3217 - // --------------------------------------------------------------------------------  
3218 - // Function : privConvertHeader2FileInfo()  
3219 - // Description :  
3220 - // This function takes the file informations from the central directory  
3221 - // entries and extract the interesting parameters that will be given back.  
3222 - // The resulting file infos are set in the array $p_info  
3223 - // $p_info['filename'] : Filename with full path. Given by user (add),  
3224 - // extracted in the filesystem (extract).  
3225 - // $p_info['stored_filename'] : Stored filename in the archive.  
3226 - // $p_info['size'] = Size of the file.  
3227 - // $p_info['compressed_size'] = Compressed size of the file.  
3228 - // $p_info['mtime'] = Last modification date of the file.  
3229 - // $p_info['comment'] = Comment associated with the file.  
3230 - // $p_info['folder'] = true/false : indicates if the entry is a folder or not.  
3231 - // $p_info['status'] = status of the action on the file.  
3232 - // $p_info['crc'] = CRC of the file content.  
3233 - // Parameters :  
3234 - // Return Values :  
3235 - // --------------------------------------------------------------------------------  
3236 - function privConvertHeader2FileInfo($p_header, &$p_info)  
3237 - {  
3238 - $v_result=1;  
3239 -  
3240 - // ----- Get the interesting attributes  
3241 - $v_temp_path = PclZipUtilPathReduction($p_header['filename']);  
3242 - $p_info['filename'] = $v_temp_path;  
3243 - $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);  
3244 - $p_info['stored_filename'] = $v_temp_path;  
3245 - $p_info['size'] = $p_header['size'];  
3246 - $p_info['compressed_size'] = $p_header['compressed_size'];  
3247 - $p_info['mtime'] = $p_header['mtime'];  
3248 - $p_info['comment'] = $p_header['comment'];  
3249 - $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);  
3250 - $p_info['index'] = $p_header['index'];  
3251 - $p_info['status'] = $p_header['status'];  
3252 - $p_info['crc'] = $p_header['crc'];  
3253 -  
3254 - // ----- Return  
3255 - return $v_result;  
3256 - }  
3257 - // --------------------------------------------------------------------------------  
3258 -  
3259 - // --------------------------------------------------------------------------------  
3260 - // Function : privExtractByRule()  
3261 - // Description :  
3262 - // Extract a file or directory depending of rules (by index, by name, ...)  
3263 - // Parameters :  
3264 - // $p_file_list : An array where will be placed the properties of each  
3265 - // extracted file  
3266 - // $p_path : Path to add while writing the extracted files  
3267 - // $p_remove_path : Path to remove (from the file memorized path) while writing the  
3268 - // extracted files. If the path does not match the file path,  
3269 - // the file is extracted with its memorized path.  
3270 - // $p_remove_path does not apply to 'list' mode.  
3271 - // $p_path and $p_remove_path are commulative.  
3272 - // Return Values :  
3273 - // 1 on success,0 or less on error (see error code list)  
3274 - // --------------------------------------------------------------------------------  
3275 - function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)  
3276 - {  
3277 - $v_result=1;  
3278 -  
3279 - // ----- Magic quotes trick  
3280 - $this->privDisableMagicQuotes();  
3281 -  
3282 - // ----- Check the path  
3283 - if ( ($p_path == "")  
3284 - || ( (substr($p_path, 0, 1) != "/")  
3285 - && (substr($p_path, 0, 3) != "../")  
3286 - && (substr($p_path,1,2)!=":/")))  
3287 - $p_path = "./".$p_path;  
3288 -  
3289 - // ----- Reduce the path last (and duplicated) '/'  
3290 - if (($p_path != "./") && ($p_path != "/"))  
3291 - {  
3292 - // ----- Look for the path end '/'  
3293 - while (substr($p_path, -1) == "/")  
3294 - {  
3295 - $p_path = substr($p_path, 0, strlen($p_path)-1);  
3296 - }  
3297 - }  
3298 -  
3299 - // ----- Look for path to remove format (should end by /)  
3300 - if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))  
3301 - {  
3302 - $p_remove_path .= '/';  
3303 - }  
3304 - $p_remove_path_size = strlen($p_remove_path);  
3305 -  
3306 - // ----- Open the zip file  
3307 - if (($v_result = $this->privOpenFd('rb')) != 1)  
3308 - {  
3309 - $this->privSwapBackMagicQuotes();  
3310 - return $v_result;  
3311 - }  
3312 -  
3313 - // ----- Read the central directory informations  
3314 - $v_central_dir = array();  
3315 - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)  
3316 - {  
3317 - // ----- Close the zip file  
3318 - $this->privCloseFd();  
3319 - $this->privSwapBackMagicQuotes();  
3320 -  
3321 - return $v_result;  
3322 - }  
3323 -  
3324 - // ----- Start at beginning of Central Dir  
3325 - $v_pos_entry = $v_central_dir['offset'];  
3326 -  
3327 - // ----- Read each entry  
3328 - $j_start = 0;  
3329 - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)  
3330 - {  
3331 -  
3332 - // ----- Read next Central dir entry  
3333 - @rewind($this->zip_fd);  
3334 - if (@fseek($this->zip_fd, $v_pos_entry))  
3335 - {  
3336 - // ----- Close the zip file  
3337 - $this->privCloseFd();  
3338 - $this->privSwapBackMagicQuotes();  
3339 -  
3340 - // ----- Error log  
3341 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');  
3342 -  
3343 - // ----- Return  
3344 - return PclZip::errorCode();  
3345 - }  
3346 -  
3347 - // ----- Read the file header  
3348 - $v_header = array();  
3349 - if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)  
3350 - {  
3351 - // ----- Close the zip file  
3352 - $this->privCloseFd();  
3353 - $this->privSwapBackMagicQuotes();  
3354 -  
3355 - return $v_result;  
3356 - }  
3357 -  
3358 - // ----- Store the index  
3359 - $v_header['index'] = $i;  
3360 -  
3361 - // ----- Store the file position  
3362 - $v_pos_entry = ftell($this->zip_fd);  
3363 -  
3364 - // ----- Look for the specific extract rules  
3365 - $v_extract = false;  
3366 -  
3367 - // ----- Look for extract by name rule  
3368 - if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))  
3369 - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {  
3370 -  
3371 - // ----- Look if the filename is in the list  
3372 - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {  
3373 -  
3374 - // ----- Look for a directory  
3375 - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {  
3376 -  
3377 - // ----- Look if the directory is in the filename path  
3378 - if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))  
3379 - && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {  
3380 - $v_extract = true;  
3381 - }  
3382 - }  
3383 - // ----- Look for a filename  
3384 - elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {  
3385 - $v_extract = true;  
3386 - }  
3387 - }  
3388 - }  
3389 -  
3390 - // ----- Look for extract by ereg rule  
3391 - // ereg() is deprecated with PHP 5.3  
3392 - /*  
3393 - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))  
3394 - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {  
3395 -  
3396 - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {  
3397 - $v_extract = true;  
3398 - }  
3399 - }  
3400 - */  
3401 -  
3402 - // ----- Look for extract by preg rule  
3403 - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))  
3404 - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {  
3405 -  
3406 - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {  
3407 - $v_extract = true;  
3408 - }  
3409 - }  
3410 -  
3411 - // ----- Look for extract by index rule  
3412 - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))  
3413 - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {  
3414 -  
3415 - // ----- Look if the index is in the list  
3416 - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {  
3417 -  
3418 - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {  
3419 - $v_extract = true;  
3420 - }  
3421 - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {  
3422 - $j_start = $j+1;  
3423 - }  
3424 -  
3425 - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {  
3426 - break;  
3427 - }  
3428 - }  
3429 - }  
3430 -  
3431 - // ----- Look for no rule, which means extract all the archive  
3432 - else {  
3433 - $v_extract = true;  
3434 - }  
3435 -  
3436 - // ----- Check compression method  
3437 - if ( ($v_extract)  
3438 - && ( ($v_header['compression'] != 8)  
3439 - && ($v_header['compression'] != 0))) {  
3440 - $v_header['status'] = 'unsupported_compression';  
3441 -  
3442 - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR  
3443 - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))  
3444 - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {  
3445 -  
3446 - $this->privSwapBackMagicQuotes();  
3447 -  
3448 - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,  
3449 - "Filename '".$v_header['stored_filename']."' is "  
3450 - ."compressed by an unsupported compression "  
3451 - ."method (".$v_header['compression'].") ");  
3452 -  
3453 - return PclZip::errorCode();  
3454 - }  
3455 - }  
3456 -  
3457 - // ----- Check encrypted files  
3458 - if (($v_extract) && (($v_header['flag'] & 1) == 1)) {  
3459 - $v_header['status'] = 'unsupported_encryption';  
3460 -  
3461 - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR  
3462 - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))  
3463 - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {  
3464 -  
3465 - $this->privSwapBackMagicQuotes();  
3466 -  
3467 - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,  
3468 - "Unsupported encryption for "  
3469 - ." filename '".$v_header['stored_filename']  
3470 - ."'");  
3471 -  
3472 - return PclZip::errorCode();  
3473 - }  
3474 - }  
3475 -  
3476 - // ----- Look for real extraction  
3477 - if (($v_extract) && ($v_header['status'] != 'ok')) {  
3478 - $v_result = $this->privConvertHeader2FileInfo($v_header,  
3479 - $p_file_list[$v_nb_extracted++]);  
3480 - if ($v_result != 1) {  
3481 - $this->privCloseFd();  
3482 - $this->privSwapBackMagicQuotes();  
3483 - return $v_result;  
3484 - }  
3485 -  
3486 - $v_extract = false;  
3487 - }  
3488 -  
3489 - // ----- Look for real extraction  
3490 - if ($v_extract)  
3491 - {  
3492 -  
3493 - // ----- Go to the file position  
3494 - @rewind($this->zip_fd);  
3495 - if (@fseek($this->zip_fd, $v_header['offset']))  
3496 - {  
3497 - // ----- Close the zip file  
3498 - $this->privCloseFd();  
3499 -  
3500 - $this->privSwapBackMagicQuotes();  
3501 -  
3502 - // ----- Error log  
3503 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');  
3504 -  
3505 - // ----- Return  
3506 - return PclZip::errorCode();  
3507 - }  
3508 -  
3509 - // ----- Look for extraction as string  
3510 - if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {  
3511 -  
3512 - $v_string = '';  
3513 -  
3514 - // ----- Extracting the file  
3515 - $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);  
3516 - if ($v_result1 < 1) {  
3517 - $this->privCloseFd();  
3518 - $this->privSwapBackMagicQuotes();  
3519 - return $v_result1;  
3520 - }  
3521 -  
3522 - // ----- Get the only interesting attributes  
3523 - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)  
3524 - {  
3525 - // ----- Close the zip file  
3526 - $this->privCloseFd();  
3527 - $this->privSwapBackMagicQuotes();  
3528 -  
3529 - return $v_result;  
3530 - }  
3531 -  
3532 - // ----- Set the file content  
3533 - $p_file_list[$v_nb_extracted]['content'] = $v_string;  
3534 -  
3535 - // ----- Next extracted file  
3536 - $v_nb_extracted++;  
3537 -  
3538 - // ----- Look for user callback abort  
3539 - if ($v_result1 == 2) {  
3540 - break;  
3541 - }  
3542 - }  
3543 - // ----- Look for extraction in standard output  
3544 - elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))  
3545 - && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {  
3546 - // ----- Extracting the file in standard output  
3547 - $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);  
3548 - if ($v_result1 < 1) {  
3549 - $this->privCloseFd();  
3550 - $this->privSwapBackMagicQuotes();  
3551 - return $v_result1;  
3552 - }  
3553 -  
3554 - // ----- Get the only interesting attributes  
3555 - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {  
3556 - $this->privCloseFd();  
3557 - $this->privSwapBackMagicQuotes();  
3558 - return $v_result;  
3559 - }  
3560 -  
3561 - // ----- Look for user callback abort  
3562 - if ($v_result1 == 2) {  
3563 - break;  
3564 - }  
3565 - }  
3566 - // ----- Look for normal extraction  
3567 - else {  
3568 - // ----- Extracting the file  
3569 - $v_result1 = $this->privExtractFile($v_header,  
3570 - $p_path, $p_remove_path,  
3571 - $p_remove_all_path,  
3572 - $p_options);  
3573 - if ($v_result1 < 1) {  
3574 - $this->privCloseFd();  
3575 - $this->privSwapBackMagicQuotes();  
3576 - return $v_result1;  
3577 - }  
3578 -  
3579 - // ----- Get the only interesting attributes  
3580 - if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)  
3581 - {  
3582 - // ----- Close the zip file  
3583 - $this->privCloseFd();  
3584 - $this->privSwapBackMagicQuotes();  
3585 -  
3586 - return $v_result;  
3587 - }  
3588 -  
3589 - // ----- Look for user callback abort  
3590 - if ($v_result1 == 2) {  
3591 - break;  
3592 - }  
3593 - }  
3594 - }  
3595 - }  
3596 -  
3597 - // ----- Close the zip file  
3598 - $this->privCloseFd();  
3599 - $this->privSwapBackMagicQuotes();  
3600 -  
3601 - // ----- Return  
3602 - return $v_result;  
3603 - }  
3604 - // --------------------------------------------------------------------------------  
3605 -  
3606 - // --------------------------------------------------------------------------------  
3607 - // Function : privExtractFile()  
3608 - // Description :  
3609 - // Parameters :  
3610 - // Return Values :  
3611 - //  
3612 - // 1 : ... ?  
3613 - // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback  
3614 - // --------------------------------------------------------------------------------  
3615 - function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)  
3616 - {  
3617 - $v_result=1;  
3618 -  
3619 - // ----- Read the file header  
3620 - if (($v_result = $this->privReadFileHeader($v_header)) != 1)  
3621 - {  
3622 - // ----- Return  
3623 - return $v_result;  
3624 - }  
3625 -  
3626 -  
3627 - // ----- Check that the file header is coherent with $p_entry info  
3628 - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {  
3629 - // TBC  
3630 - }  
3631 -  
3632 - // ----- Look for all path to remove  
3633 - if ($p_remove_all_path == true) {  
3634 - // ----- Look for folder entry that not need to be extracted  
3635 - if (($p_entry['external']&0x00000010)==0x00000010) {  
3636 -  
3637 - $p_entry['status'] = "filtered";  
3638 -  
3639 - return $v_result;  
3640 - }  
3641 -  
3642 - // ----- Get the basename of the path  
3643 - $p_entry['filename'] = basename($p_entry['filename']);  
3644 - }  
3645 -  
3646 - // ----- Look for path to remove  
3647 - else if ($p_remove_path != "")  
3648 - {  
3649 - if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)  
3650 - {  
3651 -  
3652 - // ----- Change the file status  
3653 - $p_entry['status'] = "filtered";  
3654 -  
3655 - // ----- Return  
3656 - return $v_result;  
3657 - }  
3658 -  
3659 - $p_remove_path_size = strlen($p_remove_path);  
3660 - if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)  
3661 - {  
3662 -  
3663 - // ----- Remove the path  
3664 - $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);  
3665 -  
3666 - }  
3667 - }  
3668 -  
3669 - // ----- Add the path  
3670 - if ($p_path != '') {  
3671 - $p_entry['filename'] = $p_path."/".$p_entry['filename'];  
3672 - }  
3673 -  
3674 - // ----- Check a base_dir_restriction  
3675 - if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {  
3676 - $v_inclusion  
3677 - = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],  
3678 - $p_entry['filename']);  
3679 - if ($v_inclusion == 0) {  
3680 -  
3681 - PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,  
3682 - "Filename '".$p_entry['filename']."' is "  
3683 - ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");  
3684 -  
3685 - return PclZip::errorCode();  
3686 - }  
3687 - }  
3688 -  
3689 - // ----- Look for pre-extract callback  
3690 - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {  
3691 -  
3692 - // ----- Generate a local information  
3693 - $v_local_header = array();  
3694 - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);  
3695 -  
3696 - // ----- Call the callback  
3697 - // Here I do not use call_user_func() because I need to send a reference to the  
3698 - // header.  
3699 -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');  
3700 - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);  
3701 - if ($v_result == 0) {  
3702 - // ----- Change the file status  
3703 - $p_entry['status'] = "skipped";  
3704 - $v_result = 1;  
3705 - }  
3706 -  
3707 - // ----- Look for abort result  
3708 - if ($v_result == 2) {  
3709 - // ----- This status is internal and will be changed in 'skipped'  
3710 - $p_entry['status'] = "aborted";  
3711 - $v_result = PCLZIP_ERR_USER_ABORTED;  
3712 - }  
3713 -  
3714 - // ----- Update the informations  
3715 - // Only some fields can be modified  
3716 - $p_entry['filename'] = $v_local_header['filename'];  
3717 - }  
3718 -  
3719 -  
3720 - // ----- Look if extraction should be done  
3721 - if ($p_entry['status'] == 'ok') {  
3722 -  
3723 - // ----- Look for specific actions while the file exist  
3724 - if (file_exists($p_entry['filename']))  
3725 - {  
3726 -  
3727 - // ----- Look if file is a directory  
3728 - if (is_dir($p_entry['filename']))  
3729 - {  
3730 -  
3731 - // ----- Change the file status  
3732 - $p_entry['status'] = "already_a_directory";  
3733 -  
3734 - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR  
3735 - // For historical reason first PclZip implementation does not stop  
3736 - // when this kind of error occurs.  
3737 - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))  
3738 - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {  
3739 -  
3740 - PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,  
3741 - "Filename '".$p_entry['filename']."' is "  
3742 - ."already used by an existing directory");  
3743 -  
3744 - return PclZip::errorCode();  
3745 - }  
3746 - }  
3747 - // ----- Look if file is write protected  
3748 - else if (!is_writeable($p_entry['filename']))  
3749 - {  
3750 -  
3751 - // ----- Change the file status  
3752 - $p_entry['status'] = "write_protected";  
3753 -  
3754 - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR  
3755 - // For historical reason first PclZip implementation does not stop  
3756 - // when this kind of error occurs.  
3757 - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))  
3758 - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {  
3759 -  
3760 - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,  
3761 - "Filename '".$p_entry['filename']."' exists "  
3762 - ."and is write protected");  
3763 -  
3764 - return PclZip::errorCode();  
3765 - }  
3766 - }  
3767 -  
3768 - // ----- Look if the extracted file is older  
3769 - else if (filemtime($p_entry['filename']) > $p_entry['mtime'])  
3770 - {  
3771 - // ----- Change the file status  
3772 - if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))  
3773 - && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {  
3774 - }  
3775 - else {  
3776 - $p_entry['status'] = "newer_exist";  
3777 -  
3778 - // ----- Look for PCLZIP_OPT_STOP_ON_ERROR  
3779 - // For historical reason first PclZip implementation does not stop  
3780 - // when this kind of error occurs.  
3781 - if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))  
3782 - && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {  
3783 -  
3784 - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,  
3785 - "Newer version of '".$p_entry['filename']."' exists "  
3786 - ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");  
3787 -  
3788 - return PclZip::errorCode();  
3789 - }  
3790 - }  
3791 - }  
3792 - else {  
3793 - }  
3794 - }  
3795 -  
3796 - // ----- Check the directory availability and create it if necessary  
3797 - else {  
3798 - if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))  
3799 - $v_dir_to_check = $p_entry['filename'];  
3800 - else if (!strstr($p_entry['filename'], "/"))  
3801 - $v_dir_to_check = "";  
3802 - else  
3803 - $v_dir_to_check = dirname($p_entry['filename']);  
3804 -  
3805 - if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {  
3806 -  
3807 - // ----- Change the file status  
3808 - $p_entry['status'] = "path_creation_fail";  
3809 -  
3810 - // ----- Return  
3811 - //return $v_result;  
3812 - $v_result = 1;  
3813 - }  
3814 - }  
3815 - }  
3816 -  
3817 - // ----- Look if extraction should be done  
3818 - if ($p_entry['status'] == 'ok') {  
3819 -  
3820 - // ----- Do the extraction (if not a folder)  
3821 - if (!(($p_entry['external']&0x00000010)==0x00000010))  
3822 - {  
3823 - // ----- Look for not compressed file  
3824 - if ($p_entry['compression'] == 0) {  
3825 -  
3826 - // ----- Opening destination file  
3827 - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)  
3828 - {  
3829 -  
3830 - // ----- Change the file status  
3831 - $p_entry['status'] = "write_error";  
3832 -  
3833 - // ----- Return  
3834 - return $v_result;  
3835 - }  
3836 -  
3837 -  
3838 - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks  
3839 - $v_size = $p_entry['compressed_size'];  
3840 - while ($v_size != 0)  
3841 - {  
3842 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
3843 - $v_buffer = @fread($this->zip_fd, $v_read_size);  
3844 - /* Try to speed up the code  
3845 - $v_binary_data = pack('a'.$v_read_size, $v_buffer);  
3846 - @fwrite($v_dest_file, $v_binary_data, $v_read_size);  
3847 - */  
3848 - @fwrite($v_dest_file, $v_buffer, $v_read_size);  
3849 - $v_size -= $v_read_size;  
3850 - }  
3851 -  
3852 - // ----- Closing the destination file  
3853 - fclose($v_dest_file);  
3854 -  
3855 - // ----- Change the file mtime  
3856 - touch($p_entry['filename'], $p_entry['mtime']);  
3857 -  
3858 -  
3859 - }  
3860 - else {  
3861 - // ----- TBC  
3862 - // Need to be finished  
3863 - if (($p_entry['flag'] & 1) == 1) {  
3864 - PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');  
3865 - return PclZip::errorCode();  
3866 - }  
3867 -  
3868 -  
3869 - // ----- Look for using temporary file to unzip  
3870 - if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))  
3871 - && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])  
3872 - || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])  
3873 - && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {  
3874 - $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);  
3875 - if ($v_result < PCLZIP_ERR_NO_ERROR) {  
3876 - return $v_result;  
3877 - }  
3878 - }  
3879 -  
3880 - // ----- Look for extract in memory  
3881 - else {  
3882 -  
3883 -  
3884 - // ----- Read the compressed file in a buffer (one shot)  
3885 - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);  
3886 -  
3887 - // ----- Decompress the file  
3888 - $v_file_content = @gzinflate($v_buffer);  
3889 - unset($v_buffer);  
3890 - if ($v_file_content === FALSE) {  
3891 -  
3892 - // ----- Change the file status  
3893 - // TBC  
3894 - $p_entry['status'] = "error";  
3895 -  
3896 - return $v_result;  
3897 - }  
3898 -  
3899 - // ----- Opening destination file  
3900 - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {  
3901 -  
3902 - // ----- Change the file status  
3903 - $p_entry['status'] = "write_error";  
3904 -  
3905 - return $v_result;  
3906 - }  
3907 -  
3908 - // ----- Write the uncompressed data  
3909 - @fwrite($v_dest_file, $v_file_content, $p_entry['size']);  
3910 - unset($v_file_content);  
3911 -  
3912 - // ----- Closing the destination file  
3913 - @fclose($v_dest_file);  
3914 -  
3915 - }  
3916 -  
3917 - // ----- Change the file mtime  
3918 - @touch($p_entry['filename'], $p_entry['mtime']);  
3919 - }  
3920 -  
3921 - // ----- Look for chmod option  
3922 - if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {  
3923 -  
3924 - // ----- Change the mode of the file  
3925 - @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);  
3926 - }  
3927 -  
3928 - }  
3929 - }  
3930 -  
3931 - // ----- Change abort status  
3932 - if ($p_entry['status'] == "aborted") {  
3933 - $p_entry['status'] = "skipped";  
3934 - }  
3935 -  
3936 - // ----- Look for post-extract callback  
3937 - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {  
3938 -  
3939 - // ----- Generate a local information  
3940 - $v_local_header = array();  
3941 - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);  
3942 -  
3943 - // ----- Call the callback  
3944 - // Here I do not use call_user_func() because I need to send a reference to the  
3945 - // header.  
3946 -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');  
3947 - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);  
3948 -  
3949 - // ----- Look for abort result  
3950 - if ($v_result == 2) {  
3951 - $v_result = PCLZIP_ERR_USER_ABORTED;  
3952 - }  
3953 - }  
3954 -  
3955 - // ----- Return  
3956 - return $v_result;  
3957 - }  
3958 - // --------------------------------------------------------------------------------  
3959 -  
3960 - // --------------------------------------------------------------------------------  
3961 - // Function : privExtractFileUsingTempFile()  
3962 - // Description :  
3963 - // Parameters :  
3964 - // Return Values :  
3965 - // --------------------------------------------------------------------------------  
3966 - function privExtractFileUsingTempFile(&$p_entry, &$p_options)  
3967 - {  
3968 - $v_result=1;  
3969 -  
3970 - // ----- Creates a temporary file  
3971 - $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';  
3972 - if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {  
3973 - fclose($v_file);  
3974 - PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');  
3975 - return PclZip::errorCode();  
3976 - }  
3977 -  
3978 -  
3979 - // ----- Write gz file format header  
3980 - $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));  
3981 - @fwrite($v_dest_file, $v_binary_data, 10);  
3982 -  
3983 - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks  
3984 - $v_size = $p_entry['compressed_size'];  
3985 - while ($v_size != 0)  
3986 - {  
3987 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
3988 - $v_buffer = @fread($this->zip_fd, $v_read_size);  
3989 - //$v_binary_data = pack('a'.$v_read_size, $v_buffer);  
3990 - @fwrite($v_dest_file, $v_buffer, $v_read_size);  
3991 - $v_size -= $v_read_size;  
3992 - }  
3993 -  
3994 - // ----- Write gz file format footer  
3995 - $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);  
3996 - @fwrite($v_dest_file, $v_binary_data, 8);  
3997 -  
3998 - // ----- Close the temporary file  
3999 - @fclose($v_dest_file);  
4000 -  
4001 - // ----- Opening destination file  
4002 - if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {  
4003 - $p_entry['status'] = "write_error";  
4004 - return $v_result;  
4005 - }  
4006 -  
4007 - // ----- Open the temporary gz file  
4008 - if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {  
4009 - @fclose($v_dest_file);  
4010 - $p_entry['status'] = "read_error";  
4011 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');  
4012 - return PclZip::errorCode();  
4013 - }  
4014 -  
4015 -  
4016 - // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks  
4017 - $v_size = $p_entry['size'];  
4018 - while ($v_size != 0) {  
4019 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
4020 - $v_buffer = @gzread($v_src_file, $v_read_size);  
4021 - //$v_binary_data = pack('a'.$v_read_size, $v_buffer);  
4022 - @fwrite($v_dest_file, $v_buffer, $v_read_size);  
4023 - $v_size -= $v_read_size;  
4024 - }  
4025 - @fclose($v_dest_file);  
4026 - @gzclose($v_src_file);  
4027 -  
4028 - // ----- Delete the temporary file  
4029 - @unlink($v_gzip_temp_name);  
4030 -  
4031 - // ----- Return  
4032 - return $v_result;  
4033 - }  
4034 - // --------------------------------------------------------------------------------  
4035 -  
4036 - // --------------------------------------------------------------------------------  
4037 - // Function : privExtractFileInOutput()  
4038 - // Description :  
4039 - // Parameters :  
4040 - // Return Values :  
4041 - // --------------------------------------------------------------------------------  
4042 - function privExtractFileInOutput(&$p_entry, &$p_options)  
4043 - {  
4044 - $v_result=1;  
4045 -  
4046 - // ----- Read the file header  
4047 - if (($v_result = $this->privReadFileHeader($v_header)) != 1) {  
4048 - return $v_result;  
4049 - }  
4050 -  
4051 -  
4052 - // ----- Check that the file header is coherent with $p_entry info  
4053 - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {  
4054 - // TBC  
4055 - }  
4056 -  
4057 - // ----- Look for pre-extract callback  
4058 - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {  
4059 -  
4060 - // ----- Generate a local information  
4061 - $v_local_header = array();  
4062 - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);  
4063 -  
4064 - // ----- Call the callback  
4065 - // Here I do not use call_user_func() because I need to send a reference to the  
4066 - // header.  
4067 -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');  
4068 - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);  
4069 - if ($v_result == 0) {  
4070 - // ----- Change the file status  
4071 - $p_entry['status'] = "skipped";  
4072 - $v_result = 1;  
4073 - }  
4074 -  
4075 - // ----- Look for abort result  
4076 - if ($v_result == 2) {  
4077 - // ----- This status is internal and will be changed in 'skipped'  
4078 - $p_entry['status'] = "aborted";  
4079 - $v_result = PCLZIP_ERR_USER_ABORTED;  
4080 - }  
4081 -  
4082 - // ----- Update the informations  
4083 - // Only some fields can be modified  
4084 - $p_entry['filename'] = $v_local_header['filename'];  
4085 - }  
4086 -  
4087 - // ----- Trace  
4088 -  
4089 - // ----- Look if extraction should be done  
4090 - if ($p_entry['status'] == 'ok') {  
4091 -  
4092 - // ----- Do the extraction (if not a folder)  
4093 - if (!(($p_entry['external']&0x00000010)==0x00000010)) {  
4094 - // ----- Look for not compressed file  
4095 - if ($p_entry['compressed_size'] == $p_entry['size']) {  
4096 -  
4097 - // ----- Read the file in a buffer (one shot)  
4098 - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);  
4099 -  
4100 - // ----- Send the file to the output  
4101 - echo $v_buffer;  
4102 - unset($v_buffer);  
4103 - }  
4104 - else {  
4105 -  
4106 - // ----- Read the compressed file in a buffer (one shot)  
4107 - $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);  
4108 -  
4109 - // ----- Decompress the file  
4110 - $v_file_content = gzinflate($v_buffer);  
4111 - unset($v_buffer);  
4112 -  
4113 - // ----- Send the file to the output  
4114 - echo $v_file_content;  
4115 - unset($v_file_content);  
4116 - }  
4117 - }  
4118 - }  
4119 -  
4120 - // ----- Change abort status  
4121 - if ($p_entry['status'] == "aborted") {  
4122 - $p_entry['status'] = "skipped";  
4123 - }  
4124 -  
4125 - // ----- Look for post-extract callback  
4126 - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {  
4127 -  
4128 - // ----- Generate a local information  
4129 - $v_local_header = array();  
4130 - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);  
4131 -  
4132 - // ----- Call the callback  
4133 - // Here I do not use call_user_func() because I need to send a reference to the  
4134 - // header.  
4135 -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');  
4136 - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);  
4137 -  
4138 - // ----- Look for abort result  
4139 - if ($v_result == 2) {  
4140 - $v_result = PCLZIP_ERR_USER_ABORTED;  
4141 - }  
4142 - }  
4143 -  
4144 - return $v_result;  
4145 - }  
4146 - // --------------------------------------------------------------------------------  
4147 -  
4148 - // --------------------------------------------------------------------------------  
4149 - // Function : privExtractFileAsString()  
4150 - // Description :  
4151 - // Parameters :  
4152 - // Return Values :  
4153 - // --------------------------------------------------------------------------------  
4154 - function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)  
4155 - {  
4156 - $v_result=1;  
4157 -  
4158 - // ----- Read the file header  
4159 - $v_header = array();  
4160 - if (($v_result = $this->privReadFileHeader($v_header)) != 1)  
4161 - {  
4162 - // ----- Return  
4163 - return $v_result;  
4164 - }  
4165 -  
4166 -  
4167 - // ----- Check that the file header is coherent with $p_entry info  
4168 - if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {  
4169 - // TBC  
4170 - }  
4171 -  
4172 - // ----- Look for pre-extract callback  
4173 - if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {  
4174 -  
4175 - // ----- Generate a local information  
4176 - $v_local_header = array();  
4177 - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);  
4178 -  
4179 - // ----- Call the callback  
4180 - // Here I do not use call_user_func() because I need to send a reference to the  
4181 - // header.  
4182 -// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');  
4183 - $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);  
4184 - if ($v_result == 0) {  
4185 - // ----- Change the file status  
4186 - $p_entry['status'] = "skipped";  
4187 - $v_result = 1;  
4188 - }  
4189 -  
4190 - // ----- Look for abort result  
4191 - if ($v_result == 2) {  
4192 - // ----- This status is internal and will be changed in 'skipped'  
4193 - $p_entry['status'] = "aborted";  
4194 - $v_result = PCLZIP_ERR_USER_ABORTED;  
4195 - }  
4196 -  
4197 - // ----- Update the informations  
4198 - // Only some fields can be modified  
4199 - $p_entry['filename'] = $v_local_header['filename'];  
4200 - }  
4201 -  
4202 -  
4203 - // ----- Look if extraction should be done  
4204 - if ($p_entry['status'] == 'ok') {  
4205 -  
4206 - // ----- Do the extraction (if not a folder)  
4207 - if (!(($p_entry['external']&0x00000010)==0x00000010)) {  
4208 - // ----- Look for not compressed file  
4209 - // if ($p_entry['compressed_size'] == $p_entry['size'])  
4210 - if ($p_entry['compression'] == 0) {  
4211 -  
4212 - // ----- Reading the file  
4213 - $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);  
4214 - }  
4215 - else {  
4216 -  
4217 - // ----- Reading the file  
4218 - $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);  
4219 -  
4220 - // ----- Decompress the file  
4221 - if (($p_string = @gzinflate($v_data)) === FALSE) {  
4222 - // TBC  
4223 - }  
4224 - }  
4225 -  
4226 - // ----- Trace  
4227 - }  
4228 - else {  
4229 - // TBC : error : can not extract a folder in a string  
4230 - }  
4231 -  
4232 - }  
4233 -  
4234 - // ----- Change abort status  
4235 - if ($p_entry['status'] == "aborted") {  
4236 - $p_entry['status'] = "skipped";  
4237 - }  
4238 -  
4239 - // ----- Look for post-extract callback  
4240 - elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {  
4241 -  
4242 - // ----- Generate a local information  
4243 - $v_local_header = array();  
4244 - $this->privConvertHeader2FileInfo($p_entry, $v_local_header);  
4245 -  
4246 - // ----- Swap the content to header  
4247 - $v_local_header['content'] = $p_string;  
4248 - $p_string = '';  
4249 -  
4250 - // ----- Call the callback  
4251 - // Here I do not use call_user_func() because I need to send a reference to the  
4252 - // header.  
4253 -// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');  
4254 - $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);  
4255 -  
4256 - // ----- Swap back the content to header  
4257 - $p_string = $v_local_header['content'];  
4258 - unset($v_local_header['content']);  
4259 -  
4260 - // ----- Look for abort result  
4261 - if ($v_result == 2) {  
4262 - $v_result = PCLZIP_ERR_USER_ABORTED;  
4263 - }  
4264 - }  
4265 -  
4266 - // ----- Return  
4267 - return $v_result;  
4268 - }  
4269 - // --------------------------------------------------------------------------------  
4270 -  
4271 - // --------------------------------------------------------------------------------  
4272 - // Function : privReadFileHeader()  
4273 - // Description :  
4274 - // Parameters :  
4275 - // Return Values :  
4276 - // --------------------------------------------------------------------------------  
4277 - function privReadFileHeader(&$p_header)  
4278 - {  
4279 - $v_result=1;  
4280 -  
4281 - // ----- Read the 4 bytes signature  
4282 - $v_binary_data = @fread($this->zip_fd, 4);  
4283 - $v_data = unpack('Vid', $v_binary_data);  
4284 -  
4285 - // ----- Check signature  
4286 - if ($v_data['id'] != 0x04034b50)  
4287 - {  
4288 -  
4289 - // ----- Error log  
4290 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');  
4291 -  
4292 - // ----- Return  
4293 - return PclZip::errorCode();  
4294 - }  
4295 -  
4296 - // ----- Read the first 42 bytes of the header  
4297 - $v_binary_data = fread($this->zip_fd, 26);  
4298 -  
4299 - // ----- Look for invalid block size  
4300 - if (strlen($v_binary_data) != 26)  
4301 - {  
4302 - $p_header['filename'] = "";  
4303 - $p_header['status'] = "invalid_header";  
4304 -  
4305 - // ----- Error log  
4306 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));  
4307 -  
4308 - // ----- Return  
4309 - return PclZip::errorCode();  
4310 - }  
4311 -  
4312 - // ----- Extract the values  
4313 - $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);  
4314 -  
4315 - // ----- Get filename  
4316 - $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);  
4317 -  
4318 - // ----- Get extra_fields  
4319 - if ($v_data['extra_len'] != 0) {  
4320 - $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);  
4321 - }  
4322 - else {  
4323 - $p_header['extra'] = '';  
4324 - }  
4325 -  
4326 - // ----- Extract properties  
4327 - $p_header['version_extracted'] = $v_data['version'];  
4328 - $p_header['compression'] = $v_data['compression'];  
4329 - $p_header['size'] = $v_data['size'];  
4330 - $p_header['compressed_size'] = $v_data['compressed_size'];  
4331 - $p_header['crc'] = $v_data['crc'];  
4332 - $p_header['flag'] = $v_data['flag'];  
4333 - $p_header['filename_len'] = $v_data['filename_len'];  
4334 -  
4335 - // ----- Recuperate date in UNIX format  
4336 - $p_header['mdate'] = $v_data['mdate'];  
4337 - $p_header['mtime'] = $v_data['mtime'];  
4338 - if ($p_header['mdate'] && $p_header['mtime'])  
4339 - {  
4340 - // ----- Extract time  
4341 - $v_hour = ($p_header['mtime'] & 0xF800) >> 11;  
4342 - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;  
4343 - $v_seconde = ($p_header['mtime'] & 0x001F)*2;  
4344 -  
4345 - // ----- Extract date  
4346 - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;  
4347 - $v_month = ($p_header['mdate'] & 0x01E0) >> 5;  
4348 - $v_day = $p_header['mdate'] & 0x001F;  
4349 -  
4350 - // ----- Get UNIX date format  
4351 - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);  
4352 -  
4353 - }  
4354 - else  
4355 - {  
4356 - $p_header['mtime'] = time();  
4357 - }  
4358 -  
4359 - // TBC  
4360 - //for(reset($v_data); $key = key($v_data); next($v_data)) {  
4361 - //}  
4362 -  
4363 - // ----- Set the stored filename  
4364 - $p_header['stored_filename'] = $p_header['filename'];  
4365 -  
4366 - // ----- Set the status field  
4367 - $p_header['status'] = "ok";  
4368 -  
4369 - // ----- Return  
4370 - return $v_result;  
4371 - }  
4372 - // --------------------------------------------------------------------------------  
4373 -  
4374 - // --------------------------------------------------------------------------------  
4375 - // Function : privReadCentralFileHeader()  
4376 - // Description :  
4377 - // Parameters :  
4378 - // Return Values :  
4379 - // --------------------------------------------------------------------------------  
4380 - function privReadCentralFileHeader(&$p_header)  
4381 - {  
4382 - $v_result=1;  
4383 -  
4384 - // ----- Read the 4 bytes signature  
4385 - $v_binary_data = @fread($this->zip_fd, 4);  
4386 - $v_data = unpack('Vid', $v_binary_data);  
4387 -  
4388 - // ----- Check signature  
4389 - if ($v_data['id'] != 0x02014b50)  
4390 - {  
4391 -  
4392 - // ----- Error log  
4393 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');  
4394 -  
4395 - // ----- Return  
4396 - return PclZip::errorCode();  
4397 - }  
4398 -  
4399 - // ----- Read the first 42 bytes of the header  
4400 - $v_binary_data = fread($this->zip_fd, 42);  
4401 -  
4402 - // ----- Look for invalid block size  
4403 - if (strlen($v_binary_data) != 42)  
4404 - {  
4405 - $p_header['filename'] = "";  
4406 - $p_header['status'] = "invalid_header";  
4407 -  
4408 - // ----- Error log  
4409 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));  
4410 -  
4411 - // ----- Return  
4412 - return PclZip::errorCode();  
4413 - }  
4414 -  
4415 - // ----- Extract the values  
4416 - $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);  
4417 -  
4418 - // ----- Get filename  
4419 - if ($p_header['filename_len'] != 0)  
4420 - $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);  
4421 - else  
4422 - $p_header['filename'] = '';  
4423 -  
4424 - // ----- Get extra  
4425 - if ($p_header['extra_len'] != 0)  
4426 - $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);  
4427 - else  
4428 - $p_header['extra'] = '';  
4429 -  
4430 - // ----- Get comment  
4431 - if ($p_header['comment_len'] != 0)  
4432 - $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);  
4433 - else  
4434 - $p_header['comment'] = '';  
4435 -  
4436 - // ----- Extract properties  
4437 -  
4438 - // ----- Recuperate date in UNIX format  
4439 - //if ($p_header['mdate'] && $p_header['mtime'])  
4440 - // TBC : bug : this was ignoring time with 0/0/0  
4441 - if (1)  
4442 - {  
4443 - // ----- Extract time  
4444 - $v_hour = ($p_header['mtime'] & 0xF800) >> 11;  
4445 - $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;  
4446 - $v_seconde = ($p_header['mtime'] & 0x001F)*2;  
4447 -  
4448 - // ----- Extract date  
4449 - $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;  
4450 - $v_month = ($p_header['mdate'] & 0x01E0) >> 5;  
4451 - $v_day = $p_header['mdate'] & 0x001F;  
4452 -  
4453 - // ----- Get UNIX date format  
4454 - $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);  
4455 -  
4456 - }  
4457 - else  
4458 - {  
4459 - $p_header['mtime'] = time();  
4460 - }  
4461 -  
4462 - // ----- Set the stored filename  
4463 - $p_header['stored_filename'] = $p_header['filename'];  
4464 -  
4465 - // ----- Set default status to ok  
4466 - $p_header['status'] = 'ok';  
4467 -  
4468 - // ----- Look if it is a directory  
4469 - if (substr($p_header['filename'], -1) == '/') {  
4470 - //$p_header['external'] = 0x41FF0010;  
4471 - $p_header['external'] = 0x00000010;  
4472 - }  
4473 -  
4474 -  
4475 - // ----- Return  
4476 - return $v_result;  
4477 - }  
4478 - // --------------------------------------------------------------------------------  
4479 -  
4480 - // --------------------------------------------------------------------------------  
4481 - // Function : privCheckFileHeaders()  
4482 - // Description :  
4483 - // Parameters :  
4484 - // Return Values :  
4485 - // 1 on success,  
4486 - // 0 on error;  
4487 - // --------------------------------------------------------------------------------  
4488 - function privCheckFileHeaders(&$p_local_header, &$p_central_header)  
4489 - {  
4490 - $v_result=1;  
4491 -  
4492 - // ----- Check the static values  
4493 - // TBC  
4494 - if ($p_local_header['filename'] != $p_central_header['filename']) {  
4495 - }  
4496 - if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {  
4497 - }  
4498 - if ($p_local_header['flag'] != $p_central_header['flag']) {  
4499 - }  
4500 - if ($p_local_header['compression'] != $p_central_header['compression']) {  
4501 - }  
4502 - if ($p_local_header['mtime'] != $p_central_header['mtime']) {  
4503 - }  
4504 - if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {  
4505 - }  
4506 -  
4507 - // ----- Look for flag bit 3  
4508 - if (($p_local_header['flag'] & 8) == 8) {  
4509 - $p_local_header['size'] = $p_central_header['size'];  
4510 - $p_local_header['compressed_size'] = $p_central_header['compressed_size'];  
4511 - $p_local_header['crc'] = $p_central_header['crc'];  
4512 - }  
4513 -  
4514 - // ----- Return  
4515 - return $v_result;  
4516 - }  
4517 - // --------------------------------------------------------------------------------  
4518 -  
4519 - // --------------------------------------------------------------------------------  
4520 - // Function : privReadEndCentralDir()  
4521 - // Description :  
4522 - // Parameters :  
4523 - // Return Values :  
4524 - // --------------------------------------------------------------------------------  
4525 - function privReadEndCentralDir(&$p_central_dir)  
4526 - {  
4527 - $v_result=1;  
4528 -  
4529 - // ----- Go to the end of the zip file  
4530 - $v_size = filesize($this->zipname);  
4531 - @fseek($this->zip_fd, $v_size);  
4532 - if (@ftell($this->zip_fd) != $v_size)  
4533 - {  
4534 - // ----- Error log  
4535 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');  
4536 -  
4537 - // ----- Return  
4538 - return PclZip::errorCode();  
4539 - }  
4540 -  
4541 - // ----- First try : look if this is an archive with no commentaries (most of the time)  
4542 - // in this case the end of central dir is at 22 bytes of the file end  
4543 - $v_found = 0;  
4544 - if ($v_size > 26) {  
4545 - @fseek($this->zip_fd, $v_size-22);  
4546 - if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))  
4547 - {  
4548 - // ----- Error log  
4549 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');  
4550 -  
4551 - // ----- Return  
4552 - return PclZip::errorCode();  
4553 - }  
4554 -  
4555 - // ----- Read for bytes  
4556 - $v_binary_data = @fread($this->zip_fd, 4);  
4557 - $v_data = @unpack('Vid', $v_binary_data);  
4558 -  
4559 - // ----- Check signature  
4560 - if ($v_data['id'] == 0x06054b50) {  
4561 - $v_found = 1;  
4562 - }  
4563 -  
4564 - $v_pos = ftell($this->zip_fd);  
4565 - }  
4566 -  
4567 - // ----- Go back to the maximum possible size of the Central Dir End Record  
4568 - if (!$v_found) {  
4569 - $v_maximum_size = 65557; // 0xFFFF + 22;  
4570 - if ($v_maximum_size > $v_size)  
4571 - $v_maximum_size = $v_size;  
4572 - @fseek($this->zip_fd, $v_size-$v_maximum_size);  
4573 - if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))  
4574 - {  
4575 - // ----- Error log  
4576 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');  
4577 -  
4578 - // ----- Return  
4579 - return PclZip::errorCode();  
4580 - }  
4581 -  
4582 - // ----- Read byte per byte in order to find the signature  
4583 - $v_pos = ftell($this->zip_fd);  
4584 - $v_bytes = 0x00000000;  
4585 - while ($v_pos < $v_size)  
4586 - {  
4587 - // ----- Read a byte  
4588 - $v_byte = @fread($this->zip_fd, 1);  
4589 -  
4590 - // ----- Add the byte  
4591 - //$v_bytes = ($v_bytes << 8) | Ord($v_byte);  
4592 - // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number  
4593 - // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.  
4594 - $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);  
4595 -  
4596 - // ----- Compare the bytes  
4597 - if ($v_bytes == 0x504b0506)  
4598 - {  
4599 - $v_pos++;  
4600 - break;  
4601 - }  
4602 -  
4603 - $v_pos++;  
4604 - }  
4605 -  
4606 - // ----- Look if not found end of central dir  
4607 - if ($v_pos == $v_size)  
4608 - {  
4609 -  
4610 - // ----- Error log  
4611 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");  
4612 -  
4613 - // ----- Return  
4614 - return PclZip::errorCode();  
4615 - }  
4616 - }  
4617 -  
4618 - // ----- Read the first 18 bytes of the header  
4619 - $v_binary_data = fread($this->zip_fd, 18);  
4620 -  
4621 - // ----- Look for invalid block size  
4622 - if (strlen($v_binary_data) != 18)  
4623 - {  
4624 -  
4625 - // ----- Error log  
4626 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));  
4627 -  
4628 - // ----- Return  
4629 - return PclZip::errorCode();  
4630 - }  
4631 -  
4632 - // ----- Extract the values  
4633 - $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);  
4634 -  
4635 - // ----- Check the global size  
4636 - if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {  
4637 -  
4638 - // ----- Removed in release 2.2 see readme file  
4639 - // The check of the file size is a little too strict.  
4640 - // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.  
4641 - // While decrypted, zip has training 0 bytes  
4642 - if (0) {  
4643 - // ----- Error log  
4644 - PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,  
4645 - 'The central dir is not at the end of the archive.'  
4646 - .' Some trailing bytes exists after the archive.');  
4647 -  
4648 - // ----- Return  
4649 - return PclZip::errorCode();  
4650 - }  
4651 - }  
4652 -  
4653 - // ----- Get comment  
4654 - if ($v_data['comment_size'] != 0) {  
4655 - $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);  
4656 - }  
4657 - else  
4658 - $p_central_dir['comment'] = '';  
4659 -  
4660 - $p_central_dir['entries'] = $v_data['entries'];  
4661 - $p_central_dir['disk_entries'] = $v_data['disk_entries'];  
4662 - $p_central_dir['offset'] = $v_data['offset'];  
4663 - $p_central_dir['size'] = $v_data['size'];  
4664 - $p_central_dir['disk'] = $v_data['disk'];  
4665 - $p_central_dir['disk_start'] = $v_data['disk_start'];  
4666 -  
4667 - // TBC  
4668 - //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {  
4669 - //}  
4670 -  
4671 - // ----- Return  
4672 - return $v_result;  
4673 - }  
4674 - // --------------------------------------------------------------------------------  
4675 -  
4676 - // --------------------------------------------------------------------------------  
4677 - // Function : privDeleteByRule()  
4678 - // Description :  
4679 - // Parameters :  
4680 - // Return Values :  
4681 - // --------------------------------------------------------------------------------  
4682 - function privDeleteByRule(&$p_result_list, &$p_options)  
4683 - {  
4684 - $v_result=1;  
4685 - $v_list_detail = array();  
4686 -  
4687 - // ----- Open the zip file  
4688 - if (($v_result=$this->privOpenFd('rb')) != 1)  
4689 - {  
4690 - // ----- Return  
4691 - return $v_result;  
4692 - }  
4693 -  
4694 - // ----- Read the central directory informations  
4695 - $v_central_dir = array();  
4696 - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)  
4697 - {  
4698 - $this->privCloseFd();  
4699 - return $v_result;  
4700 - }  
4701 -  
4702 - // ----- Go to beginning of File  
4703 - @rewind($this->zip_fd);  
4704 -  
4705 - // ----- Scan all the files  
4706 - // ----- Start at beginning of Central Dir  
4707 - $v_pos_entry = $v_central_dir['offset'];  
4708 - @rewind($this->zip_fd);  
4709 - if (@fseek($this->zip_fd, $v_pos_entry))  
4710 - {  
4711 - // ----- Close the zip file  
4712 - $this->privCloseFd();  
4713 -  
4714 - // ----- Error log  
4715 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');  
4716 -  
4717 - // ----- Return  
4718 - return PclZip::errorCode();  
4719 - }  
4720 -  
4721 - // ----- Read each entry  
4722 - $v_header_list = array();  
4723 - $j_start = 0;  
4724 - for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)  
4725 - {  
4726 -  
4727 - // ----- Read the file header  
4728 - $v_header_list[$v_nb_extracted] = array();  
4729 - if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)  
4730 - {  
4731 - // ----- Close the zip file  
4732 - $this->privCloseFd();  
4733 -  
4734 - return $v_result;  
4735 - }  
4736 -  
4737 -  
4738 - // ----- Store the index  
4739 - $v_header_list[$v_nb_extracted]['index'] = $i;  
4740 -  
4741 - // ----- Look for the specific extract rules  
4742 - $v_found = false;  
4743 -  
4744 - // ----- Look for extract by name rule  
4745 - if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))  
4746 - && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {  
4747 -  
4748 - // ----- Look if the filename is in the list  
4749 - for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {  
4750 -  
4751 - // ----- Look for a directory  
4752 - if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {  
4753 -  
4754 - // ----- Look if the directory is in the filename path  
4755 - if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))  
4756 - && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {  
4757 - $v_found = true;  
4758 - }  
4759 - elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */  
4760 - && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {  
4761 - $v_found = true;  
4762 - }  
4763 - }  
4764 - // ----- Look for a filename  
4765 - elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {  
4766 - $v_found = true;  
4767 - }  
4768 - }  
4769 - }  
4770 -  
4771 - // ----- Look for extract by ereg rule  
4772 - // ereg() is deprecated with PHP 5.3  
4773 - /*  
4774 - else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))  
4775 - && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {  
4776 -  
4777 - if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {  
4778 - $v_found = true;  
4779 - }  
4780 - }  
4781 - */  
4782 -  
4783 - // ----- Look for extract by preg rule  
4784 - else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))  
4785 - && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {  
4786 -  
4787 - if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {  
4788 - $v_found = true;  
4789 - }  
4790 - }  
4791 -  
4792 - // ----- Look for extract by index rule  
4793 - else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))  
4794 - && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {  
4795 -  
4796 - // ----- Look if the index is in the list  
4797 - for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {  
4798 -  
4799 - if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {  
4800 - $v_found = true;  
4801 - }  
4802 - if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {  
4803 - $j_start = $j+1;  
4804 - }  
4805 -  
4806 - if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {  
4807 - break;  
4808 - }  
4809 - }  
4810 - }  
4811 - else {  
4812 - $v_found = true;  
4813 - }  
4814 -  
4815 - // ----- Look for deletion  
4816 - if ($v_found)  
4817 - {  
4818 - unset($v_header_list[$v_nb_extracted]);  
4819 - }  
4820 - else  
4821 - {  
4822 - $v_nb_extracted++;  
4823 - }  
4824 - }  
4825 -  
4826 - // ----- Look if something need to be deleted  
4827 - if ($v_nb_extracted > 0) {  
4828 -  
4829 - // ----- Creates a temporay file  
4830 - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';  
4831 -  
4832 - // ----- Creates a temporary zip archive  
4833 - $v_temp_zip = new PclZip($v_zip_temp_name);  
4834 -  
4835 - // ----- Open the temporary zip file in write mode  
4836 - if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {  
4837 - $this->privCloseFd();  
4838 -  
4839 - // ----- Return  
4840 - return $v_result;  
4841 - }  
4842 -  
4843 - // ----- Look which file need to be kept  
4844 - for ($i=0; $i<sizeof($v_header_list); $i++) {  
4845 -  
4846 - // ----- Calculate the position of the header  
4847 - @rewind($this->zip_fd);  
4848 - if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {  
4849 - // ----- Close the zip file  
4850 - $this->privCloseFd();  
4851 - $v_temp_zip->privCloseFd();  
4852 - @unlink($v_zip_temp_name);  
4853 -  
4854 - // ----- Error log  
4855 - PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');  
4856 -  
4857 - // ----- Return  
4858 - return PclZip::errorCode();  
4859 - }  
4860 -  
4861 - // ----- Read the file header  
4862 - $v_local_header = array();  
4863 - if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {  
4864 - // ----- Close the zip file  
4865 - $this->privCloseFd();  
4866 - $v_temp_zip->privCloseFd();  
4867 - @unlink($v_zip_temp_name);  
4868 -  
4869 - // ----- Return  
4870 - return $v_result;  
4871 - }  
4872 -  
4873 - // ----- Check that local file header is same as central file header  
4874 - if ($this->privCheckFileHeaders($v_local_header,  
4875 - $v_header_list[$i]) != 1) {  
4876 - // TBC  
4877 - }  
4878 - unset($v_local_header);  
4879 -  
4880 - // ----- Write the file header  
4881 - if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {  
4882 - // ----- Close the zip file  
4883 - $this->privCloseFd();  
4884 - $v_temp_zip->privCloseFd();  
4885 - @unlink($v_zip_temp_name);  
4886 -  
4887 - // ----- Return  
4888 - return $v_result;  
4889 - }  
4890 -  
4891 - // ----- Read/write the data block  
4892 - if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {  
4893 - // ----- Close the zip file  
4894 - $this->privCloseFd();  
4895 - $v_temp_zip->privCloseFd();  
4896 - @unlink($v_zip_temp_name);  
4897 -  
4898 - // ----- Return  
4899 - return $v_result;  
4900 - }  
4901 - }  
4902 -  
4903 - // ----- Store the offset of the central dir  
4904 - $v_offset = @ftell($v_temp_zip->zip_fd);  
4905 -  
4906 - // ----- Re-Create the Central Dir files header  
4907 - for ($i=0; $i<sizeof($v_header_list); $i++) {  
4908 - // ----- Create the file header  
4909 - if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {  
4910 - $v_temp_zip->privCloseFd();  
4911 - $this->privCloseFd();  
4912 - @unlink($v_zip_temp_name);  
4913 -  
4914 - // ----- Return  
4915 - return $v_result;  
4916 - }  
4917 -  
4918 - // ----- Transform the header to a 'usable' info  
4919 - $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);  
4920 - }  
4921 -  
4922 -  
4923 - // ----- Zip file comment  
4924 - $v_comment = '';  
4925 - if (isset($p_options[PCLZIP_OPT_COMMENT])) {  
4926 - $v_comment = $p_options[PCLZIP_OPT_COMMENT];  
4927 - }  
4928 -  
4929 - // ----- Calculate the size of the central header  
4930 - $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;  
4931 -  
4932 - // ----- Create the central dir footer  
4933 - if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {  
4934 - // ----- Reset the file list  
4935 - unset($v_header_list);  
4936 - $v_temp_zip->privCloseFd();  
4937 - $this->privCloseFd();  
4938 - @unlink($v_zip_temp_name);  
4939 -  
4940 - // ----- Return  
4941 - return $v_result;  
4942 - }  
4943 -  
4944 - // ----- Close  
4945 - $v_temp_zip->privCloseFd();  
4946 - $this->privCloseFd();  
4947 -  
4948 - // ----- Delete the zip file  
4949 - // TBC : I should test the result ...  
4950 - @unlink($this->zipname);  
4951 -  
4952 - // ----- Rename the temporary file  
4953 - // TBC : I should test the result ...  
4954 - //@rename($v_zip_temp_name, $this->zipname);  
4955 - PclZipUtilRename($v_zip_temp_name, $this->zipname);  
4956 -  
4957 - // ----- Destroy the temporary archive  
4958 - unset($v_temp_zip);  
4959 - }  
4960 -  
4961 - // ----- Remove every files : reset the file  
4962 - else if ($v_central_dir['entries'] != 0) {  
4963 - $this->privCloseFd();  
4964 -  
4965 - if (($v_result = $this->privOpenFd('wb')) != 1) {  
4966 - return $v_result;  
4967 - }  
4968 -  
4969 - if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {  
4970 - return $v_result;  
4971 - }  
4972 -  
4973 - $this->privCloseFd();  
4974 - }  
4975 -  
4976 - // ----- Return  
4977 - return $v_result;  
4978 - }  
4979 - // --------------------------------------------------------------------------------  
4980 -  
4981 - // --------------------------------------------------------------------------------  
4982 - // Function : privDirCheck()  
4983 - // Description :  
4984 - // Check if a directory exists, if not it creates it and all the parents directory  
4985 - // which may be useful.  
4986 - // Parameters :  
4987 - // $p_dir : Directory path to check.  
4988 - // Return Values :  
4989 - // 1 : OK  
4990 - // -1 : Unable to create directory  
4991 - // --------------------------------------------------------------------------------  
4992 - function privDirCheck($p_dir, $p_is_dir=false)  
4993 - {  
4994 - $v_result = 1;  
4995 -  
4996 -  
4997 - // ----- Remove the final '/'  
4998 - if (($p_is_dir) && (substr($p_dir, -1)=='/'))  
4999 - {  
5000 - $p_dir = substr($p_dir, 0, strlen($p_dir)-1);  
5001 - }  
5002 -  
5003 - // ----- Check the directory availability  
5004 - if ((is_dir($p_dir)) || ($p_dir == ""))  
5005 - {  
5006 - return 1;  
5007 - }  
5008 -  
5009 - // ----- Extract parent directory  
5010 - $p_parent_dir = dirname($p_dir);  
5011 -  
5012 - // ----- Just a check  
5013 - if ($p_parent_dir != $p_dir)  
5014 - {  
5015 - // ----- Look for parent directory  
5016 - if ($p_parent_dir != "")  
5017 - {  
5018 - if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)  
5019 - {  
5020 - return $v_result;  
5021 - }  
5022 - }  
5023 - }  
5024 -  
5025 - // ----- Create the directory  
5026 - if (!@mkdir($p_dir, 0777))  
5027 - {  
5028 - // ----- Error log  
5029 - PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");  
5030 -  
5031 - // ----- Return  
5032 - return PclZip::errorCode();  
5033 - }  
5034 -  
5035 - // ----- Return  
5036 - return $v_result;  
5037 - }  
5038 - // --------------------------------------------------------------------------------  
5039 -  
5040 - // --------------------------------------------------------------------------------  
5041 - // Function : privMerge()  
5042 - // Description :  
5043 - // If $p_archive_to_add does not exist, the function exit with a success result.  
5044 - // Parameters :  
5045 - // Return Values :  
5046 - // --------------------------------------------------------------------------------  
5047 - function privMerge(&$p_archive_to_add)  
5048 - {  
5049 - $v_result=1;  
5050 -  
5051 - // ----- Look if the archive_to_add exists  
5052 - if (!is_file($p_archive_to_add->zipname))  
5053 - {  
5054 -  
5055 - // ----- Nothing to merge, so merge is a success  
5056 - $v_result = 1;  
5057 -  
5058 - // ----- Return  
5059 - return $v_result;  
5060 - }  
5061 -  
5062 - // ----- Look if the archive exists  
5063 - if (!is_file($this->zipname))  
5064 - {  
5065 -  
5066 - // ----- Do a duplicate  
5067 - $v_result = $this->privDuplicate($p_archive_to_add->zipname);  
5068 -  
5069 - // ----- Return  
5070 - return $v_result;  
5071 - }  
5072 -  
5073 - // ----- Open the zip file  
5074 - if (($v_result=$this->privOpenFd('rb')) != 1)  
5075 - {  
5076 - // ----- Return  
5077 - return $v_result;  
5078 - }  
5079 -  
5080 - // ----- Read the central directory informations  
5081 - $v_central_dir = array();  
5082 - if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)  
5083 - {  
5084 - $this->privCloseFd();  
5085 - return $v_result;  
5086 - }  
5087 -  
5088 - // ----- Go to beginning of File  
5089 - @rewind($this->zip_fd);  
5090 -  
5091 - // ----- Open the archive_to_add file  
5092 - if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)  
5093 - {  
5094 - $this->privCloseFd();  
5095 -  
5096 - // ----- Return  
5097 - return $v_result;  
5098 - }  
5099 -  
5100 - // ----- Read the central directory informations  
5101 - $v_central_dir_to_add = array();  
5102 - if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)  
5103 - {  
5104 - $this->privCloseFd();  
5105 - $p_archive_to_add->privCloseFd();  
5106 -  
5107 - return $v_result;  
5108 - }  
5109 -  
5110 - // ----- Go to beginning of File  
5111 - @rewind($p_archive_to_add->zip_fd);  
5112 -  
5113 - // ----- Creates a temporay file  
5114 - $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';  
5115 -  
5116 - // ----- Open the temporary file in write mode  
5117 - if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)  
5118 - {  
5119 - $this->privCloseFd();  
5120 - $p_archive_to_add->privCloseFd();  
5121 -  
5122 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');  
5123 -  
5124 - // ----- Return  
5125 - return PclZip::errorCode();  
5126 - }  
5127 -  
5128 - // ----- Copy the files from the archive to the temporary file  
5129 - // TBC : Here I should better append the file and go back to erase the central dir  
5130 - $v_size = $v_central_dir['offset'];  
5131 - while ($v_size != 0)  
5132 - {  
5133 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
5134 - $v_buffer = fread($this->zip_fd, $v_read_size);  
5135 - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);  
5136 - $v_size -= $v_read_size;  
5137 - }  
5138 -  
5139 - // ----- Copy the files from the archive_to_add into the temporary file  
5140 - $v_size = $v_central_dir_to_add['offset'];  
5141 - while ($v_size != 0)  
5142 - {  
5143 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
5144 - $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);  
5145 - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);  
5146 - $v_size -= $v_read_size;  
5147 - }  
5148 -  
5149 - // ----- Store the offset of the central dir  
5150 - $v_offset = @ftell($v_zip_temp_fd);  
5151 -  
5152 - // ----- Copy the block of file headers from the old archive  
5153 - $v_size = $v_central_dir['size'];  
5154 - while ($v_size != 0)  
5155 - {  
5156 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
5157 - $v_buffer = @fread($this->zip_fd, $v_read_size);  
5158 - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);  
5159 - $v_size -= $v_read_size;  
5160 - }  
5161 -  
5162 - // ----- Copy the block of file headers from the archive_to_add  
5163 - $v_size = $v_central_dir_to_add['size'];  
5164 - while ($v_size != 0)  
5165 - {  
5166 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
5167 - $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);  
5168 - @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);  
5169 - $v_size -= $v_read_size;  
5170 - }  
5171 -  
5172 - // ----- Merge the file comments  
5173 - $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];  
5174 -  
5175 - // ----- Calculate the size of the (new) central header  
5176 - $v_size = @ftell($v_zip_temp_fd)-$v_offset;  
5177 -  
5178 - // ----- Swap the file descriptor  
5179 - // Here is a trick : I swap the temporary fd with the zip fd, in order to use  
5180 - // the following methods on the temporary fil and not the real archive fd  
5181 - $v_swap = $this->zip_fd;  
5182 - $this->zip_fd = $v_zip_temp_fd;  
5183 - $v_zip_temp_fd = $v_swap;  
5184 -  
5185 - // ----- Create the central dir footer  
5186 - if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)  
5187 - {  
5188 - $this->privCloseFd();  
5189 - $p_archive_to_add->privCloseFd();  
5190 - @fclose($v_zip_temp_fd);  
5191 - $this->zip_fd = null;  
5192 -  
5193 - // ----- Reset the file list  
5194 - unset($v_header_list);  
5195 -  
5196 - // ----- Return  
5197 - return $v_result;  
5198 - }  
5199 -  
5200 - // ----- Swap back the file descriptor  
5201 - $v_swap = $this->zip_fd;  
5202 - $this->zip_fd = $v_zip_temp_fd;  
5203 - $v_zip_temp_fd = $v_swap;  
5204 -  
5205 - // ----- Close  
5206 - $this->privCloseFd();  
5207 - $p_archive_to_add->privCloseFd();  
5208 -  
5209 - // ----- Close the temporary file  
5210 - @fclose($v_zip_temp_fd);  
5211 -  
5212 - // ----- Delete the zip file  
5213 - // TBC : I should test the result ...  
5214 - @unlink($this->zipname);  
5215 -  
5216 - // ----- Rename the temporary file  
5217 - // TBC : I should test the result ...  
5218 - //@rename($v_zip_temp_name, $this->zipname);  
5219 - PclZipUtilRename($v_zip_temp_name, $this->zipname);  
5220 -  
5221 - // ----- Return  
5222 - return $v_result;  
5223 - }  
5224 - // --------------------------------------------------------------------------------  
5225 -  
5226 - // --------------------------------------------------------------------------------  
5227 - // Function : privDuplicate()  
5228 - // Description :  
5229 - // Parameters :  
5230 - // Return Values :  
5231 - // --------------------------------------------------------------------------------  
5232 - function privDuplicate($p_archive_filename)  
5233 - {  
5234 - $v_result=1;  
5235 -  
5236 - // ----- Look if the $p_archive_filename exists  
5237 - if (!is_file($p_archive_filename))  
5238 - {  
5239 -  
5240 - // ----- Nothing to duplicate, so duplicate is a success.  
5241 - $v_result = 1;  
5242 -  
5243 - // ----- Return  
5244 - return $v_result;  
5245 - }  
5246 -  
5247 - // ----- Open the zip file  
5248 - if (($v_result=$this->privOpenFd('wb')) != 1)  
5249 - {  
5250 - // ----- Return  
5251 - return $v_result;  
5252 - }  
5253 -  
5254 - // ----- Open the temporary file in write mode  
5255 - if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)  
5256 - {  
5257 - $this->privCloseFd();  
5258 -  
5259 - PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');  
5260 -  
5261 - // ----- Return  
5262 - return PclZip::errorCode();  
5263 - }  
5264 -  
5265 - // ----- Copy the files from the archive to the temporary file  
5266 - // TBC : Here I should better append the file and go back to erase the central dir  
5267 - $v_size = filesize($p_archive_filename);  
5268 - while ($v_size != 0)  
5269 - {  
5270 - $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);  
5271 - $v_buffer = fread($v_zip_temp_fd, $v_read_size);  
5272 - @fwrite($this->zip_fd, $v_buffer, $v_read_size);  
5273 - $v_size -= $v_read_size;  
5274 - }  
5275 -  
5276 - // ----- Close  
5277 - $this->privCloseFd();  
5278 -  
5279 - // ----- Close the temporary file  
5280 - @fclose($v_zip_temp_fd);  
5281 -  
5282 - // ----- Return  
5283 - return $v_result;  
5284 - }  
5285 - // --------------------------------------------------------------------------------  
5286 -  
5287 - // --------------------------------------------------------------------------------  
5288 - // Function : privErrorLog()  
5289 - // Description :  
5290 - // Parameters :  
5291 - // --------------------------------------------------------------------------------  
5292 - function privErrorLog($p_error_code=0, $p_error_string='')  
5293 - {  
5294 - if (PCLZIP_ERROR_EXTERNAL == 1) {  
5295 - PclError($p_error_code, $p_error_string);  
5296 - }  
5297 - else {  
5298 - $this->error_code = $p_error_code;  
5299 - $this->error_string = $p_error_string;  
5300 - }  
5301 - }  
5302 - // --------------------------------------------------------------------------------  
5303 -  
5304 - // --------------------------------------------------------------------------------  
5305 - // Function : privErrorReset()  
5306 - // Description :  
5307 - // Parameters :  
5308 - // --------------------------------------------------------------------------------  
5309 - function privErrorReset()  
5310 - {  
5311 - if (PCLZIP_ERROR_EXTERNAL == 1) {  
5312 - PclErrorReset();  
5313 - }  
5314 - else {  
5315 - $this->error_code = 0;  
5316 - $this->error_string = '';  
5317 - }  
5318 - }  
5319 - // --------------------------------------------------------------------------------  
5320 -  
5321 - // --------------------------------------------------------------------------------  
5322 - // Function : privDisableMagicQuotes()  
5323 - // Description :  
5324 - // Parameters :  
5325 - // Return Values :  
5326 - // --------------------------------------------------------------------------------  
5327 - function privDisableMagicQuotes()  
5328 - {  
5329 - $v_result=1;  
5330 -  
5331 - // ----- Look if function exists  
5332 - if ( (!function_exists("get_magic_quotes_runtime"))  
5333 - || (!function_exists("set_magic_quotes_runtime"))) {  
5334 - return $v_result;  
5335 - }  
5336 -  
5337 - // ----- Look if already done  
5338 - if ($this->magic_quotes_status != -1) {  
5339 - return $v_result;  
5340 - }  
5341 -  
5342 - // ----- Get and memorize the magic_quote value  
5343 - $this->magic_quotes_status = @get_magic_quotes_runtime();  
5344 -  
5345 - // ----- Disable magic_quotes  
5346 - if ($this->magic_quotes_status == 1) {  
5347 - @set_magic_quotes_runtime(0);  
5348 - }  
5349 -  
5350 - // ----- Return  
5351 - return $v_result;  
5352 - }  
5353 - // --------------------------------------------------------------------------------  
5354 -  
5355 - // --------------------------------------------------------------------------------  
5356 - // Function : privSwapBackMagicQuotes()  
5357 - // Description :  
5358 - // Parameters :  
5359 - // Return Values :  
5360 - // --------------------------------------------------------------------------------  
5361 - function privSwapBackMagicQuotes()  
5362 - {  
5363 - $v_result=1;  
5364 -  
5365 - // ----- Look if function exists  
5366 - if ( (!function_exists("get_magic_quotes_runtime"))  
5367 - || (!function_exists("set_magic_quotes_runtime"))) {  
5368 - return $v_result;  
5369 - }  
5370 -  
5371 - // ----- Look if something to do  
5372 - if ($this->magic_quotes_status != -1) {  
5373 - return $v_result;  
5374 - }  
5375 -  
5376 - // ----- Swap back magic_quotes  
5377 - if ($this->magic_quotes_status == 1) {  
5378 - @set_magic_quotes_runtime($this->magic_quotes_status);  
5379 - }  
5380 -  
5381 - // ----- Return  
5382 - return $v_result;  
5383 - }  
5384 - // --------------------------------------------------------------------------------  
5385 -  
5386 - }  
5387 - // End of class  
5388 - // --------------------------------------------------------------------------------  
5389 -  
5390 - // --------------------------------------------------------------------------------  
5391 - // Function : PclZipUtilPathReduction()  
5392 - // Description :  
5393 - // Parameters :  
5394 - // Return Values :  
5395 - // --------------------------------------------------------------------------------  
5396 - function PclZipUtilPathReduction($p_dir)  
5397 - {  
5398 - $v_result = "";  
5399 -  
5400 - // ----- Look for not empty path  
5401 - if ($p_dir != "") {  
5402 - // ----- Explode path by directory names  
5403 - $v_list = explode("/", $p_dir);  
5404 -  
5405 - // ----- Study directories from last to first  
5406 - $v_skip = 0;  
5407 - for ($i=sizeof($v_list)-1; $i>=0; $i--) {  
5408 - // ----- Look for current path  
5409 - if ($v_list[$i] == ".") {  
5410 - // ----- Ignore this directory  
5411 - // Should be the first $i=0, but no check is done  
5412 - }  
5413 - else if ($v_list[$i] == "..") {  
5414 - $v_skip++;  
5415 - }  
5416 - else if ($v_list[$i] == "") {  
5417 - // ----- First '/' i.e. root slash  
5418 - if ($i == 0) {  
5419 - $v_result = "/".$v_result;  
5420 - if ($v_skip > 0) {  
5421 - // ----- It is an invalid path, so the path is not modified  
5422 - // TBC  
5423 - $v_result = $p_dir;  
5424 - $v_skip = 0;  
5425 - }  
5426 - }  
5427 - // ----- Last '/' i.e. indicates a directory  
5428 - else if ($i == (sizeof($v_list)-1)) {  
5429 - $v_result = $v_list[$i];  
5430 - }  
5431 - // ----- Double '/' inside the path  
5432 - else {  
5433 - // ----- Ignore only the double '//' in path,  
5434 - // but not the first and last '/'  
5435 - }  
5436 - }  
5437 - else {  
5438 - // ----- Look for item to skip  
5439 - if ($v_skip > 0) {  
5440 - $v_skip--;  
5441 - }  
5442 - else {  
5443 - $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");  
5444 - }  
5445 - }  
5446 - }  
5447 -  
5448 - // ----- Look for skip  
5449 - if ($v_skip > 0) {  
5450 - while ($v_skip > 0) {  
5451 - $v_result = '../'.$v_result;  
5452 - $v_skip--;  
5453 - }  
5454 - }  
5455 - }  
5456 -  
5457 - // ----- Return  
5458 - return $v_result;  
5459 - }  
5460 - // --------------------------------------------------------------------------------  
5461 -  
5462 - // --------------------------------------------------------------------------------  
5463 - // Function : PclZipUtilPathInclusion()  
5464 - // Description :  
5465 - // This function indicates if the path $p_path is under the $p_dir tree. Or,  
5466 - // said in an other way, if the file or sub-dir $p_path is inside the dir  
5467 - // $p_dir.  
5468 - // The function indicates also if the path is exactly the same as the dir.  
5469 - // This function supports path with duplicated '/' like '//', but does not  
5470 - // support '.' or '..' statements.  
5471 - // Parameters :  
5472 - // Return Values :  
5473 - // 0 if $p_path is not inside directory $p_dir  
5474 - // 1 if $p_path is inside directory $p_dir  
5475 - // 2 if $p_path is exactly the same as $p_dir  
5476 - // --------------------------------------------------------------------------------  
5477 - function PclZipUtilPathInclusion($p_dir, $p_path)  
5478 - {  
5479 - $v_result = 1;  
5480 -  
5481 - // ----- Look for path beginning by ./  
5482 - if ( ($p_dir == '.')  
5483 - || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {  
5484 - $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);  
5485 - }  
5486 - if ( ($p_path == '.')  
5487 - || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {  
5488 - $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);  
5489 - }  
5490 -  
5491 - // ----- Explode dir and path by directory separator  
5492 - $v_list_dir = explode("/", $p_dir);  
5493 - $v_list_dir_size = sizeof($v_list_dir);  
5494 - $v_list_path = explode("/", $p_path);  
5495 - $v_list_path_size = sizeof($v_list_path);  
5496 -  
5497 - // ----- Study directories paths  
5498 - $i = 0;  
5499 - $j = 0;  
5500 - while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {  
5501 -  
5502 - // ----- Look for empty dir (path reduction)  
5503 - if ($v_list_dir[$i] == '') {  
5504 - $i++;  
5505 - continue;  
5506 - }  
5507 - if ($v_list_path[$j] == '') {  
5508 - $j++;  
5509 - continue;  
5510 - }  
5511 -  
5512 - // ----- Compare the items  
5513 - if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {  
5514 - $v_result = 0;  
5515 - }  
5516 -  
5517 - // ----- Next items  
5518 - $i++;  
5519 - $j++;  
5520 - }  
5521 -  
5522 - // ----- Look if everything seems to be the same  
5523 - if ($v_result) {  
5524 - // ----- Skip all the empty items  
5525 - while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;  
5526 - while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;  
5527 -  
5528 - if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {  
5529 - // ----- There are exactly the same  
5530 - $v_result = 2;  
5531 - }  
5532 - else if ($i < $v_list_dir_size) {  
5533 - // ----- The path is shorter than the dir  
5534 - $v_result = 0;  
5535 - }  
5536 - }  
5537 -  
5538 - // ----- Return  
5539 - return $v_result;  
5540 - }  
5541 - // --------------------------------------------------------------------------------  
5542 -  
5543 - // --------------------------------------------------------------------------------  
5544 - // Function : PclZipUtilCopyBlock()  
5545 - // Description :  
5546 - // Parameters :  
5547 - // $p_mode : read/write compression mode  
5548 - // 0 : src & dest normal  
5549 - // 1 : src gzip, dest normal  
5550 - // 2 : src normal, dest gzip  
5551 - // 3 : src & dest gzip  
5552 - // Return Values :  
5553 - // --------------------------------------------------------------------------------  
5554 - function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)  
5555 - {  
5556 - $v_result = 1;  
5557 -  
5558 - if ($p_mode==0)  
5559 - {  
5560 - while ($p_size != 0)  
5561 - {  
5562 - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);  
5563 - $v_buffer = @fread($p_src, $v_read_size);  
5564 - @fwrite($p_dest, $v_buffer, $v_read_size);  
5565 - $p_size -= $v_read_size;  
5566 - }  
5567 - }  
5568 - else if ($p_mode==1)  
5569 - {  
5570 - while ($p_size != 0)  
5571 - {  
5572 - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);  
5573 - $v_buffer = @gzread($p_src, $v_read_size);  
5574 - @fwrite($p_dest, $v_buffer, $v_read_size);  
5575 - $p_size -= $v_read_size;  
5576 - }  
5577 - }  
5578 - else if ($p_mode==2)  
5579 - {  
5580 - while ($p_size != 0)  
5581 - {  
5582 - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);  
5583 - $v_buffer = @fread($p_src, $v_read_size);  
5584 - @gzwrite($p_dest, $v_buffer, $v_read_size);  
5585 - $p_size -= $v_read_size;  
5586 - }  
5587 - }  
5588 - else if ($p_mode==3)  
5589 - {  
5590 - while ($p_size != 0)  
5591 - {  
5592 - $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);  
5593 - $v_buffer = @gzread($p_src, $v_read_size);  
5594 - @gzwrite($p_dest, $v_buffer, $v_read_size);  
5595 - $p_size -= $v_read_size;  
5596 - }  
5597 - }  
5598 -  
5599 - // ----- Return  
5600 - return $v_result;  
5601 - }  
5602 - // --------------------------------------------------------------------------------  
5603 -  
5604 - // --------------------------------------------------------------------------------  
5605 - // Function : PclZipUtilRename()  
5606 - // Description :  
5607 - // This function tries to do a simple rename() function. If it fails, it  
5608 - // tries to copy the $p_src file in a new $p_dest file and then unlink the  
5609 - // first one.  
5610 - // Parameters :  
5611 - // $p_src : Old filename  
5612 - // $p_dest : New filename  
5613 - // Return Values :  
5614 - // 1 on success, 0 on failure.  
5615 - // --------------------------------------------------------------------------------  
5616 - function PclZipUtilRename($p_src, $p_dest)  
5617 - {  
5618 - $v_result = 1;  
5619 -  
5620 - // ----- Try to rename the files  
5621 - if (!@rename($p_src, $p_dest)) {  
5622 -  
5623 - // ----- Try to copy & unlink the src  
5624 - if (!@copy($p_src, $p_dest)) {  
5625 - $v_result = 0;  
5626 - }  
5627 - else if (!@unlink($p_src)) {  
5628 - $v_result = 0;  
5629 - }  
5630 - }  
5631 -  
5632 - // ----- Return  
5633 - return $v_result;  
5634 - }  
5635 - // --------------------------------------------------------------------------------  
5636 -  
5637 - // --------------------------------------------------------------------------------  
5638 - // Function : PclZipUtilOptionText()  
5639 - // Description :  
5640 - // Translate option value in text. Mainly for debug purpose.  
5641 - // Parameters :  
5642 - // $p_option : the option value.  
5643 - // Return Values :  
5644 - // The option text value.  
5645 - // --------------------------------------------------------------------------------  
5646 - function PclZipUtilOptionText($p_option)  
5647 - {  
5648 -  
5649 - $v_list = get_defined_constants();  
5650 - for (reset($v_list); $v_key = key($v_list); next($v_list)) {  
5651 - $v_prefix = substr($v_key, 0, 10);  
5652 - if (( ($v_prefix == 'PCLZIP_OPT')  
5653 - || ($v_prefix == 'PCLZIP_CB_')  
5654 - || ($v_prefix == 'PCLZIP_ATT'))  
5655 - && ($v_list[$v_key] == $p_option)) {  
5656 - return $v_key;  
5657 - }  
5658 - }  
5659 -  
5660 - $v_result = 'Unknown';  
5661 -  
5662 - return $v_result;  
5663 - }  
5664 - // --------------------------------------------------------------------------------  
5665 -  
5666 - // --------------------------------------------------------------------------------  
5667 - // Function : PclZipUtilTranslateWinPath()  
5668 - // Description :  
5669 - // Translate windows path by replacing '\' by '/' and optionally removing  
5670 - // drive letter.  
5671 - // Parameters :  
5672 - // $p_path : path to translate.  
5673 - // $p_remove_disk_letter : true | false  
5674 - // Return Values :  
5675 - // The path translated.  
5676 - // --------------------------------------------------------------------------------  
5677 - function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)  
5678 - {  
5679 - if (stristr(php_uname(), 'windows')) {  
5680 - // ----- Look for potential disk letter  
5681 - if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {  
5682 - $p_path = substr($p_path, $v_position+1);  
5683 - }  
5684 - // ----- Change potential windows directory separator  
5685 - if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {  
5686 - $p_path = strtr($p_path, '\\', '/');  
5687 - }  
5688 - }  
5689 - return $p_path;  
5690 - }  
5691 - // --------------------------------------------------------------------------------  
5692 -  
5693 -  
5694 -?> 1 +<?php
  2 +// --------------------------------------------------------------------------------
  3 +// PhpConcept Library - Zip Module 2.8.2
  4 +// --------------------------------------------------------------------------------
  5 +// License GNU/LGPL - Vincent Blavet - August 2009
  6 +// http://www.phpconcept.net
  7 +// --------------------------------------------------------------------------------
  8 +//
  9 +// Presentation :
  10 +// PclZip is a PHP library that manage ZIP archives.
  11 +// So far tests show that archives generated by PclZip are readable by
  12 +// WinZip application and other tools.
  13 +//
  14 +// Description :
  15 +// See readme.txt and http://www.phpconcept.net
  16 +//
  17 +// Warning :
  18 +// This library and the associated files are non commercial, non professional
  19 +// work.
  20 +// It should not have unexpected results. However if any damage is caused by
  21 +// this software the author can not be responsible.
  22 +// The use of this software is at the risk of the user.
  23 +//
  24 +// --------------------------------------------------------------------------------
  25 +// $Id: pclzip.lib.php,v 1.60 2009/09/30 21:01:04 vblavet Exp $
  26 +// --------------------------------------------------------------------------------
  27 +
  28 + // ----- Constants
  29 + if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
  30 + define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
  31 + }
  32 +
  33 + // ----- File list separator
  34 + // In version 1.x of PclZip, the separator for file list is a space
  35 + // (which is not a very smart choice, specifically for windows paths !).
  36 + // A better separator should be a comma (,). This constant gives you the
  37 + // abilty to change that.
  38 + // However notice that changing this value, may have impact on existing
  39 + // scripts, using space separated filenames.
  40 + // Recommanded values for compatibility with older versions :
  41 + //define( 'PCLZIP_SEPARATOR', ' ' );
  42 + // Recommanded values for smart separation of filenames.
  43 + if (!defined('PCLZIP_SEPARATOR')) {
  44 + define( 'PCLZIP_SEPARATOR', ',' );
  45 + }
  46 +
  47 + // ----- Error configuration
  48 + // 0 : PclZip Class integrated error handling
  49 + // 1 : PclError external library error handling. By enabling this
  50 + // you must ensure that you have included PclError library.
  51 + // [2,...] : reserved for futur use
  52 + if (!defined('PCLZIP_ERROR_EXTERNAL')) {
  53 + define( 'PCLZIP_ERROR_EXTERNAL', 0 );
  54 + }
  55 +
  56 + // ----- Optional static temporary directory
  57 + // By default temporary files are generated in the script current
  58 + // path.
  59 + // If defined :
  60 + // - MUST BE terminated by a '/'.
  61 + // - MUST be a valid, already created directory
  62 + // Samples :
  63 + // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
  64 + // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
  65 + if (!defined('PCLZIP_TEMPORARY_DIR')) {
  66 + define( 'PCLZIP_TEMPORARY_DIR', '' );
  67 + }
  68 +
  69 + // ----- Optional threshold ratio for use of temporary files
  70 + // Pclzip sense the size of the file to add/extract and decide to
  71 + // use or not temporary file. The algorythm is looking for
  72 + // memory_limit of PHP and apply a ratio.
  73 + // threshold = memory_limit * ratio.
  74 + // Recommended values are under 0.5. Default 0.47.
  75 + // Samples :
  76 + // define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.5 );
  77 + if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
  78 + define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
  79 + }
  80 +
  81 +// --------------------------------------------------------------------------------
  82 +// ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
  83 +// --------------------------------------------------------------------------------
  84 +
  85 + // ----- Global variables
  86 + $g_pclzip_version = "2.8.2";
  87 +
  88 + // ----- Error codes
  89 + // -1 : Unable to open file in binary write mode
  90 + // -2 : Unable to open file in binary read mode
  91 + // -3 : Invalid parameters
  92 + // -4 : File does not exist
  93 + // -5 : Filename is too long (max. 255)
  94 + // -6 : Not a valid zip file
  95 + // -7 : Invalid extracted file size
  96 + // -8 : Unable to create directory
  97 + // -9 : Invalid archive extension
  98 + // -10 : Invalid archive format
  99 + // -11 : Unable to delete file (unlink)
  100 + // -12 : Unable to rename file (rename)
  101 + // -13 : Invalid header checksum
  102 + // -14 : Invalid archive size
  103 + define( 'PCLZIP_ERR_USER_ABORTED', 2 );
  104 + define( 'PCLZIP_ERR_NO_ERROR', 0 );
  105 + define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
  106 + define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
  107 + define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
  108 + define( 'PCLZIP_ERR_MISSING_FILE', -4 );
  109 + define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
  110 + define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
  111 + define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
  112 + define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
  113 + define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
  114 + define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
  115 + define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
  116 + define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
  117 + define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
  118 + define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
  119 + define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
  120 + define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
  121 + define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
  122 + define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
  123 + define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
  124 + define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
  125 + define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
  126 +
  127 + // ----- Options values
  128 + define( 'PCLZIP_OPT_PATH', 77001 );
  129 + define( 'PCLZIP_OPT_ADD_PATH', 77002 );
  130 + define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
  131 + define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
  132 + define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
  133 + define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
  134 + define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
  135 + define( 'PCLZIP_OPT_BY_NAME', 77008 );
  136 + define( 'PCLZIP_OPT_BY_INDEX', 77009 );
  137 + define( 'PCLZIP_OPT_BY_EREG', 77010 );
  138 + define( 'PCLZIP_OPT_BY_PREG', 77011 );
  139 + define( 'PCLZIP_OPT_COMMENT', 77012 );
  140 + define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
  141 + define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
  142 + define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
  143 + define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
  144 + define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
  145 + // Having big trouble with crypt. Need to multiply 2 long int
  146 + // which is not correctly supported by PHP ...
  147 + //define( 'PCLZIP_OPT_CRYPT', 77018 );
  148 + define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
  149 + define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
  150 + define( 'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 ); // alias
  151 + define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
  152 + define( 'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 ); // alias
  153 + define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
  154 + define( 'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 ); // alias
  155 +
  156 + // ----- File description attributes
  157 + define( 'PCLZIP_ATT_FILE_NAME', 79001 );
  158 + define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
  159 + define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
  160 + define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
  161 + define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
  162 + define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
  163 +
  164 + // ----- Call backs values
  165 + define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
  166 + define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
  167 + define( 'PCLZIP_CB_PRE_ADD', 78003 );
  168 + define( 'PCLZIP_CB_POST_ADD', 78004 );
  169 + /* For futur use
  170 + define( 'PCLZIP_CB_PRE_LIST', 78005 );
  171 + define( 'PCLZIP_CB_POST_LIST', 78006 );
  172 + define( 'PCLZIP_CB_PRE_DELETE', 78007 );
  173 + define( 'PCLZIP_CB_POST_DELETE', 78008 );
  174 + */
  175 +
  176 + // --------------------------------------------------------------------------------
  177 + // Class : PclZip
  178 + // Description :
  179 + // PclZip is the class that represent a Zip archive.
  180 + // The public methods allow the manipulation of the archive.
  181 + // Attributes :
  182 + // Attributes must not be accessed directly.
  183 + // Methods :
  184 + // PclZip() : Object creator
  185 + // create() : Creates the Zip archive
  186 + // listContent() : List the content of the Zip archive
  187 + // extract() : Extract the content of the archive
  188 + // properties() : List the properties of the archive
  189 + // --------------------------------------------------------------------------------
  190 + class PclZip
  191 + {
  192 + // ----- Filename of the zip file
  193 + var $zipname = '';
  194 +
  195 + // ----- File descriptor of the zip file
  196 + var $zip_fd = 0;
  197 +
  198 + // ----- Internal error handling
  199 + var $error_code = 1;
  200 + var $error_string = '';
  201 +
  202 + // ----- Current status of the magic_quotes_runtime
  203 + // This value store the php configuration for magic_quotes
  204 + // The class can then disable the magic_quotes and reset it after
  205 + var $magic_quotes_status;
  206 +
  207 + // --------------------------------------------------------------------------------
  208 + // Function : PclZip()
  209 + // Description :
  210 + // Creates a PclZip object and set the name of the associated Zip archive
  211 + // filename.
  212 + // Note that no real action is taken, if the archive does not exist it is not
  213 + // created. Use create() for that.
  214 + // --------------------------------------------------------------------------------
  215 + function PclZip($p_zipname)
  216 + {
  217 +
  218 + // ----- Tests the zlib
  219 + if (!function_exists('gzopen'))
  220 + {
  221 + die('Abort '.basename(__FILE__).' : Missing zlib extensions');
  222 + }
  223 +
  224 + // ----- Set the attributes
  225 + $this->zipname = $p_zipname;
  226 + $this->zip_fd = 0;
  227 + $this->magic_quotes_status = -1;
  228 +
  229 + // ----- Return
  230 + return;
  231 + }
  232 + // --------------------------------------------------------------------------------
  233 +
  234 + // --------------------------------------------------------------------------------
  235 + // Function :
  236 + // create($p_filelist, $p_add_dir="", $p_remove_dir="")
  237 + // create($p_filelist, $p_option, $p_option_value, ...)
  238 + // Description :
  239 + // This method supports two different synopsis. The first one is historical.
  240 + // This method creates a Zip Archive. The Zip file is created in the
  241 + // filesystem. The files and directories indicated in $p_filelist
  242 + // are added in the archive. See the parameters description for the
  243 + // supported format of $p_filelist.
  244 + // When a directory is in the list, the directory and its content is added
  245 + // in the archive.
  246 + // In this synopsis, the function takes an optional variable list of
  247 + // options. See bellow the supported options.
  248 + // Parameters :
  249 + // $p_filelist : An array containing file or directory names, or
  250 + // a string containing one filename or one directory name, or
  251 + // a string containing a list of filenames and/or directory
  252 + // names separated by spaces.
  253 + // $p_add_dir : A path to add before the real path of the archived file,
  254 + // in order to have it memorized in the archive.
  255 + // $p_remove_dir : A path to remove from the real path of the file to archive,
  256 + // in order to have a shorter path memorized in the archive.
  257 + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  258 + // is removed first, before $p_add_dir is added.
  259 + // Options :
  260 + // PCLZIP_OPT_ADD_PATH :
  261 + // PCLZIP_OPT_REMOVE_PATH :
  262 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  263 + // PCLZIP_OPT_COMMENT :
  264 + // PCLZIP_CB_PRE_ADD :
  265 + // PCLZIP_CB_POST_ADD :
  266 + // Return Values :
  267 + // 0 on failure,
  268 + // The list of the added files, with a status of the add action.
  269 + // (see PclZip::listContent() for list entry format)
  270 + // --------------------------------------------------------------------------------
  271 + function create($p_filelist)
  272 + {
  273 + $v_result=1;
  274 +
  275 + // ----- Reset the error handler
  276 + $this->privErrorReset();
  277 +
  278 + // ----- Set default values
  279 + $v_options = array();
  280 + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  281 +
  282 + // ----- Look for variable options arguments
  283 + $v_size = func_num_args();
  284 +
  285 + // ----- Look for arguments
  286 + if ($v_size > 1) {
  287 + // ----- Get the arguments
  288 + $v_arg_list = func_get_args();
  289 +
  290 + // ----- Remove from the options list the first argument
  291 + array_shift($v_arg_list);
  292 + $v_size--;
  293 +
  294 + // ----- Look for first arg
  295 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  296 +
  297 + // ----- Parse the options
  298 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  299 + array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  300 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  301 + PCLZIP_OPT_ADD_PATH => 'optional',
  302 + PCLZIP_CB_PRE_ADD => 'optional',
  303 + PCLZIP_CB_POST_ADD => 'optional',
  304 + PCLZIP_OPT_NO_COMPRESSION => 'optional',
  305 + PCLZIP_OPT_COMMENT => 'optional',
  306 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  307 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  308 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  309 + //, PCLZIP_OPT_CRYPT => 'optional'
  310 + ));
  311 + if ($v_result != 1) {
  312 + return 0;
  313 + }
  314 + }
  315 +
  316 + // ----- Look for 2 args
  317 + // Here we need to support the first historic synopsis of the
  318 + // method.
  319 + else {
  320 +
  321 + // ----- Get the first argument
  322 + $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
  323 +
  324 + // ----- Look for the optional second argument
  325 + if ($v_size == 2) {
  326 + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
  327 + }
  328 + else if ($v_size > 2) {
  329 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  330 + "Invalid number / type of arguments");
  331 + return 0;
  332 + }
  333 + }
  334 + }
  335 +
  336 + // ----- Look for default option values
  337 + $this->privOptionDefaultThreshold($v_options);
  338 +
  339 + // ----- Init
  340 + $v_string_list = array();
  341 + $v_att_list = array();
  342 + $v_filedescr_list = array();
  343 + $p_result_list = array();
  344 +
  345 + // ----- Look if the $p_filelist is really an array
  346 + if (is_array($p_filelist)) {
  347 +
  348 + // ----- Look if the first element is also an array
  349 + // This will mean that this is a file description entry
  350 + if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
  351 + $v_att_list = $p_filelist;
  352 + }
  353 +
  354 + // ----- The list is a list of string names
  355 + else {
  356 + $v_string_list = $p_filelist;
  357 + }
  358 + }
  359 +
  360 + // ----- Look if the $p_filelist is a string
  361 + else if (is_string($p_filelist)) {
  362 + // ----- Create a list from the string
  363 + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  364 + }
  365 +
  366 + // ----- Invalid variable type for $p_filelist
  367 + else {
  368 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
  369 + return 0;
  370 + }
  371 +
  372 + // ----- Reformat the string list
  373 + if (sizeof($v_string_list) != 0) {
  374 + foreach ($v_string_list as $v_string) {
  375 + if ($v_string != '') {
  376 + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
  377 + }
  378 + else {
  379 + }
  380 + }
  381 + }
  382 +
  383 + // ----- For each file in the list check the attributes
  384 + $v_supported_attributes
  385 + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
  386 + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
  387 + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
  388 + ,PCLZIP_ATT_FILE_MTIME => 'optional'
  389 + ,PCLZIP_ATT_FILE_CONTENT => 'optional'
  390 + ,PCLZIP_ATT_FILE_COMMENT => 'optional'
  391 + );
  392 + foreach ($v_att_list as $v_entry) {
  393 + $v_result = $this->privFileDescrParseAtt($v_entry,
  394 + $v_filedescr_list[],
  395 + $v_options,
  396 + $v_supported_attributes);
  397 + if ($v_result != 1) {
  398 + return 0;
  399 + }
  400 + }
  401 +
  402 + // ----- Expand the filelist (expand directories)
  403 + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
  404 + if ($v_result != 1) {
  405 + return 0;
  406 + }
  407 +
  408 + // ----- Call the create fct
  409 + $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
  410 + if ($v_result != 1) {
  411 + return 0;
  412 + }
  413 +
  414 + // ----- Return
  415 + return $p_result_list;
  416 + }
  417 + // --------------------------------------------------------------------------------
  418 +
  419 + // --------------------------------------------------------------------------------
  420 + // Function :
  421 + // add($p_filelist, $p_add_dir="", $p_remove_dir="")
  422 + // add($p_filelist, $p_option, $p_option_value, ...)
  423 + // Description :
  424 + // This method supports two synopsis. The first one is historical.
  425 + // This methods add the list of files in an existing archive.
  426 + // If a file with the same name already exists, it is added at the end of the
  427 + // archive, the first one is still present.
  428 + // If the archive does not exist, it is created.
  429 + // Parameters :
  430 + // $p_filelist : An array containing file or directory names, or
  431 + // a string containing one filename or one directory name, or
  432 + // a string containing a list of filenames and/or directory
  433 + // names separated by spaces.
  434 + // $p_add_dir : A path to add before the real path of the archived file,
  435 + // in order to have it memorized in the archive.
  436 + // $p_remove_dir : A path to remove from the real path of the file to archive,
  437 + // in order to have a shorter path memorized in the archive.
  438 + // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
  439 + // is removed first, before $p_add_dir is added.
  440 + // Options :
  441 + // PCLZIP_OPT_ADD_PATH :
  442 + // PCLZIP_OPT_REMOVE_PATH :
  443 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  444 + // PCLZIP_OPT_COMMENT :
  445 + // PCLZIP_OPT_ADD_COMMENT :
  446 + // PCLZIP_OPT_PREPEND_COMMENT :
  447 + // PCLZIP_CB_PRE_ADD :
  448 + // PCLZIP_CB_POST_ADD :
  449 + // Return Values :
  450 + // 0 on failure,
  451 + // The list of the added files, with a status of the add action.
  452 + // (see PclZip::listContent() for list entry format)
  453 + // --------------------------------------------------------------------------------
  454 + function add($p_filelist)
  455 + {
  456 + $v_result=1;
  457 +
  458 + // ----- Reset the error handler
  459 + $this->privErrorReset();
  460 +
  461 + // ----- Set default values
  462 + $v_options = array();
  463 + $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
  464 +
  465 + // ----- Look for variable options arguments
  466 + $v_size = func_num_args();
  467 +
  468 + // ----- Look for arguments
  469 + if ($v_size > 1) {
  470 + // ----- Get the arguments
  471 + $v_arg_list = func_get_args();
  472 +
  473 + // ----- Remove form the options list the first argument
  474 + array_shift($v_arg_list);
  475 + $v_size--;
  476 +
  477 + // ----- Look for first arg
  478 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  479 +
  480 + // ----- Parse the options
  481 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  482 + array (PCLZIP_OPT_REMOVE_PATH => 'optional',
  483 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  484 + PCLZIP_OPT_ADD_PATH => 'optional',
  485 + PCLZIP_CB_PRE_ADD => 'optional',
  486 + PCLZIP_CB_POST_ADD => 'optional',
  487 + PCLZIP_OPT_NO_COMPRESSION => 'optional',
  488 + PCLZIP_OPT_COMMENT => 'optional',
  489 + PCLZIP_OPT_ADD_COMMENT => 'optional',
  490 + PCLZIP_OPT_PREPEND_COMMENT => 'optional',
  491 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  492 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  493 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  494 + //, PCLZIP_OPT_CRYPT => 'optional'
  495 + ));
  496 + if ($v_result != 1) {
  497 + return 0;
  498 + }
  499 + }
  500 +
  501 + // ----- Look for 2 args
  502 + // Here we need to support the first historic synopsis of the
  503 + // method.
  504 + else {
  505 +
  506 + // ----- Get the first argument
  507 + $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
  508 +
  509 + // ----- Look for the optional second argument
  510 + if ($v_size == 2) {
  511 + $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
  512 + }
  513 + else if ($v_size > 2) {
  514 + // ----- Error log
  515 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  516 +
  517 + // ----- Return
  518 + return 0;
  519 + }
  520 + }
  521 + }
  522 +
  523 + // ----- Look for default option values
  524 + $this->privOptionDefaultThreshold($v_options);
  525 +
  526 + // ----- Init
  527 + $v_string_list = array();
  528 + $v_att_list = array();
  529 + $v_filedescr_list = array();
  530 + $p_result_list = array();
  531 +
  532 + // ----- Look if the $p_filelist is really an array
  533 + if (is_array($p_filelist)) {
  534 +
  535 + // ----- Look if the first element is also an array
  536 + // This will mean that this is a file description entry
  537 + if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
  538 + $v_att_list = $p_filelist;
  539 + }
  540 +
  541 + // ----- The list is a list of string names
  542 + else {
  543 + $v_string_list = $p_filelist;
  544 + }
  545 + }
  546 +
  547 + // ----- Look if the $p_filelist is a string
  548 + else if (is_string($p_filelist)) {
  549 + // ----- Create a list from the string
  550 + $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
  551 + }
  552 +
  553 + // ----- Invalid variable type for $p_filelist
  554 + else {
  555 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
  556 + return 0;
  557 + }
  558 +
  559 + // ----- Reformat the string list
  560 + if (sizeof($v_string_list) != 0) {
  561 + foreach ($v_string_list as $v_string) {
  562 + $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
  563 + }
  564 + }
  565 +
  566 + // ----- For each file in the list check the attributes
  567 + $v_supported_attributes
  568 + = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
  569 + ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
  570 + ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
  571 + ,PCLZIP_ATT_FILE_MTIME => 'optional'
  572 + ,PCLZIP_ATT_FILE_CONTENT => 'optional'
  573 + ,PCLZIP_ATT_FILE_COMMENT => 'optional'
  574 + );
  575 + foreach ($v_att_list as $v_entry) {
  576 + $v_result = $this->privFileDescrParseAtt($v_entry,
  577 + $v_filedescr_list[],
  578 + $v_options,
  579 + $v_supported_attributes);
  580 + if ($v_result != 1) {
  581 + return 0;
  582 + }
  583 + }
  584 +
  585 + // ----- Expand the filelist (expand directories)
  586 + $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
  587 + if ($v_result != 1) {
  588 + return 0;
  589 + }
  590 +
  591 + // ----- Call the create fct
  592 + $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
  593 + if ($v_result != 1) {
  594 + return 0;
  595 + }
  596 +
  597 + // ----- Return
  598 + return $p_result_list;
  599 + }
  600 + // --------------------------------------------------------------------------------
  601 +
  602 + // --------------------------------------------------------------------------------
  603 + // Function : listContent()
  604 + // Description :
  605 + // This public method, gives the list of the files and directories, with their
  606 + // properties.
  607 + // The properties of each entries in the list are (used also in other functions) :
  608 + // filename : Name of the file. For a create or add action it is the filename
  609 + // given by the user. For an extract function it is the filename
  610 + // of the extracted file.
  611 + // stored_filename : Name of the file / directory stored in the archive.
  612 + // size : Size of the stored file.
  613 + // compressed_size : Size of the file's data compressed in the archive
  614 + // (without the headers overhead)
  615 + // mtime : Last known modification date of the file (UNIX timestamp)
  616 + // comment : Comment associated with the file
  617 + // folder : true | false
  618 + // index : index of the file in the archive
  619 + // status : status of the action (depending of the action) :
  620 + // Values are :
  621 + // ok : OK !
  622 + // filtered : the file / dir is not extracted (filtered by user)
  623 + // already_a_directory : the file can not be extracted because a
  624 + // directory with the same name already exists
  625 + // write_protected : the file can not be extracted because a file
  626 + // with the same name already exists and is
  627 + // write protected
  628 + // newer_exist : the file was not extracted because a newer file exists
  629 + // path_creation_fail : the file is not extracted because the folder
  630 + // does not exist and can not be created
  631 + // write_error : the file was not extracted because there was a
  632 + // error while writing the file
  633 + // read_error : the file was not extracted because there was a error
  634 + // while reading the file
  635 + // invalid_header : the file was not extracted because of an archive
  636 + // format error (bad file header)
  637 + // Note that each time a method can continue operating when there
  638 + // is an action error on a file, the error is only logged in the file status.
  639 + // Return Values :
  640 + // 0 on an unrecoverable failure,
  641 + // The list of the files in the archive.
  642 + // --------------------------------------------------------------------------------
  643 + function listContent()
  644 + {
  645 + $v_result=1;
  646 +
  647 + // ----- Reset the error handler
  648 + $this->privErrorReset();
  649 +
  650 + // ----- Check archive
  651 + if (!$this->privCheckFormat()) {
  652 + return(0);
  653 + }
  654 +
  655 + // ----- Call the extracting fct
  656 + $p_list = array();
  657 + if (($v_result = $this->privList($p_list)) != 1)
  658 + {
  659 + unset($p_list);
  660 + return(0);
  661 + }
  662 +
  663 + // ----- Return
  664 + return $p_list;
  665 + }
  666 + // --------------------------------------------------------------------------------
  667 +
  668 + // --------------------------------------------------------------------------------
  669 + // Function :
  670 + // extract($p_path="./", $p_remove_path="")
  671 + // extract([$p_option, $p_option_value, ...])
  672 + // Description :
  673 + // This method supports two synopsis. The first one is historical.
  674 + // This method extract all the files / directories from the archive to the
  675 + // folder indicated in $p_path.
  676 + // If you want to ignore the 'root' part of path of the memorized files
  677 + // you can indicate this in the optional $p_remove_path parameter.
  678 + // By default, if a newer file with the same name already exists, the
  679 + // file is not extracted.
  680 + //
  681 + // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
  682 + // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
  683 + // at the end of the path value of PCLZIP_OPT_PATH.
  684 + // Parameters :
  685 + // $p_path : Path where the files and directories are to be extracted
  686 + // $p_remove_path : First part ('root' part) of the memorized path
  687 + // (if any similar) to remove while extracting.
  688 + // Options :
  689 + // PCLZIP_OPT_PATH :
  690 + // PCLZIP_OPT_ADD_PATH :
  691 + // PCLZIP_OPT_REMOVE_PATH :
  692 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  693 + // PCLZIP_CB_PRE_EXTRACT :
  694 + // PCLZIP_CB_POST_EXTRACT :
  695 + // Return Values :
  696 + // 0 or a negative value on failure,
  697 + // The list of the extracted files, with a status of the action.
  698 + // (see PclZip::listContent() for list entry format)
  699 + // --------------------------------------------------------------------------------
  700 + function extract()
  701 + {
  702 + $v_result=1;
  703 +
  704 + // ----- Reset the error handler
  705 + $this->privErrorReset();
  706 +
  707 + // ----- Check archive
  708 + if (!$this->privCheckFormat()) {
  709 + return(0);
  710 + }
  711 +
  712 + // ----- Set default values
  713 + $v_options = array();
  714 +// $v_path = "./";
  715 + $v_path = '';
  716 + $v_remove_path = "";
  717 + $v_remove_all_path = false;
  718 +
  719 + // ----- Look for variable options arguments
  720 + $v_size = func_num_args();
  721 +
  722 + // ----- Default values for option
  723 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  724 +
  725 + // ----- Look for arguments
  726 + if ($v_size > 0) {
  727 + // ----- Get the arguments
  728 + $v_arg_list = func_get_args();
  729 +
  730 + // ----- Look for first arg
  731 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  732 +
  733 + // ----- Parse the options
  734 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  735 + array (PCLZIP_OPT_PATH => 'optional',
  736 + PCLZIP_OPT_REMOVE_PATH => 'optional',
  737 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  738 + PCLZIP_OPT_ADD_PATH => 'optional',
  739 + PCLZIP_CB_PRE_EXTRACT => 'optional',
  740 + PCLZIP_CB_POST_EXTRACT => 'optional',
  741 + PCLZIP_OPT_SET_CHMOD => 'optional',
  742 + PCLZIP_OPT_BY_NAME => 'optional',
  743 + PCLZIP_OPT_BY_EREG => 'optional',
  744 + PCLZIP_OPT_BY_PREG => 'optional',
  745 + PCLZIP_OPT_BY_INDEX => 'optional',
  746 + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  747 + PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
  748 + PCLZIP_OPT_REPLACE_NEWER => 'optional'
  749 + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
  750 + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
  751 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  752 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  753 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  754 + ));
  755 + if ($v_result != 1) {
  756 + return 0;
  757 + }
  758 +
  759 + // ----- Set the arguments
  760 + if (isset($v_options[PCLZIP_OPT_PATH])) {
  761 + $v_path = $v_options[PCLZIP_OPT_PATH];
  762 + }
  763 + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  764 + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  765 + }
  766 + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  767 + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  768 + }
  769 + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  770 + // ----- Check for '/' in last path char
  771 + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  772 + $v_path .= '/';
  773 + }
  774 + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  775 + }
  776 + }
  777 +
  778 + // ----- Look for 2 args
  779 + // Here we need to support the first historic synopsis of the
  780 + // method.
  781 + else {
  782 +
  783 + // ----- Get the first argument
  784 + $v_path = $v_arg_list[0];
  785 +
  786 + // ----- Look for the optional second argument
  787 + if ($v_size == 2) {
  788 + $v_remove_path = $v_arg_list[1];
  789 + }
  790 + else if ($v_size > 2) {
  791 + // ----- Error log
  792 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  793 +
  794 + // ----- Return
  795 + return 0;
  796 + }
  797 + }
  798 + }
  799 +
  800 + // ----- Look for default option values
  801 + $this->privOptionDefaultThreshold($v_options);
  802 +
  803 + // ----- Trace
  804 +
  805 + // ----- Call the extracting fct
  806 + $p_list = array();
  807 + $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
  808 + $v_remove_all_path, $v_options);
  809 + if ($v_result < 1) {
  810 + unset($p_list);
  811 + return(0);
  812 + }
  813 +
  814 + // ----- Return
  815 + return $p_list;
  816 + }
  817 + // --------------------------------------------------------------------------------
  818 +
  819 +
  820 + // --------------------------------------------------------------------------------
  821 + // Function :
  822 + // extractByIndex($p_index, $p_path="./", $p_remove_path="")
  823 + // extractByIndex($p_index, [$p_option, $p_option_value, ...])
  824 + // Description :
  825 + // This method supports two synopsis. The first one is historical.
  826 + // This method is doing a partial extract of the archive.
  827 + // The extracted files or folders are identified by their index in the
  828 + // archive (from 0 to n).
  829 + // Note that if the index identify a folder, only the folder entry is
  830 + // extracted, not all the files included in the archive.
  831 + // Parameters :
  832 + // $p_index : A single index (integer) or a string of indexes of files to
  833 + // extract. The form of the string is "0,4-6,8-12" with only numbers
  834 + // and '-' for range or ',' to separate ranges. No spaces or ';'
  835 + // are allowed.
  836 + // $p_path : Path where the files and directories are to be extracted
  837 + // $p_remove_path : First part ('root' part) of the memorized path
  838 + // (if any similar) to remove while extracting.
  839 + // Options :
  840 + // PCLZIP_OPT_PATH :
  841 + // PCLZIP_OPT_ADD_PATH :
  842 + // PCLZIP_OPT_REMOVE_PATH :
  843 + // PCLZIP_OPT_REMOVE_ALL_PATH :
  844 + // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
  845 + // not as files.
  846 + // The resulting content is in a new field 'content' in the file
  847 + // structure.
  848 + // This option must be used alone (any other options are ignored).
  849 + // PCLZIP_CB_PRE_EXTRACT :
  850 + // PCLZIP_CB_POST_EXTRACT :
  851 + // Return Values :
  852 + // 0 on failure,
  853 + // The list of the extracted files, with a status of the action.
  854 + // (see PclZip::listContent() for list entry format)
  855 + // --------------------------------------------------------------------------------
  856 + //function extractByIndex($p_index, options...)
  857 + function extractByIndex($p_index)
  858 + {
  859 + $v_result=1;
  860 +
  861 + // ----- Reset the error handler
  862 + $this->privErrorReset();
  863 +
  864 + // ----- Check archive
  865 + if (!$this->privCheckFormat()) {
  866 + return(0);
  867 + }
  868 +
  869 + // ----- Set default values
  870 + $v_options = array();
  871 +// $v_path = "./";
  872 + $v_path = '';
  873 + $v_remove_path = "";
  874 + $v_remove_all_path = false;
  875 +
  876 + // ----- Look for variable options arguments
  877 + $v_size = func_num_args();
  878 +
  879 + // ----- Default values for option
  880 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  881 +
  882 + // ----- Look for arguments
  883 + if ($v_size > 1) {
  884 + // ----- Get the arguments
  885 + $v_arg_list = func_get_args();
  886 +
  887 + // ----- Remove form the options list the first argument
  888 + array_shift($v_arg_list);
  889 + $v_size--;
  890 +
  891 + // ----- Look for first arg
  892 + if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
  893 +
  894 + // ----- Parse the options
  895 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  896 + array (PCLZIP_OPT_PATH => 'optional',
  897 + PCLZIP_OPT_REMOVE_PATH => 'optional',
  898 + PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
  899 + PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
  900 + PCLZIP_OPT_ADD_PATH => 'optional',
  901 + PCLZIP_CB_PRE_EXTRACT => 'optional',
  902 + PCLZIP_CB_POST_EXTRACT => 'optional',
  903 + PCLZIP_OPT_SET_CHMOD => 'optional',
  904 + PCLZIP_OPT_REPLACE_NEWER => 'optional'
  905 + ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
  906 + ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
  907 + PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
  908 + PCLZIP_OPT_TEMP_FILE_ON => 'optional',
  909 + PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
  910 + ));
  911 + if ($v_result != 1) {
  912 + return 0;
  913 + }
  914 +
  915 + // ----- Set the arguments
  916 + if (isset($v_options[PCLZIP_OPT_PATH])) {
  917 + $v_path = $v_options[PCLZIP_OPT_PATH];
  918 + }
  919 + if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
  920 + $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
  921 + }
  922 + if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  923 + $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  924 + }
  925 + if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
  926 + // ----- Check for '/' in last path char
  927 + if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
  928 + $v_path .= '/';
  929 + }
  930 + $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
  931 + }
  932 + if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
  933 + $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
  934 + }
  935 + else {
  936 + }
  937 + }
  938 +
  939 + // ----- Look for 2 args
  940 + // Here we need to support the first historic synopsis of the
  941 + // method.
  942 + else {
  943 +
  944 + // ----- Get the first argument
  945 + $v_path = $v_arg_list[0];
  946 +
  947 + // ----- Look for the optional second argument
  948 + if ($v_size == 2) {
  949 + $v_remove_path = $v_arg_list[1];
  950 + }
  951 + else if ($v_size > 2) {
  952 + // ----- Error log
  953 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
  954 +
  955 + // ----- Return
  956 + return 0;
  957 + }
  958 + }
  959 + }
  960 +
  961 + // ----- Trace
  962 +
  963 + // ----- Trick
  964 + // Here I want to reuse extractByRule(), so I need to parse the $p_index
  965 + // with privParseOptions()
  966 + $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
  967 + $v_options_trick = array();
  968 + $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
  969 + array (PCLZIP_OPT_BY_INDEX => 'optional' ));
  970 + if ($v_result != 1) {
  971 + return 0;
  972 + }
  973 + $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
  974 +
  975 + // ----- Look for default option values
  976 + $this->privOptionDefaultThreshold($v_options);
  977 +
  978 + // ----- Call the extracting fct
  979 + if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
  980 + return(0);
  981 + }
  982 +
  983 + // ----- Return
  984 + return $p_list;
  985 + }
  986 + // --------------------------------------------------------------------------------
  987 +
  988 + // --------------------------------------------------------------------------------
  989 + // Function :
  990 + // delete([$p_option, $p_option_value, ...])
  991 + // Description :
  992 + // This method removes files from the archive.
  993 + // If no parameters are given, then all the archive is emptied.
  994 + // Parameters :
  995 + // None or optional arguments.
  996 + // Options :
  997 + // PCLZIP_OPT_BY_INDEX :
  998 + // PCLZIP_OPT_BY_NAME :
  999 + // PCLZIP_OPT_BY_EREG :
  1000 + // PCLZIP_OPT_BY_PREG :
  1001 + // Return Values :
  1002 + // 0 on failure,
  1003 + // The list of the files which are still present in the archive.
  1004 + // (see PclZip::listContent() for list entry format)
  1005 + // --------------------------------------------------------------------------------
  1006 + function delete()
  1007 + {
  1008 + $v_result=1;
  1009 +
  1010 + // ----- Reset the error handler
  1011 + $this->privErrorReset();
  1012 +
  1013 + // ----- Check archive
  1014 + if (!$this->privCheckFormat()) {
  1015 + return(0);
  1016 + }
  1017 +
  1018 + // ----- Set default values
  1019 + $v_options = array();
  1020 +
  1021 + // ----- Look for variable options arguments
  1022 + $v_size = func_num_args();
  1023 +
  1024 + // ----- Look for arguments
  1025 + if ($v_size > 0) {
  1026 + // ----- Get the arguments
  1027 + $v_arg_list = func_get_args();
  1028 +
  1029 + // ----- Parse the options
  1030 + $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
  1031 + array (PCLZIP_OPT_BY_NAME => 'optional',
  1032 + PCLZIP_OPT_BY_EREG => 'optional',
  1033 + PCLZIP_OPT_BY_PREG => 'optional',
  1034 + PCLZIP_OPT_BY_INDEX => 'optional' ));
  1035 + if ($v_result != 1) {
  1036 + return 0;
  1037 + }
  1038 + }
  1039 +
  1040 + // ----- Magic quotes trick
  1041 + $this->privDisableMagicQuotes();
  1042 +
  1043 + // ----- Call the delete fct
  1044 + $v_list = array();
  1045 + if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
  1046 + $this->privSwapBackMagicQuotes();
  1047 + unset($v_list);
  1048 + return(0);
  1049 + }
  1050 +
  1051 + // ----- Magic quotes trick
  1052 + $this->privSwapBackMagicQuotes();
  1053 +
  1054 + // ----- Return
  1055 + return $v_list;
  1056 + }
  1057 + // --------------------------------------------------------------------------------
  1058 +
  1059 + // --------------------------------------------------------------------------------
  1060 + // Function : deleteByIndex()
  1061 + // Description :
  1062 + // ***** Deprecated *****
  1063 + // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
  1064 + // --------------------------------------------------------------------------------
  1065 + function deleteByIndex($p_index)
  1066 + {
  1067 +
  1068 + $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
  1069 +
  1070 + // ----- Return
  1071 + return $p_list;
  1072 + }
  1073 + // --------------------------------------------------------------------------------
  1074 +
  1075 + // --------------------------------------------------------------------------------
  1076 + // Function : properties()
  1077 + // Description :
  1078 + // This method gives the properties of the archive.
  1079 + // The properties are :
  1080 + // nb : Number of files in the archive
  1081 + // comment : Comment associated with the archive file
  1082 + // status : not_exist, ok
  1083 + // Parameters :
  1084 + // None
  1085 + // Return Values :
  1086 + // 0 on failure,
  1087 + // An array with the archive properties.
  1088 + // --------------------------------------------------------------------------------
  1089 + function properties()
  1090 + {
  1091 +
  1092 + // ----- Reset the error handler
  1093 + $this->privErrorReset();
  1094 +
  1095 + // ----- Magic quotes trick
  1096 + $this->privDisableMagicQuotes();
  1097 +
  1098 + // ----- Check archive
  1099 + if (!$this->privCheckFormat()) {
  1100 + $this->privSwapBackMagicQuotes();
  1101 + return(0);
  1102 + }
  1103 +
  1104 + // ----- Default properties
  1105 + $v_prop = array();
  1106 + $v_prop['comment'] = '';
  1107 + $v_prop['nb'] = 0;
  1108 + $v_prop['status'] = 'not_exist';
  1109 +
  1110 + // ----- Look if file exists
  1111 + if (@is_file($this->zipname))
  1112 + {
  1113 + // ----- Open the zip file
  1114 + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  1115 + {
  1116 + $this->privSwapBackMagicQuotes();
  1117 +
  1118 + // ----- Error log
  1119 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  1120 +
  1121 + // ----- Return
  1122 + return 0;
  1123 + }
  1124 +
  1125 + // ----- Read the central directory informations
  1126 + $v_central_dir = array();
  1127 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  1128 + {
  1129 + $this->privSwapBackMagicQuotes();
  1130 + return 0;
  1131 + }
  1132 +
  1133 + // ----- Close the zip file
  1134 + $this->privCloseFd();
  1135 +
  1136 + // ----- Set the user attributes
  1137 + $v_prop['comment'] = $v_central_dir['comment'];
  1138 + $v_prop['nb'] = $v_central_dir['entries'];
  1139 + $v_prop['status'] = 'ok';
  1140 + }
  1141 +
  1142 + // ----- Magic quotes trick
  1143 + $this->privSwapBackMagicQuotes();
  1144 +
  1145 + // ----- Return
  1146 + return $v_prop;
  1147 + }
  1148 + // --------------------------------------------------------------------------------
  1149 +
  1150 + // --------------------------------------------------------------------------------
  1151 + // Function : duplicate()
  1152 + // Description :
  1153 + // This method creates an archive by copying the content of an other one. If
  1154 + // the archive already exist, it is replaced by the new one without any warning.
  1155 + // Parameters :
  1156 + // $p_archive : The filename of a valid archive, or
  1157 + // a valid PclZip object.
  1158 + // Return Values :
  1159 + // 1 on success.
  1160 + // 0 or a negative value on error (error code).
  1161 + // --------------------------------------------------------------------------------
  1162 + function duplicate($p_archive)
  1163 + {
  1164 + $v_result = 1;
  1165 +
  1166 + // ----- Reset the error handler
  1167 + $this->privErrorReset();
  1168 +
  1169 + // ----- Look if the $p_archive is a PclZip object
  1170 + if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
  1171 + {
  1172 +
  1173 + // ----- Duplicate the archive
  1174 + $v_result = $this->privDuplicate($p_archive->zipname);
  1175 + }
  1176 +
  1177 + // ----- Look if the $p_archive is a string (so a filename)
  1178 + else if (is_string($p_archive))
  1179 + {
  1180 +
  1181 + // ----- Check that $p_archive is a valid zip file
  1182 + // TBC : Should also check the archive format
  1183 + if (!is_file($p_archive)) {
  1184 + // ----- Error log
  1185 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
  1186 + $v_result = PCLZIP_ERR_MISSING_FILE;
  1187 + }
  1188 + else {
  1189 + // ----- Duplicate the archive
  1190 + $v_result = $this->privDuplicate($p_archive);
  1191 + }
  1192 + }
  1193 +
  1194 + // ----- Invalid variable
  1195 + else
  1196 + {
  1197 + // ----- Error log
  1198 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1199 + $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1200 + }
  1201 +
  1202 + // ----- Return
  1203 + return $v_result;
  1204 + }
  1205 + // --------------------------------------------------------------------------------
  1206 +
  1207 + // --------------------------------------------------------------------------------
  1208 + // Function : merge()
  1209 + // Description :
  1210 + // This method merge the $p_archive_to_add archive at the end of the current
  1211 + // one ($this).
  1212 + // If the archive ($this) does not exist, the merge becomes a duplicate.
  1213 + // If the $p_archive_to_add archive does not exist, the merge is a success.
  1214 + // Parameters :
  1215 + // $p_archive_to_add : It can be directly the filename of a valid zip archive,
  1216 + // or a PclZip object archive.
  1217 + // Return Values :
  1218 + // 1 on success,
  1219 + // 0 or negative values on error (see below).
  1220 + // --------------------------------------------------------------------------------
  1221 + function merge($p_archive_to_add)
  1222 + {
  1223 + $v_result = 1;
  1224 +
  1225 + // ----- Reset the error handler
  1226 + $this->privErrorReset();
  1227 +
  1228 + // ----- Check archive
  1229 + if (!$this->privCheckFormat()) {
  1230 + return(0);
  1231 + }
  1232 +
  1233 + // ----- Look if the $p_archive_to_add is a PclZip object
  1234 + if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
  1235 + {
  1236 +
  1237 + // ----- Merge the archive
  1238 + $v_result = $this->privMerge($p_archive_to_add);
  1239 + }
  1240 +
  1241 + // ----- Look if the $p_archive_to_add is a string (so a filename)
  1242 + else if (is_string($p_archive_to_add))
  1243 + {
  1244 +
  1245 + // ----- Create a temporary archive
  1246 + $v_object_archive = new PclZip($p_archive_to_add);
  1247 +
  1248 + // ----- Merge the archive
  1249 + $v_result = $this->privMerge($v_object_archive);
  1250 + }
  1251 +
  1252 + // ----- Invalid variable
  1253 + else
  1254 + {
  1255 + // ----- Error log
  1256 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
  1257 + $v_result = PCLZIP_ERR_INVALID_PARAMETER;
  1258 + }
  1259 +
  1260 + // ----- Return
  1261 + return $v_result;
  1262 + }
  1263 + // --------------------------------------------------------------------------------
  1264 +
  1265 +
  1266 +
  1267 + // --------------------------------------------------------------------------------
  1268 + // Function : errorCode()
  1269 + // Description :
  1270 + // Parameters :
  1271 + // --------------------------------------------------------------------------------
  1272 + function errorCode()
  1273 + {
  1274 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  1275 + return(PclErrorCode());
  1276 + }
  1277 + else {
  1278 + return($this->error_code);
  1279 + }
  1280 + }
  1281 + // --------------------------------------------------------------------------------
  1282 +
  1283 + // --------------------------------------------------------------------------------
  1284 + // Function : errorName()
  1285 + // Description :
  1286 + // Parameters :
  1287 + // --------------------------------------------------------------------------------
  1288 + function errorName($p_with_code=false)
  1289 + {
  1290 + $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
  1291 + PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
  1292 + PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
  1293 + PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
  1294 + PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
  1295 + PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
  1296 + PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
  1297 + PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
  1298 + PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
  1299 + PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
  1300 + PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
  1301 + PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
  1302 + PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
  1303 + PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
  1304 + PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
  1305 + PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
  1306 + PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
  1307 + PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
  1308 + PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
  1309 + ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
  1310 + ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
  1311 + );
  1312 +
  1313 + if (isset($v_name[$this->error_code])) {
  1314 + $v_value = $v_name[$this->error_code];
  1315 + }
  1316 + else {
  1317 + $v_value = 'NoName';
  1318 + }
  1319 +
  1320 + if ($p_with_code) {
  1321 + return($v_value.' ('.$this->error_code.')');
  1322 + }
  1323 + else {
  1324 + return($v_value);
  1325 + }
  1326 + }
  1327 + // --------------------------------------------------------------------------------
  1328 +
  1329 + // --------------------------------------------------------------------------------
  1330 + // Function : errorInfo()
  1331 + // Description :
  1332 + // Parameters :
  1333 + // --------------------------------------------------------------------------------
  1334 + function errorInfo($p_full=false)
  1335 + {
  1336 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  1337 + return(PclErrorString());
  1338 + }
  1339 + else {
  1340 + if ($p_full) {
  1341 + return($this->errorName(true)." : ".$this->error_string);
  1342 + }
  1343 + else {
  1344 + return($this->error_string." [code ".$this->error_code."]");
  1345 + }
  1346 + }
  1347 + }
  1348 + // --------------------------------------------------------------------------------
  1349 +
  1350 +
  1351 +// --------------------------------------------------------------------------------
  1352 +// ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
  1353 +// ***** *****
  1354 +// ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
  1355 +// --------------------------------------------------------------------------------
  1356 +
  1357 +
  1358 +
  1359 + // --------------------------------------------------------------------------------
  1360 + // Function : privCheckFormat()
  1361 + // Description :
  1362 + // This method check that the archive exists and is a valid zip archive.
  1363 + // Several level of check exists. (futur)
  1364 + // Parameters :
  1365 + // $p_level : Level of check. Default 0.
  1366 + // 0 : Check the first bytes (magic codes) (default value))
  1367 + // 1 : 0 + Check the central directory (futur)
  1368 + // 2 : 1 + Check each file header (futur)
  1369 + // Return Values :
  1370 + // true on success,
  1371 + // false on error, the error code is set.
  1372 + // --------------------------------------------------------------------------------
  1373 + function privCheckFormat($p_level=0)
  1374 + {
  1375 + $v_result = true;
  1376 +
  1377 + // ----- Reset the file system cache
  1378 + clearstatcache();
  1379 +
  1380 + // ----- Reset the error handler
  1381 + $this->privErrorReset();
  1382 +
  1383 + // ----- Look if the file exits
  1384 + if (!is_file($this->zipname)) {
  1385 + // ----- Error log
  1386 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
  1387 + return(false);
  1388 + }
  1389 +
  1390 + // ----- Check that the file is readeable
  1391 + if (!is_readable($this->zipname)) {
  1392 + // ----- Error log
  1393 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
  1394 + return(false);
  1395 + }
  1396 +
  1397 + // ----- Check the magic code
  1398 + // TBC
  1399 +
  1400 + // ----- Check the central header
  1401 + // TBC
  1402 +
  1403 + // ----- Check each file header
  1404 + // TBC
  1405 +
  1406 + // ----- Return
  1407 + return $v_result;
  1408 + }
  1409 + // --------------------------------------------------------------------------------
  1410 +
  1411 + // --------------------------------------------------------------------------------
  1412 + // Function : privParseOptions()
  1413 + // Description :
  1414 + // This internal methods reads the variable list of arguments ($p_options_list,
  1415 + // $p_size) and generate an array with the options and values ($v_result_list).
  1416 + // $v_requested_options contains the options that can be present and those that
  1417 + // must be present.
  1418 + // $v_requested_options is an array, with the option value as key, and 'optional',
  1419 + // or 'mandatory' as value.
  1420 + // Parameters :
  1421 + // See above.
  1422 + // Return Values :
  1423 + // 1 on success.
  1424 + // 0 on failure.
  1425 + // --------------------------------------------------------------------------------
  1426 + function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
  1427 + {
  1428 + $v_result=1;
  1429 +
  1430 + // ----- Read the options
  1431 + $i=0;
  1432 + while ($i<$p_size) {
  1433 +
  1434 + // ----- Check if the option is supported
  1435 + if (!isset($v_requested_options[$p_options_list[$i]])) {
  1436 + // ----- Error log
  1437 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
  1438 +
  1439 + // ----- Return
  1440 + return PclZip::errorCode();
  1441 + }
  1442 +
  1443 + // ----- Look for next option
  1444 + switch ($p_options_list[$i]) {
  1445 + // ----- Look for options that request a path value
  1446 + case PCLZIP_OPT_PATH :
  1447 + case PCLZIP_OPT_REMOVE_PATH :
  1448 + case PCLZIP_OPT_ADD_PATH :
  1449 + // ----- Check the number of parameters
  1450 + if (($i+1) >= $p_size) {
  1451 + // ----- Error log
  1452 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1453 +
  1454 + // ----- Return
  1455 + return PclZip::errorCode();
  1456 + }
  1457 +
  1458 + // ----- Get the value
  1459 + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
  1460 + $i++;
  1461 + break;
  1462 +
  1463 + case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
  1464 + // ----- Check the number of parameters
  1465 + if (($i+1) >= $p_size) {
  1466 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1467 + return PclZip::errorCode();
  1468 + }
  1469 +
  1470 + // ----- Check for incompatible options
  1471 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
  1472 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
  1473 + return PclZip::errorCode();
  1474 + }
  1475 +
  1476 + // ----- Check the value
  1477 + $v_value = $p_options_list[$i+1];
  1478 + if ((!is_integer($v_value)) || ($v_value<0)) {
  1479 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1480 + return PclZip::errorCode();
  1481 + }
  1482 +
  1483 + // ----- Get the value (and convert it in bytes)
  1484 + $v_result_list[$p_options_list[$i]] = $v_value*1048576;
  1485 + $i++;
  1486 + break;
  1487 +
  1488 + case PCLZIP_OPT_TEMP_FILE_ON :
  1489 + // ----- Check for incompatible options
  1490 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
  1491 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
  1492 + return PclZip::errorCode();
  1493 + }
  1494 +
  1495 + $v_result_list[$p_options_list[$i]] = true;
  1496 + break;
  1497 +
  1498 + case PCLZIP_OPT_TEMP_FILE_OFF :
  1499 + // ----- Check for incompatible options
  1500 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
  1501 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
  1502 + return PclZip::errorCode();
  1503 + }
  1504 + // ----- Check for incompatible options
  1505 + if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
  1506 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
  1507 + return PclZip::errorCode();
  1508 + }
  1509 +
  1510 + $v_result_list[$p_options_list[$i]] = true;
  1511 + break;
  1512 +
  1513 + case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
  1514 + // ----- Check the number of parameters
  1515 + if (($i+1) >= $p_size) {
  1516 + // ----- Error log
  1517 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1518 +
  1519 + // ----- Return
  1520 + return PclZip::errorCode();
  1521 + }
  1522 +
  1523 + // ----- Get the value
  1524 + if ( is_string($p_options_list[$i+1])
  1525 + && ($p_options_list[$i+1] != '')) {
  1526 + $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
  1527 + $i++;
  1528 + }
  1529 + else {
  1530 + }
  1531 + break;
  1532 +
  1533 + // ----- Look for options that request an array of string for value
  1534 + case PCLZIP_OPT_BY_NAME :
  1535 + // ----- Check the number of parameters
  1536 + if (($i+1) >= $p_size) {
  1537 + // ----- Error log
  1538 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1539 +
  1540 + // ----- Return
  1541 + return PclZip::errorCode();
  1542 + }
  1543 +
  1544 + // ----- Get the value
  1545 + if (is_string($p_options_list[$i+1])) {
  1546 + $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
  1547 + }
  1548 + else if (is_array($p_options_list[$i+1])) {
  1549 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1550 + }
  1551 + else {
  1552 + // ----- Error log
  1553 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1554 +
  1555 + // ----- Return
  1556 + return PclZip::errorCode();
  1557 + }
  1558 + $i++;
  1559 + break;
  1560 +
  1561 + // ----- Look for options that request an EREG or PREG expression
  1562 + case PCLZIP_OPT_BY_EREG :
  1563 + // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG
  1564 + // to PCLZIP_OPT_BY_PREG
  1565 + $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
  1566 + case PCLZIP_OPT_BY_PREG :
  1567 + //case PCLZIP_OPT_CRYPT :
  1568 + // ----- Check the number of parameters
  1569 + if (($i+1) >= $p_size) {
  1570 + // ----- Error log
  1571 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1572 +
  1573 + // ----- Return
  1574 + return PclZip::errorCode();
  1575 + }
  1576 +
  1577 + // ----- Get the value
  1578 + if (is_string($p_options_list[$i+1])) {
  1579 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1580 + }
  1581 + else {
  1582 + // ----- Error log
  1583 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1584 +
  1585 + // ----- Return
  1586 + return PclZip::errorCode();
  1587 + }
  1588 + $i++;
  1589 + break;
  1590 +
  1591 + // ----- Look for options that takes a string
  1592 + case PCLZIP_OPT_COMMENT :
  1593 + case PCLZIP_OPT_ADD_COMMENT :
  1594 + case PCLZIP_OPT_PREPEND_COMMENT :
  1595 + // ----- Check the number of parameters
  1596 + if (($i+1) >= $p_size) {
  1597 + // ----- Error log
  1598 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
  1599 + "Missing parameter value for option '"
  1600 + .PclZipUtilOptionText($p_options_list[$i])
  1601 + ."'");
  1602 +
  1603 + // ----- Return
  1604 + return PclZip::errorCode();
  1605 + }
  1606 +
  1607 + // ----- Get the value
  1608 + if (is_string($p_options_list[$i+1])) {
  1609 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1610 + }
  1611 + else {
  1612 + // ----- Error log
  1613 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
  1614 + "Wrong parameter value for option '"
  1615 + .PclZipUtilOptionText($p_options_list[$i])
  1616 + ."'");
  1617 +
  1618 + // ----- Return
  1619 + return PclZip::errorCode();
  1620 + }
  1621 + $i++;
  1622 + break;
  1623 +
  1624 + // ----- Look for options that request an array of index
  1625 + case PCLZIP_OPT_BY_INDEX :
  1626 + // ----- Check the number of parameters
  1627 + if (($i+1) >= $p_size) {
  1628 + // ----- Error log
  1629 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1630 +
  1631 + // ----- Return
  1632 + return PclZip::errorCode();
  1633 + }
  1634 +
  1635 + // ----- Get the value
  1636 + $v_work_list = array();
  1637 + if (is_string($p_options_list[$i+1])) {
  1638 +
  1639 + // ----- Remove spaces
  1640 + $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
  1641 +
  1642 + // ----- Parse items
  1643 + $v_work_list = explode(",", $p_options_list[$i+1]);
  1644 + }
  1645 + else if (is_integer($p_options_list[$i+1])) {
  1646 + $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
  1647 + }
  1648 + else if (is_array($p_options_list[$i+1])) {
  1649 + $v_work_list = $p_options_list[$i+1];
  1650 + }
  1651 + else {
  1652 + // ----- Error log
  1653 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1654 +
  1655 + // ----- Return
  1656 + return PclZip::errorCode();
  1657 + }
  1658 +
  1659 + // ----- Reduce the index list
  1660 + // each index item in the list must be a couple with a start and
  1661 + // an end value : [0,3], [5-5], [8-10], ...
  1662 + // ----- Check the format of each item
  1663 + $v_sort_flag=false;
  1664 + $v_sort_value=0;
  1665 + for ($j=0; $j<sizeof($v_work_list); $j++) {
  1666 + // ----- Explode the item
  1667 + $v_item_list = explode("-", $v_work_list[$j]);
  1668 + $v_size_item_list = sizeof($v_item_list);
  1669 +
  1670 + // ----- TBC : Here we might check that each item is a
  1671 + // real integer ...
  1672 +
  1673 + // ----- Look for single value
  1674 + if ($v_size_item_list == 1) {
  1675 + // ----- Set the option value
  1676 + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1677 + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
  1678 + }
  1679 + elseif ($v_size_item_list == 2) {
  1680 + // ----- Set the option value
  1681 + $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
  1682 + $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
  1683 + }
  1684 + else {
  1685 + // ----- Error log
  1686 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1687 +
  1688 + // ----- Return
  1689 + return PclZip::errorCode();
  1690 + }
  1691 +
  1692 +
  1693 + // ----- Look for list sort
  1694 + if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
  1695 + $v_sort_flag=true;
  1696 +
  1697 + // ----- TBC : An automatic sort should be writen ...
  1698 + // ----- Error log
  1699 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1700 +
  1701 + // ----- Return
  1702 + return PclZip::errorCode();
  1703 + }
  1704 + $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
  1705 + }
  1706 +
  1707 + // ----- Sort the items
  1708 + if ($v_sort_flag) {
  1709 + // TBC : To Be Completed
  1710 + }
  1711 +
  1712 + // ----- Next option
  1713 + $i++;
  1714 + break;
  1715 +
  1716 + // ----- Look for options that request no value
  1717 + case PCLZIP_OPT_REMOVE_ALL_PATH :
  1718 + case PCLZIP_OPT_EXTRACT_AS_STRING :
  1719 + case PCLZIP_OPT_NO_COMPRESSION :
  1720 + case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
  1721 + case PCLZIP_OPT_REPLACE_NEWER :
  1722 + case PCLZIP_OPT_STOP_ON_ERROR :
  1723 + $v_result_list[$p_options_list[$i]] = true;
  1724 + break;
  1725 +
  1726 + // ----- Look for options that request an octal value
  1727 + case PCLZIP_OPT_SET_CHMOD :
  1728 + // ----- Check the number of parameters
  1729 + if (($i+1) >= $p_size) {
  1730 + // ----- Error log
  1731 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1732 +
  1733 + // ----- Return
  1734 + return PclZip::errorCode();
  1735 + }
  1736 +
  1737 + // ----- Get the value
  1738 + $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
  1739 + $i++;
  1740 + break;
  1741 +
  1742 + // ----- Look for options that request a call-back
  1743 + case PCLZIP_CB_PRE_EXTRACT :
  1744 + case PCLZIP_CB_POST_EXTRACT :
  1745 + case PCLZIP_CB_PRE_ADD :
  1746 + case PCLZIP_CB_POST_ADD :
  1747 + /* for futur use
  1748 + case PCLZIP_CB_PRE_DELETE :
  1749 + case PCLZIP_CB_POST_DELETE :
  1750 + case PCLZIP_CB_PRE_LIST :
  1751 + case PCLZIP_CB_POST_LIST :
  1752 + */
  1753 + // ----- Check the number of parameters
  1754 + if (($i+1) >= $p_size) {
  1755 + // ----- Error log
  1756 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1757 +
  1758 + // ----- Return
  1759 + return PclZip::errorCode();
  1760 + }
  1761 +
  1762 + // ----- Get the value
  1763 + $v_function_name = $p_options_list[$i+1];
  1764 +
  1765 + // ----- Check that the value is a valid existing function
  1766 + if (!function_exists($v_function_name)) {
  1767 + // ----- Error log
  1768 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
  1769 +
  1770 + // ----- Return
  1771 + return PclZip::errorCode();
  1772 + }
  1773 +
  1774 + // ----- Set the attribute
  1775 + $v_result_list[$p_options_list[$i]] = $v_function_name;
  1776 + $i++;
  1777 + break;
  1778 +
  1779 + default :
  1780 + // ----- Error log
  1781 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  1782 + "Unknown parameter '"
  1783 + .$p_options_list[$i]."'");
  1784 +
  1785 + // ----- Return
  1786 + return PclZip::errorCode();
  1787 + }
  1788 +
  1789 + // ----- Next options
  1790 + $i++;
  1791 + }
  1792 +
  1793 + // ----- Look for mandatory options
  1794 + if ($v_requested_options !== false) {
  1795 + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1796 + // ----- Look for mandatory option
  1797 + if ($v_requested_options[$key] == 'mandatory') {
  1798 + // ----- Look if present
  1799 + if (!isset($v_result_list[$key])) {
  1800 + // ----- Error log
  1801 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1802 +
  1803 + // ----- Return
  1804 + return PclZip::errorCode();
  1805 + }
  1806 + }
  1807 + }
  1808 + }
  1809 +
  1810 + // ----- Look for default values
  1811 + if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
  1812 +
  1813 + }
  1814 +
  1815 + // ----- Return
  1816 + return $v_result;
  1817 + }
  1818 + // --------------------------------------------------------------------------------
  1819 +
  1820 + // --------------------------------------------------------------------------------
  1821 + // Function : privOptionDefaultThreshold()
  1822 + // Description :
  1823 + // Parameters :
  1824 + // Return Values :
  1825 + // --------------------------------------------------------------------------------
  1826 + function privOptionDefaultThreshold(&$p_options)
  1827 + {
  1828 + $v_result=1;
  1829 +
  1830 + if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
  1831 + || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
  1832 + return $v_result;
  1833 + }
  1834 +
  1835 + // ----- Get 'memory_limit' configuration value
  1836 + $v_memory_limit = ini_get('memory_limit');
  1837 + $v_memory_limit = trim($v_memory_limit);
  1838 + $last = strtolower(substr($v_memory_limit, -1));
  1839 +
  1840 + if($last == 'g')
  1841 + //$v_memory_limit = $v_memory_limit*1024*1024*1024;
  1842 + $v_memory_limit = $v_memory_limit*1073741824;
  1843 + if($last == 'm')
  1844 + //$v_memory_limit = $v_memory_limit*1024*1024;
  1845 + $v_memory_limit = $v_memory_limit*1048576;
  1846 + if($last == 'k')
  1847 + $v_memory_limit = $v_memory_limit*1024;
  1848 +
  1849 + $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
  1850 +
  1851 +
  1852 + // ----- Sanity check : No threshold if value lower than 1M
  1853 + if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
  1854 + unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
  1855 + }
  1856 +
  1857 + // ----- Return
  1858 + return $v_result;
  1859 + }
  1860 + // --------------------------------------------------------------------------------
  1861 +
  1862 + // --------------------------------------------------------------------------------
  1863 + // Function : privFileDescrParseAtt()
  1864 + // Description :
  1865 + // Parameters :
  1866 + // Return Values :
  1867 + // 1 on success.
  1868 + // 0 on failure.
  1869 + // --------------------------------------------------------------------------------
  1870 + function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
  1871 + {
  1872 + $v_result=1;
  1873 +
  1874 + // ----- For each file in the list check the attributes
  1875 + foreach ($p_file_list as $v_key => $v_value) {
  1876 +
  1877 + // ----- Check if the option is supported
  1878 + if (!isset($v_requested_options[$v_key])) {
  1879 + // ----- Error log
  1880 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
  1881 +
  1882 + // ----- Return
  1883 + return PclZip::errorCode();
  1884 + }
  1885 +
  1886 + // ----- Look for attribute
  1887 + switch ($v_key) {
  1888 + case PCLZIP_ATT_FILE_NAME :
  1889 + if (!is_string($v_value)) {
  1890 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1891 + return PclZip::errorCode();
  1892 + }
  1893 +
  1894 + $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
  1895 +
  1896 + if ($p_filedescr['filename'] == '') {
  1897 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1898 + return PclZip::errorCode();
  1899 + }
  1900 +
  1901 + break;
  1902 +
  1903 + case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
  1904 + if (!is_string($v_value)) {
  1905 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1906 + return PclZip::errorCode();
  1907 + }
  1908 +
  1909 + $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
  1910 +
  1911 + if ($p_filedescr['new_short_name'] == '') {
  1912 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1913 + return PclZip::errorCode();
  1914 + }
  1915 + break;
  1916 +
  1917 + case PCLZIP_ATT_FILE_NEW_FULL_NAME :
  1918 + if (!is_string($v_value)) {
  1919 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1920 + return PclZip::errorCode();
  1921 + }
  1922 +
  1923 + $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
  1924 +
  1925 + if ($p_filedescr['new_full_name'] == '') {
  1926 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
  1927 + return PclZip::errorCode();
  1928 + }
  1929 + break;
  1930 +
  1931 + // ----- Look for options that takes a string
  1932 + case PCLZIP_ATT_FILE_COMMENT :
  1933 + if (!is_string($v_value)) {
  1934 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1935 + return PclZip::errorCode();
  1936 + }
  1937 +
  1938 + $p_filedescr['comment'] = $v_value;
  1939 + break;
  1940 +
  1941 + case PCLZIP_ATT_FILE_MTIME :
  1942 + if (!is_integer($v_value)) {
  1943 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
  1944 + return PclZip::errorCode();
  1945 + }
  1946 +
  1947 + $p_filedescr['mtime'] = $v_value;
  1948 + break;
  1949 +
  1950 + case PCLZIP_ATT_FILE_CONTENT :
  1951 + $p_filedescr['content'] = $v_value;
  1952 + break;
  1953 +
  1954 + default :
  1955 + // ----- Error log
  1956 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
  1957 + "Unknown parameter '".$v_key."'");
  1958 +
  1959 + // ----- Return
  1960 + return PclZip::errorCode();
  1961 + }
  1962 +
  1963 + // ----- Look for mandatory options
  1964 + if ($v_requested_options !== false) {
  1965 + for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
  1966 + // ----- Look for mandatory option
  1967 + if ($v_requested_options[$key] == 'mandatory') {
  1968 + // ----- Look if present
  1969 + if (!isset($p_file_list[$key])) {
  1970 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
  1971 + return PclZip::errorCode();
  1972 + }
  1973 + }
  1974 + }
  1975 + }
  1976 +
  1977 + // end foreach
  1978 + }
  1979 +
  1980 + // ----- Return
  1981 + return $v_result;
  1982 + }
  1983 + // --------------------------------------------------------------------------------
  1984 +
  1985 + // --------------------------------------------------------------------------------
  1986 + // Function : privFileDescrExpand()
  1987 + // Description :
  1988 + // This method look for each item of the list to see if its a file, a folder
  1989 + // or a string to be added as file. For any other type of files (link, other)
  1990 + // just ignore the item.
  1991 + // Then prepare the information that will be stored for that file.
  1992 + // When its a folder, expand the folder with all the files that are in that
  1993 + // folder (recursively).
  1994 + // Parameters :
  1995 + // Return Values :
  1996 + // 1 on success.
  1997 + // 0 on failure.
  1998 + // --------------------------------------------------------------------------------
  1999 + function privFileDescrExpand(&$p_filedescr_list, &$p_options)
  2000 + {
  2001 + $v_result=1;
  2002 +
  2003 + // ----- Create a result list
  2004 + $v_result_list = array();
  2005 +
  2006 + // ----- Look each entry
  2007 + for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
  2008 +
  2009 + // ----- Get filedescr
  2010 + $v_descr = $p_filedescr_list[$i];
  2011 +
  2012 + // ----- Reduce the filename
  2013 + $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
  2014 + $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
  2015 +
  2016 + // ----- Look for real file or folder
  2017 + if (file_exists($v_descr['filename'])) {
  2018 + if (@is_file($v_descr['filename'])) {
  2019 + $v_descr['type'] = 'file';
  2020 + }
  2021 + else if (@is_dir($v_descr['filename'])) {
  2022 + $v_descr['type'] = 'folder';
  2023 + }
  2024 + else if (@is_link($v_descr['filename'])) {
  2025 + // skip
  2026 + continue;
  2027 + }
  2028 + else {
  2029 + // skip
  2030 + continue;
  2031 + }
  2032 + }
  2033 +
  2034 + // ----- Look for string added as file
  2035 + else if (isset($v_descr['content'])) {
  2036 + $v_descr['type'] = 'virtual_file';
  2037 + }
  2038 +
  2039 + // ----- Missing file
  2040 + else {
  2041 + // ----- Error log
  2042 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
  2043 +
  2044 + // ----- Return
  2045 + return PclZip::errorCode();
  2046 + }
  2047 +
  2048 + // ----- Calculate the stored filename
  2049 + $this->privCalculateStoredFilename($v_descr, $p_options);
  2050 +
  2051 + // ----- Add the descriptor in result list
  2052 + $v_result_list[sizeof($v_result_list)] = $v_descr;
  2053 +
  2054 + // ----- Look for folder
  2055 + if ($v_descr['type'] == 'folder') {
  2056 + // ----- List of items in folder
  2057 + $v_dirlist_descr = array();
  2058 + $v_dirlist_nb = 0;
  2059 + if ($v_folder_handler = @opendir($v_descr['filename'])) {
  2060 + while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
  2061 +
  2062 + // ----- Skip '.' and '..'
  2063 + if (($v_item_handler == '.') || ($v_item_handler == '..')) {
  2064 + continue;
  2065 + }
  2066 +
  2067 + // ----- Compose the full filename
  2068 + $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
  2069 +
  2070 + // ----- Look for different stored filename
  2071 + // Because the name of the folder was changed, the name of the
  2072 + // files/sub-folders also change
  2073 + if (($v_descr['stored_filename'] != $v_descr['filename'])
  2074 + && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
  2075 + if ($v_descr['stored_filename'] != '') {
  2076 + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
  2077 + }
  2078 + else {
  2079 + $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
  2080 + }
  2081 + }
  2082 +
  2083 + $v_dirlist_nb++;
  2084 + }
  2085 +
  2086 + @closedir($v_folder_handler);
  2087 + }
  2088 + else {
  2089 + // TBC : unable to open folder in read mode
  2090 + }
  2091 +
  2092 + // ----- Expand each element of the list
  2093 + if ($v_dirlist_nb != 0) {
  2094 + // ----- Expand
  2095 + if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
  2096 + return $v_result;
  2097 + }
  2098 +
  2099 + // ----- Concat the resulting list
  2100 + $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
  2101 + }
  2102 + else {
  2103 + }
  2104 +
  2105 + // ----- Free local array
  2106 + unset($v_dirlist_descr);
  2107 + }
  2108 + }
  2109 +
  2110 + // ----- Get the result list
  2111 + $p_filedescr_list = $v_result_list;
  2112 +
  2113 + // ----- Return
  2114 + return $v_result;
  2115 + }
  2116 + // --------------------------------------------------------------------------------
  2117 +
  2118 + // --------------------------------------------------------------------------------
  2119 + // Function : privCreate()
  2120 + // Description :
  2121 + // Parameters :
  2122 + // Return Values :
  2123 + // --------------------------------------------------------------------------------
  2124 + function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
  2125 + {
  2126 + $v_result=1;
  2127 + $v_list_detail = array();
  2128 +
  2129 + // ----- Magic quotes trick
  2130 + $this->privDisableMagicQuotes();
  2131 +
  2132 + // ----- Open the file in write mode
  2133 + if (($v_result = $this->privOpenFd('wb')) != 1)
  2134 + {
  2135 + // ----- Return
  2136 + return $v_result;
  2137 + }
  2138 +
  2139 + // ----- Add the list of files
  2140 + $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
  2141 +
  2142 + // ----- Close
  2143 + $this->privCloseFd();
  2144 +
  2145 + // ----- Magic quotes trick
  2146 + $this->privSwapBackMagicQuotes();
  2147 +
  2148 + // ----- Return
  2149 + return $v_result;
  2150 + }
  2151 + // --------------------------------------------------------------------------------
  2152 +
  2153 + // --------------------------------------------------------------------------------
  2154 + // Function : privAdd()
  2155 + // Description :
  2156 + // Parameters :
  2157 + // Return Values :
  2158 + // --------------------------------------------------------------------------------
  2159 + function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
  2160 + {
  2161 + $v_result=1;
  2162 + $v_list_detail = array();
  2163 +
  2164 + // ----- Look if the archive exists or is empty
  2165 + if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
  2166 + {
  2167 +
  2168 + // ----- Do a create
  2169 + $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
  2170 +
  2171 + // ----- Return
  2172 + return $v_result;
  2173 + }
  2174 + // ----- Magic quotes trick
  2175 + $this->privDisableMagicQuotes();
  2176 +
  2177 + // ----- Open the zip file
  2178 + if (($v_result=$this->privOpenFd('rb')) != 1)
  2179 + {
  2180 + // ----- Magic quotes trick
  2181 + $this->privSwapBackMagicQuotes();
  2182 +
  2183 + // ----- Return
  2184 + return $v_result;
  2185 + }
  2186 +
  2187 + // ----- Read the central directory informations
  2188 + $v_central_dir = array();
  2189 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  2190 + {
  2191 + $this->privCloseFd();
  2192 + $this->privSwapBackMagicQuotes();
  2193 + return $v_result;
  2194 + }
  2195 +
  2196 + // ----- Go to beginning of File
  2197 + @rewind($this->zip_fd);
  2198 +
  2199 + // ----- Creates a temporay file
  2200 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  2201 +
  2202 + // ----- Open the temporary file in write mode
  2203 + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  2204 + {
  2205 + $this->privCloseFd();
  2206 + $this->privSwapBackMagicQuotes();
  2207 +
  2208 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  2209 +
  2210 + // ----- Return
  2211 + return PclZip::errorCode();
  2212 + }
  2213 +
  2214 + // ----- Copy the files from the archive to the temporary file
  2215 + // TBC : Here I should better append the file and go back to erase the central dir
  2216 + $v_size = $v_central_dir['offset'];
  2217 + while ($v_size != 0)
  2218 + {
  2219 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2220 + $v_buffer = fread($this->zip_fd, $v_read_size);
  2221 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  2222 + $v_size -= $v_read_size;
  2223 + }
  2224 +
  2225 + // ----- Swap the file descriptor
  2226 + // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  2227 + // the following methods on the temporary fil and not the real archive
  2228 + $v_swap = $this->zip_fd;
  2229 + $this->zip_fd = $v_zip_temp_fd;
  2230 + $v_zip_temp_fd = $v_swap;
  2231 +
  2232 + // ----- Add the files
  2233 + $v_header_list = array();
  2234 + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
  2235 + {
  2236 + fclose($v_zip_temp_fd);
  2237 + $this->privCloseFd();
  2238 + @unlink($v_zip_temp_name);
  2239 + $this->privSwapBackMagicQuotes();
  2240 +
  2241 + // ----- Return
  2242 + return $v_result;
  2243 + }
  2244 +
  2245 + // ----- Store the offset of the central dir
  2246 + $v_offset = @ftell($this->zip_fd);
  2247 +
  2248 + // ----- Copy the block of file headers from the old archive
  2249 + $v_size = $v_central_dir['size'];
  2250 + while ($v_size != 0)
  2251 + {
  2252 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2253 + $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
  2254 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  2255 + $v_size -= $v_read_size;
  2256 + }
  2257 +
  2258 + // ----- Create the Central Dir files header
  2259 + for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
  2260 + {
  2261 + // ----- Create the file header
  2262 + if ($v_header_list[$i]['status'] == 'ok') {
  2263 + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  2264 + fclose($v_zip_temp_fd);
  2265 + $this->privCloseFd();
  2266 + @unlink($v_zip_temp_name);
  2267 + $this->privSwapBackMagicQuotes();
  2268 +
  2269 + // ----- Return
  2270 + return $v_result;
  2271 + }
  2272 + $v_count++;
  2273 + }
  2274 +
  2275 + // ----- Transform the header to a 'usable' info
  2276 + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  2277 + }
  2278 +
  2279 + // ----- Zip file comment
  2280 + $v_comment = $v_central_dir['comment'];
  2281 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  2282 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  2283 + }
  2284 + if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
  2285 + $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
  2286 + }
  2287 + if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
  2288 + $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
  2289 + }
  2290 +
  2291 + // ----- Calculate the size of the central header
  2292 + $v_size = @ftell($this->zip_fd)-$v_offset;
  2293 +
  2294 + // ----- Create the central dir footer
  2295 + if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
  2296 + {
  2297 + // ----- Reset the file list
  2298 + unset($v_header_list);
  2299 + $this->privSwapBackMagicQuotes();
  2300 +
  2301 + // ----- Return
  2302 + return $v_result;
  2303 + }
  2304 +
  2305 + // ----- Swap back the file descriptor
  2306 + $v_swap = $this->zip_fd;
  2307 + $this->zip_fd = $v_zip_temp_fd;
  2308 + $v_zip_temp_fd = $v_swap;
  2309 +
  2310 + // ----- Close
  2311 + $this->privCloseFd();
  2312 +
  2313 + // ----- Close the temporary file
  2314 + @fclose($v_zip_temp_fd);
  2315 +
  2316 + // ----- Magic quotes trick
  2317 + $this->privSwapBackMagicQuotes();
  2318 +
  2319 + // ----- Delete the zip file
  2320 + // TBC : I should test the result ...
  2321 + @unlink($this->zipname);
  2322 +
  2323 + // ----- Rename the temporary file
  2324 + // TBC : I should test the result ...
  2325 + //@rename($v_zip_temp_name, $this->zipname);
  2326 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  2327 +
  2328 + // ----- Return
  2329 + return $v_result;
  2330 + }
  2331 + // --------------------------------------------------------------------------------
  2332 +
  2333 + // --------------------------------------------------------------------------------
  2334 + // Function : privOpenFd()
  2335 + // Description :
  2336 + // Parameters :
  2337 + // --------------------------------------------------------------------------------
  2338 + function privOpenFd($p_mode)
  2339 + {
  2340 + $v_result=1;
  2341 +
  2342 + // ----- Look if already open
  2343 + if ($this->zip_fd != 0)
  2344 + {
  2345 + // ----- Error log
  2346 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
  2347 +
  2348 + // ----- Return
  2349 + return PclZip::errorCode();
  2350 + }
  2351 +
  2352 + // ----- Open the zip file
  2353 + if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
  2354 + {
  2355 + // ----- Error log
  2356 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
  2357 +
  2358 + // ----- Return
  2359 + return PclZip::errorCode();
  2360 + }
  2361 +
  2362 + // ----- Return
  2363 + return $v_result;
  2364 + }
  2365 + // --------------------------------------------------------------------------------
  2366 +
  2367 + // --------------------------------------------------------------------------------
  2368 + // Function : privCloseFd()
  2369 + // Description :
  2370 + // Parameters :
  2371 + // --------------------------------------------------------------------------------
  2372 + function privCloseFd()
  2373 + {
  2374 + $v_result=1;
  2375 +
  2376 + if ($this->zip_fd != 0)
  2377 + @fclose($this->zip_fd);
  2378 + $this->zip_fd = 0;
  2379 +
  2380 + // ----- Return
  2381 + return $v_result;
  2382 + }
  2383 + // --------------------------------------------------------------------------------
  2384 +
  2385 + // --------------------------------------------------------------------------------
  2386 + // Function : privAddList()
  2387 + // Description :
  2388 + // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
  2389 + // different from the real path of the file. This is usefull if you want to have PclTar
  2390 + // running in any directory, and memorize relative path from an other directory.
  2391 + // Parameters :
  2392 + // $p_list : An array containing the file or directory names to add in the tar
  2393 + // $p_result_list : list of added files with their properties (specially the status field)
  2394 + // $p_add_dir : Path to add in the filename path archived
  2395 + // $p_remove_dir : Path to remove in the filename path archived
  2396 + // Return Values :
  2397 + // --------------------------------------------------------------------------------
  2398 +// function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
  2399 + function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
  2400 + {
  2401 + $v_result=1;
  2402 +
  2403 + // ----- Add the files
  2404 + $v_header_list = array();
  2405 + if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
  2406 + {
  2407 + // ----- Return
  2408 + return $v_result;
  2409 + }
  2410 +
  2411 + // ----- Store the offset of the central dir
  2412 + $v_offset = @ftell($this->zip_fd);
  2413 +
  2414 + // ----- Create the Central Dir files header
  2415 + for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
  2416 + {
  2417 + // ----- Create the file header
  2418 + if ($v_header_list[$i]['status'] == 'ok') {
  2419 + if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  2420 + // ----- Return
  2421 + return $v_result;
  2422 + }
  2423 + $v_count++;
  2424 + }
  2425 +
  2426 + // ----- Transform the header to a 'usable' info
  2427 + $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  2428 + }
  2429 +
  2430 + // ----- Zip file comment
  2431 + $v_comment = '';
  2432 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  2433 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  2434 + }
  2435 +
  2436 + // ----- Calculate the size of the central header
  2437 + $v_size = @ftell($this->zip_fd)-$v_offset;
  2438 +
  2439 + // ----- Create the central dir footer
  2440 + if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
  2441 + {
  2442 + // ----- Reset the file list
  2443 + unset($v_header_list);
  2444 +
  2445 + // ----- Return
  2446 + return $v_result;
  2447 + }
  2448 +
  2449 + // ----- Return
  2450 + return $v_result;
  2451 + }
  2452 + // --------------------------------------------------------------------------------
  2453 +
  2454 + // --------------------------------------------------------------------------------
  2455 + // Function : privAddFileList()
  2456 + // Description :
  2457 + // Parameters :
  2458 + // $p_filedescr_list : An array containing the file description
  2459 + // or directory names to add in the zip
  2460 + // $p_result_list : list of added files with their properties (specially the status field)
  2461 + // Return Values :
  2462 + // --------------------------------------------------------------------------------
  2463 + function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
  2464 + {
  2465 + $v_result=1;
  2466 + $v_header = array();
  2467 +
  2468 + // ----- Recuperate the current number of elt in list
  2469 + $v_nb = sizeof($p_result_list);
  2470 +
  2471 + // ----- Loop on the files
  2472 + for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
  2473 + // ----- Format the filename
  2474 + $p_filedescr_list[$j]['filename']
  2475 + = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
  2476 +
  2477 +
  2478 + // ----- Skip empty file names
  2479 + // TBC : Can this be possible ? not checked in DescrParseAtt ?
  2480 + if ($p_filedescr_list[$j]['filename'] == "") {
  2481 + continue;
  2482 + }
  2483 +
  2484 + // ----- Check the filename
  2485 + if ( ($p_filedescr_list[$j]['type'] != 'virtual_file')
  2486 + && (!file_exists($p_filedescr_list[$j]['filename']))) {
  2487 + PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
  2488 + return PclZip::errorCode();
  2489 + }
  2490 +
  2491 + // ----- Look if it is a file or a dir with no all path remove option
  2492 + // or a dir with all its path removed
  2493 +// if ( (is_file($p_filedescr_list[$j]['filename']))
  2494 +// || ( is_dir($p_filedescr_list[$j]['filename'])
  2495 + if ( ($p_filedescr_list[$j]['type'] == 'file')
  2496 + || ($p_filedescr_list[$j]['type'] == 'virtual_file')
  2497 + || ( ($p_filedescr_list[$j]['type'] == 'folder')
  2498 + && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
  2499 + || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
  2500 + ) {
  2501 +
  2502 + // ----- Add the file
  2503 + $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
  2504 + $p_options);
  2505 + if ($v_result != 1) {
  2506 + return $v_result;
  2507 + }
  2508 +
  2509 + // ----- Store the file infos
  2510 + $p_result_list[$v_nb++] = $v_header;
  2511 + }
  2512 + }
  2513 +
  2514 + // ----- Return
  2515 + return $v_result;
  2516 + }
  2517 + // --------------------------------------------------------------------------------
  2518 +
  2519 + // --------------------------------------------------------------------------------
  2520 + // Function : privAddFile()
  2521 + // Description :
  2522 + // Parameters :
  2523 + // Return Values :
  2524 + // --------------------------------------------------------------------------------
  2525 + function privAddFile($p_filedescr, &$p_header, &$p_options)
  2526 + {
  2527 + $v_result=1;
  2528 +
  2529 + // ----- Working variable
  2530 + $p_filename = $p_filedescr['filename'];
  2531 +
  2532 + // TBC : Already done in the fileAtt check ... ?
  2533 + if ($p_filename == "") {
  2534 + // ----- Error log
  2535 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
  2536 +
  2537 + // ----- Return
  2538 + return PclZip::errorCode();
  2539 + }
  2540 +
  2541 + // ----- Look for a stored different filename
  2542 + /* TBC : Removed
  2543 + if (isset($p_filedescr['stored_filename'])) {
  2544 + $v_stored_filename = $p_filedescr['stored_filename'];
  2545 + }
  2546 + else {
  2547 + $v_stored_filename = $p_filedescr['stored_filename'];
  2548 + }
  2549 + */
  2550 +
  2551 + // ----- Set the file properties
  2552 + clearstatcache();
  2553 + $p_header['version'] = 20;
  2554 + $p_header['version_extracted'] = 10;
  2555 + $p_header['flag'] = 0;
  2556 + $p_header['compression'] = 0;
  2557 + $p_header['crc'] = 0;
  2558 + $p_header['compressed_size'] = 0;
  2559 + $p_header['filename_len'] = strlen($p_filename);
  2560 + $p_header['extra_len'] = 0;
  2561 + $p_header['disk'] = 0;
  2562 + $p_header['internal'] = 0;
  2563 + $p_header['offset'] = 0;
  2564 + $p_header['filename'] = $p_filename;
  2565 +// TBC : Removed $p_header['stored_filename'] = $v_stored_filename;
  2566 + $p_header['stored_filename'] = $p_filedescr['stored_filename'];
  2567 + $p_header['extra'] = '';
  2568 + $p_header['status'] = 'ok';
  2569 + $p_header['index'] = -1;
  2570 +
  2571 + // ----- Look for regular file
  2572 + if ($p_filedescr['type']=='file') {
  2573 + $p_header['external'] = 0x00000000;
  2574 + $p_header['size'] = filesize($p_filename);
  2575 + }
  2576 +
  2577 + // ----- Look for regular folder
  2578 + else if ($p_filedescr['type']=='folder') {
  2579 + $p_header['external'] = 0x00000010;
  2580 + $p_header['mtime'] = filemtime($p_filename);
  2581 + $p_header['size'] = filesize($p_filename);
  2582 + }
  2583 +
  2584 + // ----- Look for virtual file
  2585 + else if ($p_filedescr['type'] == 'virtual_file') {
  2586 + $p_header['external'] = 0x00000000;
  2587 + $p_header['size'] = strlen($p_filedescr['content']);
  2588 + }
  2589 +
  2590 +
  2591 + // ----- Look for filetime
  2592 + if (isset($p_filedescr['mtime'])) {
  2593 + $p_header['mtime'] = $p_filedescr['mtime'];
  2594 + }
  2595 + else if ($p_filedescr['type'] == 'virtual_file') {
  2596 + $p_header['mtime'] = time();
  2597 + }
  2598 + else {
  2599 + $p_header['mtime'] = filemtime($p_filename);
  2600 + }
  2601 +
  2602 + // ------ Look for file comment
  2603 + if (isset($p_filedescr['comment'])) {
  2604 + $p_header['comment_len'] = strlen($p_filedescr['comment']);
  2605 + $p_header['comment'] = $p_filedescr['comment'];
  2606 + }
  2607 + else {
  2608 + $p_header['comment_len'] = 0;
  2609 + $p_header['comment'] = '';
  2610 + }
  2611 +
  2612 + // ----- Look for pre-add callback
  2613 + if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
  2614 +
  2615 + // ----- Generate a local information
  2616 + $v_local_header = array();
  2617 + $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2618 +
  2619 + // ----- Call the callback
  2620 + // Here I do not use call_user_func() because I need to send a reference to the
  2621 + // header.
  2622 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
  2623 + $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header);
  2624 + if ($v_result == 0) {
  2625 + // ----- Change the file status
  2626 + $p_header['status'] = "skipped";
  2627 + $v_result = 1;
  2628 + }
  2629 +
  2630 + // ----- Update the informations
  2631 + // Only some fields can be modified
  2632 + if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
  2633 + $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
  2634 + }
  2635 + }
  2636 +
  2637 + // ----- Look for empty stored filename
  2638 + if ($p_header['stored_filename'] == "") {
  2639 + $p_header['status'] = "filtered";
  2640 + }
  2641 +
  2642 + // ----- Check the path length
  2643 + if (strlen($p_header['stored_filename']) > 0xFF) {
  2644 + $p_header['status'] = 'filename_too_long';
  2645 + }
  2646 +
  2647 + // ----- Look if no error, or file not skipped
  2648 + if ($p_header['status'] == 'ok') {
  2649 +
  2650 + // ----- Look for a file
  2651 + if ($p_filedescr['type'] == 'file') {
  2652 + // ----- Look for using temporary file to zip
  2653 + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
  2654 + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
  2655 + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
  2656 + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
  2657 + $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
  2658 + if ($v_result < PCLZIP_ERR_NO_ERROR) {
  2659 + return $v_result;
  2660 + }
  2661 + }
  2662 +
  2663 + // ----- Use "in memory" zip algo
  2664 + else {
  2665 +
  2666 + // ----- Open the source file
  2667 + if (($v_file = @fopen($p_filename, "rb")) == 0) {
  2668 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
  2669 + return PclZip::errorCode();
  2670 + }
  2671 +
  2672 + // ----- Read the file content
  2673 + $v_content = @fread($v_file, $p_header['size']);
  2674 +
  2675 + // ----- Close the file
  2676 + @fclose($v_file);
  2677 +
  2678 + // ----- Calculate the CRC
  2679 + $p_header['crc'] = @crc32($v_content);
  2680 +
  2681 + // ----- Look for no compression
  2682 + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
  2683 + // ----- Set header parameters
  2684 + $p_header['compressed_size'] = $p_header['size'];
  2685 + $p_header['compression'] = 0;
  2686 + }
  2687 +
  2688 + // ----- Look for normal compression
  2689 + else {
  2690 + // ----- Compress the content
  2691 + $v_content = @gzdeflate($v_content);
  2692 +
  2693 + // ----- Set header parameters
  2694 + $p_header['compressed_size'] = strlen($v_content);
  2695 + $p_header['compression'] = 8;
  2696 + }
  2697 +
  2698 + // ----- Call the header generation
  2699 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2700 + @fclose($v_file);
  2701 + return $v_result;
  2702 + }
  2703 +
  2704 + // ----- Write the compressed (or not) content
  2705 + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
  2706 +
  2707 + }
  2708 +
  2709 + }
  2710 +
  2711 + // ----- Look for a virtual file (a file from string)
  2712 + else if ($p_filedescr['type'] == 'virtual_file') {
  2713 +
  2714 + $v_content = $p_filedescr['content'];
  2715 +
  2716 + // ----- Calculate the CRC
  2717 + $p_header['crc'] = @crc32($v_content);
  2718 +
  2719 + // ----- Look for no compression
  2720 + if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
  2721 + // ----- Set header parameters
  2722 + $p_header['compressed_size'] = $p_header['size'];
  2723 + $p_header['compression'] = 0;
  2724 + }
  2725 +
  2726 + // ----- Look for normal compression
  2727 + else {
  2728 + // ----- Compress the content
  2729 + $v_content = @gzdeflate($v_content);
  2730 +
  2731 + // ----- Set header parameters
  2732 + $p_header['compressed_size'] = strlen($v_content);
  2733 + $p_header['compression'] = 8;
  2734 + }
  2735 +
  2736 + // ----- Call the header generation
  2737 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2738 + @fclose($v_file);
  2739 + return $v_result;
  2740 + }
  2741 +
  2742 + // ----- Write the compressed (or not) content
  2743 + @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
  2744 + }
  2745 +
  2746 + // ----- Look for a directory
  2747 + else if ($p_filedescr['type'] == 'folder') {
  2748 + // ----- Look for directory last '/'
  2749 + if (@substr($p_header['stored_filename'], -1) != '/') {
  2750 + $p_header['stored_filename'] .= '/';
  2751 + }
  2752 +
  2753 + // ----- Set the file properties
  2754 + $p_header['size'] = 0;
  2755 + //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
  2756 + $p_header['external'] = 0x00000010; // Value for a folder : to be checked
  2757 +
  2758 + // ----- Call the header generation
  2759 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
  2760 + {
  2761 + return $v_result;
  2762 + }
  2763 + }
  2764 + }
  2765 +
  2766 + // ----- Look for post-add callback
  2767 + if (isset($p_options[PCLZIP_CB_POST_ADD])) {
  2768 +
  2769 + // ----- Generate a local information
  2770 + $v_local_header = array();
  2771 + $this->privConvertHeader2FileInfo($p_header, $v_local_header);
  2772 +
  2773 + // ----- Call the callback
  2774 + // Here I do not use call_user_func() because I need to send a reference to the
  2775 + // header.
  2776 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
  2777 + $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header);
  2778 + if ($v_result == 0) {
  2779 + // ----- Ignored
  2780 + $v_result = 1;
  2781 + }
  2782 +
  2783 + // ----- Update the informations
  2784 + // Nothing can be modified
  2785 + }
  2786 +
  2787 + // ----- Return
  2788 + return $v_result;
  2789 + }
  2790 + // --------------------------------------------------------------------------------
  2791 +
  2792 + // --------------------------------------------------------------------------------
  2793 + // Function : privAddFileUsingTempFile()
  2794 + // Description :
  2795 + // Parameters :
  2796 + // Return Values :
  2797 + // --------------------------------------------------------------------------------
  2798 + function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
  2799 + {
  2800 + $v_result=PCLZIP_ERR_NO_ERROR;
  2801 +
  2802 + // ----- Working variable
  2803 + $p_filename = $p_filedescr['filename'];
  2804 +
  2805 +
  2806 + // ----- Open the source file
  2807 + if (($v_file = @fopen($p_filename, "rb")) == 0) {
  2808 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
  2809 + return PclZip::errorCode();
  2810 + }
  2811 +
  2812 + // ----- Creates a compressed temporary file
  2813 + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
  2814 + if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
  2815 + fclose($v_file);
  2816 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
  2817 + return PclZip::errorCode();
  2818 + }
  2819 +
  2820 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  2821 + $v_size = filesize($p_filename);
  2822 + while ($v_size != 0) {
  2823 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2824 + $v_buffer = @fread($v_file, $v_read_size);
  2825 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  2826 + @gzputs($v_file_compressed, $v_buffer, $v_read_size);
  2827 + $v_size -= $v_read_size;
  2828 + }
  2829 +
  2830 + // ----- Close the file
  2831 + @fclose($v_file);
  2832 + @gzclose($v_file_compressed);
  2833 +
  2834 + // ----- Check the minimum file size
  2835 + if (filesize($v_gzip_temp_name) < 18) {
  2836 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
  2837 + return PclZip::errorCode();
  2838 + }
  2839 +
  2840 + // ----- Extract the compressed attributes
  2841 + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
  2842 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
  2843 + return PclZip::errorCode();
  2844 + }
  2845 +
  2846 + // ----- Read the gzip file header
  2847 + $v_binary_data = @fread($v_file_compressed, 10);
  2848 + $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
  2849 +
  2850 + // ----- Check some parameters
  2851 + $v_data_header['os'] = bin2hex($v_data_header['os']);
  2852 +
  2853 + // ----- Read the gzip file footer
  2854 + @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
  2855 + $v_binary_data = @fread($v_file_compressed, 8);
  2856 + $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
  2857 +
  2858 + // ----- Set the attributes
  2859 + $p_header['compression'] = ord($v_data_header['cm']);
  2860 + //$p_header['mtime'] = $v_data_header['mtime'];
  2861 + $p_header['crc'] = $v_data_footer['crc'];
  2862 + $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
  2863 +
  2864 + // ----- Close the file
  2865 + @fclose($v_file_compressed);
  2866 +
  2867 + // ----- Call the header generation
  2868 + if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
  2869 + return $v_result;
  2870 + }
  2871 +
  2872 + // ----- Add the compressed data
  2873 + if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
  2874 + {
  2875 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
  2876 + return PclZip::errorCode();
  2877 + }
  2878 +
  2879 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  2880 + fseek($v_file_compressed, 10);
  2881 + $v_size = $p_header['compressed_size'];
  2882 + while ($v_size != 0)
  2883 + {
  2884 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  2885 + $v_buffer = @fread($v_file_compressed, $v_read_size);
  2886 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  2887 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  2888 + $v_size -= $v_read_size;
  2889 + }
  2890 +
  2891 + // ----- Close the file
  2892 + @fclose($v_file_compressed);
  2893 +
  2894 + // ----- Unlink the temporary file
  2895 + @unlink($v_gzip_temp_name);
  2896 +
  2897 + // ----- Return
  2898 + return $v_result;
  2899 + }
  2900 + // --------------------------------------------------------------------------------
  2901 +
  2902 + // --------------------------------------------------------------------------------
  2903 + // Function : privCalculateStoredFilename()
  2904 + // Description :
  2905 + // Based on file descriptor properties and global options, this method
  2906 + // calculate the filename that will be stored in the archive.
  2907 + // Parameters :
  2908 + // Return Values :
  2909 + // --------------------------------------------------------------------------------
  2910 + function privCalculateStoredFilename(&$p_filedescr, &$p_options)
  2911 + {
  2912 + $v_result=1;
  2913 +
  2914 + // ----- Working variables
  2915 + $p_filename = $p_filedescr['filename'];
  2916 + if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
  2917 + $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
  2918 + }
  2919 + else {
  2920 + $p_add_dir = '';
  2921 + }
  2922 + if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
  2923 + $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
  2924 + }
  2925 + else {
  2926 + $p_remove_dir = '';
  2927 + }
  2928 + if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
  2929 + $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
  2930 + }
  2931 + else {
  2932 + $p_remove_all_dir = 0;
  2933 + }
  2934 +
  2935 +
  2936 + // ----- Look for full name change
  2937 + if (isset($p_filedescr['new_full_name'])) {
  2938 + // ----- Remove drive letter if any
  2939 + $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
  2940 + }
  2941 +
  2942 + // ----- Look for path and/or short name change
  2943 + else {
  2944 +
  2945 + // ----- Look for short name change
  2946 + // Its when we cahnge just the filename but not the path
  2947 + if (isset($p_filedescr['new_short_name'])) {
  2948 + $v_path_info = pathinfo($p_filename);
  2949 + $v_dir = '';
  2950 + if ($v_path_info['dirname'] != '') {
  2951 + $v_dir = $v_path_info['dirname'].'/';
  2952 + }
  2953 + $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
  2954 + }
  2955 + else {
  2956 + // ----- Calculate the stored filename
  2957 + $v_stored_filename = $p_filename;
  2958 + }
  2959 +
  2960 + // ----- Look for all path to remove
  2961 + if ($p_remove_all_dir) {
  2962 + $v_stored_filename = basename($p_filename);
  2963 + }
  2964 + // ----- Look for partial path remove
  2965 + else if ($p_remove_dir != "") {
  2966 + if (substr($p_remove_dir, -1) != '/')
  2967 + $p_remove_dir .= "/";
  2968 +
  2969 + if ( (substr($p_filename, 0, 2) == "./")
  2970 + || (substr($p_remove_dir, 0, 2) == "./")) {
  2971 +
  2972 + if ( (substr($p_filename, 0, 2) == "./")
  2973 + && (substr($p_remove_dir, 0, 2) != "./")) {
  2974 + $p_remove_dir = "./".$p_remove_dir;
  2975 + }
  2976 + if ( (substr($p_filename, 0, 2) != "./")
  2977 + && (substr($p_remove_dir, 0, 2) == "./")) {
  2978 + $p_remove_dir = substr($p_remove_dir, 2);
  2979 + }
  2980 + }
  2981 +
  2982 + $v_compare = PclZipUtilPathInclusion($p_remove_dir,
  2983 + $v_stored_filename);
  2984 + if ($v_compare > 0) {
  2985 + if ($v_compare == 2) {
  2986 + $v_stored_filename = "";
  2987 + }
  2988 + else {
  2989 + $v_stored_filename = substr($v_stored_filename,
  2990 + strlen($p_remove_dir));
  2991 + }
  2992 + }
  2993 + }
  2994 +
  2995 + // ----- Remove drive letter if any
  2996 + $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
  2997 +
  2998 + // ----- Look for path to add
  2999 + if ($p_add_dir != "") {
  3000 + if (substr($p_add_dir, -1) == "/")
  3001 + $v_stored_filename = $p_add_dir.$v_stored_filename;
  3002 + else
  3003 + $v_stored_filename = $p_add_dir."/".$v_stored_filename;
  3004 + }
  3005 + }
  3006 +
  3007 + // ----- Filename (reduce the path of stored name)
  3008 + $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
  3009 + $p_filedescr['stored_filename'] = $v_stored_filename;
  3010 +
  3011 + // ----- Return
  3012 + return $v_result;
  3013 + }
  3014 + // --------------------------------------------------------------------------------
  3015 +
  3016 + // --------------------------------------------------------------------------------
  3017 + // Function : privWriteFileHeader()
  3018 + // Description :
  3019 + // Parameters :
  3020 + // Return Values :
  3021 + // --------------------------------------------------------------------------------
  3022 + function privWriteFileHeader(&$p_header)
  3023 + {
  3024 + $v_result=1;
  3025 +
  3026 + // ----- Store the offset position of the file
  3027 + $p_header['offset'] = ftell($this->zip_fd);
  3028 +
  3029 + // ----- Transform UNIX mtime to DOS format mdate/mtime
  3030 + $v_date = getdate($p_header['mtime']);
  3031 + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  3032 + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  3033 +
  3034 + // ----- Packed data
  3035 + $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
  3036 + $p_header['version_extracted'], $p_header['flag'],
  3037 + $p_header['compression'], $v_mtime, $v_mdate,
  3038 + $p_header['crc'], $p_header['compressed_size'],
  3039 + $p_header['size'],
  3040 + strlen($p_header['stored_filename']),
  3041 + $p_header['extra_len']);
  3042 +
  3043 + // ----- Write the first 148 bytes of the header in the archive
  3044 + fputs($this->zip_fd, $v_binary_data, 30);
  3045 +
  3046 + // ----- Write the variable fields
  3047 + if (strlen($p_header['stored_filename']) != 0)
  3048 + {
  3049 + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  3050 + }
  3051 + if ($p_header['extra_len'] != 0)
  3052 + {
  3053 + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  3054 + }
  3055 +
  3056 + // ----- Return
  3057 + return $v_result;
  3058 + }
  3059 + // --------------------------------------------------------------------------------
  3060 +
  3061 + // --------------------------------------------------------------------------------
  3062 + // Function : privWriteCentralFileHeader()
  3063 + // Description :
  3064 + // Parameters :
  3065 + // Return Values :
  3066 + // --------------------------------------------------------------------------------
  3067 + function privWriteCentralFileHeader(&$p_header)
  3068 + {
  3069 + $v_result=1;
  3070 +
  3071 + // TBC
  3072 + //for(reset($p_header); $key = key($p_header); next($p_header)) {
  3073 + //}
  3074 +
  3075 + // ----- Transform UNIX mtime to DOS format mdate/mtime
  3076 + $v_date = getdate($p_header['mtime']);
  3077 + $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
  3078 + $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
  3079 +
  3080 +
  3081 + // ----- Packed data
  3082 + $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
  3083 + $p_header['version'], $p_header['version_extracted'],
  3084 + $p_header['flag'], $p_header['compression'],
  3085 + $v_mtime, $v_mdate, $p_header['crc'],
  3086 + $p_header['compressed_size'], $p_header['size'],
  3087 + strlen($p_header['stored_filename']),
  3088 + $p_header['extra_len'], $p_header['comment_len'],
  3089 + $p_header['disk'], $p_header['internal'],
  3090 + $p_header['external'], $p_header['offset']);
  3091 +
  3092 + // ----- Write the 42 bytes of the header in the zip file
  3093 + fputs($this->zip_fd, $v_binary_data, 46);
  3094 +
  3095 + // ----- Write the variable fields
  3096 + if (strlen($p_header['stored_filename']) != 0)
  3097 + {
  3098 + fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
  3099 + }
  3100 + if ($p_header['extra_len'] != 0)
  3101 + {
  3102 + fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
  3103 + }
  3104 + if ($p_header['comment_len'] != 0)
  3105 + {
  3106 + fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
  3107 + }
  3108 +
  3109 + // ----- Return
  3110 + return $v_result;
  3111 + }
  3112 + // --------------------------------------------------------------------------------
  3113 +
  3114 + // --------------------------------------------------------------------------------
  3115 + // Function : privWriteCentralHeader()
  3116 + // Description :
  3117 + // Parameters :
  3118 + // Return Values :
  3119 + // --------------------------------------------------------------------------------
  3120 + function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
  3121 + {
  3122 + $v_result=1;
  3123 +
  3124 + // ----- Packed data
  3125 + $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
  3126 + $p_nb_entries, $p_size,
  3127 + $p_offset, strlen($p_comment));
  3128 +
  3129 + // ----- Write the 22 bytes of the header in the zip file
  3130 + fputs($this->zip_fd, $v_binary_data, 22);
  3131 +
  3132 + // ----- Write the variable fields
  3133 + if (strlen($p_comment) != 0)
  3134 + {
  3135 + fputs($this->zip_fd, $p_comment, strlen($p_comment));
  3136 + }
  3137 +
  3138 + // ----- Return
  3139 + return $v_result;
  3140 + }
  3141 + // --------------------------------------------------------------------------------
  3142 +
  3143 + // --------------------------------------------------------------------------------
  3144 + // Function : privList()
  3145 + // Description :
  3146 + // Parameters :
  3147 + // Return Values :
  3148 + // --------------------------------------------------------------------------------
  3149 + function privList(&$p_list)
  3150 + {
  3151 + $v_result=1;
  3152 +
  3153 + // ----- Magic quotes trick
  3154 + $this->privDisableMagicQuotes();
  3155 +
  3156 + // ----- Open the zip file
  3157 + if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
  3158 + {
  3159 + // ----- Magic quotes trick
  3160 + $this->privSwapBackMagicQuotes();
  3161 +
  3162 + // ----- Error log
  3163 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
  3164 +
  3165 + // ----- Return
  3166 + return PclZip::errorCode();
  3167 + }
  3168 +
  3169 + // ----- Read the central directory informations
  3170 + $v_central_dir = array();
  3171 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3172 + {
  3173 + $this->privSwapBackMagicQuotes();
  3174 + return $v_result;
  3175 + }
  3176 +
  3177 + // ----- Go to beginning of Central Dir
  3178 + @rewind($this->zip_fd);
  3179 + if (@fseek($this->zip_fd, $v_central_dir['offset']))
  3180 + {
  3181 + $this->privSwapBackMagicQuotes();
  3182 +
  3183 + // ----- Error log
  3184 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3185 +
  3186 + // ----- Return
  3187 + return PclZip::errorCode();
  3188 + }
  3189 +
  3190 + // ----- Read each entry
  3191 + for ($i=0; $i<$v_central_dir['entries']; $i++)
  3192 + {
  3193 + // ----- Read the file header
  3194 + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  3195 + {
  3196 + $this->privSwapBackMagicQuotes();
  3197 + return $v_result;
  3198 + }
  3199 + $v_header['index'] = $i;
  3200 +
  3201 + // ----- Get the only interesting attributes
  3202 + $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
  3203 + unset($v_header);
  3204 + }
  3205 +
  3206 + // ----- Close the zip file
  3207 + $this->privCloseFd();
  3208 +
  3209 + // ----- Magic quotes trick
  3210 + $this->privSwapBackMagicQuotes();
  3211 +
  3212 + // ----- Return
  3213 + return $v_result;
  3214 + }
  3215 + // --------------------------------------------------------------------------------
  3216 +
  3217 + // --------------------------------------------------------------------------------
  3218 + // Function : privConvertHeader2FileInfo()
  3219 + // Description :
  3220 + // This function takes the file informations from the central directory
  3221 + // entries and extract the interesting parameters that will be given back.
  3222 + // The resulting file infos are set in the array $p_info
  3223 + // $p_info['filename'] : Filename with full path. Given by user (add),
  3224 + // extracted in the filesystem (extract).
  3225 + // $p_info['stored_filename'] : Stored filename in the archive.
  3226 + // $p_info['size'] = Size of the file.
  3227 + // $p_info['compressed_size'] = Compressed size of the file.
  3228 + // $p_info['mtime'] = Last modification date of the file.
  3229 + // $p_info['comment'] = Comment associated with the file.
  3230 + // $p_info['folder'] = true/false : indicates if the entry is a folder or not.
  3231 + // $p_info['status'] = status of the action on the file.
  3232 + // $p_info['crc'] = CRC of the file content.
  3233 + // Parameters :
  3234 + // Return Values :
  3235 + // --------------------------------------------------------------------------------
  3236 + function privConvertHeader2FileInfo($p_header, &$p_info)
  3237 + {
  3238 + $v_result=1;
  3239 +
  3240 + // ----- Get the interesting attributes
  3241 + $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
  3242 + $p_info['filename'] = $v_temp_path;
  3243 + $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
  3244 + $p_info['stored_filename'] = $v_temp_path;
  3245 + $p_info['size'] = $p_header['size'];
  3246 + $p_info['compressed_size'] = $p_header['compressed_size'];
  3247 + $p_info['mtime'] = $p_header['mtime'];
  3248 + $p_info['comment'] = $p_header['comment'];
  3249 + $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
  3250 + $p_info['index'] = $p_header['index'];
  3251 + $p_info['status'] = $p_header['status'];
  3252 + $p_info['crc'] = $p_header['crc'];
  3253 +
  3254 + // ----- Return
  3255 + return $v_result;
  3256 + }
  3257 + // --------------------------------------------------------------------------------
  3258 +
  3259 + // --------------------------------------------------------------------------------
  3260 + // Function : privExtractByRule()
  3261 + // Description :
  3262 + // Extract a file or directory depending of rules (by index, by name, ...)
  3263 + // Parameters :
  3264 + // $p_file_list : An array where will be placed the properties of each
  3265 + // extracted file
  3266 + // $p_path : Path to add while writing the extracted files
  3267 + // $p_remove_path : Path to remove (from the file memorized path) while writing the
  3268 + // extracted files. If the path does not match the file path,
  3269 + // the file is extracted with its memorized path.
  3270 + // $p_remove_path does not apply to 'list' mode.
  3271 + // $p_path and $p_remove_path are commulative.
  3272 + // Return Values :
  3273 + // 1 on success,0 or less on error (see error code list)
  3274 + // --------------------------------------------------------------------------------
  3275 + function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  3276 + {
  3277 + $v_result=1;
  3278 +
  3279 + // ----- Magic quotes trick
  3280 + $this->privDisableMagicQuotes();
  3281 +
  3282 + // ----- Check the path
  3283 + if ( ($p_path == "")
  3284 + || ( (substr($p_path, 0, 1) != "/")
  3285 + && (substr($p_path, 0, 3) != "../")
  3286 + && (substr($p_path,1,2)!=":/")))
  3287 + $p_path = "./".$p_path;
  3288 +
  3289 + // ----- Reduce the path last (and duplicated) '/'
  3290 + if (($p_path != "./") && ($p_path != "/"))
  3291 + {
  3292 + // ----- Look for the path end '/'
  3293 + while (substr($p_path, -1) == "/")
  3294 + {
  3295 + $p_path = substr($p_path, 0, strlen($p_path)-1);
  3296 + }
  3297 + }
  3298 +
  3299 + // ----- Look for path to remove format (should end by /)
  3300 + if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
  3301 + {
  3302 + $p_remove_path .= '/';
  3303 + }
  3304 + $p_remove_path_size = strlen($p_remove_path);
  3305 +
  3306 + // ----- Open the zip file
  3307 + if (($v_result = $this->privOpenFd('rb')) != 1)
  3308 + {
  3309 + $this->privSwapBackMagicQuotes();
  3310 + return $v_result;
  3311 + }
  3312 +
  3313 + // ----- Read the central directory informations
  3314 + $v_central_dir = array();
  3315 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  3316 + {
  3317 + // ----- Close the zip file
  3318 + $this->privCloseFd();
  3319 + $this->privSwapBackMagicQuotes();
  3320 +
  3321 + return $v_result;
  3322 + }
  3323 +
  3324 + // ----- Start at beginning of Central Dir
  3325 + $v_pos_entry = $v_central_dir['offset'];
  3326 +
  3327 + // ----- Read each entry
  3328 + $j_start = 0;
  3329 + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  3330 + {
  3331 +
  3332 + // ----- Read next Central dir entry
  3333 + @rewind($this->zip_fd);
  3334 + if (@fseek($this->zip_fd, $v_pos_entry))
  3335 + {
  3336 + // ----- Close the zip file
  3337 + $this->privCloseFd();
  3338 + $this->privSwapBackMagicQuotes();
  3339 +
  3340 + // ----- Error log
  3341 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3342 +
  3343 + // ----- Return
  3344 + return PclZip::errorCode();
  3345 + }
  3346 +
  3347 + // ----- Read the file header
  3348 + $v_header = array();
  3349 + if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
  3350 + {
  3351 + // ----- Close the zip file
  3352 + $this->privCloseFd();
  3353 + $this->privSwapBackMagicQuotes();
  3354 +
  3355 + return $v_result;
  3356 + }
  3357 +
  3358 + // ----- Store the index
  3359 + $v_header['index'] = $i;
  3360 +
  3361 + // ----- Store the file position
  3362 + $v_pos_entry = ftell($this->zip_fd);
  3363 +
  3364 + // ----- Look for the specific extract rules
  3365 + $v_extract = false;
  3366 +
  3367 + // ----- Look for extract by name rule
  3368 + if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
  3369 + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  3370 +
  3371 + // ----- Look if the filename is in the list
  3372 + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
  3373 +
  3374 + // ----- Look for a directory
  3375 + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  3376 +
  3377 + // ----- Look if the directory is in the filename path
  3378 + if ( (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  3379 + && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  3380 + $v_extract = true;
  3381 + }
  3382 + }
  3383 + // ----- Look for a filename
  3384 + elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  3385 + $v_extract = true;
  3386 + }
  3387 + }
  3388 + }
  3389 +
  3390 + // ----- Look for extract by ereg rule
  3391 + // ereg() is deprecated with PHP 5.3
  3392 + /*
  3393 + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
  3394 + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  3395 +
  3396 + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename'])) {
  3397 + $v_extract = true;
  3398 + }
  3399 + }
  3400 + */
  3401 +
  3402 + // ----- Look for extract by preg rule
  3403 + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
  3404 + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  3405 +
  3406 + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
  3407 + $v_extract = true;
  3408 + }
  3409 + }
  3410 +
  3411 + // ----- Look for extract by index rule
  3412 + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  3413 + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  3414 +
  3415 + // ----- Look if the index is in the list
  3416 + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
  3417 +
  3418 + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  3419 + $v_extract = true;
  3420 + }
  3421 + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  3422 + $j_start = $j+1;
  3423 + }
  3424 +
  3425 + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  3426 + break;
  3427 + }
  3428 + }
  3429 + }
  3430 +
  3431 + // ----- Look for no rule, which means extract all the archive
  3432 + else {
  3433 + $v_extract = true;
  3434 + }
  3435 +
  3436 + // ----- Check compression method
  3437 + if ( ($v_extract)
  3438 + && ( ($v_header['compression'] != 8)
  3439 + && ($v_header['compression'] != 0))) {
  3440 + $v_header['status'] = 'unsupported_compression';
  3441 +
  3442 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3443 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3444 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3445 +
  3446 + $this->privSwapBackMagicQuotes();
  3447 +
  3448 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
  3449 + "Filename '".$v_header['stored_filename']."' is "
  3450 + ."compressed by an unsupported compression "
  3451 + ."method (".$v_header['compression'].") ");
  3452 +
  3453 + return PclZip::errorCode();
  3454 + }
  3455 + }
  3456 +
  3457 + // ----- Check encrypted files
  3458 + if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
  3459 + $v_header['status'] = 'unsupported_encryption';
  3460 +
  3461 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3462 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3463 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3464 +
  3465 + $this->privSwapBackMagicQuotes();
  3466 +
  3467 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
  3468 + "Unsupported encryption for "
  3469 + ." filename '".$v_header['stored_filename']
  3470 + ."'");
  3471 +
  3472 + return PclZip::errorCode();
  3473 + }
  3474 + }
  3475 +
  3476 + // ----- Look for real extraction
  3477 + if (($v_extract) && ($v_header['status'] != 'ok')) {
  3478 + $v_result = $this->privConvertHeader2FileInfo($v_header,
  3479 + $p_file_list[$v_nb_extracted++]);
  3480 + if ($v_result != 1) {
  3481 + $this->privCloseFd();
  3482 + $this->privSwapBackMagicQuotes();
  3483 + return $v_result;
  3484 + }
  3485 +
  3486 + $v_extract = false;
  3487 + }
  3488 +
  3489 + // ----- Look for real extraction
  3490 + if ($v_extract)
  3491 + {
  3492 +
  3493 + // ----- Go to the file position
  3494 + @rewind($this->zip_fd);
  3495 + if (@fseek($this->zip_fd, $v_header['offset']))
  3496 + {
  3497 + // ----- Close the zip file
  3498 + $this->privCloseFd();
  3499 +
  3500 + $this->privSwapBackMagicQuotes();
  3501 +
  3502 + // ----- Error log
  3503 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  3504 +
  3505 + // ----- Return
  3506 + return PclZip::errorCode();
  3507 + }
  3508 +
  3509 + // ----- Look for extraction as string
  3510 + if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
  3511 +
  3512 + $v_string = '';
  3513 +
  3514 + // ----- Extracting the file
  3515 + $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options);
  3516 + if ($v_result1 < 1) {
  3517 + $this->privCloseFd();
  3518 + $this->privSwapBackMagicQuotes();
  3519 + return $v_result1;
  3520 + }
  3521 +
  3522 + // ----- Get the only interesting attributes
  3523 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
  3524 + {
  3525 + // ----- Close the zip file
  3526 + $this->privCloseFd();
  3527 + $this->privSwapBackMagicQuotes();
  3528 +
  3529 + return $v_result;
  3530 + }
  3531 +
  3532 + // ----- Set the file content
  3533 + $p_file_list[$v_nb_extracted]['content'] = $v_string;
  3534 +
  3535 + // ----- Next extracted file
  3536 + $v_nb_extracted++;
  3537 +
  3538 + // ----- Look for user callback abort
  3539 + if ($v_result1 == 2) {
  3540 + break;
  3541 + }
  3542 + }
  3543 + // ----- Look for extraction in standard output
  3544 + elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
  3545 + && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
  3546 + // ----- Extracting the file in standard output
  3547 + $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
  3548 + if ($v_result1 < 1) {
  3549 + $this->privCloseFd();
  3550 + $this->privSwapBackMagicQuotes();
  3551 + return $v_result1;
  3552 + }
  3553 +
  3554 + // ----- Get the only interesting attributes
  3555 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
  3556 + $this->privCloseFd();
  3557 + $this->privSwapBackMagicQuotes();
  3558 + return $v_result;
  3559 + }
  3560 +
  3561 + // ----- Look for user callback abort
  3562 + if ($v_result1 == 2) {
  3563 + break;
  3564 + }
  3565 + }
  3566 + // ----- Look for normal extraction
  3567 + else {
  3568 + // ----- Extracting the file
  3569 + $v_result1 = $this->privExtractFile($v_header,
  3570 + $p_path, $p_remove_path,
  3571 + $p_remove_all_path,
  3572 + $p_options);
  3573 + if ($v_result1 < 1) {
  3574 + $this->privCloseFd();
  3575 + $this->privSwapBackMagicQuotes();
  3576 + return $v_result1;
  3577 + }
  3578 +
  3579 + // ----- Get the only interesting attributes
  3580 + if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
  3581 + {
  3582 + // ----- Close the zip file
  3583 + $this->privCloseFd();
  3584 + $this->privSwapBackMagicQuotes();
  3585 +
  3586 + return $v_result;
  3587 + }
  3588 +
  3589 + // ----- Look for user callback abort
  3590 + if ($v_result1 == 2) {
  3591 + break;
  3592 + }
  3593 + }
  3594 + }
  3595 + }
  3596 +
  3597 + // ----- Close the zip file
  3598 + $this->privCloseFd();
  3599 + $this->privSwapBackMagicQuotes();
  3600 +
  3601 + // ----- Return
  3602 + return $v_result;
  3603 + }
  3604 + // --------------------------------------------------------------------------------
  3605 +
  3606 + // --------------------------------------------------------------------------------
  3607 + // Function : privExtractFile()
  3608 + // Description :
  3609 + // Parameters :
  3610 + // Return Values :
  3611 + //
  3612 + // 1 : ... ?
  3613 + // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback
  3614 + // --------------------------------------------------------------------------------
  3615 + function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
  3616 + {
  3617 + $v_result=1;
  3618 +
  3619 + // ----- Read the file header
  3620 + if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  3621 + {
  3622 + // ----- Return
  3623 + return $v_result;
  3624 + }
  3625 +
  3626 +
  3627 + // ----- Check that the file header is coherent with $p_entry info
  3628 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  3629 + // TBC
  3630 + }
  3631 +
  3632 + // ----- Look for all path to remove
  3633 + if ($p_remove_all_path == true) {
  3634 + // ----- Look for folder entry that not need to be extracted
  3635 + if (($p_entry['external']&0x00000010)==0x00000010) {
  3636 +
  3637 + $p_entry['status'] = "filtered";
  3638 +
  3639 + return $v_result;
  3640 + }
  3641 +
  3642 + // ----- Get the basename of the path
  3643 + $p_entry['filename'] = basename($p_entry['filename']);
  3644 + }
  3645 +
  3646 + // ----- Look for path to remove
  3647 + else if ($p_remove_path != "")
  3648 + {
  3649 + if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
  3650 + {
  3651 +
  3652 + // ----- Change the file status
  3653 + $p_entry['status'] = "filtered";
  3654 +
  3655 + // ----- Return
  3656 + return $v_result;
  3657 + }
  3658 +
  3659 + $p_remove_path_size = strlen($p_remove_path);
  3660 + if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
  3661 + {
  3662 +
  3663 + // ----- Remove the path
  3664 + $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
  3665 +
  3666 + }
  3667 + }
  3668 +
  3669 + // ----- Add the path
  3670 + if ($p_path != '') {
  3671 + $p_entry['filename'] = $p_path."/".$p_entry['filename'];
  3672 + }
  3673 +
  3674 + // ----- Check a base_dir_restriction
  3675 + if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
  3676 + $v_inclusion
  3677 + = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
  3678 + $p_entry['filename']);
  3679 + if ($v_inclusion == 0) {
  3680 +
  3681 + PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
  3682 + "Filename '".$p_entry['filename']."' is "
  3683 + ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
  3684 +
  3685 + return PclZip::errorCode();
  3686 + }
  3687 + }
  3688 +
  3689 + // ----- Look for pre-extract callback
  3690 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  3691 +
  3692 + // ----- Generate a local information
  3693 + $v_local_header = array();
  3694 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3695 +
  3696 + // ----- Call the callback
  3697 + // Here I do not use call_user_func() because I need to send a reference to the
  3698 + // header.
  3699 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  3700 + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
  3701 + if ($v_result == 0) {
  3702 + // ----- Change the file status
  3703 + $p_entry['status'] = "skipped";
  3704 + $v_result = 1;
  3705 + }
  3706 +
  3707 + // ----- Look for abort result
  3708 + if ($v_result == 2) {
  3709 + // ----- This status is internal and will be changed in 'skipped'
  3710 + $p_entry['status'] = "aborted";
  3711 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3712 + }
  3713 +
  3714 + // ----- Update the informations
  3715 + // Only some fields can be modified
  3716 + $p_entry['filename'] = $v_local_header['filename'];
  3717 + }
  3718 +
  3719 +
  3720 + // ----- Look if extraction should be done
  3721 + if ($p_entry['status'] == 'ok') {
  3722 +
  3723 + // ----- Look for specific actions while the file exist
  3724 + if (file_exists($p_entry['filename']))
  3725 + {
  3726 +
  3727 + // ----- Look if file is a directory
  3728 + if (is_dir($p_entry['filename']))
  3729 + {
  3730 +
  3731 + // ----- Change the file status
  3732 + $p_entry['status'] = "already_a_directory";
  3733 +
  3734 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3735 + // For historical reason first PclZip implementation does not stop
  3736 + // when this kind of error occurs.
  3737 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3738 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3739 +
  3740 + PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
  3741 + "Filename '".$p_entry['filename']."' is "
  3742 + ."already used by an existing directory");
  3743 +
  3744 + return PclZip::errorCode();
  3745 + }
  3746 + }
  3747 + // ----- Look if file is write protected
  3748 + else if (!is_writeable($p_entry['filename']))
  3749 + {
  3750 +
  3751 + // ----- Change the file status
  3752 + $p_entry['status'] = "write_protected";
  3753 +
  3754 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3755 + // For historical reason first PclZip implementation does not stop
  3756 + // when this kind of error occurs.
  3757 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3758 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3759 +
  3760 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  3761 + "Filename '".$p_entry['filename']."' exists "
  3762 + ."and is write protected");
  3763 +
  3764 + return PclZip::errorCode();
  3765 + }
  3766 + }
  3767 +
  3768 + // ----- Look if the extracted file is older
  3769 + else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
  3770 + {
  3771 + // ----- Change the file status
  3772 + if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
  3773 + && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
  3774 + }
  3775 + else {
  3776 + $p_entry['status'] = "newer_exist";
  3777 +
  3778 + // ----- Look for PCLZIP_OPT_STOP_ON_ERROR
  3779 + // For historical reason first PclZip implementation does not stop
  3780 + // when this kind of error occurs.
  3781 + if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
  3782 + && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
  3783 +
  3784 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
  3785 + "Newer version of '".$p_entry['filename']."' exists "
  3786 + ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
  3787 +
  3788 + return PclZip::errorCode();
  3789 + }
  3790 + }
  3791 + }
  3792 + else {
  3793 + }
  3794 + }
  3795 +
  3796 + // ----- Check the directory availability and create it if necessary
  3797 + else {
  3798 + if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
  3799 + $v_dir_to_check = $p_entry['filename'];
  3800 + else if (!strstr($p_entry['filename'], "/"))
  3801 + $v_dir_to_check = "";
  3802 + else
  3803 + $v_dir_to_check = dirname($p_entry['filename']);
  3804 +
  3805 + if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
  3806 +
  3807 + // ----- Change the file status
  3808 + $p_entry['status'] = "path_creation_fail";
  3809 +
  3810 + // ----- Return
  3811 + //return $v_result;
  3812 + $v_result = 1;
  3813 + }
  3814 + }
  3815 + }
  3816 +
  3817 + // ----- Look if extraction should be done
  3818 + if ($p_entry['status'] == 'ok') {
  3819 +
  3820 + // ----- Do the extraction (if not a folder)
  3821 + if (!(($p_entry['external']&0x00000010)==0x00000010))
  3822 + {
  3823 + // ----- Look for not compressed file
  3824 + if ($p_entry['compression'] == 0) {
  3825 +
  3826 + // ----- Opening destination file
  3827 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
  3828 + {
  3829 +
  3830 + // ----- Change the file status
  3831 + $p_entry['status'] = "write_error";
  3832 +
  3833 + // ----- Return
  3834 + return $v_result;
  3835 + }
  3836 +
  3837 +
  3838 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  3839 + $v_size = $p_entry['compressed_size'];
  3840 + while ($v_size != 0)
  3841 + {
  3842 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  3843 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  3844 + /* Try to speed up the code
  3845 + $v_binary_data = pack('a'.$v_read_size, $v_buffer);
  3846 + @fwrite($v_dest_file, $v_binary_data, $v_read_size);
  3847 + */
  3848 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  3849 + $v_size -= $v_read_size;
  3850 + }
  3851 +
  3852 + // ----- Closing the destination file
  3853 + fclose($v_dest_file);
  3854 +
  3855 + // ----- Change the file mtime
  3856 + touch($p_entry['filename'], $p_entry['mtime']);
  3857 +
  3858 +
  3859 + }
  3860 + else {
  3861 + // ----- TBC
  3862 + // Need to be finished
  3863 + if (($p_entry['flag'] & 1) == 1) {
  3864 + PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
  3865 + return PclZip::errorCode();
  3866 + }
  3867 +
  3868 +
  3869 + // ----- Look for using temporary file to unzip
  3870 + if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF]))
  3871 + && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
  3872 + || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
  3873 + && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
  3874 + $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
  3875 + if ($v_result < PCLZIP_ERR_NO_ERROR) {
  3876 + return $v_result;
  3877 + }
  3878 + }
  3879 +
  3880 + // ----- Look for extract in memory
  3881 + else {
  3882 +
  3883 +
  3884 + // ----- Read the compressed file in a buffer (one shot)
  3885 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  3886 +
  3887 + // ----- Decompress the file
  3888 + $v_file_content = @gzinflate($v_buffer);
  3889 + unset($v_buffer);
  3890 + if ($v_file_content === FALSE) {
  3891 +
  3892 + // ----- Change the file status
  3893 + // TBC
  3894 + $p_entry['status'] = "error";
  3895 +
  3896 + return $v_result;
  3897 + }
  3898 +
  3899 + // ----- Opening destination file
  3900 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  3901 +
  3902 + // ----- Change the file status
  3903 + $p_entry['status'] = "write_error";
  3904 +
  3905 + return $v_result;
  3906 + }
  3907 +
  3908 + // ----- Write the uncompressed data
  3909 + @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
  3910 + unset($v_file_content);
  3911 +
  3912 + // ----- Closing the destination file
  3913 + @fclose($v_dest_file);
  3914 +
  3915 + }
  3916 +
  3917 + // ----- Change the file mtime
  3918 + @touch($p_entry['filename'], $p_entry['mtime']);
  3919 + }
  3920 +
  3921 + // ----- Look for chmod option
  3922 + if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
  3923 +
  3924 + // ----- Change the mode of the file
  3925 + @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
  3926 + }
  3927 +
  3928 + }
  3929 + }
  3930 +
  3931 + // ----- Change abort status
  3932 + if ($p_entry['status'] == "aborted") {
  3933 + $p_entry['status'] = "skipped";
  3934 + }
  3935 +
  3936 + // ----- Look for post-extract callback
  3937 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  3938 +
  3939 + // ----- Generate a local information
  3940 + $v_local_header = array();
  3941 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  3942 +
  3943 + // ----- Call the callback
  3944 + // Here I do not use call_user_func() because I need to send a reference to the
  3945 + // header.
  3946 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  3947 + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
  3948 +
  3949 + // ----- Look for abort result
  3950 + if ($v_result == 2) {
  3951 + $v_result = PCLZIP_ERR_USER_ABORTED;
  3952 + }
  3953 + }
  3954 +
  3955 + // ----- Return
  3956 + return $v_result;
  3957 + }
  3958 + // --------------------------------------------------------------------------------
  3959 +
  3960 + // --------------------------------------------------------------------------------
  3961 + // Function : privExtractFileUsingTempFile()
  3962 + // Description :
  3963 + // Parameters :
  3964 + // Return Values :
  3965 + // --------------------------------------------------------------------------------
  3966 + function privExtractFileUsingTempFile(&$p_entry, &$p_options)
  3967 + {
  3968 + $v_result=1;
  3969 +
  3970 + // ----- Creates a temporary file
  3971 + $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
  3972 + if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
  3973 + fclose($v_file);
  3974 + PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
  3975 + return PclZip::errorCode();
  3976 + }
  3977 +
  3978 +
  3979 + // ----- Write gz file format header
  3980 + $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
  3981 + @fwrite($v_dest_file, $v_binary_data, 10);
  3982 +
  3983 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  3984 + $v_size = $p_entry['compressed_size'];
  3985 + while ($v_size != 0)
  3986 + {
  3987 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  3988 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  3989 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  3990 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  3991 + $v_size -= $v_read_size;
  3992 + }
  3993 +
  3994 + // ----- Write gz file format footer
  3995 + $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
  3996 + @fwrite($v_dest_file, $v_binary_data, 8);
  3997 +
  3998 + // ----- Close the temporary file
  3999 + @fclose($v_dest_file);
  4000 +
  4001 + // ----- Opening destination file
  4002 + if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
  4003 + $p_entry['status'] = "write_error";
  4004 + return $v_result;
  4005 + }
  4006 +
  4007 + // ----- Open the temporary gz file
  4008 + if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
  4009 + @fclose($v_dest_file);
  4010 + $p_entry['status'] = "read_error";
  4011 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
  4012 + return PclZip::errorCode();
  4013 + }
  4014 +
  4015 +
  4016 + // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks
  4017 + $v_size = $p_entry['size'];
  4018 + while ($v_size != 0) {
  4019 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  4020 + $v_buffer = @gzread($v_src_file, $v_read_size);
  4021 + //$v_binary_data = pack('a'.$v_read_size, $v_buffer);
  4022 + @fwrite($v_dest_file, $v_buffer, $v_read_size);
  4023 + $v_size -= $v_read_size;
  4024 + }
  4025 + @fclose($v_dest_file);
  4026 + @gzclose($v_src_file);
  4027 +
  4028 + // ----- Delete the temporary file
  4029 + @unlink($v_gzip_temp_name);
  4030 +
  4031 + // ----- Return
  4032 + return $v_result;
  4033 + }
  4034 + // --------------------------------------------------------------------------------
  4035 +
  4036 + // --------------------------------------------------------------------------------
  4037 + // Function : privExtractFileInOutput()
  4038 + // Description :
  4039 + // Parameters :
  4040 + // Return Values :
  4041 + // --------------------------------------------------------------------------------
  4042 + function privExtractFileInOutput(&$p_entry, &$p_options)
  4043 + {
  4044 + $v_result=1;
  4045 +
  4046 + // ----- Read the file header
  4047 + if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
  4048 + return $v_result;
  4049 + }
  4050 +
  4051 +
  4052 + // ----- Check that the file header is coherent with $p_entry info
  4053 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  4054 + // TBC
  4055 + }
  4056 +
  4057 + // ----- Look for pre-extract callback
  4058 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  4059 +
  4060 + // ----- Generate a local information
  4061 + $v_local_header = array();
  4062 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4063 +
  4064 + // ----- Call the callback
  4065 + // Here I do not use call_user_func() because I need to send a reference to the
  4066 + // header.
  4067 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  4068 + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
  4069 + if ($v_result == 0) {
  4070 + // ----- Change the file status
  4071 + $p_entry['status'] = "skipped";
  4072 + $v_result = 1;
  4073 + }
  4074 +
  4075 + // ----- Look for abort result
  4076 + if ($v_result == 2) {
  4077 + // ----- This status is internal and will be changed in 'skipped'
  4078 + $p_entry['status'] = "aborted";
  4079 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4080 + }
  4081 +
  4082 + // ----- Update the informations
  4083 + // Only some fields can be modified
  4084 + $p_entry['filename'] = $v_local_header['filename'];
  4085 + }
  4086 +
  4087 + // ----- Trace
  4088 +
  4089 + // ----- Look if extraction should be done
  4090 + if ($p_entry['status'] == 'ok') {
  4091 +
  4092 + // ----- Do the extraction (if not a folder)
  4093 + if (!(($p_entry['external']&0x00000010)==0x00000010)) {
  4094 + // ----- Look for not compressed file
  4095 + if ($p_entry['compressed_size'] == $p_entry['size']) {
  4096 +
  4097 + // ----- Read the file in a buffer (one shot)
  4098 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  4099 +
  4100 + // ----- Send the file to the output
  4101 + echo $v_buffer;
  4102 + unset($v_buffer);
  4103 + }
  4104 + else {
  4105 +
  4106 + // ----- Read the compressed file in a buffer (one shot)
  4107 + $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
  4108 +
  4109 + // ----- Decompress the file
  4110 + $v_file_content = gzinflate($v_buffer);
  4111 + unset($v_buffer);
  4112 +
  4113 + // ----- Send the file to the output
  4114 + echo $v_file_content;
  4115 + unset($v_file_content);
  4116 + }
  4117 + }
  4118 + }
  4119 +
  4120 + // ----- Change abort status
  4121 + if ($p_entry['status'] == "aborted") {
  4122 + $p_entry['status'] = "skipped";
  4123 + }
  4124 +
  4125 + // ----- Look for post-extract callback
  4126 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  4127 +
  4128 + // ----- Generate a local information
  4129 + $v_local_header = array();
  4130 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4131 +
  4132 + // ----- Call the callback
  4133 + // Here I do not use call_user_func() because I need to send a reference to the
  4134 + // header.
  4135 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  4136 + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
  4137 +
  4138 + // ----- Look for abort result
  4139 + if ($v_result == 2) {
  4140 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4141 + }
  4142 + }
  4143 +
  4144 + return $v_result;
  4145 + }
  4146 + // --------------------------------------------------------------------------------
  4147 +
  4148 + // --------------------------------------------------------------------------------
  4149 + // Function : privExtractFileAsString()
  4150 + // Description :
  4151 + // Parameters :
  4152 + // Return Values :
  4153 + // --------------------------------------------------------------------------------
  4154 + function privExtractFileAsString(&$p_entry, &$p_string, &$p_options)
  4155 + {
  4156 + $v_result=1;
  4157 +
  4158 + // ----- Read the file header
  4159 + $v_header = array();
  4160 + if (($v_result = $this->privReadFileHeader($v_header)) != 1)
  4161 + {
  4162 + // ----- Return
  4163 + return $v_result;
  4164 + }
  4165 +
  4166 +
  4167 + // ----- Check that the file header is coherent with $p_entry info
  4168 + if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
  4169 + // TBC
  4170 + }
  4171 +
  4172 + // ----- Look for pre-extract callback
  4173 + if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
  4174 +
  4175 + // ----- Generate a local information
  4176 + $v_local_header = array();
  4177 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4178 +
  4179 + // ----- Call the callback
  4180 + // Here I do not use call_user_func() because I need to send a reference to the
  4181 + // header.
  4182 +// eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
  4183 + $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header);
  4184 + if ($v_result == 0) {
  4185 + // ----- Change the file status
  4186 + $p_entry['status'] = "skipped";
  4187 + $v_result = 1;
  4188 + }
  4189 +
  4190 + // ----- Look for abort result
  4191 + if ($v_result == 2) {
  4192 + // ----- This status is internal and will be changed in 'skipped'
  4193 + $p_entry['status'] = "aborted";
  4194 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4195 + }
  4196 +
  4197 + // ----- Update the informations
  4198 + // Only some fields can be modified
  4199 + $p_entry['filename'] = $v_local_header['filename'];
  4200 + }
  4201 +
  4202 +
  4203 + // ----- Look if extraction should be done
  4204 + if ($p_entry['status'] == 'ok') {
  4205 +
  4206 + // ----- Do the extraction (if not a folder)
  4207 + if (!(($p_entry['external']&0x00000010)==0x00000010)) {
  4208 + // ----- Look for not compressed file
  4209 + // if ($p_entry['compressed_size'] == $p_entry['size'])
  4210 + if ($p_entry['compression'] == 0) {
  4211 +
  4212 + // ----- Reading the file
  4213 + $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
  4214 + }
  4215 + else {
  4216 +
  4217 + // ----- Reading the file
  4218 + $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
  4219 +
  4220 + // ----- Decompress the file
  4221 + if (($p_string = @gzinflate($v_data)) === FALSE) {
  4222 + // TBC
  4223 + }
  4224 + }
  4225 +
  4226 + // ----- Trace
  4227 + }
  4228 + else {
  4229 + // TBC : error : can not extract a folder in a string
  4230 + }
  4231 +
  4232 + }
  4233 +
  4234 + // ----- Change abort status
  4235 + if ($p_entry['status'] == "aborted") {
  4236 + $p_entry['status'] = "skipped";
  4237 + }
  4238 +
  4239 + // ----- Look for post-extract callback
  4240 + elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
  4241 +
  4242 + // ----- Generate a local information
  4243 + $v_local_header = array();
  4244 + $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
  4245 +
  4246 + // ----- Swap the content to header
  4247 + $v_local_header['content'] = $p_string;
  4248 + $p_string = '';
  4249 +
  4250 + // ----- Call the callback
  4251 + // Here I do not use call_user_func() because I need to send a reference to the
  4252 + // header.
  4253 +// eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
  4254 + $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header);
  4255 +
  4256 + // ----- Swap back the content to header
  4257 + $p_string = $v_local_header['content'];
  4258 + unset($v_local_header['content']);
  4259 +
  4260 + // ----- Look for abort result
  4261 + if ($v_result == 2) {
  4262 + $v_result = PCLZIP_ERR_USER_ABORTED;
  4263 + }
  4264 + }
  4265 +
  4266 + // ----- Return
  4267 + return $v_result;
  4268 + }
  4269 + // --------------------------------------------------------------------------------
  4270 +
  4271 + // --------------------------------------------------------------------------------
  4272 + // Function : privReadFileHeader()
  4273 + // Description :
  4274 + // Parameters :
  4275 + // Return Values :
  4276 + // --------------------------------------------------------------------------------
  4277 + function privReadFileHeader(&$p_header)
  4278 + {
  4279 + $v_result=1;
  4280 +
  4281 + // ----- Read the 4 bytes signature
  4282 + $v_binary_data = @fread($this->zip_fd, 4);
  4283 + $v_data = unpack('Vid', $v_binary_data);
  4284 +
  4285 + // ----- Check signature
  4286 + if ($v_data['id'] != 0x04034b50)
  4287 + {
  4288 +
  4289 + // ----- Error log
  4290 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  4291 +
  4292 + // ----- Return
  4293 + return PclZip::errorCode();
  4294 + }
  4295 +
  4296 + // ----- Read the first 42 bytes of the header
  4297 + $v_binary_data = fread($this->zip_fd, 26);
  4298 +
  4299 + // ----- Look for invalid block size
  4300 + if (strlen($v_binary_data) != 26)
  4301 + {
  4302 + $p_header['filename'] = "";
  4303 + $p_header['status'] = "invalid_header";
  4304 +
  4305 + // ----- Error log
  4306 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  4307 +
  4308 + // ----- Return
  4309 + return PclZip::errorCode();
  4310 + }
  4311 +
  4312 + // ----- Extract the values
  4313 + $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
  4314 +
  4315 + // ----- Get filename
  4316 + $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
  4317 +
  4318 + // ----- Get extra_fields
  4319 + if ($v_data['extra_len'] != 0) {
  4320 + $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
  4321 + }
  4322 + else {
  4323 + $p_header['extra'] = '';
  4324 + }
  4325 +
  4326 + // ----- Extract properties
  4327 + $p_header['version_extracted'] = $v_data['version'];
  4328 + $p_header['compression'] = $v_data['compression'];
  4329 + $p_header['size'] = $v_data['size'];
  4330 + $p_header['compressed_size'] = $v_data['compressed_size'];
  4331 + $p_header['crc'] = $v_data['crc'];
  4332 + $p_header['flag'] = $v_data['flag'];
  4333 + $p_header['filename_len'] = $v_data['filename_len'];
  4334 +
  4335 + // ----- Recuperate date in UNIX format
  4336 + $p_header['mdate'] = $v_data['mdate'];
  4337 + $p_header['mtime'] = $v_data['mtime'];
  4338 + if ($p_header['mdate'] && $p_header['mtime'])
  4339 + {
  4340 + // ----- Extract time
  4341 + $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  4342 + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  4343 + $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  4344 +
  4345 + // ----- Extract date
  4346 + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  4347 + $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  4348 + $v_day = $p_header['mdate'] & 0x001F;
  4349 +
  4350 + // ----- Get UNIX date format
  4351 + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  4352 +
  4353 + }
  4354 + else
  4355 + {
  4356 + $p_header['mtime'] = time();
  4357 + }
  4358 +
  4359 + // TBC
  4360 + //for(reset($v_data); $key = key($v_data); next($v_data)) {
  4361 + //}
  4362 +
  4363 + // ----- Set the stored filename
  4364 + $p_header['stored_filename'] = $p_header['filename'];
  4365 +
  4366 + // ----- Set the status field
  4367 + $p_header['status'] = "ok";
  4368 +
  4369 + // ----- Return
  4370 + return $v_result;
  4371 + }
  4372 + // --------------------------------------------------------------------------------
  4373 +
  4374 + // --------------------------------------------------------------------------------
  4375 + // Function : privReadCentralFileHeader()
  4376 + // Description :
  4377 + // Parameters :
  4378 + // Return Values :
  4379 + // --------------------------------------------------------------------------------
  4380 + function privReadCentralFileHeader(&$p_header)
  4381 + {
  4382 + $v_result=1;
  4383 +
  4384 + // ----- Read the 4 bytes signature
  4385 + $v_binary_data = @fread($this->zip_fd, 4);
  4386 + $v_data = unpack('Vid', $v_binary_data);
  4387 +
  4388 + // ----- Check signature
  4389 + if ($v_data['id'] != 0x02014b50)
  4390 + {
  4391 +
  4392 + // ----- Error log
  4393 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
  4394 +
  4395 + // ----- Return
  4396 + return PclZip::errorCode();
  4397 + }
  4398 +
  4399 + // ----- Read the first 42 bytes of the header
  4400 + $v_binary_data = fread($this->zip_fd, 42);
  4401 +
  4402 + // ----- Look for invalid block size
  4403 + if (strlen($v_binary_data) != 42)
  4404 + {
  4405 + $p_header['filename'] = "";
  4406 + $p_header['status'] = "invalid_header";
  4407 +
  4408 + // ----- Error log
  4409 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
  4410 +
  4411 + // ----- Return
  4412 + return PclZip::errorCode();
  4413 + }
  4414 +
  4415 + // ----- Extract the values
  4416 + $p_header = unpack('vversion/vversion_extracted/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len/vcomment_len/vdisk/vinternal/Vexternal/Voffset', $v_binary_data);
  4417 +
  4418 + // ----- Get filename
  4419 + if ($p_header['filename_len'] != 0)
  4420 + $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
  4421 + else
  4422 + $p_header['filename'] = '';
  4423 +
  4424 + // ----- Get extra
  4425 + if ($p_header['extra_len'] != 0)
  4426 + $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
  4427 + else
  4428 + $p_header['extra'] = '';
  4429 +
  4430 + // ----- Get comment
  4431 + if ($p_header['comment_len'] != 0)
  4432 + $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
  4433 + else
  4434 + $p_header['comment'] = '';
  4435 +
  4436 + // ----- Extract properties
  4437 +
  4438 + // ----- Recuperate date in UNIX format
  4439 + //if ($p_header['mdate'] && $p_header['mtime'])
  4440 + // TBC : bug : this was ignoring time with 0/0/0
  4441 + if (1)
  4442 + {
  4443 + // ----- Extract time
  4444 + $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
  4445 + $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
  4446 + $v_seconde = ($p_header['mtime'] & 0x001F)*2;
  4447 +
  4448 + // ----- Extract date
  4449 + $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
  4450 + $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
  4451 + $v_day = $p_header['mdate'] & 0x001F;
  4452 +
  4453 + // ----- Get UNIX date format
  4454 + $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
  4455 +
  4456 + }
  4457 + else
  4458 + {
  4459 + $p_header['mtime'] = time();
  4460 + }
  4461 +
  4462 + // ----- Set the stored filename
  4463 + $p_header['stored_filename'] = $p_header['filename'];
  4464 +
  4465 + // ----- Set default status to ok
  4466 + $p_header['status'] = 'ok';
  4467 +
  4468 + // ----- Look if it is a directory
  4469 + if (substr($p_header['filename'], -1) == '/') {
  4470 + //$p_header['external'] = 0x41FF0010;
  4471 + $p_header['external'] = 0x00000010;
  4472 + }
  4473 +
  4474 +
  4475 + // ----- Return
  4476 + return $v_result;
  4477 + }
  4478 + // --------------------------------------------------------------------------------
  4479 +
  4480 + // --------------------------------------------------------------------------------
  4481 + // Function : privCheckFileHeaders()
  4482 + // Description :
  4483 + // Parameters :
  4484 + // Return Values :
  4485 + // 1 on success,
  4486 + // 0 on error;
  4487 + // --------------------------------------------------------------------------------
  4488 + function privCheckFileHeaders(&$p_local_header, &$p_central_header)
  4489 + {
  4490 + $v_result=1;
  4491 +
  4492 + // ----- Check the static values
  4493 + // TBC
  4494 + if ($p_local_header['filename'] != $p_central_header['filename']) {
  4495 + }
  4496 + if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
  4497 + }
  4498 + if ($p_local_header['flag'] != $p_central_header['flag']) {
  4499 + }
  4500 + if ($p_local_header['compression'] != $p_central_header['compression']) {
  4501 + }
  4502 + if ($p_local_header['mtime'] != $p_central_header['mtime']) {
  4503 + }
  4504 + if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
  4505 + }
  4506 +
  4507 + // ----- Look for flag bit 3
  4508 + if (($p_local_header['flag'] & 8) == 8) {
  4509 + $p_local_header['size'] = $p_central_header['size'];
  4510 + $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
  4511 + $p_local_header['crc'] = $p_central_header['crc'];
  4512 + }
  4513 +
  4514 + // ----- Return
  4515 + return $v_result;
  4516 + }
  4517 + // --------------------------------------------------------------------------------
  4518 +
  4519 + // --------------------------------------------------------------------------------
  4520 + // Function : privReadEndCentralDir()
  4521 + // Description :
  4522 + // Parameters :
  4523 + // Return Values :
  4524 + // --------------------------------------------------------------------------------
  4525 + function privReadEndCentralDir(&$p_central_dir)
  4526 + {
  4527 + $v_result=1;
  4528 +
  4529 + // ----- Go to the end of the zip file
  4530 + $v_size = filesize($this->zipname);
  4531 + @fseek($this->zip_fd, $v_size);
  4532 + if (@ftell($this->zip_fd) != $v_size)
  4533 + {
  4534 + // ----- Error log
  4535 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
  4536 +
  4537 + // ----- Return
  4538 + return PclZip::errorCode();
  4539 + }
  4540 +
  4541 + // ----- First try : look if this is an archive with no commentaries (most of the time)
  4542 + // in this case the end of central dir is at 22 bytes of the file end
  4543 + $v_found = 0;
  4544 + if ($v_size > 26) {
  4545 + @fseek($this->zip_fd, $v_size-22);
  4546 + if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
  4547 + {
  4548 + // ----- Error log
  4549 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  4550 +
  4551 + // ----- Return
  4552 + return PclZip::errorCode();
  4553 + }
  4554 +
  4555 + // ----- Read for bytes
  4556 + $v_binary_data = @fread($this->zip_fd, 4);
  4557 + $v_data = @unpack('Vid', $v_binary_data);
  4558 +
  4559 + // ----- Check signature
  4560 + if ($v_data['id'] == 0x06054b50) {
  4561 + $v_found = 1;
  4562 + }
  4563 +
  4564 + $v_pos = ftell($this->zip_fd);
  4565 + }
  4566 +
  4567 + // ----- Go back to the maximum possible size of the Central Dir End Record
  4568 + if (!$v_found) {
  4569 + $v_maximum_size = 65557; // 0xFFFF + 22;
  4570 + if ($v_maximum_size > $v_size)
  4571 + $v_maximum_size = $v_size;
  4572 + @fseek($this->zip_fd, $v_size-$v_maximum_size);
  4573 + if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
  4574 + {
  4575 + // ----- Error log
  4576 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
  4577 +
  4578 + // ----- Return
  4579 + return PclZip::errorCode();
  4580 + }
  4581 +
  4582 + // ----- Read byte per byte in order to find the signature
  4583 + $v_pos = ftell($this->zip_fd);
  4584 + $v_bytes = 0x00000000;
  4585 + while ($v_pos < $v_size)
  4586 + {
  4587 + // ----- Read a byte
  4588 + $v_byte = @fread($this->zip_fd, 1);
  4589 +
  4590 + // ----- Add the byte
  4591 + //$v_bytes = ($v_bytes << 8) | Ord($v_byte);
  4592 + // Note we mask the old value down such that once shifted we can never end up with more than a 32bit number
  4593 + // Otherwise on systems where we have 64bit integers the check below for the magic number will fail.
  4594 + $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
  4595 +
  4596 + // ----- Compare the bytes
  4597 + if ($v_bytes == 0x504b0506)
  4598 + {
  4599 + $v_pos++;
  4600 + break;
  4601 + }
  4602 +
  4603 + $v_pos++;
  4604 + }
  4605 +
  4606 + // ----- Look if not found end of central dir
  4607 + if ($v_pos == $v_size)
  4608 + {
  4609 +
  4610 + // ----- Error log
  4611 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
  4612 +
  4613 + // ----- Return
  4614 + return PclZip::errorCode();
  4615 + }
  4616 + }
  4617 +
  4618 + // ----- Read the first 18 bytes of the header
  4619 + $v_binary_data = fread($this->zip_fd, 18);
  4620 +
  4621 + // ----- Look for invalid block size
  4622 + if (strlen($v_binary_data) != 18)
  4623 + {
  4624 +
  4625 + // ----- Error log
  4626 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
  4627 +
  4628 + // ----- Return
  4629 + return PclZip::errorCode();
  4630 + }
  4631 +
  4632 + // ----- Extract the values
  4633 + $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
  4634 +
  4635 + // ----- Check the global size
  4636 + if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
  4637 +
  4638 + // ----- Removed in release 2.2 see readme file
  4639 + // The check of the file size is a little too strict.
  4640 + // Some bugs where found when a zip is encrypted/decrypted with 'crypt'.
  4641 + // While decrypted, zip has training 0 bytes
  4642 + if (0) {
  4643 + // ----- Error log
  4644 + PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
  4645 + 'The central dir is not at the end of the archive.'
  4646 + .' Some trailing bytes exists after the archive.');
  4647 +
  4648 + // ----- Return
  4649 + return PclZip::errorCode();
  4650 + }
  4651 + }
  4652 +
  4653 + // ----- Get comment
  4654 + if ($v_data['comment_size'] != 0) {
  4655 + $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
  4656 + }
  4657 + else
  4658 + $p_central_dir['comment'] = '';
  4659 +
  4660 + $p_central_dir['entries'] = $v_data['entries'];
  4661 + $p_central_dir['disk_entries'] = $v_data['disk_entries'];
  4662 + $p_central_dir['offset'] = $v_data['offset'];
  4663 + $p_central_dir['size'] = $v_data['size'];
  4664 + $p_central_dir['disk'] = $v_data['disk'];
  4665 + $p_central_dir['disk_start'] = $v_data['disk_start'];
  4666 +
  4667 + // TBC
  4668 + //for(reset($p_central_dir); $key = key($p_central_dir); next($p_central_dir)) {
  4669 + //}
  4670 +
  4671 + // ----- Return
  4672 + return $v_result;
  4673 + }
  4674 + // --------------------------------------------------------------------------------
  4675 +
  4676 + // --------------------------------------------------------------------------------
  4677 + // Function : privDeleteByRule()
  4678 + // Description :
  4679 + // Parameters :
  4680 + // Return Values :
  4681 + // --------------------------------------------------------------------------------
  4682 + function privDeleteByRule(&$p_result_list, &$p_options)
  4683 + {
  4684 + $v_result=1;
  4685 + $v_list_detail = array();
  4686 +
  4687 + // ----- Open the zip file
  4688 + if (($v_result=$this->privOpenFd('rb')) != 1)
  4689 + {
  4690 + // ----- Return
  4691 + return $v_result;
  4692 + }
  4693 +
  4694 + // ----- Read the central directory informations
  4695 + $v_central_dir = array();
  4696 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  4697 + {
  4698 + $this->privCloseFd();
  4699 + return $v_result;
  4700 + }
  4701 +
  4702 + // ----- Go to beginning of File
  4703 + @rewind($this->zip_fd);
  4704 +
  4705 + // ----- Scan all the files
  4706 + // ----- Start at beginning of Central Dir
  4707 + $v_pos_entry = $v_central_dir['offset'];
  4708 + @rewind($this->zip_fd);
  4709 + if (@fseek($this->zip_fd, $v_pos_entry))
  4710 + {
  4711 + // ----- Close the zip file
  4712 + $this->privCloseFd();
  4713 +
  4714 + // ----- Error log
  4715 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  4716 +
  4717 + // ----- Return
  4718 + return PclZip::errorCode();
  4719 + }
  4720 +
  4721 + // ----- Read each entry
  4722 + $v_header_list = array();
  4723 + $j_start = 0;
  4724 + for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
  4725 + {
  4726 +
  4727 + // ----- Read the file header
  4728 + $v_header_list[$v_nb_extracted] = array();
  4729 + if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
  4730 + {
  4731 + // ----- Close the zip file
  4732 + $this->privCloseFd();
  4733 +
  4734 + return $v_result;
  4735 + }
  4736 +
  4737 +
  4738 + // ----- Store the index
  4739 + $v_header_list[$v_nb_extracted]['index'] = $i;
  4740 +
  4741 + // ----- Look for the specific extract rules
  4742 + $v_found = false;
  4743 +
  4744 + // ----- Look for extract by name rule
  4745 + if ( (isset($p_options[PCLZIP_OPT_BY_NAME]))
  4746 + && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
  4747 +
  4748 + // ----- Look if the filename is in the list
  4749 + for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
  4750 +
  4751 + // ----- Look for a directory
  4752 + if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
  4753 +
  4754 + // ----- Look if the directory is in the filename path
  4755 + if ( (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
  4756 + && (substr($v_header_list[$v_nb_extracted]['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  4757 + $v_found = true;
  4758 + }
  4759 + elseif ( (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
  4760 + && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
  4761 + $v_found = true;
  4762 + }
  4763 + }
  4764 + // ----- Look for a filename
  4765 + elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
  4766 + $v_found = true;
  4767 + }
  4768 + }
  4769 + }
  4770 +
  4771 + // ----- Look for extract by ereg rule
  4772 + // ereg() is deprecated with PHP 5.3
  4773 + /*
  4774 + else if ( (isset($p_options[PCLZIP_OPT_BY_EREG]))
  4775 + && ($p_options[PCLZIP_OPT_BY_EREG] != "")) {
  4776 +
  4777 + if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  4778 + $v_found = true;
  4779 + }
  4780 + }
  4781 + */
  4782 +
  4783 + // ----- Look for extract by preg rule
  4784 + else if ( (isset($p_options[PCLZIP_OPT_BY_PREG]))
  4785 + && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
  4786 +
  4787 + if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
  4788 + $v_found = true;
  4789 + }
  4790 + }
  4791 +
  4792 + // ----- Look for extract by index rule
  4793 + else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX]))
  4794 + && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
  4795 +
  4796 + // ----- Look if the index is in the list
  4797 + for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
  4798 +
  4799 + if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
  4800 + $v_found = true;
  4801 + }
  4802 + if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
  4803 + $j_start = $j+1;
  4804 + }
  4805 +
  4806 + if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
  4807 + break;
  4808 + }
  4809 + }
  4810 + }
  4811 + else {
  4812 + $v_found = true;
  4813 + }
  4814 +
  4815 + // ----- Look for deletion
  4816 + if ($v_found)
  4817 + {
  4818 + unset($v_header_list[$v_nb_extracted]);
  4819 + }
  4820 + else
  4821 + {
  4822 + $v_nb_extracted++;
  4823 + }
  4824 + }
  4825 +
  4826 + // ----- Look if something need to be deleted
  4827 + if ($v_nb_extracted > 0) {
  4828 +
  4829 + // ----- Creates a temporay file
  4830 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  4831 +
  4832 + // ----- Creates a temporary zip archive
  4833 + $v_temp_zip = new PclZip($v_zip_temp_name);
  4834 +
  4835 + // ----- Open the temporary zip file in write mode
  4836 + if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
  4837 + $this->privCloseFd();
  4838 +
  4839 + // ----- Return
  4840 + return $v_result;
  4841 + }
  4842 +
  4843 + // ----- Look which file need to be kept
  4844 + for ($i=0; $i<sizeof($v_header_list); $i++) {
  4845 +
  4846 + // ----- Calculate the position of the header
  4847 + @rewind($this->zip_fd);
  4848 + if (@fseek($this->zip_fd, $v_header_list[$i]['offset'])) {
  4849 + // ----- Close the zip file
  4850 + $this->privCloseFd();
  4851 + $v_temp_zip->privCloseFd();
  4852 + @unlink($v_zip_temp_name);
  4853 +
  4854 + // ----- Error log
  4855 + PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
  4856 +
  4857 + // ----- Return
  4858 + return PclZip::errorCode();
  4859 + }
  4860 +
  4861 + // ----- Read the file header
  4862 + $v_local_header = array();
  4863 + if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
  4864 + // ----- Close the zip file
  4865 + $this->privCloseFd();
  4866 + $v_temp_zip->privCloseFd();
  4867 + @unlink($v_zip_temp_name);
  4868 +
  4869 + // ----- Return
  4870 + return $v_result;
  4871 + }
  4872 +
  4873 + // ----- Check that local file header is same as central file header
  4874 + if ($this->privCheckFileHeaders($v_local_header,
  4875 + $v_header_list[$i]) != 1) {
  4876 + // TBC
  4877 + }
  4878 + unset($v_local_header);
  4879 +
  4880 + // ----- Write the file header
  4881 + if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
  4882 + // ----- Close the zip file
  4883 + $this->privCloseFd();
  4884 + $v_temp_zip->privCloseFd();
  4885 + @unlink($v_zip_temp_name);
  4886 +
  4887 + // ----- Return
  4888 + return $v_result;
  4889 + }
  4890 +
  4891 + // ----- Read/write the data block
  4892 + if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
  4893 + // ----- Close the zip file
  4894 + $this->privCloseFd();
  4895 + $v_temp_zip->privCloseFd();
  4896 + @unlink($v_zip_temp_name);
  4897 +
  4898 + // ----- Return
  4899 + return $v_result;
  4900 + }
  4901 + }
  4902 +
  4903 + // ----- Store the offset of the central dir
  4904 + $v_offset = @ftell($v_temp_zip->zip_fd);
  4905 +
  4906 + // ----- Re-Create the Central Dir files header
  4907 + for ($i=0; $i<sizeof($v_header_list); $i++) {
  4908 + // ----- Create the file header
  4909 + if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
  4910 + $v_temp_zip->privCloseFd();
  4911 + $this->privCloseFd();
  4912 + @unlink($v_zip_temp_name);
  4913 +
  4914 + // ----- Return
  4915 + return $v_result;
  4916 + }
  4917 +
  4918 + // ----- Transform the header to a 'usable' info
  4919 + $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
  4920 + }
  4921 +
  4922 +
  4923 + // ----- Zip file comment
  4924 + $v_comment = '';
  4925 + if (isset($p_options[PCLZIP_OPT_COMMENT])) {
  4926 + $v_comment = $p_options[PCLZIP_OPT_COMMENT];
  4927 + }
  4928 +
  4929 + // ----- Calculate the size of the central header
  4930 + $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
  4931 +
  4932 + // ----- Create the central dir footer
  4933 + if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
  4934 + // ----- Reset the file list
  4935 + unset($v_header_list);
  4936 + $v_temp_zip->privCloseFd();
  4937 + $this->privCloseFd();
  4938 + @unlink($v_zip_temp_name);
  4939 +
  4940 + // ----- Return
  4941 + return $v_result;
  4942 + }
  4943 +
  4944 + // ----- Close
  4945 + $v_temp_zip->privCloseFd();
  4946 + $this->privCloseFd();
  4947 +
  4948 + // ----- Delete the zip file
  4949 + // TBC : I should test the result ...
  4950 + @unlink($this->zipname);
  4951 +
  4952 + // ----- Rename the temporary file
  4953 + // TBC : I should test the result ...
  4954 + //@rename($v_zip_temp_name, $this->zipname);
  4955 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  4956 +
  4957 + // ----- Destroy the temporary archive
  4958 + unset($v_temp_zip);
  4959 + }
  4960 +
  4961 + // ----- Remove every files : reset the file
  4962 + else if ($v_central_dir['entries'] != 0) {
  4963 + $this->privCloseFd();
  4964 +
  4965 + if (($v_result = $this->privOpenFd('wb')) != 1) {
  4966 + return $v_result;
  4967 + }
  4968 +
  4969 + if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
  4970 + return $v_result;
  4971 + }
  4972 +
  4973 + $this->privCloseFd();
  4974 + }
  4975 +
  4976 + // ----- Return
  4977 + return $v_result;
  4978 + }
  4979 + // --------------------------------------------------------------------------------
  4980 +
  4981 + // --------------------------------------------------------------------------------
  4982 + // Function : privDirCheck()
  4983 + // Description :
  4984 + // Check if a directory exists, if not it creates it and all the parents directory
  4985 + // which may be useful.
  4986 + // Parameters :
  4987 + // $p_dir : Directory path to check.
  4988 + // Return Values :
  4989 + // 1 : OK
  4990 + // -1 : Unable to create directory
  4991 + // --------------------------------------------------------------------------------
  4992 + function privDirCheck($p_dir, $p_is_dir=false)
  4993 + {
  4994 + $v_result = 1;
  4995 +
  4996 +
  4997 + // ----- Remove the final '/'
  4998 + if (($p_is_dir) && (substr($p_dir, -1)=='/'))
  4999 + {
  5000 + $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
  5001 + }
  5002 +
  5003 + // ----- Check the directory availability
  5004 + if ((is_dir($p_dir)) || ($p_dir == ""))
  5005 + {
  5006 + return 1;
  5007 + }
  5008 +
  5009 + // ----- Extract parent directory
  5010 + $p_parent_dir = dirname($p_dir);
  5011 +
  5012 + // ----- Just a check
  5013 + if ($p_parent_dir != $p_dir)
  5014 + {
  5015 + // ----- Look for parent directory
  5016 + if ($p_parent_dir != "")
  5017 + {
  5018 + if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
  5019 + {
  5020 + return $v_result;
  5021 + }
  5022 + }
  5023 + }
  5024 +
  5025 + // ----- Create the directory
  5026 + if (!@mkdir($p_dir, 0777))
  5027 + {
  5028 + // ----- Error log
  5029 + PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
  5030 +
  5031 + // ----- Return
  5032 + return PclZip::errorCode();
  5033 + }
  5034 +
  5035 + // ----- Return
  5036 + return $v_result;
  5037 + }
  5038 + // --------------------------------------------------------------------------------
  5039 +
  5040 + // --------------------------------------------------------------------------------
  5041 + // Function : privMerge()
  5042 + // Description :
  5043 + // If $p_archive_to_add does not exist, the function exit with a success result.
  5044 + // Parameters :
  5045 + // Return Values :
  5046 + // --------------------------------------------------------------------------------
  5047 + function privMerge(&$p_archive_to_add)
  5048 + {
  5049 + $v_result=1;
  5050 +
  5051 + // ----- Look if the archive_to_add exists
  5052 + if (!is_file($p_archive_to_add->zipname))
  5053 + {
  5054 +
  5055 + // ----- Nothing to merge, so merge is a success
  5056 + $v_result = 1;
  5057 +
  5058 + // ----- Return
  5059 + return $v_result;
  5060 + }
  5061 +
  5062 + // ----- Look if the archive exists
  5063 + if (!is_file($this->zipname))
  5064 + {
  5065 +
  5066 + // ----- Do a duplicate
  5067 + $v_result = $this->privDuplicate($p_archive_to_add->zipname);
  5068 +
  5069 + // ----- Return
  5070 + return $v_result;
  5071 + }
  5072 +
  5073 + // ----- Open the zip file
  5074 + if (($v_result=$this->privOpenFd('rb')) != 1)
  5075 + {
  5076 + // ----- Return
  5077 + return $v_result;
  5078 + }
  5079 +
  5080 + // ----- Read the central directory informations
  5081 + $v_central_dir = array();
  5082 + if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
  5083 + {
  5084 + $this->privCloseFd();
  5085 + return $v_result;
  5086 + }
  5087 +
  5088 + // ----- Go to beginning of File
  5089 + @rewind($this->zip_fd);
  5090 +
  5091 + // ----- Open the archive_to_add file
  5092 + if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
  5093 + {
  5094 + $this->privCloseFd();
  5095 +
  5096 + // ----- Return
  5097 + return $v_result;
  5098 + }
  5099 +
  5100 + // ----- Read the central directory informations
  5101 + $v_central_dir_to_add = array();
  5102 + if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
  5103 + {
  5104 + $this->privCloseFd();
  5105 + $p_archive_to_add->privCloseFd();
  5106 +
  5107 + return $v_result;
  5108 + }
  5109 +
  5110 + // ----- Go to beginning of File
  5111 + @rewind($p_archive_to_add->zip_fd);
  5112 +
  5113 + // ----- Creates a temporay file
  5114 + $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
  5115 +
  5116 + // ----- Open the temporary file in write mode
  5117 + if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
  5118 + {
  5119 + $this->privCloseFd();
  5120 + $p_archive_to_add->privCloseFd();
  5121 +
  5122 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
  5123 +
  5124 + // ----- Return
  5125 + return PclZip::errorCode();
  5126 + }
  5127 +
  5128 + // ----- Copy the files from the archive to the temporary file
  5129 + // TBC : Here I should better append the file and go back to erase the central dir
  5130 + $v_size = $v_central_dir['offset'];
  5131 + while ($v_size != 0)
  5132 + {
  5133 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5134 + $v_buffer = fread($this->zip_fd, $v_read_size);
  5135 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5136 + $v_size -= $v_read_size;
  5137 + }
  5138 +
  5139 + // ----- Copy the files from the archive_to_add into the temporary file
  5140 + $v_size = $v_central_dir_to_add['offset'];
  5141 + while ($v_size != 0)
  5142 + {
  5143 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5144 + $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
  5145 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5146 + $v_size -= $v_read_size;
  5147 + }
  5148 +
  5149 + // ----- Store the offset of the central dir
  5150 + $v_offset = @ftell($v_zip_temp_fd);
  5151 +
  5152 + // ----- Copy the block of file headers from the old archive
  5153 + $v_size = $v_central_dir['size'];
  5154 + while ($v_size != 0)
  5155 + {
  5156 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5157 + $v_buffer = @fread($this->zip_fd, $v_read_size);
  5158 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5159 + $v_size -= $v_read_size;
  5160 + }
  5161 +
  5162 + // ----- Copy the block of file headers from the archive_to_add
  5163 + $v_size = $v_central_dir_to_add['size'];
  5164 + while ($v_size != 0)
  5165 + {
  5166 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5167 + $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
  5168 + @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
  5169 + $v_size -= $v_read_size;
  5170 + }
  5171 +
  5172 + // ----- Merge the file comments
  5173 + $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
  5174 +
  5175 + // ----- Calculate the size of the (new) central header
  5176 + $v_size = @ftell($v_zip_temp_fd)-$v_offset;
  5177 +
  5178 + // ----- Swap the file descriptor
  5179 + // Here is a trick : I swap the temporary fd with the zip fd, in order to use
  5180 + // the following methods on the temporary fil and not the real archive fd
  5181 + $v_swap = $this->zip_fd;
  5182 + $this->zip_fd = $v_zip_temp_fd;
  5183 + $v_zip_temp_fd = $v_swap;
  5184 +
  5185 + // ----- Create the central dir footer
  5186 + if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
  5187 + {
  5188 + $this->privCloseFd();
  5189 + $p_archive_to_add->privCloseFd();
  5190 + @fclose($v_zip_temp_fd);
  5191 + $this->zip_fd = null;
  5192 +
  5193 + // ----- Reset the file list
  5194 + unset($v_header_list);
  5195 +
  5196 + // ----- Return
  5197 + return $v_result;
  5198 + }
  5199 +
  5200 + // ----- Swap back the file descriptor
  5201 + $v_swap = $this->zip_fd;
  5202 + $this->zip_fd = $v_zip_temp_fd;
  5203 + $v_zip_temp_fd = $v_swap;
  5204 +
  5205 + // ----- Close
  5206 + $this->privCloseFd();
  5207 + $p_archive_to_add->privCloseFd();
  5208 +
  5209 + // ----- Close the temporary file
  5210 + @fclose($v_zip_temp_fd);
  5211 +
  5212 + // ----- Delete the zip file
  5213 + // TBC : I should test the result ...
  5214 + @unlink($this->zipname);
  5215 +
  5216 + // ----- Rename the temporary file
  5217 + // TBC : I should test the result ...
  5218 + //@rename($v_zip_temp_name, $this->zipname);
  5219 + PclZipUtilRename($v_zip_temp_name, $this->zipname);
  5220 +
  5221 + // ----- Return
  5222 + return $v_result;
  5223 + }
  5224 + // --------------------------------------------------------------------------------
  5225 +
  5226 + // --------------------------------------------------------------------------------
  5227 + // Function : privDuplicate()
  5228 + // Description :
  5229 + // Parameters :
  5230 + // Return Values :
  5231 + // --------------------------------------------------------------------------------
  5232 + function privDuplicate($p_archive_filename)
  5233 + {
  5234 + $v_result=1;
  5235 +
  5236 + // ----- Look if the $p_archive_filename exists
  5237 + if (!is_file($p_archive_filename))
  5238 + {
  5239 +
  5240 + // ----- Nothing to duplicate, so duplicate is a success.
  5241 + $v_result = 1;
  5242 +
  5243 + // ----- Return
  5244 + return $v_result;
  5245 + }
  5246 +
  5247 + // ----- Open the zip file
  5248 + if (($v_result=$this->privOpenFd('wb')) != 1)
  5249 + {
  5250 + // ----- Return
  5251 + return $v_result;
  5252 + }
  5253 +
  5254 + // ----- Open the temporary file in write mode
  5255 + if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
  5256 + {
  5257 + $this->privCloseFd();
  5258 +
  5259 + PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
  5260 +
  5261 + // ----- Return
  5262 + return PclZip::errorCode();
  5263 + }
  5264 +
  5265 + // ----- Copy the files from the archive to the temporary file
  5266 + // TBC : Here I should better append the file and go back to erase the central dir
  5267 + $v_size = filesize($p_archive_filename);
  5268 + while ($v_size != 0)
  5269 + {
  5270 + $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
  5271 + $v_buffer = fread($v_zip_temp_fd, $v_read_size);
  5272 + @fwrite($this->zip_fd, $v_buffer, $v_read_size);
  5273 + $v_size -= $v_read_size;
  5274 + }
  5275 +
  5276 + // ----- Close
  5277 + $this->privCloseFd();
  5278 +
  5279 + // ----- Close the temporary file
  5280 + @fclose($v_zip_temp_fd);
  5281 +
  5282 + // ----- Return
  5283 + return $v_result;
  5284 + }
  5285 + // --------------------------------------------------------------------------------
  5286 +
  5287 + // --------------------------------------------------------------------------------
  5288 + // Function : privErrorLog()
  5289 + // Description :
  5290 + // Parameters :
  5291 + // --------------------------------------------------------------------------------
  5292 + function privErrorLog($p_error_code=0, $p_error_string='')
  5293 + {
  5294 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  5295 + PclError($p_error_code, $p_error_string);
  5296 + }
  5297 + else {
  5298 + $this->error_code = $p_error_code;
  5299 + $this->error_string = $p_error_string;
  5300 + }
  5301 + }
  5302 + // --------------------------------------------------------------------------------
  5303 +
  5304 + // --------------------------------------------------------------------------------
  5305 + // Function : privErrorReset()
  5306 + // Description :
  5307 + // Parameters :
  5308 + // --------------------------------------------------------------------------------
  5309 + function privErrorReset()
  5310 + {
  5311 + if (PCLZIP_ERROR_EXTERNAL == 1) {
  5312 + PclErrorReset();
  5313 + }
  5314 + else {
  5315 + $this->error_code = 0;
  5316 + $this->error_string = '';
  5317 + }
  5318 + }
  5319 + // --------------------------------------------------------------------------------
  5320 +
  5321 + // --------------------------------------------------------------------------------
  5322 + // Function : privDisableMagicQuotes()
  5323 + // Description :
  5324 + // Parameters :
  5325 + // Return Values :
  5326 + // --------------------------------------------------------------------------------
  5327 + function privDisableMagicQuotes()
  5328 + {
  5329 + $v_result=1;
  5330 +
  5331 + // ----- Look if function exists
  5332 + if ( (!function_exists("get_magic_quotes_runtime"))
  5333 + || (!function_exists("set_magic_quotes_runtime"))) {
  5334 + return $v_result;
  5335 + }
  5336 +
  5337 + // ----- Look if already done
  5338 + if ($this->magic_quotes_status != -1) {
  5339 + return $v_result;
  5340 + }
  5341 +
  5342 + // ----- Get and memorize the magic_quote value
  5343 + $this->magic_quotes_status = @get_magic_quotes_runtime();
  5344 +
  5345 + // ----- Disable magic_quotes
  5346 + if ($this->magic_quotes_status == 1) {
  5347 + @set_magic_quotes_runtime(0);
  5348 + }
  5349 +
  5350 + // ----- Return
  5351 + return $v_result;
  5352 + }
  5353 + // --------------------------------------------------------------------------------
  5354 +
  5355 + // --------------------------------------------------------------------------------
  5356 + // Function : privSwapBackMagicQuotes()
  5357 + // Description :
  5358 + // Parameters :
  5359 + // Return Values :
  5360 + // --------------------------------------------------------------------------------
  5361 + function privSwapBackMagicQuotes()
  5362 + {
  5363 + $v_result=1;
  5364 +
  5365 + // ----- Look if function exists
  5366 + if ( (!function_exists("get_magic_quotes_runtime"))
  5367 + || (!function_exists("set_magic_quotes_runtime"))) {
  5368 + return $v_result;
  5369 + }
  5370 +
  5371 + // ----- Look if something to do
  5372 + if ($this->magic_quotes_status != -1) {
  5373 + return $v_result;
  5374 + }
  5375 +
  5376 + // ----- Swap back magic_quotes
  5377 + if ($this->magic_quotes_status == 1) {
  5378 + @set_magic_quotes_runtime($this->magic_quotes_status);
  5379 + }
  5380 +
  5381 + // ----- Return
  5382 + return $v_result;
  5383 + }
  5384 + // --------------------------------------------------------------------------------
  5385 +
  5386 + }
  5387 + // End of class
  5388 + // --------------------------------------------------------------------------------
  5389 +
  5390 + // --------------------------------------------------------------------------------
  5391 + // Function : PclZipUtilPathReduction()
  5392 + // Description :
  5393 + // Parameters :
  5394 + // Return Values :
  5395 + // --------------------------------------------------------------------------------
  5396 + function PclZipUtilPathReduction($p_dir)
  5397 + {
  5398 + $v_result = "";
  5399 +
  5400 + // ----- Look for not empty path
  5401 + if ($p_dir != "") {
  5402 + // ----- Explode path by directory names
  5403 + $v_list = explode("/", $p_dir);
  5404 +
  5405 + // ----- Study directories from last to first
  5406 + $v_skip = 0;
  5407 + for ($i=sizeof($v_list)-1; $i>=0; $i--) {
  5408 + // ----- Look for current path
  5409 + if ($v_list[$i] == ".") {
  5410 + // ----- Ignore this directory
  5411 + // Should be the first $i=0, but no check is done
  5412 + }
  5413 + else if ($v_list[$i] == "..") {
  5414 + $v_skip++;
  5415 + }
  5416 + else if ($v_list[$i] == "") {
  5417 + // ----- First '/' i.e. root slash
  5418 + if ($i == 0) {
  5419 + $v_result = "/".$v_result;
  5420 + if ($v_skip > 0) {
  5421 + // ----- It is an invalid path, so the path is not modified
  5422 + // TBC
  5423 + $v_result = $p_dir;
  5424 + $v_skip = 0;
  5425 + }
  5426 + }
  5427 + // ----- Last '/' i.e. indicates a directory
  5428 + else if ($i == (sizeof($v_list)-1)) {
  5429 + $v_result = $v_list[$i];
  5430 + }
  5431 + // ----- Double '/' inside the path
  5432 + else {
  5433 + // ----- Ignore only the double '//' in path,
  5434 + // but not the first and last '/'
  5435 + }
  5436 + }
  5437 + else {
  5438 + // ----- Look for item to skip
  5439 + if ($v_skip > 0) {
  5440 + $v_skip--;
  5441 + }
  5442 + else {
  5443 + $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
  5444 + }
  5445 + }
  5446 + }
  5447 +
  5448 + // ----- Look for skip
  5449 + if ($v_skip > 0) {
  5450 + while ($v_skip > 0) {
  5451 + $v_result = '../'.$v_result;
  5452 + $v_skip--;
  5453 + }
  5454 + }
  5455 + }
  5456 +
  5457 + // ----- Return
  5458 + return $v_result;
  5459 + }
  5460 + // --------------------------------------------------------------------------------
  5461 +
  5462 + // --------------------------------------------------------------------------------
  5463 + // Function : PclZipUtilPathInclusion()
  5464 + // Description :
  5465 + // This function indicates if the path $p_path is under the $p_dir tree. Or,
  5466 + // said in an other way, if the file or sub-dir $p_path is inside the dir
  5467 + // $p_dir.
  5468 + // The function indicates also if the path is exactly the same as the dir.
  5469 + // This function supports path with duplicated '/' like '//', but does not
  5470 + // support '.' or '..' statements.
  5471 + // Parameters :
  5472 + // Return Values :
  5473 + // 0 if $p_path is not inside directory $p_dir
  5474 + // 1 if $p_path is inside directory $p_dir
  5475 + // 2 if $p_path is exactly the same as $p_dir
  5476 + // --------------------------------------------------------------------------------
  5477 + function PclZipUtilPathInclusion($p_dir, $p_path)
  5478 + {
  5479 + $v_result = 1;
  5480 +
  5481 + // ----- Look for path beginning by ./
  5482 + if ( ($p_dir == '.')
  5483 + || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
  5484 + $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
  5485 + }
  5486 + if ( ($p_path == '.')
  5487 + || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
  5488 + $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
  5489 + }
  5490 +
  5491 + // ----- Explode dir and path by directory separator
  5492 + $v_list_dir = explode("/", $p_dir);
  5493 + $v_list_dir_size = sizeof($v_list_dir);
  5494 + $v_list_path = explode("/", $p_path);
  5495 + $v_list_path_size = sizeof($v_list_path);
  5496 +
  5497 + // ----- Study directories paths
  5498 + $i = 0;
  5499 + $j = 0;
  5500 + while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
  5501 +
  5502 + // ----- Look for empty dir (path reduction)
  5503 + if ($v_list_dir[$i] == '') {
  5504 + $i++;
  5505 + continue;
  5506 + }
  5507 + if ($v_list_path[$j] == '') {
  5508 + $j++;
  5509 + continue;
  5510 + }
  5511 +
  5512 + // ----- Compare the items
  5513 + if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != '')) {
  5514 + $v_result = 0;
  5515 + }
  5516 +
  5517 + // ----- Next items
  5518 + $i++;
  5519 + $j++;
  5520 + }
  5521 +
  5522 + // ----- Look if everything seems to be the same
  5523 + if ($v_result) {
  5524 + // ----- Skip all the empty items
  5525 + while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
  5526 + while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
  5527 +
  5528 + if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
  5529 + // ----- There are exactly the same
  5530 + $v_result = 2;
  5531 + }
  5532 + else if ($i < $v_list_dir_size) {
  5533 + // ----- The path is shorter than the dir
  5534 + $v_result = 0;
  5535 + }
  5536 + }
  5537 +
  5538 + // ----- Return
  5539 + return $v_result;
  5540 + }
  5541 + // --------------------------------------------------------------------------------
  5542 +
  5543 + // --------------------------------------------------------------------------------
  5544 + // Function : PclZipUtilCopyBlock()
  5545 + // Description :
  5546 + // Parameters :
  5547 + // $p_mode : read/write compression mode
  5548 + // 0 : src & dest normal
  5549 + // 1 : src gzip, dest normal
  5550 + // 2 : src normal, dest gzip
  5551 + // 3 : src & dest gzip
  5552 + // Return Values :
  5553 + // --------------------------------------------------------------------------------
  5554 + function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
  5555 + {
  5556 + $v_result = 1;
  5557 +
  5558 + if ($p_mode==0)
  5559 + {
  5560 + while ($p_size != 0)
  5561 + {
  5562 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5563 + $v_buffer = @fread($p_src, $v_read_size);
  5564 + @fwrite($p_dest, $v_buffer, $v_read_size);
  5565 + $p_size -= $v_read_size;
  5566 + }
  5567 + }
  5568 + else if ($p_mode==1)
  5569 + {
  5570 + while ($p_size != 0)
  5571 + {
  5572 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5573 + $v_buffer = @gzread($p_src, $v_read_size);
  5574 + @fwrite($p_dest, $v_buffer, $v_read_size);
  5575 + $p_size -= $v_read_size;
  5576 + }
  5577 + }
  5578 + else if ($p_mode==2)
  5579 + {
  5580 + while ($p_size != 0)
  5581 + {
  5582 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5583 + $v_buffer = @fread($p_src, $v_read_size);
  5584 + @gzwrite($p_dest, $v_buffer, $v_read_size);
  5585 + $p_size -= $v_read_size;
  5586 + }
  5587 + }
  5588 + else if ($p_mode==3)
  5589 + {
  5590 + while ($p_size != 0)
  5591 + {
  5592 + $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
  5593 + $v_buffer = @gzread($p_src, $v_read_size);
  5594 + @gzwrite($p_dest, $v_buffer, $v_read_size);
  5595 + $p_size -= $v_read_size;
  5596 + }
  5597 + }
  5598 +
  5599 + // ----- Return
  5600 + return $v_result;
  5601 + }
  5602 + // --------------------------------------------------------------------------------
  5603 +
  5604 + // --------------------------------------------------------------------------------
  5605 + // Function : PclZipUtilRename()
  5606 + // Description :
  5607 + // This function tries to do a simple rename() function. If it fails, it
  5608 + // tries to copy the $p_src file in a new $p_dest file and then unlink the
  5609 + // first one.
  5610 + // Parameters :
  5611 + // $p_src : Old filename
  5612 + // $p_dest : New filename
  5613 + // Return Values :
  5614 + // 1 on success, 0 on failure.
  5615 + // --------------------------------------------------------------------------------
  5616 + function PclZipUtilRename($p_src, $p_dest)
  5617 + {
  5618 + $v_result = 1;
  5619 +
  5620 + // ----- Try to rename the files
  5621 + if (!@rename($p_src, $p_dest)) {
  5622 +
  5623 + // ----- Try to copy & unlink the src
  5624 + if (!@copy($p_src, $p_dest)) {
  5625 + $v_result = 0;
  5626 + }
  5627 + else if (!@unlink($p_src)) {
  5628 + $v_result = 0;
  5629 + }
  5630 + }
  5631 +
  5632 + // ----- Return
  5633 + return $v_result;
  5634 + }
  5635 + // --------------------------------------------------------------------------------
  5636 +
  5637 + // --------------------------------------------------------------------------------
  5638 + // Function : PclZipUtilOptionText()
  5639 + // Description :
  5640 + // Translate option value in text. Mainly for debug purpose.
  5641 + // Parameters :
  5642 + // $p_option : the option value.
  5643 + // Return Values :
  5644 + // The option text value.
  5645 + // --------------------------------------------------------------------------------
  5646 + function PclZipUtilOptionText($p_option)
  5647 + {
  5648 +
  5649 + $v_list = get_defined_constants();
  5650 + for (reset($v_list); $v_key = key($v_list); next($v_list)) {
  5651 + $v_prefix = substr($v_key, 0, 10);
  5652 + if (( ($v_prefix == 'PCLZIP_OPT')
  5653 + || ($v_prefix == 'PCLZIP_CB_')
  5654 + || ($v_prefix == 'PCLZIP_ATT'))
  5655 + && ($v_list[$v_key] == $p_option)) {
  5656 + return $v_key;
  5657 + }
  5658 + }
  5659 +
  5660 + $v_result = 'Unknown';
  5661 +
  5662 + return $v_result;
  5663 + }
  5664 + // --------------------------------------------------------------------------------
  5665 +
  5666 + // --------------------------------------------------------------------------------
  5667 + // Function : PclZipUtilTranslateWinPath()
  5668 + // Description :
  5669 + // Translate windows path by replacing '\' by '/' and optionally removing
  5670 + // drive letter.
  5671 + // Parameters :
  5672 + // $p_path : path to translate.
  5673 + // $p_remove_disk_letter : true | false
  5674 + // Return Values :
  5675 + // The path translated.
  5676 + // --------------------------------------------------------------------------------
  5677 + function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
  5678 + {
  5679 + if (stristr(php_uname(), 'windows')) {
  5680 + // ----- Look for potential disk letter
  5681 + if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
  5682 + $p_path = substr($p_path, $v_position+1);
  5683 + }
  5684 + // ----- Change potential windows directory separator
  5685 + if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
  5686 + $p_path = strtr($p_path, '\\', '/');
  5687 + }
  5688 + }
  5689 + return $p_path;
  5690 + }
  5691 + // --------------------------------------------------------------------------------
  5692 +
  5693 +
  5694 +?>