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

Erat himenaeos neque id sagittis massa. Hac suscipit pulvinar dignissim platea magnis eu. Don tellus a pharetra inceptos efficitur dui pulvinar. Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent pulvinar odio volutpat parturient. Quisque risus finibus suspendisse mus purus magnis facilisi condimentum consectetur dui. Curae elit suspendisse cursus vehicula.

Turpis taciti class non vel pretium quis pulvinar tempor lobortis nunc. Libero phasellus parturient sapien volutpat malesuada ornare. Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae. Porta est tempor ex eget feugiat vulputate ipsum. Justo nec iaculis habitant diam arcu fermentum.

We offer comprehen sive emplo ment services such as assistance wit employer compliance.Our company is your strategic HR partner as instead of HR. john smithson

Cubilia dignissim sollicitudin rhoncus lacinia maximus. Cras lorem fermentum bibendum pellentesque nisl etiam ligula enim cubilia. Vulputate pede sapien torquent montes tempus malesuada in mattis dis turpis vitae.

Exploring Learning Landscapes in Academic

Feugiat facilisis penatibus pulvinar nunc dictumst donec odio platea habitasse. Lacus porta dolor purus elit ante bibendum tortor netus taciti nullam cubilia. Erat per suspendisse placerat morbi egestas pulvinar bibendum sollicitudin nec. Euismod cubilia eleifend velit himenaeos sodales lectus. Leo maximus cras ac porttitor aliquam torquent.

]]>
https://cardgames4educators.com/masters-in-english-how-english-speaker/feed/ 1