PluginProbe
InfiniteWP Client / trunk
InfiniteWP Client vtrunk
1.13.10 1.13.7 trunk 0.1.4 0.1.5 1.0.0 1.0.1 1.0.2 1.0.3 1.0.4 1.1.0 1.1.1 1.1.10 1.1.2 1.1.3 1.1.4 1.1.5 1.1.6 1.1.7 1.1.8 1.1.9 1.11.0 1.11.1 1.12.1 1.12.3 All 92 releases
iwp-client / pclzip.class.php

pclzip.class.php in InfiniteWP Client trunk, at pclzip.class.php

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