Mise en route du suivi.
[aidenligne_francais_universite.git] / ecrire / inc / pclzip.php
1 <?php
2 // --------------------------------------------------------------------------------
3 // PhpConcept Library - Zip Module 2.5
4 // --------------------------------------------------------------------------------
5 // License GNU/LGPL - Vincent Blavet - March 2006
6 // http://www.phpconcept.net
7 // --------------------------------------------------------------------------------
8 //
9 // Presentation :
10 // PclZip is a PHP library that manage ZIP archives.
11 // So far tests show that archives generated by PclZip are readable by
12 // WinZip application and other tools.
13 //
14 // Description :
15 // See readme.txt and http://www.phpconcept.net
16 //
17 // Warning :
18 // This library and the associated files are non commercial, non professional
19 // work.
20 // It should not have unexpected results. However if any damage is caused by
21 // this software the author can not be responsible.
22 // The use of this software is at the risk of the user.
23 //
24 // --------------------------------------------------------------------------------
25 // $Id: pclzip.php 8710 2007-02-16 10:10:34Z cedric@yterium.com $
26 // --------------------------------------------------------------------------------
27
28 // ----- Constants
29 define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
30
31 // ----- File list separator
32 // In version 1.x of PclZip, the separator for file list is a space
33 // (which is not a very smart choice, specifically for windows paths !).
34 // A better separator should be a comma (,). This constant gives you the
35 // abilty to change that.
36 // However notice that changing this value, may have impact on existing
37 // scripts, using space separated filenames.
38 // Recommanded values for compatibility with older versions :
39 //define( 'PCLZIP_SEPARATOR', ' ' );
40 // Recommanded values for smart separation of filenames.
41 define( 'PCLZIP_SEPARATOR', ',' );
42
43 // ----- Error configuration
44 // 0 : PclZip Class integrated error handling
45 // 1 : PclError external library error handling. By enabling this
46 // you must ensure that you have included PclError library.
47 // [2,...] : reserved for futur use
48 define( 'PCLZIP_ERROR_EXTERNAL', 0 );
49
50 // ----- Optional static temporary directory
51 // By default temporary files are generated in the script current
52 // path.
53 // If defined :
54 // - MUST BE terminated by a '/'.
55 // - MUST be a valid, already created directory
56 // Samples :
57 // define( 'PCLZIP_TEMPORARY_DIR', '/temp/' );
58 // define( 'PCLZIP_TEMPORARY_DIR', 'C:/Temp/' );
59 define( 'PCLZIP_TEMPORARY_DIR', _DIR_TMP );
60
61 // --------------------------------------------------------------------------------
62 // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED *****
63 // --------------------------------------------------------------------------------
64
65 // ----- Global variables
66 $g_pclzip_version = "2.5";
67
68 // ----- Error codes
69 // -1 : Unable to open file in binary write mode
70 // -2 : Unable to open file in binary read mode
71 // -3 : Invalid parameters
72 // -4 : File does not exist
73 // -5 : Filename is too long (max. 255)
74 // -6 : Not a valid zip file
75 // -7 : Invalid extracted file size
76 // -8 : Unable to create directory
77 // -9 : Invalid archive extension
78 // -10 : Invalid archive format
79 // -11 : Unable to delete file (unlink)
80 // -12 : Unable to rename file (rename)
81 // -13 : Invalid header checksum
82 // -14 : Invalid archive size
83 define( 'PCLZIP_ERR_USER_ABORTED', 2 );
84 define( 'PCLZIP_ERR_NO_ERROR', 0 );
85 define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
86 define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
87 define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
88 define( 'PCLZIP_ERR_MISSING_FILE', -4 );
89 define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
90 define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
91 define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
92 define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
93 define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
94 define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
95 define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
96 define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
97 define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
98 define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
99 define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
100 define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
101 define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
102 define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
103 define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
104 define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
105 define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
106
107 // ----- Options values
108 define( 'PCLZIP_OPT_PATH', 77001 );
109 define( 'PCLZIP_OPT_ADD_PATH', 77002 );
110 define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
111 define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
112 define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
113 define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
114 define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
115 define( 'PCLZIP_OPT_BY_NAME', 77008 );
116 define( 'PCLZIP_OPT_BY_INDEX', 77009 );
117 define( 'PCLZIP_OPT_BY_EREG', 77010 );
118 define( 'PCLZIP_OPT_BY_PREG', 77011 );
119 define( 'PCLZIP_OPT_COMMENT', 77012 );
120 define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
121 define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
122 define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
123 define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
124 define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
125 // Having big trouble with crypt. Need to multiply 2 long int
126 // which is not correctly supported by PHP ...
127 //define( 'PCLZIP_OPT_CRYPT', 77018 );
128 define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
129
130 // ----- File description attributes
131 define( 'PCLZIP_ATT_FILE_NAME', 79001 );
132 define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
133 define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
134
135 // ----- Call backs values
136 define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
137 define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
138 define( 'PCLZIP_CB_PRE_ADD', 78003 );
139 define( 'PCLZIP_CB_POST_ADD', 78004 );
140 /* For futur use
141 define( 'PCLZIP_CB_PRE_LIST', 78005 );
142 define( 'PCLZIP_CB_POST_LIST', 78006 );
143 define( 'PCLZIP_CB_PRE_DELETE', 78007 );
144 define( 'PCLZIP_CB_POST_DELETE', 78008 );
145 */
146
147 // --------------------------------------------------------------------------------
148 // Class : PclZip
149 // Description :
150 // PclZip is the class that represent a Zip archive.
151 // The public methods allow the manipulation of the archive.
152 // Attributes :
153 // Attributes must not be accessed directly.
154 // Methods :
155 // PclZip() : Object creator
156 // create() : Creates the Zip archive
157 // listContent() : List the content of the Zip archive
158 // extract() : Extract the content of the archive
159 // properties() : List the properties of the archive
160 // --------------------------------------------------------------------------------
161 class PclZip
162 {
163 // ----- Filename of the zip file
164 var $zipname = '';
165
166 // ----- File descriptor of the zip file
167 var $zip_fd = 0;
168
169 // ----- Internal error handling
170 var $error_code = 1;
171 var $error_string = '';
172
173 // ----- Current status of the magic_quotes_runtime
174 // This value store the php configuration for magic_quotes
175 // The class can then disable the magic_quotes and reset it after
176 var $magic_quotes_status;
177
178 // --------------------------------------------------------------------------------
179 // Function : PclZip()
180 // Description :
181 // Creates a PclZip object and set the name of the associated Zip archive
182 // filename.
183 // Note that no real action is taken, if the archive does not exist it is not
184 // created. Use create() for that.
185 // --------------------------------------------------------------------------------
186 // http://doc.spip.org/@PclZip
187 function PclZip($p_zipname)
188 {
189 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::PclZip', "zipname=$p_zipname");
190
191 // ----- Tests the zlib
192 if (!function_exists('gzopen'))
193 {
194 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 1, "zlib extension seems to be missing");
195 die('Abort '.basename(__FILE__).' : Missing zlib extensions');
196 }
197
198 // ----- Set the attributes
199 $this->zipname = $p_zipname;
200 $this->zip_fd = 0;
201 $this->magic_quotes_status = -1;
202
203 // ----- Return
204 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 1);
205 return;
206 }
207 // --------------------------------------------------------------------------------
208
209 // --------------------------------------------------------------------------------
210 // Function :
211 // create($p_filelist, $p_add_dir="", $p_remove_dir="")
212 // create($p_filelist, $p_option, $p_option_value, ...)
213 // Description :
214 // This method supports two different synopsis. The first one is historical.
215 // This method creates a Zip Archive. The Zip file is created in the
216 // filesystem. The files and directories indicated in $p_filelist
217 // are added in the archive. See the parameters description for the
218 // supported format of $p_filelist.
219 // When a directory is in the list, the directory and its content is added
220 // in the archive.
221 // In this synopsis, the function takes an optional variable list of
222 // options. See bellow the supported options.
223 // Parameters :
224 // $p_filelist : An array containing file or directory names, or
225 // a string containing one filename or one directory name, or
226 // a string containing a list of filenames and/or directory
227 // names separated by spaces.
228 // $p_add_dir : A path to add before the real path of the archived file,
229 // in order to have it memorized in the archive.
230 // $p_remove_dir : A path to remove from the real path of the file to archive,
231 // in order to have a shorter path memorized in the archive.
232 // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
233 // is removed first, before $p_add_dir is added.
234 // Options :
235 // PCLZIP_OPT_ADD_PATH :
236 // PCLZIP_OPT_REMOVE_PATH :
237 // PCLZIP_OPT_REMOVE_ALL_PATH :
238 // PCLZIP_OPT_COMMENT :
239 // PCLZIP_CB_PRE_ADD :
240 // PCLZIP_CB_POST_ADD :
241 // Return Values :
242 // 0 on failure,
243 // The list of the added files, with a status of the add action.
244 // (see PclZip::listContent() for list entry format)
245 // --------------------------------------------------------------------------------
246 // http://doc.spip.org/@create
247 function create($p_filelist)
248 {
249 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::create', "filelist='$p_filelist', ...");
250 $v_result=1;
251
252 // ----- Reset the error handler
253 $this->privErrorReset();
254
255 // ----- Set default values
256 $v_options = array();
257 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
258
259 // ----- Look for variable options arguments
260 $v_size = func_num_args();
261 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
262
263 // ----- Look for arguments
264 if ($v_size > 1) {
265 // ----- Get the arguments
266 $v_arg_list = func_get_args();
267
268 // ----- Remove from the options list the first argument
269 array_shift($v_arg_list);
270 $v_size--;
271
272 // ----- Look for first arg
273 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
274 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
275
276 // ----- Parse the options
277 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
278 array (PCLZIP_OPT_REMOVE_PATH => 'optional',
279 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
280 PCLZIP_OPT_ADD_PATH => 'optional',
281 PCLZIP_CB_PRE_ADD => 'optional',
282 PCLZIP_CB_POST_ADD => 'optional',
283 PCLZIP_OPT_NO_COMPRESSION => 'optional',
284 PCLZIP_OPT_COMMENT => 'optional'
285 //, PCLZIP_OPT_CRYPT => 'optional'
286 ));
287 if ($v_result != 1) {
288 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
289 return 0;
290 }
291 }
292
293 // ----- Look for 2 args
294 // Here we need to support the first historic synopsis of the
295 // method.
296 else {
297 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
298
299 // ----- Get the first argument
300 $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
301
302 // ----- Look for the optional second argument
303 if ($v_size == 2) {
304 $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
305 }
306 else if ($v_size > 2) {
307 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
308 "Invalid number / type of arguments");
309 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
310 return 0;
311 }
312 }
313 }
314
315 // ----- Init
316 $v_string_list = array();
317 $v_att_list = array();
318 $v_filedescr_list = array();
319 $p_result_list = array();
320
321 // ----- Look if the $p_filelist is really an array
322 if (is_array($p_filelist)) {
323
324 // ----- Look if the first element is also an array
325 // This will mean that this is a file description entry
326 if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
327 $v_att_list = $p_filelist;
328 }
329
330 // ----- The list is a list of string names
331 else {
332 $v_string_list = $p_filelist;
333 }
334 }
335
336 // ----- Look if the $p_filelist is a string
337 else if (is_string($p_filelist)) {
338 // ----- Create a list from the string
339 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
340 }
341
342 // ----- Invalid variable type for $p_filelist
343 else {
344 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
345 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
346 return 0;
347 }
348
349 // ----- Reformat the string list
350 if (sizeof($v_string_list) != 0) {
351 foreach ($v_string_list as $v_string) {
352 if ($v_string != '') {
353 $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
354 }
355 else {
356 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Ignore an empty filename");
357 }
358 }
359 }
360
361 // ----- For each file in the list check the attributes
362 $v_supported_attributes
363 = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
364 ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
365 ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
366 );
367 foreach ($v_att_list as $v_entry) {
368 $v_result = $this->privFileDescrParseAtt($v_entry,
369 $v_filedescr_list[],
370 $v_options,
371 $v_supported_attributes);
372 if ($v_result != 1) {
373 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
374 return 0;
375 }
376 }
377
378 // ----- Expand the filelist (expand directories)
379 $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
380 if ($v_result != 1) {
381 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
382 return 0;
383 }
384
385 // ----- Call the create fct
386 $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
387 if ($v_result != 1) {
388 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
389 return 0;
390 }
391
392 // ----- Return
393 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
394 return $p_result_list;
395 }
396 // --------------------------------------------------------------------------------
397
398 // --------------------------------------------------------------------------------
399 // Function :
400 // add($p_filelist, $p_add_dir="", $p_remove_dir="")
401 // add($p_filelist, $p_option, $p_option_value, ...)
402 // Description :
403 // This method supports two synopsis. The first one is historical.
404 // This methods add the list of files in an existing archive.
405 // If a file with the same name already exists, it is added at the end of the
406 // archive, the first one is still present.
407 // If the archive does not exist, it is created.
408 // Parameters :
409 // $p_filelist : An array containing file or directory names, or
410 // a string containing one filename or one directory name, or
411 // a string containing a list of filenames and/or directory
412 // names separated by spaces.
413 // $p_add_dir : A path to add before the real path of the archived file,
414 // in order to have it memorized in the archive.
415 // $p_remove_dir : A path to remove from the real path of the file to archive,
416 // in order to have a shorter path memorized in the archive.
417 // When $p_add_dir and $p_remove_dir are set, $p_remove_dir
418 // is removed first, before $p_add_dir is added.
419 // Options :
420 // PCLZIP_OPT_ADD_PATH :
421 // PCLZIP_OPT_REMOVE_PATH :
422 // PCLZIP_OPT_REMOVE_ALL_PATH :
423 // PCLZIP_OPT_COMMENT :
424 // PCLZIP_OPT_ADD_COMMENT :
425 // PCLZIP_OPT_PREPEND_COMMENT :
426 // PCLZIP_CB_PRE_ADD :
427 // PCLZIP_CB_POST_ADD :
428 // Return Values :
429 // 0 on failure,
430 // The list of the added files, with a status of the add action.
431 // (see PclZip::listContent() for list entry format)
432 // --------------------------------------------------------------------------------
433 // http://doc.spip.org/@add
434 function add($p_filelist)
435 {
436 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::add', "filelist='$p_filelist', ...");
437 $v_result=1;
438
439 // ----- Reset the error handler
440 $this->privErrorReset();
441
442 // ----- Set default values
443 $v_options = array();
444 $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
445
446 // ----- Look for variable options arguments
447 $v_size = func_num_args();
448 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
449
450 // ----- Look for arguments
451 if ($v_size > 1) {
452 // ----- Get the arguments
453 $v_arg_list = func_get_args();
454
455 // ----- Remove form the options list the first argument
456 array_shift($v_arg_list);
457 $v_size--;
458
459 // ----- Look for first arg
460 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
461 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options detected");
462
463 // ----- Parse the options
464 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
465 array (PCLZIP_OPT_REMOVE_PATH => 'optional',
466 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
467 PCLZIP_OPT_ADD_PATH => 'optional',
468 PCLZIP_CB_PRE_ADD => 'optional',
469 PCLZIP_CB_POST_ADD => 'optional',
470 PCLZIP_OPT_NO_COMPRESSION => 'optional',
471 PCLZIP_OPT_COMMENT => 'optional',
472 PCLZIP_OPT_ADD_COMMENT => 'optional',
473 PCLZIP_OPT_PREPEND_COMMENT => 'optional'
474 //, PCLZIP_OPT_CRYPT => 'optional'
475 ));
476 if ($v_result != 1) {
477 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
478 return 0;
479 }
480 }
481
482 // ----- Look for 2 args
483 // Here we need to support the first historic synopsis of the
484 // method.
485 else {
486 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
487
488 // ----- Get the first argument
489 $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
490
491 // ----- Look for the optional second argument
492 if ($v_size == 2) {
493 $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
494 }
495 else if ($v_size > 2) {
496 // ----- Error log
497 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
498
499 // ----- Return
500 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
501 return 0;
502 }
503 }
504 }
505
506 // ----- Init
507 $v_string_list = array();
508 $v_att_list = array();
509 $v_filedescr_list = array();
510 $p_result_list = array();
511
512 // ----- Look if the $p_filelist is really an array
513 if (is_array($p_filelist)) {
514
515 // ----- Look if the first element is also an array
516 // This will mean that this is a file description entry
517 if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
518 $v_att_list = $p_filelist;
519 }
520
521 // ----- The list is a list of string names
522 else {
523 $v_string_list = $p_filelist;
524 }
525 }
526
527 // ----- Look if the $p_filelist is a string
528 else if (is_string($p_filelist)) {
529 // ----- Create a list from the string
530 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
531 }
532
533 // ----- Invalid variable type for $p_filelist
534 else {
535 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
536 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
537 return 0;
538 }
539
540 // ----- Reformat the string list
541 if (sizeof($v_string_list) != 0) {
542 foreach ($v_string_list as $v_string) {
543 $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
544 }
545 }
546
547 // ----- For each file in the list check the attributes
548 $v_supported_attributes
549 = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
550 ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
551 ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
552 );
553 foreach ($v_att_list as $v_entry) {
554 $v_result = $this->privFileDescrParseAtt($v_entry,
555 $v_filedescr_list[],
556 $v_options,
557 $v_supported_attributes);
558 if ($v_result != 1) {
559 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
560 return 0;
561 }
562 }
563
564 // ----- Expand the filelist (expand directories)
565 $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
566 if ($v_result != 1) {
567 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
568 return 0;
569 }
570
571 // ----- Call the create fct
572 $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
573 if ($v_result != 1) {
574 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
575 return 0;
576 }
577
578 // ----- Return
579 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_result_list);
580 return $p_result_list;
581 }
582 // --------------------------------------------------------------------------------
583
584 // --------------------------------------------------------------------------------
585 // Function : listContent()
586 // Description :
587 // This public method, gives the list of the files and directories, with their
588 // properties.
589 // The properties of each entries in the list are (used also in other functions) :
590 // filename : Name of the file. For a create or add action it is the filename
591 // given by the user. For an extract function it is the filename
592 // of the extracted file.
593 // stored_filename : Name of the file / directory stored in the archive.
594 // size : Size of the stored file.
595 // compressed_size : Size of the file's data compressed in the archive
596 // (without the headers overhead)
597 // mtime : Last known modification date of the file (UNIX timestamp)
598 // comment : Comment associated with the file
599 // folder : true | false
600 // index : index of the file in the archive
601 // status : status of the action (depending of the action) :
602 // Values are :
603 // ok : OK !
604 // filtered : the file / dir is not extracted (filtered by user)
605 // already_a_directory : the file can not be extracted because a
606 // directory with the same name already exists
607 // write_protected : the file can not be extracted because a file
608 // with the same name already exists and is
609 // write protected
610 // newer_exist : the file was not extracted because a newer file exists
611 // path_creation_fail : the file is not extracted because the folder
612 // does not exists and can not be created
613 // write_error : the file was not extracted because there was a
614 // error while writing the file
615 // read_error : the file was not extracted because there was a error
616 // while reading the file
617 // invalid_header : the file was not extracted because of an archive
618 // format error (bad file header)
619 // Note that each time a method can continue operating when there
620 // is an action error on a file, the error is only logged in the file status.
621 // Return Values :
622 // 0 on an unrecoverable failure,
623 // The list of the files in the archive.
624 // --------------------------------------------------------------------------------
625 // http://doc.spip.org/@listContent
626 function listContent()
627 {
628 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, 'PclZip::listContent', "");
629 $v_result=1;
630
631 // ----- Reset the error handler
632 $this->privErrorReset();
633
634 // ----- Check archive
635 if (!$this->privCheckFormat()) {
636 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
637 return(0);
638 }
639
640 // ----- Call the extracting fct
641 $p_list = array();
642 if (($v_result = $this->privList($p_list)) != 1)
643 {
644 unset($p_list);
645 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
646 return(0);
647 }
648
649 // ----- Return
650 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
651 return $p_list;
652 }
653 // --------------------------------------------------------------------------------
654
655 // --------------------------------------------------------------------------------
656 // Function :
657 // extract($p_path="./", $p_remove_path="")
658 // extract([$p_option, $p_option_value, ...])
659 // Description :
660 // This method supports two synopsis. The first one is historical.
661 // This method extract all the files / directories from the archive to the
662 // folder indicated in $p_path.
663 // If you want to ignore the 'root' part of path of the memorized files
664 // you can indicate this in the optional $p_remove_path parameter.
665 // By default, if a newer file with the same name already exists, the
666 // file is not extracted.
667 //
668 // If both PCLZIP_OPT_PATH and PCLZIP_OPT_ADD_PATH aoptions
669 // are used, the path indicated in PCLZIP_OPT_ADD_PATH is append
670 // at the end of the path value of PCLZIP_OPT_PATH.
671 // Parameters :
672 // $p_path : Path where the files and directories are to be extracted
673 // $p_remove_path : First part ('root' part) of the memorized path
674 // (if any similar) to remove while extracting.
675 // Options :
676 // PCLZIP_OPT_PATH :
677 // PCLZIP_OPT_ADD_PATH :
678 // PCLZIP_OPT_REMOVE_PATH :
679 // PCLZIP_OPT_REMOVE_ALL_PATH :
680 // PCLZIP_CB_PRE_EXTRACT :
681 // PCLZIP_CB_POST_EXTRACT :
682 // Return Values :
683 // 0 or a negative value on failure,
684 // The list of the extracted files, with a status of the action.
685 // (see PclZip::listContent() for list entry format)
686 // --------------------------------------------------------------------------------
687 // http://doc.spip.org/@extract
688 function extract()
689 {
690 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extract", "");
691 $v_result=1;
692
693 // ----- Reset the error handler
694 $this->privErrorReset();
695
696 // ----- Check archive
697 if (!$this->privCheckFormat()) {
698 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
699 return(0);
700 }
701
702 // ----- Set default values
703 $v_options = array();
704 // $v_path = "./";
705 $v_path = '';
706 $v_remove_path = "";
707 $v_remove_all_path = false;
708
709 // ----- Look for variable options arguments
710 $v_size = func_num_args();
711 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
712
713 // ----- Default values for option
714 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
715
716 // ----- Look for arguments
717 if ($v_size > 0) {
718 // ----- Get the arguments
719 $v_arg_list = func_get_args();
720
721 // ----- Look for first arg
722 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
723 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
724
725 // ----- Parse the options
726 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
727 array (PCLZIP_OPT_PATH => 'optional',
728 PCLZIP_OPT_REMOVE_PATH => 'optional',
729 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
730 PCLZIP_OPT_ADD_PATH => 'optional',
731 PCLZIP_CB_PRE_EXTRACT => 'optional',
732 PCLZIP_CB_POST_EXTRACT => 'optional',
733 PCLZIP_OPT_SET_CHMOD => 'optional',
734 PCLZIP_OPT_BY_NAME => 'optional',
735 PCLZIP_OPT_BY_EREG => 'optional',
736 PCLZIP_OPT_BY_PREG => 'optional',
737 PCLZIP_OPT_BY_INDEX => 'optional',
738 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
739 PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
740 PCLZIP_OPT_REPLACE_NEWER => 'optional'
741 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
742 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
743 ));
744 if ($v_result != 1) {
745 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
746 return 0;
747 }
748
749 // ----- Set the arguments
750 if (isset($v_options[PCLZIP_OPT_PATH])) {
751 $v_path = $v_options[PCLZIP_OPT_PATH];
752 }
753 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
754 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
755 }
756 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
757 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
758 }
759 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
760 // ----- Check for '/' in last path char
761 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
762 $v_path .= '/';
763 }
764 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
765 }
766 }
767
768 // ----- Look for 2 args
769 // Here we need to support the first historic synopsis of the
770 // method.
771 else {
772 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
773
774 // ----- Get the first argument
775 $v_path = $v_arg_list[0];
776
777 // ----- Look for the optional second argument
778 if ($v_size == 2) {
779 $v_remove_path = $v_arg_list[1];
780 }
781 else if ($v_size > 2) {
782 // ----- Error log
783 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
784
785 // ----- Return
786 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
787 return 0;
788 }
789 }
790 }
791
792 // ----- Trace
793 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
794
795 // ----- Call the extracting fct
796 $p_list = array();
797 $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
798 $v_remove_all_path, $v_options);
799 if ($v_result < 1) {
800 unset($p_list);
801 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
802 return(0);
803 }
804
805 // ----- Return
806 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
807 return $p_list;
808 }
809 // --------------------------------------------------------------------------------
810
811
812 // --------------------------------------------------------------------------------
813 // Function :
814 // extractByIndex($p_index, $p_path="./", $p_remove_path="")
815 // extractByIndex($p_index, [$p_option, $p_option_value, ...])
816 // Description :
817 // This method supports two synopsis. The first one is historical.
818 // This method is doing a partial extract of the archive.
819 // The extracted files or folders are identified by their index in the
820 // archive (from 0 to n).
821 // Note that if the index identify a folder, only the folder entry is
822 // extracted, not all the files included in the archive.
823 // Parameters :
824 // $p_index : A single index (integer) or a string of indexes of files to
825 // extract. The form of the string is "0,4-6,8-12" with only numbers
826 // and '-' for range or ',' to separate ranges. No spaces or ';'
827 // are allowed.
828 // $p_path : Path where the files and directories are to be extracted
829 // $p_remove_path : First part ('root' part) of the memorized path
830 // (if any similar) to remove while extracting.
831 // Options :
832 // PCLZIP_OPT_PATH :
833 // PCLZIP_OPT_ADD_PATH :
834 // PCLZIP_OPT_REMOVE_PATH :
835 // PCLZIP_OPT_REMOVE_ALL_PATH :
836 // PCLZIP_OPT_EXTRACT_AS_STRING : The files are extracted as strings and
837 // not as files.
838 // The resulting content is in a new field 'content' in the file
839 // structure.
840 // This option must be used alone (any other options are ignored).
841 // PCLZIP_CB_PRE_EXTRACT :
842 // PCLZIP_CB_POST_EXTRACT :
843 // Return Values :
844 // 0 on failure,
845 // The list of the extracted files, with a status of the action.
846 // (see PclZip::listContent() for list entry format)
847 // --------------------------------------------------------------------------------
848 //function extractByIndex($p_index, options...)
849 // http://doc.spip.org/@extractByIndex
850 function extractByIndex($p_index)
851 {
852 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::extractByIndex", "index='$p_index', ...");
853 $v_result=1;
854
855 // ----- Reset the error handler
856 $this->privErrorReset();
857
858 // ----- Check archive
859 if (!$this->privCheckFormat()) {
860 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
861 return(0);
862 }
863
864 // ----- Set default values
865 $v_options = array();
866 // $v_path = "./";
867 $v_path = '';
868 $v_remove_path = "";
869 $v_remove_all_path = false;
870
871 // ----- Look for variable options arguments
872 $v_size = func_num_args();
873 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
874
875 // ----- Default values for option
876 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
877
878 // ----- Look for arguments
879 if ($v_size > 1) {
880 // ----- Get the arguments
881 $v_arg_list = func_get_args();
882
883 // ----- Remove form the options list the first argument
884 array_shift($v_arg_list);
885 $v_size--;
886
887 // ----- Look for first arg
888 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
889 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Variable list of options");
890
891 // ----- Parse the options
892 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
893 array (PCLZIP_OPT_PATH => 'optional',
894 PCLZIP_OPT_REMOVE_PATH => 'optional',
895 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
896 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
897 PCLZIP_OPT_ADD_PATH => 'optional',
898 PCLZIP_CB_PRE_EXTRACT => 'optional',
899 PCLZIP_CB_POST_EXTRACT => 'optional',
900 PCLZIP_OPT_SET_CHMOD => 'optional',
901 PCLZIP_OPT_REPLACE_NEWER => 'optional'
902 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
903 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional'
904 ));
905 if ($v_result != 1) {
906 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
907 return 0;
908 }
909
910 // ----- Set the arguments
911 if (isset($v_options[PCLZIP_OPT_PATH])) {
912 $v_path = $v_options[PCLZIP_OPT_PATH];
913 }
914 if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
915 $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
916 }
917 if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
918 $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
919 }
920 if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
921 // ----- Check for '/' in last path char
922 if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
923 $v_path .= '/';
924 }
925 $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
926 }
927 if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
928 $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
929 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING not set.");
930 }
931 else {
932 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Option PCLZIP_OPT_EXTRACT_AS_STRING set.");
933 }
934 }
935
936 // ----- Look for 2 args
937 // Here we need to support the first historic synopsis of the
938 // method.
939 else {
940 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Static synopsis");
941
942 // ----- Get the first argument
943 $v_path = $v_arg_list[0];
944
945 // ----- Look for the optional second argument
946 if ($v_size == 2) {
947 $v_remove_path = $v_arg_list[1];
948 }
949 else if ($v_size > 2) {
950 // ----- Error log
951 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
952
953 // ----- Return
954 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
955 return 0;
956 }
957 }
958 }
959
960 // ----- Trace
961 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "index='$p_index', path='$v_path', remove_path='$v_remove_path', remove_all_path='".($v_remove_path?'true':'false')."'");
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 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
972 return 0;
973 }
974 $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
975
976 // ----- Call the extracting fct
977 if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
978 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
979 return(0);
980 }
981
982 // ----- Return
983 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
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 // http://doc.spip.org/@delete
1007 function delete()
1008 {
1009 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::delete", "");
1010 $v_result=1;
1011
1012 // ----- Reset the error handler
1013 $this->privErrorReset();
1014
1015 // ----- Check archive
1016 if (!$this->privCheckFormat()) {
1017 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1018 return(0);
1019 }
1020
1021 // ----- Set default values
1022 $v_options = array();
1023
1024 // ----- Look for variable options arguments
1025 $v_size = func_num_args();
1026 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "$v_size arguments passed to the method");
1027
1028 // ----- Look for arguments
1029 if ($v_size > 0) {
1030 // ----- Get the arguments
1031 $v_arg_list = func_get_args();
1032
1033 // ----- Parse the options
1034 $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
1035 array (PCLZIP_OPT_BY_NAME => 'optional',
1036 PCLZIP_OPT_BY_EREG => 'optional',
1037 PCLZIP_OPT_BY_PREG => 'optional',
1038 PCLZIP_OPT_BY_INDEX => 'optional' ));
1039 if ($v_result != 1) {
1040 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1041 return 0;
1042 }
1043 }
1044
1045 // ----- Magic quotes trick
1046 $this->privDisableMagicQuotes();
1047
1048 // ----- Call the delete fct
1049 $v_list = array();
1050 if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
1051 $this->privSwapBackMagicQuotes();
1052 unset($v_list);
1053 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0, PclZip::errorInfo());
1054 return(0);
1055 }
1056
1057 // ----- Magic quotes trick
1058 $this->privSwapBackMagicQuotes();
1059
1060 // ----- Return
1061 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_list);
1062 return $v_list;
1063 }
1064 // --------------------------------------------------------------------------------
1065
1066 // --------------------------------------------------------------------------------
1067 // Function : deleteByIndex()
1068 // Description :
1069 // ***** Deprecated *****
1070 // delete(PCLZIP_OPT_BY_INDEX, $p_index) should be prefered.
1071 // --------------------------------------------------------------------------------
1072 // http://doc.spip.org/@deleteByIndex
1073 function deleteByIndex($p_index)
1074 {
1075 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::deleteByIndex", "index='$p_index'");
1076
1077 $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
1078
1079 // ----- Return
1080 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $p_list);
1081 return $p_list;
1082 }
1083 // --------------------------------------------------------------------------------
1084
1085 // --------------------------------------------------------------------------------
1086 // Function : properties()
1087 // Description :
1088 // This method gives the properties of the archive.
1089 // The properties are :
1090 // nb : Number of files in the archive
1091 // comment : Comment associated with the archive file
1092 // status : not_exist, ok
1093 // Parameters :
1094 // None
1095 // Return Values :
1096 // 0 on failure,
1097 // An array with the archive properties.
1098 // --------------------------------------------------------------------------------
1099 // http://doc.spip.org/@properties
1100 function properties()
1101 {
1102 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::properties", "");
1103
1104 // ----- Reset the error handler
1105 $this->privErrorReset();
1106
1107 // ----- Magic quotes trick
1108 $this->privDisableMagicQuotes();
1109
1110 // ----- Check archive
1111 if (!$this->privCheckFormat()) {
1112 $this->privSwapBackMagicQuotes();
1113 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1114 return(0);
1115 }
1116
1117 // ----- Default properties
1118 $v_prop = array();
1119 $v_prop['comment'] = '';
1120 $v_prop['nb'] = 0;
1121 $v_prop['status'] = 'not_exist';
1122
1123 // ----- Look if file exists
1124 if (@is_file($this->zipname))
1125 {
1126 // ----- Open the zip file
1127 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
1128 if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
1129 {
1130 $this->privSwapBackMagicQuotes();
1131
1132 // ----- Error log
1133 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
1134
1135 // ----- Return
1136 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), 0);
1137 return 0;
1138 }
1139
1140 // ----- Read the central directory informations
1141 $v_central_dir = array();
1142 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1143 {
1144 $this->privSwapBackMagicQuotes();
1145 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1146 return 0;
1147 }
1148
1149 // ----- Close the zip file
1150 $this->privCloseFd();
1151
1152 // ----- Set the user attributes
1153 $v_prop['comment'] = $v_central_dir['comment'];
1154 $v_prop['nb'] = $v_central_dir['entries'];
1155 $v_prop['status'] = 'ok';
1156 }
1157
1158 // ----- Magic quotes trick
1159 $this->privSwapBackMagicQuotes();
1160
1161 // ----- Return
1162 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_prop);
1163 return $v_prop;
1164 }
1165 // --------------------------------------------------------------------------------
1166
1167 // --------------------------------------------------------------------------------
1168 // Function : duplicate()
1169 // Description :
1170 // This method creates an archive by copying the content of an other one. If
1171 // the archive already exist, it is replaced by the new one without any warning.
1172 // Parameters :
1173 // $p_archive : The filename of a valid archive, or
1174 // a valid PclZip object.
1175 // Return Values :
1176 // 1 on success.
1177 // 0 or a negative value on error (error code).
1178 // --------------------------------------------------------------------------------
1179 // http://doc.spip.org/@duplicate
1180 function duplicate($p_archive)
1181 {
1182 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::duplicate", "");
1183 $v_result = 1;
1184
1185 // ----- Reset the error handler
1186 $this->privErrorReset();
1187
1188 // ----- Look if the $p_archive is a PclZip object
1189 if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
1190 {
1191 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is valid PclZip object '".$p_archive->zipname."'");
1192
1193 // ----- Duplicate the archive
1194 $v_result = $this->privDuplicate($p_archive->zipname);
1195 }
1196
1197 // ----- Look if the $p_archive is a string (so a filename)
1198 else if (is_string($p_archive))
1199 {
1200 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "The parameter is a filename '$p_archive'");
1201
1202 // ----- Check that $p_archive is a valid zip file
1203 // TBC : Should also check the archive format
1204 if (!is_file($p_archive)) {
1205 // ----- Error log
1206 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
1207 $v_result = PCLZIP_ERR_MISSING_FILE;
1208 }
1209 else {
1210 // ----- Duplicate the archive
1211 $v_result = $this->privDuplicate($p_archive);
1212 }
1213 }
1214
1215 // ----- Invalid variable
1216 else
1217 {
1218 // ----- Error log
1219 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1220 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1221 }
1222
1223 // ----- Return
1224 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1225 return $v_result;
1226 }
1227 // --------------------------------------------------------------------------------
1228
1229 // --------------------------------------------------------------------------------
1230 // Function : merge()
1231 // Description :
1232 // This method merge the $p_archive_to_add archive at the end of the current
1233 // one ($this).
1234 // If the archive ($this) does not exist, the merge becomes a duplicate.
1235 // If the $p_archive_to_add archive does not exist, the merge is a success.
1236 // Parameters :
1237 // $p_archive_to_add : It can be directly the filename of a valid zip archive,
1238 // or a PclZip object archive.
1239 // Return Values :
1240 // 1 on success,
1241 // 0 or negative values on error (see below).
1242 // --------------------------------------------------------------------------------
1243 // http://doc.spip.org/@merge
1244 function merge($p_archive_to_add)
1245 {
1246 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::merge", "");
1247 $v_result = 1;
1248
1249 // ----- Reset the error handler
1250 $this->privErrorReset();
1251
1252 // ----- Check archive
1253 if (!$this->privCheckFormat()) {
1254 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, 0);
1255 return(0);
1256 }
1257
1258 // ----- Look if the $p_archive_to_add is a PclZip object
1259 if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
1260 {
1261 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is valid PclZip object");
1262
1263 // ----- Merge the archive
1264 $v_result = $this->privMerge($p_archive_to_add);
1265 }
1266
1267 // ----- Look if the $p_archive_to_add is a string (so a filename)
1268 else if (is_string($p_archive_to_add))
1269 {
1270 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The parameter is a filename");
1271
1272 // ----- Create a temporary archive
1273 $v_object_archive = new PclZip($p_archive_to_add);
1274
1275 // ----- Merge the archive
1276 $v_result = $this->privMerge($v_object_archive);
1277 }
1278
1279 // ----- Invalid variable
1280 else
1281 {
1282 // ----- Error log
1283 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
1284 $v_result = PCLZIP_ERR_INVALID_PARAMETER;
1285 }
1286
1287 // ----- Return
1288 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1289 return $v_result;
1290 }
1291 // --------------------------------------------------------------------------------
1292
1293
1294
1295 // --------------------------------------------------------------------------------
1296 // Function : errorCode()
1297 // Description :
1298 // Parameters :
1299 // --------------------------------------------------------------------------------
1300 // http://doc.spip.org/@errorCode
1301 function errorCode()
1302 {
1303 if (PCLZIP_ERROR_EXTERNAL == 1) {
1304 return(PclErrorCode());
1305 }
1306 else {
1307 return($this->error_code);
1308 }
1309 }
1310 // --------------------------------------------------------------------------------
1311
1312 // --------------------------------------------------------------------------------
1313 // Function : errorName()
1314 // Description :
1315 // Parameters :
1316 // --------------------------------------------------------------------------------
1317 // http://doc.spip.org/@errorName
1318 function errorName($p_with_code=false)
1319 {
1320 $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
1321 PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
1322 PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
1323 PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
1324 PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
1325 PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
1326 PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
1327 PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
1328 PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
1329 PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
1330 PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
1331 PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
1332 PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
1333 PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
1334 PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
1335 PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
1336 PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
1337 PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
1338 PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
1339 ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
1340 ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
1341 );
1342
1343 if (isset($v_name[$this->error_code])) {
1344 $v_value = $v_name[$this->error_code];
1345 }
1346 else {
1347 $v_value = 'NoName';
1348 }
1349
1350 if ($p_with_code) {
1351 return($v_value.' ('.$this->error_code.')');
1352 }
1353 else {
1354 return($v_value);
1355 }
1356 }
1357 // --------------------------------------------------------------------------------
1358
1359 // --------------------------------------------------------------------------------
1360 // Function : errorInfo()
1361 // Description :
1362 // Parameters :
1363 // --------------------------------------------------------------------------------
1364 // http://doc.spip.org/@errorInfo
1365 function errorInfo($p_full=false)
1366 {
1367 if (PCLZIP_ERROR_EXTERNAL == 1) {
1368 return(PclErrorString());
1369 }
1370 else {
1371 if ($p_full) {
1372 return($this->errorName(true)." : ".$this->error_string);
1373 }
1374 else {
1375 return($this->error_string." [code ".$this->error_code."]");
1376 }
1377 }
1378 }
1379 // --------------------------------------------------------------------------------
1380
1381
1382 // --------------------------------------------------------------------------------
1383 // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS *****
1384 // ***** *****
1385 // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY *****
1386 // --------------------------------------------------------------------------------
1387
1388
1389
1390 // --------------------------------------------------------------------------------
1391 // Function : privCheckFormat()
1392 // Description :
1393 // This method check that the archive exists and is a valid zip archive.
1394 // Several level of check exists. (futur)
1395 // Parameters :
1396 // $p_level : Level of check. Default 0.
1397 // 0 : Check the first bytes (magic codes) (default value))
1398 // 1 : 0 + Check the central directory (futur)
1399 // 2 : 1 + Check each file header (futur)
1400 // Return Values :
1401 // true on success,
1402 // false on error, the error code is set.
1403 // --------------------------------------------------------------------------------
1404 // http://doc.spip.org/@privCheckFormat
1405 function privCheckFormat($p_level=0)
1406 {
1407 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCheckFormat", "");
1408 $v_result = true;
1409
1410 // ----- Reset the file system cache
1411 clearstatcache();
1412
1413 // ----- Reset the error handler
1414 $this->privErrorReset();
1415
1416 // ----- Look if the file exits
1417 if (!is_file($this->zipname)) {
1418 // ----- Error log
1419 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
1420 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
1421 return(false);
1422 }
1423
1424 // ----- Check that the file is readeable
1425 if (!is_readable($this->zipname)) {
1426 // ----- Error log
1427 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
1428 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, false, PclZip::errorInfo());
1429 return(false);
1430 }
1431
1432 // ----- Check the magic code
1433 // TBC
1434
1435 // ----- Check the central header
1436 // TBC
1437
1438 // ----- Check each file header
1439 // TBC
1440
1441 // ----- Return
1442 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1443 return $v_result;
1444 }
1445 // --------------------------------------------------------------------------------
1446
1447 // --------------------------------------------------------------------------------
1448 // Function : privParseOptions()
1449 // Description :
1450 // This internal methods reads the variable list of arguments ($p_options_list,
1451 // $p_size) and generate an array with the options and values ($v_result_list).
1452 // $v_requested_options contains the options that can be present and those that
1453 // must be present.
1454 // $v_requested_options is an array, with the option value as key, and 'optional',
1455 // or 'mandatory' as value.
1456 // Parameters :
1457 // See above.
1458 // Return Values :
1459 // 1 on success.
1460 // 0 on failure.
1461 // --------------------------------------------------------------------------------
1462 // http://doc.spip.org/@privParseOptions
1463 function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
1464 {
1465 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privParseOptions", "");
1466 $v_result=1;
1467
1468 // ----- Read the options
1469 $i=0;
1470 while ($i<$p_size) {
1471 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Looking for table index $i, option = '".PclZipUtilOptionText($p_options_list[$i])."(".$p_options_list[$i].")'");
1472
1473 // ----- Check if the option is supported
1474 if (!isset($v_requested_options[$p_options_list[$i]])) {
1475 // ----- Error log
1476 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
1477
1478 // ----- Return
1479 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1480 return PclZip::errorCode();
1481 }
1482
1483 // ----- Look for next option
1484 switch ($p_options_list[$i]) {
1485 // ----- Look for options that request a path value
1486 case PCLZIP_OPT_PATH :
1487 case PCLZIP_OPT_REMOVE_PATH :
1488 case PCLZIP_OPT_ADD_PATH :
1489 // ----- Check the number of parameters
1490 if (($i+1) >= $p_size) {
1491 // ----- Error log
1492 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1493
1494 // ----- Return
1495 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1496 return PclZip::errorCode();
1497 }
1498
1499 // ----- Get the value
1500 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1501 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1502 $i++;
1503 break;
1504
1505 case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
1506 // ----- Check the number of parameters
1507 if (($i+1) >= $p_size) {
1508 // ----- Error log
1509 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1510
1511 // ----- Return
1512 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1513 return PclZip::errorCode();
1514 }
1515
1516 // ----- Get the value
1517 if ( is_string($p_options_list[$i+1])
1518 && ($p_options_list[$i+1] != '')) {
1519 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], false);
1520 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1521 $i++;
1522 }
1523 else {
1524 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." set with an empty value is ignored.");
1525 }
1526 break;
1527
1528 // ----- Look for options that request an array of string for value
1529 case PCLZIP_OPT_BY_NAME :
1530 // ----- Check the number of parameters
1531 if (($i+1) >= $p_size) {
1532 // ----- Error log
1533 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1534
1535 // ----- Return
1536 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1537 return PclZip::errorCode();
1538 }
1539
1540 // ----- Get the value
1541 if (is_string($p_options_list[$i+1])) {
1542 $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
1543 }
1544 else if (is_array($p_options_list[$i+1])) {
1545 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1546 }
1547 else {
1548 // ----- Error log
1549 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1550
1551 // ----- Return
1552 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1553 return PclZip::errorCode();
1554 }
1555 ////--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1556 $i++;
1557 break;
1558
1559 // ----- Look for options that request an EREG or PREG expression
1560 case PCLZIP_OPT_BY_EREG :
1561 case PCLZIP_OPT_BY_PREG :
1562 //case PCLZIP_OPT_CRYPT :
1563 // ----- Check the number of parameters
1564 if (($i+1) >= $p_size) {
1565 // ----- Error log
1566 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1567
1568 // ----- Return
1569 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1570 return PclZip::errorCode();
1571 }
1572
1573 // ----- Get the value
1574 if (is_string($p_options_list[$i+1])) {
1575 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1576 }
1577 else {
1578 // ----- Error log
1579 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1580
1581 // ----- Return
1582 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1583 return PclZip::errorCode();
1584 }
1585 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1586 $i++;
1587 break;
1588
1589 // ----- Look for options that takes a string
1590 case PCLZIP_OPT_COMMENT :
1591 case PCLZIP_OPT_ADD_COMMENT :
1592 case PCLZIP_OPT_PREPEND_COMMENT :
1593 // ----- Check the number of parameters
1594 if (($i+1) >= $p_size) {
1595 // ----- Error log
1596 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
1597 "Missing parameter value for option '"
1598 .PclZipUtilOptionText($p_options_list[$i])
1599 ."'");
1600
1601 // ----- Return
1602 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1603 return PclZip::errorCode();
1604 }
1605
1606 // ----- Get the value
1607 if (is_string($p_options_list[$i+1])) {
1608 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1609 }
1610 else {
1611 // ----- Error log
1612 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
1613 "Wrong parameter value for option '"
1614 .PclZipUtilOptionText($p_options_list[$i])
1615 ."'");
1616
1617 // ----- Return
1618 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1619 return PclZip::errorCode();
1620 }
1621 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1622 $i++;
1623 break;
1624
1625 // ----- Look for options that request an array of index
1626 case PCLZIP_OPT_BY_INDEX :
1627 // ----- Check the number of parameters
1628 if (($i+1) >= $p_size) {
1629 // ----- Error log
1630 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1631
1632 // ----- Return
1633 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1634 return PclZip::errorCode();
1635 }
1636
1637 // ----- Get the value
1638 $v_work_list = array();
1639 if (is_string($p_options_list[$i+1])) {
1640 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is a string '".$p_options_list[$i+1]."'");
1641
1642 // ----- Remove spaces
1643 $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1644
1645 // ----- Parse items
1646 $v_work_list = explode(",", $p_options_list[$i+1]);
1647 }
1648 else if (is_integer($p_options_list[$i+1])) {
1649 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an integer '".$p_options_list[$i+1]."'");
1650 $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1651 }
1652 else if (is_array($p_options_list[$i+1])) {
1653 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Index value is an array");
1654 $v_work_list = $p_options_list[$i+1];
1655 }
1656 else {
1657 // ----- Error log
1658 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1659
1660 // ----- Return
1661 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1662 return PclZip::errorCode();
1663 }
1664
1665 // ----- Reduce the index list
1666 // each index item in the list must be a couple with a start and
1667 // an end value : [0,3], [5-5], [8-10], ...
1668 // ----- Check the format of each item
1669 $v_sort_flag=false;
1670 $v_sort_value=0;
1671 for ($j=0; $j<sizeof($v_work_list); $j++) {
1672 // ----- Explode the item
1673 $v_item_list = explode("-", $v_work_list[$j]);
1674 $v_size_item_list = sizeof($v_item_list);
1675
1676 // ----- TBC : Here we might check that each item is a
1677 // real integer ...
1678
1679 // ----- Look for single value
1680 if ($v_size_item_list == 1) {
1681 // ----- Set the option value
1682 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1683 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1684 }
1685 elseif ($v_size_item_list == 2) {
1686 // ----- Set the option value
1687 $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1688 $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1689 }
1690 else {
1691 // ----- Error log
1692 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1693
1694 // ----- Return
1695 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1696 return PclZip::errorCode();
1697 }
1698
1699 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Extracted index item = [".$v_result_list[$p_options_list[$i]][$j]['start'].",".$v_result_list[$p_options_list[$i]][$j]['end']."]");
1700
1701 // ----- Look for list sort
1702 if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1703 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "The list should be sorted ...");
1704 $v_sort_flag=true;
1705
1706 // ----- TBC : An automatic sort should be writen ...
1707 // ----- Error log
1708 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1709
1710 // ----- Return
1711 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1712 return PclZip::errorCode();
1713 }
1714 $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1715 }
1716
1717 // ----- Sort the items
1718 if ($v_sort_flag) {
1719 // TBC : To Be Completed
1720 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "List sorting is not yet write ...");
1721 }
1722
1723 // ----- Next option
1724 $i++;
1725 break;
1726
1727 // ----- Look for options that request no value
1728 case PCLZIP_OPT_REMOVE_ALL_PATH :
1729 case PCLZIP_OPT_EXTRACT_AS_STRING :
1730 case PCLZIP_OPT_NO_COMPRESSION :
1731 case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1732 case PCLZIP_OPT_REPLACE_NEWER :
1733 case PCLZIP_OPT_STOP_ON_ERROR :
1734 $v_result_list[$p_options_list[$i]] = true;
1735 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1736 break;
1737
1738 // ----- Look for options that request an octal value
1739 case PCLZIP_OPT_SET_CHMOD :
1740 // ----- Check the number of parameters
1741 if (($i+1) >= $p_size) {
1742 // ----- Error log
1743 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1744
1745 // ----- Return
1746 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1747 return PclZip::errorCode();
1748 }
1749
1750 // ----- Get the value
1751 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1752 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($p_options_list[$i])." = '".$v_result_list[$p_options_list[$i]]."'");
1753 $i++;
1754 break;
1755
1756 // ----- Look for options that request a call-back
1757 case PCLZIP_CB_PRE_EXTRACT :
1758 case PCLZIP_CB_POST_EXTRACT :
1759 case PCLZIP_CB_PRE_ADD :
1760 case PCLZIP_CB_POST_ADD :
1761 /* for futur use
1762 case PCLZIP_CB_PRE_DELETE :
1763 case PCLZIP_CB_POST_DELETE :
1764 case PCLZIP_CB_PRE_LIST :
1765 case PCLZIP_CB_POST_LIST :
1766 */
1767 // ----- Check the number of parameters
1768 if (($i+1) >= $p_size) {
1769 // ----- Error log
1770 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1771
1772 // ----- Return
1773 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1774 return PclZip::errorCode();
1775 }
1776
1777 // ----- Get the value
1778 $v_function_name = $p_options_list[$i+1];
1779 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "call-back ".PclZipUtilOptionText($p_options_list[$i])." = '".$v_function_name."'");
1780
1781 // ----- Check that the value is a valid existing function
1782 if (!function_exists($v_function_name)) {
1783 // ----- Error log
1784 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1785
1786 // ----- Return
1787 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1788 return PclZip::errorCode();
1789 }
1790
1791 // ----- Set the attribute
1792 $v_result_list[$p_options_list[$i]] = $v_function_name;
1793 $i++;
1794 break;
1795
1796 default :
1797 // ----- Error log
1798 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1799 "Unknown parameter '"
1800 .$p_options_list[$i]."'");
1801
1802 // ----- Return
1803 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1804 return PclZip::errorCode();
1805 }
1806
1807 // ----- Next options
1808 $i++;
1809 }
1810
1811 // ----- Look for mandatory options
1812 if ($v_requested_options !== false) {
1813 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1814 // ----- Look for mandatory option
1815 if ($v_requested_options[$key] == 'mandatory') {
1816 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
1817 // ----- Look if present
1818 if (!isset($v_result_list[$key])) {
1819 // ----- Error log
1820 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1821
1822 // ----- Return
1823 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1824 return PclZip::errorCode();
1825 }
1826 }
1827 }
1828 }
1829
1830 // ----- Return
1831 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1832 return $v_result;
1833 }
1834 // --------------------------------------------------------------------------------
1835
1836 // --------------------------------------------------------------------------------
1837 // Function : privFileDescrParseAtt()
1838 // Description :
1839 // Parameters :
1840 // Return Values :
1841 // 1 on success.
1842 // 0 on failure.
1843 // --------------------------------------------------------------------------------
1844 // http://doc.spip.org/@privFileDescrParseAtt
1845 function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1846 {
1847 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrParseAtt", "");
1848 $v_result=1;
1849
1850 // ----- For each file in the list check the attributes
1851 foreach ($p_file_list as $v_key => $v_value) {
1852
1853 // ----- Check if the option is supported
1854 if (!isset($v_requested_options[$v_key])) {
1855 // ----- Error log
1856 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1857
1858 // ----- Return
1859 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1860 return PclZip::errorCode();
1861 }
1862
1863 // ----- Look for attribute
1864 switch ($v_key) {
1865 case PCLZIP_ATT_FILE_NAME :
1866 if (!is_string($v_value)) {
1867 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1868 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1869 return PclZip::errorCode();
1870 }
1871
1872 $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1873 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
1874
1875 if ($p_filedescr['filename'] == '') {
1876 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1877 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1878 return PclZip::errorCode();
1879 }
1880
1881 break;
1882
1883 case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1884 if (!is_string($v_value)) {
1885 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1886 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1887 return PclZip::errorCode();
1888 }
1889
1890 $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1891 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
1892
1893 if ($p_filedescr['new_short_name'] == '') {
1894 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1895 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1896 return PclZip::errorCode();
1897 }
1898 break;
1899
1900 case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1901 if (!is_string($v_value)) {
1902 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1903 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1904 return PclZip::errorCode();
1905 }
1906
1907 $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1908 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "".PclZipUtilOptionText($v_key)." = '".$v_value."'");
1909
1910 if ($p_filedescr['new_full_name'] == '') {
1911 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1912 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1913 return PclZip::errorCode();
1914 }
1915 break;
1916
1917 default :
1918 // ----- Error log
1919 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1920 "Unknown parameter '".$v_key."'");
1921
1922 // ----- Return
1923 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1924 return PclZip::errorCode();
1925 }
1926
1927 // ----- Look for mandatory options
1928 if ($v_requested_options !== false) {
1929 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1930 // ----- Look for mandatory option
1931 if ($v_requested_options[$key] == 'mandatory') {
1932 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Detect a mandatory option : ".PclZipUtilOptionText($key)."(".$key.")");
1933 // ----- Look if present
1934 if (!isset($p_file_list[$key])) {
1935 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1936 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1937 return PclZip::errorCode();
1938 }
1939 }
1940 }
1941 }
1942
1943 // end foreach
1944 }
1945
1946 // ----- Return
1947 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
1948 return $v_result;
1949 }
1950 // --------------------------------------------------------------------------------
1951
1952 // --------------------------------------------------------------------------------
1953 // Function : privFileDescrExpand()
1954 // Description :
1955 // Parameters :
1956 // Return Values :
1957 // 1 on success.
1958 // 0 on failure.
1959 // --------------------------------------------------------------------------------
1960 // http://doc.spip.org/@privFileDescrExpand
1961 function privFileDescrExpand(&$p_filedescr_list, &$p_options)
1962 {
1963 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privFileDescrExpand", "");
1964 $v_result=1;
1965
1966 // ----- Create a result list
1967 $v_result_list = array();
1968
1969 // ----- Look each entry
1970 for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
1971 // ----- Get filedescr
1972 $v_descr = $p_filedescr_list[$i];
1973
1974 // ----- Reduce the filename
1975 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr before reduction :'".$v_descr['filename']."'");
1976 $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename']);
1977 $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
1978 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Filedescr after reduction :'".$v_descr['filename']."'");
1979
1980 // ----- Get type of descr
1981 if (!file_exists($v_descr['filename'])) {
1982 // ----- Error log
1983 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$v_descr['filename']."' does not exists");
1984 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exists");
1985
1986 // ----- Return
1987 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
1988 return PclZip::errorCode();
1989 }
1990 if (@is_file($v_descr['filename'])) {
1991 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a file");
1992 $v_descr['type'] = 'file';
1993 }
1994 else if (@is_dir($v_descr['filename'])) {
1995 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "This is a folder");
1996 $v_descr['type'] = 'folder';
1997 }
1998 else if (@is_link($v_descr['filename'])) {
1999 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : link");
2000 // skip
2001 continue;
2002 }
2003 else {
2004 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Unsupported file type : unknown type");
2005 // skip
2006 continue;
2007 }
2008
2009 // ----- Calculate the stored filename
2010 $this->privCalculateStoredFilename($v_descr, $p_options);
2011
2012 // ----- Add the descriptor in result list
2013 $v_result_list[sizeof($v_result_list)] = $v_descr;
2014
2015 // ----- Look for folder
2016 if ($v_descr['type'] == 'folder') {
2017 // ----- List of items in folder
2018 $v_dirlist_descr = array();
2019 $v_dirlist_nb = 0;
2020 if ($v_folder_handler = @opendir($v_descr['filename'])) {
2021 while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
2022 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for '".$v_item_handler."' in the directory");
2023
2024 // ----- Skip '.' and '..'
2025 if (($v_item_handler == '.') || ($v_item_handler == '..')) {
2026 continue;
2027 }
2028
2029 // ----- Compose the full filename
2030 $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
2031
2032 // ----- Look for different stored filename
2033 // Because the name of the folder was changed, the name of the
2034 // files/sub-folders also change
2035 if ($v_descr['stored_filename'] != $v_descr['filename']) {
2036 $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
2037 }
2038
2039 $v_dirlist_nb++;
2040 }
2041 }
2042 else {
2043 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Unable to open dir '".$v_descr['filename']."' in read mode. Skipped.");
2044 // TBC : unable to open folder in read mode
2045 }
2046
2047 // ----- Expand each element of the list
2048 if ($v_dirlist_nb != 0) {
2049 // ----- Expand
2050 if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
2051 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2052 return $v_result;
2053 }
2054
2055 // ----- Concat the resulting list
2056 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Merging result list (size '".sizeof($v_result_list)."') with dirlist (size '".sizeof($v_dirlist_descr)."')");
2057 $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
2058 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "merged result list is size '".sizeof($v_result_list)."'");
2059 }
2060 else {
2061 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Nothing in this folder to expand.");
2062 }
2063
2064 // ----- Free local array
2065 unset($v_dirlist_descr);
2066 }
2067 }
2068
2069 // ----- Get the result list
2070 $p_filedescr_list = $v_result_list;
2071
2072 // ----- Return
2073 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2074 return $v_result;
2075 }
2076 // --------------------------------------------------------------------------------
2077
2078 // --------------------------------------------------------------------------------
2079 // Function : privCreate()
2080 // Description :
2081 // Parameters :
2082 // Return Values :
2083 // --------------------------------------------------------------------------------
2084 // http://doc.spip.org/@privCreate
2085 function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
2086 {
2087 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCreate", "list");
2088 $v_result=1;
2089 $v_list_detail = array();
2090
2091 // ----- Magic quotes trick
2092 $this->privDisableMagicQuotes();
2093
2094 // ----- Open the file in write mode
2095 if (($v_result = $this->privOpenFd('wb')) != 1)
2096 {
2097 // ----- Return
2098 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2099 return $v_result;
2100 }
2101
2102 // ----- Add the list of files
2103 $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
2104
2105 // ----- Close
2106 $this->privCloseFd();
2107
2108 // ----- Magic quotes trick
2109 $this->privSwapBackMagicQuotes();
2110
2111 // ----- Return
2112 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2113 return $v_result;
2114 }
2115 // --------------------------------------------------------------------------------
2116
2117 // --------------------------------------------------------------------------------
2118 // Function : privAdd()
2119 // Description :
2120 // Parameters :
2121 // Return Values :
2122 // --------------------------------------------------------------------------------
2123 // http://doc.spip.org/@privAdd
2124 function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
2125 {
2126 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAdd", "list");
2127 $v_result=1;
2128 $v_list_detail = array();
2129
2130 // ----- Look if the archive exists or is empty
2131 if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
2132 {
2133 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Archive does not exist, or is empty, create it.");
2134
2135 // ----- Do a create
2136 $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
2137
2138 // ----- Return
2139 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2140 return $v_result;
2141 }
2142 // ----- Magic quotes trick
2143 $this->privDisableMagicQuotes();
2144
2145 // ----- Open the zip file
2146 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2147 if (($v_result=$this->privOpenFd('rb')) != 1)
2148 {
2149 // ----- Magic quotes trick
2150 $this->privSwapBackMagicQuotes();
2151
2152 // ----- Return
2153 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2154 return $v_result;
2155 }
2156
2157 // ----- Read the central directory informations
2158 $v_central_dir = array();
2159 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2160 {
2161 $this->privCloseFd();
2162 $this->privSwapBackMagicQuotes();
2163 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2164 return $v_result;
2165 }
2166
2167 // ----- Go to beginning of File
2168 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
2169 @rewind($this->zip_fd);
2170 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Position in file : ".ftell($this->zip_fd)."'");
2171
2172 // ----- Creates a temporay file
2173 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
2174
2175 // ----- Open the temporary file in write mode
2176 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode");
2177 if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
2178 {
2179 $this->privCloseFd();
2180 $this->privSwapBackMagicQuotes();
2181
2182 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
2183
2184 // ----- Return
2185 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2186 return PclZip::errorCode();
2187 }
2188
2189 // ----- Copy the files from the archive to the temporary file
2190 // TBC : Here I should better append the file and go back to erase the central dir
2191 $v_size = $v_central_dir['offset'];
2192 while ($v_size != 0)
2193 {
2194 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2195 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
2196 $v_buffer = fread($this->zip_fd, $v_read_size);
2197 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
2198 $v_size -= $v_read_size;
2199 }
2200
2201 // ----- Swap the file descriptor
2202 // Here is a trick : I swap the temporary fd with the zip fd, in order to use
2203 // the following methods on the temporary fil and not the real archive
2204 $v_swap = $this->zip_fd;
2205 $this->zip_fd = $v_zip_temp_fd;
2206 $v_zip_temp_fd = $v_swap;
2207
2208 // ----- Add the files
2209 $v_header_list = array();
2210 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2211 {
2212 fclose($v_zip_temp_fd);
2213 $this->privCloseFd();
2214 @unlink($v_zip_temp_name);
2215 $this->privSwapBackMagicQuotes();
2216
2217 // ----- Return
2218 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2219 return $v_result;
2220 }
2221
2222 // ----- Store the offset of the central dir
2223 $v_offset = @ftell($this->zip_fd);
2224 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "New offset of central dir : $v_offset");
2225
2226 // ----- Copy the block of file headers from the old archive
2227 $v_size = $v_central_dir['size'];
2228 while ($v_size != 0)
2229 {
2230 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2231 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Read $v_read_size bytes");
2232 $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
2233 @fwrite($this->zip_fd, $v_buffer, $v_read_size);
2234 $v_size -= $v_read_size;
2235 }
2236
2237 // ----- Create the Central Dir files header
2238 for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
2239 {
2240 // ----- Create the file header
2241 if ($v_header_list[$i]['status'] == 'ok') {
2242 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2243 fclose($v_zip_temp_fd);
2244 $this->privCloseFd();
2245 @unlink($v_zip_temp_name);
2246 $this->privSwapBackMagicQuotes();
2247
2248 // ----- Return
2249 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2250 return $v_result;
2251 }
2252 $v_count++;
2253 }
2254
2255 // ----- Transform the header to a 'usable' info
2256 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2257 }
2258
2259 // ----- Zip file comment
2260 $v_comment = $v_central_dir['comment'];
2261 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2262 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2263 }
2264 if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
2265 $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
2266 }
2267 if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
2268 $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
2269 }
2270
2271 // ----- Calculate the size of the central header
2272 $v_size = @ftell($this->zip_fd)-$v_offset;
2273
2274 // ----- Create the central dir footer
2275 if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
2276 {
2277 // ----- Reset the file list
2278 unset($v_header_list);
2279 $this->privSwapBackMagicQuotes();
2280
2281 // ----- Return
2282 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2283 return $v_result;
2284 }
2285
2286 // ----- Swap back the file descriptor
2287 $v_swap = $this->zip_fd;
2288 $this->zip_fd = $v_zip_temp_fd;
2289 $v_zip_temp_fd = $v_swap;
2290
2291 // ----- Close
2292 $this->privCloseFd();
2293
2294 // ----- Close the temporary file
2295 @fclose($v_zip_temp_fd);
2296
2297 // ----- Magic quotes trick
2298 $this->privSwapBackMagicQuotes();
2299
2300 // ----- Delete the zip file
2301 // TBC : I should test the result ...
2302 @unlink($this->zipname);
2303
2304 // ----- Rename the temporary file
2305 // TBC : I should test the result ...
2306 //@rename($v_zip_temp_name, $this->zipname);
2307 PclZipUtilRename($v_zip_temp_name, $this->zipname);
2308
2309 // ----- Return
2310 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2311 return $v_result;
2312 }
2313 // --------------------------------------------------------------------------------
2314
2315 // --------------------------------------------------------------------------------
2316 // Function : privOpenFd()
2317 // Description :
2318 // Parameters :
2319 // --------------------------------------------------------------------------------
2320 // http://doc.spip.org/@privOpenFd
2321 function privOpenFd($p_mode)
2322 {
2323 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privOpenFd", 'mode='.$p_mode);
2324 $v_result=1;
2325
2326 // ----- Look if already open
2327 if ($this->zip_fd != 0)
2328 {
2329 // ----- Error log
2330 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
2331
2332 // ----- Return
2333 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2334 return PclZip::errorCode();
2335 }
2336
2337 // ----- Open the zip file
2338 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Open file in '.$p_mode.' mode');
2339 if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
2340 {
2341 // ----- Error log
2342 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
2343
2344 // ----- Return
2345 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2346 return PclZip::errorCode();
2347 }
2348
2349 // ----- Return
2350 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2351 return $v_result;
2352 }
2353 // --------------------------------------------------------------------------------
2354
2355 // --------------------------------------------------------------------------------
2356 // Function : privCloseFd()
2357 // Description :
2358 // Parameters :
2359 // --------------------------------------------------------------------------------
2360 // http://doc.spip.org/@privCloseFd
2361 function privCloseFd()
2362 {
2363 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCloseFd", "");
2364 $v_result=1;
2365
2366 if ($this->zip_fd != 0)
2367 @fclose($this->zip_fd);
2368 $this->zip_fd = 0;
2369
2370 // ----- Return
2371 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2372 return $v_result;
2373 }
2374 // --------------------------------------------------------------------------------
2375
2376 // --------------------------------------------------------------------------------
2377 // Function : privAddList()
2378 // Description :
2379 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is
2380 // different from the real path of the file. This is usefull if you want to have PclTar
2381 // running in any directory, and memorize relative path from an other directory.
2382 // Parameters :
2383 // $p_list : An array containing the file or directory names to add in the tar
2384 // $p_result_list : list of added files with their properties (specially the status field)
2385 // $p_add_dir : Path to add in the filename path archived
2386 // $p_remove_dir : Path to remove in the filename path archived
2387 // Return Values :
2388 // --------------------------------------------------------------------------------
2389 // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options)
2390 // http://doc.spip.org/@privAddList
2391 function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
2392 {
2393 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddList", "list");
2394 $v_result=1;
2395
2396 // ----- Add the files
2397 $v_header_list = array();
2398 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
2399 {
2400 // ----- Return
2401 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2402 return $v_result;
2403 }
2404
2405 // ----- Store the offset of the central dir
2406 $v_offset = @ftell($this->zip_fd);
2407
2408 // ----- Create the Central Dir files header
2409 for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
2410 {
2411 // ----- Create the file header
2412 if ($v_header_list[$i]['status'] == 'ok') {
2413 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
2414 // ----- Return
2415 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2416 return $v_result;
2417 }
2418 $v_count++;
2419 }
2420
2421 // ----- Transform the header to a 'usable' info
2422 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
2423 }
2424
2425 // ----- Zip file comment
2426 $v_comment = '';
2427 if (isset($p_options[PCLZIP_OPT_COMMENT])) {
2428 $v_comment = $p_options[PCLZIP_OPT_COMMENT];
2429 }
2430
2431 // ----- Calculate the size of the central header
2432 $v_size = @ftell($this->zip_fd)-$v_offset;
2433
2434 // ----- Create the central dir footer
2435 if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
2436 {
2437 // ----- Reset the file list
2438 unset($v_header_list);
2439
2440 // ----- Return
2441 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2442 return $v_result;
2443 }
2444
2445 // ----- Return
2446 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2447 return $v_result;
2448 }
2449 // --------------------------------------------------------------------------------
2450
2451 // --------------------------------------------------------------------------------
2452 // Function : privAddFileList()
2453 // Description :
2454 // Parameters :
2455 // $p_filedescr_list : An array containing the file description
2456 // or directory names to add in the zip
2457 // $p_result_list : list of added files with their properties (specially the status field)
2458 // Return Values :
2459 // --------------------------------------------------------------------------------
2460 // http://doc.spip.org/@privAddFileList
2461 function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
2462 {
2463 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFileList", "filedescr_list");
2464 $v_result=1;
2465 $v_header = array();
2466
2467 // ----- Recuperate the current number of elt in list
2468 $v_nb = sizeof($p_result_list);
2469 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Before add, list have ".$v_nb." elements");
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 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Looking for file '".$p_filedescr_list[$j]['filename']."'");
2478
2479 // ----- Skip empty file names
2480 // TBC : Can this be possible ? not checked in DescrParseAtt ?
2481 if ($p_filedescr_list[$j]['filename'] == "") {
2482 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Skip empty filename");
2483 continue;
2484 }
2485
2486 // ----- Check the filename
2487 if (!file_exists($p_filedescr_list[$j]['filename'])) {
2488 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
2489 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exists");
2490 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2491 return PclZip::errorCode();
2492 }
2493
2494 // ----- Look if it is a file or a dir with no all path remove option
2495 if ( (is_file($p_filedescr_list[$j]['filename']))
2496 || ( is_dir($p_filedescr_list[$j]['filename'])
2497 && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
2498 || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) {
2499
2500 // ----- Add the file
2501 $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
2502 $p_options);
2503 if ($v_result != 1) {
2504 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2505 return $v_result;
2506 }
2507
2508 // ----- Store the file infos
2509 $p_result_list[$v_nb++] = $v_header;
2510 }
2511 }
2512 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "After add, list have ".$v_nb." elements");
2513
2514 // ----- Return
2515 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2516 return $v_result;
2517 }
2518 // --------------------------------------------------------------------------------
2519
2520 // --------------------------------------------------------------------------------
2521 // Function : privAddFile()
2522 // Description :
2523 // Parameters :
2524 // Return Values :
2525 // --------------------------------------------------------------------------------
2526 // http://doc.spip.org/@privAddFile
2527 function privAddFile($p_filedescr, &$p_header, &$p_options)
2528 {
2529 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privAddFile", "filename='".$p_filedescr['filename']."'");
2530 $v_result=1;
2531
2532 // ----- Working variable
2533 $p_filename = $p_filedescr['filename'];
2534
2535 // TBC : Already done in the fileAtt check ... ?
2536 if ($p_filename == "") {
2537 // ----- Error log
2538 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
2539
2540 // ----- Return
2541 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2542 return PclZip::errorCode();
2543 }
2544
2545 // ----- Look for a stored different filename
2546 if (isset($p_filedescr['stored_filename'])) {
2547 $v_stored_filename = $p_filedescr['stored_filename'];
2548 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is NOT the same "'.$v_stored_filename.'"');
2549 }
2550 else {
2551 $v_stored_filename = $p_filedescr['stored_filename'];
2552 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'Stored filename is the same');
2553 }
2554
2555 // ----- Set the file properties
2556 clearstatcache();
2557 $p_header['version'] = 20;
2558 $p_header['version_extracted'] = 10;
2559 $p_header['flag'] = 0;
2560 $p_header['compression'] = 0;
2561 $p_header['mtime'] = filemtime($p_filename);
2562 $p_header['crc'] = 0;
2563 $p_header['compressed_size'] = 0;
2564 $p_header['size'] = filesize($p_filename);
2565 $p_header['filename_len'] = strlen($p_filename);
2566 $p_header['extra_len'] = 0;
2567 $p_header['comment_len'] = 0;
2568 $p_header['disk'] = 0;
2569 $p_header['internal'] = 0;
2570 // $p_header['external'] = (is_file($p_filename)?0xFE49FFE0:0x41FF0010);
2571 $p_header['external'] = (is_file($p_filename)?0x00000000:0x00000010);
2572 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 5, "Header external extension '".sprintf("0x%X",$p_header['external'])."'");
2573 $p_header['offset'] = 0;
2574 $p_header['filename'] = $p_filename;
2575 $p_header['stored_filename'] = $v_stored_filename;
2576 $p_header['extra'] = '';
2577 $p_header['comment'] = '';
2578 $p_header['status'] = 'ok';
2579 $p_header['index'] = -1;
2580
2581 // ----- Look for pre-add callback
2582 if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
2583 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A pre-callback '".$p_options[PCLZIP_CB_PRE_ADD]."()') is defined for the extraction");
2584
2585 // ----- Generate a local information
2586 $v_local_header = array();
2587 $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2588
2589 // ----- Call the callback
2590 // Here I do not use call_user_func() because I need to send a reference to the
2591 // header.
2592 eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
2593 if ($v_result == 0) {
2594 // ----- Change the file status
2595 $p_header['status'] = "skipped";
2596 $v_result = 1;
2597 }
2598
2599 // ----- Update the informations
2600 // Only some fields can be modified
2601 if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
2602 $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
2603 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "New stored filename is '".$p_header['stored_filename']."'");
2604 }
2605 }
2606
2607 // ----- Look for empty stored filename
2608 if ($p_header['stored_filename'] == "") {
2609 $p_header['status'] = "filtered";
2610 }
2611
2612 // ----- Check the path length
2613 if (strlen($p_header['stored_filename']) > 0xFF) {
2614 $p_header['status'] = 'filename_too_long';
2615 }
2616
2617 // ----- Look if no error, or file not skipped
2618 if ($p_header['status'] == 'ok') {
2619
2620 // ----- Look for a file
2621 if (is_file($p_filename))
2622 {
2623 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a file");
2624 // ----- Open the source file
2625 if (($v_file = @fopen($p_filename, "rb")) == 0) {
2626 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
2627 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, PclZip::errorCode(), PclZip::errorInfo());
2628 return PclZip::errorCode();
2629 }
2630
2631 if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
2632 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will not be compressed");
2633 // ----- Read the file content
2634 $v_content_compressed = @fread($v_file, $p_header['size']);
2635
2636 // ----- Calculate the CRC
2637 $p_header['crc'] = @crc32($v_content_compressed);
2638
2639 // ----- Set header parameters
2640 $p_header['compressed_size'] = $p_header['size'];
2641 $p_header['compression'] = 0;
2642 }
2643 else {
2644 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File will be compressed");
2645 // ----- Read the file content
2646 $v_content = @fread($v_file, $p_header['size']);
2647
2648 // ----- Calculate the CRC
2649 $p_header['crc'] = @crc32($v_content);
2650
2651 // ----- Compress the file
2652 $v_content_compressed = @gzdeflate($v_content);
2653
2654 // ----- Set header parameters
2655 $p_header['compressed_size'] = strlen($v_content_compressed);
2656 $p_header['compression'] = 8;
2657 }
2658
2659 // ----- Look for encryption
2660 /*
2661 if ((isset($p_options[PCLZIP_OPT_CRYPT]))
2662 && ($p_options[PCLZIP_OPT_CRYPT] != "")) {
2663 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "File need to be crypted ....");
2664
2665 // Should be a random header
2666 $v_header = 'xxxxxxxxxxxx';
2667 $v_content_compressed = PclZipUtilZipEncrypt($v_content_compressed,
2668 $p_header['compressed_size'],
2669 $v_header,
2670 $p_header['crc'],
2671 "test");
2672
2673 $p_header['compressed_size'] += 12;
2674 $p_header['flag'] = 1;
2675
2676 // ----- Add the header to the data
2677 $v_content_compressed = $v_header.$v_content_compressed;
2678 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Size after header : ".strlen($v_content_compressed)."");
2679 }
2680 */
2681
2682 // ----- Call the header generation
2683 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
2684 @fclose($v_file);
2685 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2686 return $v_result;
2687 }
2688
2689 // ----- Write the compressed (or not) content
2690 @fwrite($this->zip_fd,
2691 $v_content_compressed, $p_header['compressed_size']);
2692
2693 // ----- Close the file
2694 @fclose($v_file);
2695 }
2696
2697 // ----- Look for a directory
2698 else {
2699 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "'".$p_filename."' is a folder");
2700 // ----- Look for directory last '/'
2701 if (@substr($p_header['stored_filename'], -1) != '/') {
2702 $p_header['stored_filename'] .= '/';
2703 }
2704
2705 // ----- Set the file properties
2706 $p_header['size'] = 0;
2707 //$p_header['external'] = 0x41FF0010; // Value for a folder : to be checked
2708 $p_header['external'] = 0x00000010; // Value for a folder : to be checked
2709
2710 // ----- Call the header generation
2711 if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
2712 {
2713 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2714 return $v_result;
2715 }
2716 }
2717 }
2718
2719 // ----- Look for post-add callback
2720 if (isset($p_options[PCLZIP_CB_POST_ADD])) {
2721 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "A post-callback '".$p_options[PCLZIP_CB_POST_ADD]."()') is defined for the extraction");
2722
2723 // ----- Generate a local information
2724 $v_local_header = array();
2725 $this->privConvertHeader2FileInfo($p_header, $v_local_header);
2726
2727 // ----- Call the callback
2728 // Here I do not use call_user_func() because I need to send a reference to the
2729 // header.
2730 eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
2731 if ($v_result == 0) {
2732 // ----- Ignored
2733 $v_result = 1;
2734 }
2735
2736 // ----- Update the informations
2737 // Nothing can be modified
2738 }
2739
2740 // ----- Return
2741 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2742 return $v_result;
2743 }
2744 // --------------------------------------------------------------------------------
2745
2746 // --------------------------------------------------------------------------------
2747 // Function : privCalculateStoredFilename()
2748 // Description :
2749 // Based on file descriptor properties and global options, this method
2750 // calculate the filename that will be stored in the archive.
2751 // Parameters :
2752 // Return Values :
2753 // --------------------------------------------------------------------------------
2754 // http://doc.spip.org/@privCalculateStoredFilename
2755 function privCalculateStoredFilename(&$p_filedescr, &$p_options)
2756 {
2757 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privCalculateStoredFilename", "filename='".$p_filedescr['filename']."'");
2758 $v_result=1;
2759
2760 // ----- Working variables
2761 $p_filename = $p_filedescr['filename'];
2762 if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
2763 $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
2764 }
2765 else {
2766 $p_add_dir = '';
2767 }
2768 if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
2769 $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
2770 }
2771 else {
2772 $p_remove_dir = '';
2773 }
2774 if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
2775 $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
2776 }
2777 else {
2778 $p_remove_all_dir = 0;
2779 }
2780
2781 // ----- Look for full name change
2782 if (isset($p_filedescr['new_full_name'])) {
2783 $v_stored_filename = $p_filedescr['new_full_name'];
2784 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing full name of '".$p_filename."' for '".$v_stored_filename."'");
2785 }
2786
2787 // ----- Look for path and/or short name change
2788 else {
2789
2790 // ----- Look for short name change
2791 if (isset($p_filedescr['new_short_name'])) {
2792 $v_path_info = pathinfo($p_filename);
2793 $v_dir = '';
2794 if ($v_path_info['dirname'] != '') {
2795 $v_dir = $v_path_info['dirname'].'/';
2796 }
2797 $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
2798 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Changing short name of '".$p_filename."' for '".$v_stored_filename."'");
2799 }
2800 else {
2801 // ----- Calculate the stored filename
2802 $v_stored_filename = $p_filename;
2803 }
2804
2805 // ----- Look for all path to remove
2806 if ($p_remove_all_dir) {
2807 $v_stored_filename = basename($p_filename);
2808 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove all path selected change '".$p_filename."' for '".$v_stored_filename."'");
2809 }
2810 // ----- Look for partial path remove
2811 else if ($p_remove_dir != "") {
2812 if (substr($p_remove_dir, -1) != '/')
2813 $p_remove_dir .= "/";
2814
2815 if ( (substr($p_filename, 0, 2) == "./")
2816 || (substr($p_remove_dir, 0, 2) == "./")) {
2817
2818 if ( (substr($p_filename, 0, 2) == "./")
2819 && (substr($p_remove_dir, 0, 2) != "./")) {
2820 $p_remove_dir = "./".$p_remove_dir;
2821 }
2822 if ( (substr($p_filename, 0, 2) != "./")
2823 && (substr($p_remove_dir, 0, 2) == "./")) {
2824 $p_remove_dir = substr($p_remove_dir, 2);
2825 }
2826 }
2827
2828 $v_compare = PclZipUtilPathInclusion($p_remove_dir,
2829 $v_stored_filename);
2830 if ($v_compare > 0) {
2831 if ($v_compare == 2) {
2832 $v_stored_filename = "";
2833 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Path to remove is the current folder");
2834 }
2835 else {
2836 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Remove path '$p_remove_dir' in file '$v_stored_filename'");
2837 $v_stored_filename = substr($v_stored_filename,
2838 strlen($p_remove_dir));
2839 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 4, "Result is '$v_stored_filename'");
2840 }
2841 }
2842 }
2843 // ----- Look for path to add
2844 if ($p_add_dir != "") {
2845 if (substr($p_add_dir, -1) == "/")
2846 $v_stored_filename = $p_add_dir.$v_stored_filename;
2847 else
2848 $v_stored_filename = $p_add_dir."/".$v_stored_filename;
2849 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'");
2850 }
2851 }
2852
2853 // ----- Filename (reduce the path of stored name)
2854 $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
2855 $p_filedescr['stored_filename'] = $v_stored_filename;
2856 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, "Stored filename will be '".$p_filedescr['stored_filename']."', strlen ".strlen($p_filedescr['stored_filename']));
2857
2858 // ----- Return
2859 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2860 return $v_result;
2861 }
2862 // --------------------------------------------------------------------------------
2863
2864 // --------------------------------------------------------------------------------
2865 // Function : privWriteFileHeader()
2866 // Description :
2867 // Parameters :
2868 // Return Values :
2869 // --------------------------------------------------------------------------------
2870 // http://doc.spip.org/@privWriteFileHeader
2871 function privWriteFileHeader(&$p_header)
2872 {
2873 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
2874 $v_result=1;
2875
2876 // ----- Store the offset position of the file
2877 $p_header['offset'] = ftell($this->zip_fd);
2878 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 2, 'File offset of the header :'.$p_header['offset']);
2879
2880 // ----- Transform UNIX mtime to DOS format mdate/mtime
2881 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
2882 $v_date = getdate($p_header['mtime']);
2883 $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2884 $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2885
2886 // ----- Packed data
2887 $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
2888 $p_header['version_extracted'], $p_header['flag'],
2889 $p_header['compression'], $v_mtime, $v_mdate,
2890 $p_header['crc'], $p_header['compressed_size'],
2891 $p_header['size'],
2892 strlen($p_header['stored_filename']),
2893 $p_header['extra_len']);
2894
2895 // ----- Write the first 148 bytes of the header in the archive
2896 fputs($this->zip_fd, $v_binary_data, 30);
2897
2898 // ----- Write the variable fields
2899 if (strlen($p_header['stored_filename']) != 0)
2900 {
2901 fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2902 }
2903 if ($p_header['extra_len'] != 0)
2904 {
2905 fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2906 }
2907
2908 // ----- Return
2909 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2910 return $v_result;
2911 }
2912 // --------------------------------------------------------------------------------
2913
2914 // --------------------------------------------------------------------------------
2915 // Function : privWriteCentralFileHeader()
2916 // Description :
2917 // Parameters :
2918 // Return Values :
2919 // --------------------------------------------------------------------------------
2920 // http://doc.spip.org/@privWriteCentralFileHeader
2921 function privWriteCentralFileHeader(&$p_header)
2922 {
2923 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralFileHeader", 'file="'.$p_header['filename'].'", stored as "'.$p_header['stored_filename'].'"');
2924 $v_result=1;
2925
2926 // TBC
2927 //for(reset($p_header); $key = key($p_header); next($p_header)) {
2928 // //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, "header[$key] = ".$p_header[$key]);
2929 //}
2930
2931 // ----- Transform UNIX mtime to DOS format mdate/mtime
2932 //--(MAGIC-PclTrace)--//PclTraceFctMessage(__FILE__, __LINE__, 3, 'Date : \''.date("d/m/y H:i:s", $p_header['mtime']).'\'');
2933 $v_date = getdate($p_header['mtime']);
2934 $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2935 $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2936
2937 // ----- Packed data
2938 $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
2939 $p_header['version'], $p_header['version_extracted'],
2940 $p_header['flag'], $p_header['compression'],
2941 $v_mtime, $v_mdate, $p_header['crc'],
2942 $p_header['compressed_size'], $p_header['size'],
2943 strlen($p_header['stored_filename']),
2944 $p_header['extra_len'], $p_header['comment_len'],
2945 $p_header['disk'], $p_header['internal'],
2946 $p_header['external'], $p_header['offset']);
2947
2948 // ----- Write the 42 bytes of the header in the zip file
2949 fputs($this->zip_fd, $v_binary_data, 46);
2950
2951 // ----- Write the variable fields
2952 if (strlen($p_header['stored_filename']) != 0)
2953 {
2954 fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2955 }
2956 if ($p_header['extra_len'] != 0)
2957 {
2958 fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2959 }
2960 if ($p_header['comment_len'] != 0)
2961 {
2962 fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
2963 }
2964
2965 // ----- Return
2966 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2967 return $v_result;
2968 }
2969 // --------------------------------------------------------------------------------
2970
2971 // --------------------------------------------------------------------------------
2972 // Function : privWriteCentralHeader()
2973 // Description :
2974 // Parameters :
2975 // Return Values :
2976 // --------------------------------------------------------------------------------
2977 // http://doc.spip.org/@privWriteCentralHeader
2978 function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
2979 {
2980 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privWriteCentralHeader", 'nb_entries='.$p_nb_entries.', size='.$p_size.', offset='.$p_offset.', comment="'.$p_comment.'"');
2981 $v_result=1;
2982
2983 // ----- Packed data
2984 $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
2985 $p_nb_entries, $p_size,
2986 $p_offset, strlen($p_comment));
2987
2988 // ----- Write the 22 bytes of the header in the zip file
2989 fputs($this->zip_fd, $v_binary_data, 22);
2990
2991 // ----- Write the variable fields
2992 if (strlen($p_comment) != 0)
2993 {
2994 fputs($this->zip_fd, $p_comment, strlen($p_comment));
2995 }
2996
2997 // ----- Return
2998 //--(MAGIC-PclTrace)--//PclTraceFctEnd(__FILE__, __LINE__, $v_result);
2999 return $v_result;
3000 }
3001 // --------------------------------------------------------------------------------
3002
3003 // --------------------------------------------------------------------------------
3004 // Function : privList()
3005 // Description :
3006 // Parameters :
3007 // Return Values :
3008 // --------------------------------------------------------------------------------
3009 // http://doc.spip.org/@privList
3010 function privList(&$p_list)
3011 {
3012 //--(MAGIC-PclTrace)--//PclTraceFctStart(__FILE__, __LINE__, "PclZip::privList", "list");
3013 $v_result=1;
3014
3015 // ----- Magic quotes trick
3016 $this->privDisableMagicQuotes();
3017
3018 // ----- Open the zip file