source: trunk/admin/include/pclzip.lib.php @ 3823

Last change on this file since 3823 was 3823, checked in by patdenice, 15 years ago

merge r3822 from branch 2.0 to trunk
Update pclzip to 2.8.1 (PHP 5.3 compatibility)

  • Property svn:eol-style set to LF
File size: 106.0 KB
Line 
1<?php
2// --------------------------------------------------------------------------------
3// PhpConcept Library - Zip Module 2.8.1
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
26if (!defined('PCLZIP_READ_BLOCK_SIZE')) {
27  define( 'PCLZIP_READ_BLOCK_SIZE', 2048 );
28}
29
30if (!defined('PCLZIP_SEPARATOR')) {
31  define( 'PCLZIP_SEPARATOR', ',' );
32}
33
34if (!defined('PCLZIP_ERROR_EXTERNAL')) {
35  define( 'PCLZIP_ERROR_EXTERNAL', 0 );
36}
37
38if (!defined('PCLZIP_TEMPORARY_DIR')) {
39  define( 'PCLZIP_TEMPORARY_DIR', '' );
40}
41
42if (!defined('PCLZIP_TEMPORARY_FILE_RATIO')) {
43  define( 'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
44}
45
46
47$g_pclzip_version = "2.8.1";
48
49define( 'PCLZIP_ERR_USER_ABORTED', 2 );
50define( 'PCLZIP_ERR_NO_ERROR', 0 );
51define( 'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
52define( 'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
53define( 'PCLZIP_ERR_INVALID_PARAMETER', -3 );
54define( 'PCLZIP_ERR_MISSING_FILE', -4 );
55define( 'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
56define( 'PCLZIP_ERR_INVALID_ZIP', -6 );
57define( 'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
58define( 'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
59define( 'PCLZIP_ERR_BAD_EXTENSION', -9 );
60define( 'PCLZIP_ERR_BAD_FORMAT', -10 );
61define( 'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
62define( 'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
63define( 'PCLZIP_ERR_BAD_CHECKSUM', -13 );
64define( 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
65define( 'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
66define( 'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
67define( 'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
68define( 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
69define( 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
70define( 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
71define( 'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
72
73define( 'PCLZIP_OPT_PATH', 77001 );
74define( 'PCLZIP_OPT_ADD_PATH', 77002 );
75define( 'PCLZIP_OPT_REMOVE_PATH', 77003 );
76define( 'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
77define( 'PCLZIP_OPT_SET_CHMOD', 77005 );
78define( 'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
79define( 'PCLZIP_OPT_NO_COMPRESSION', 77007 );
80define( 'PCLZIP_OPT_BY_NAME', 77008 );
81define( 'PCLZIP_OPT_BY_INDEX', 77009 );
82define( 'PCLZIP_OPT_BY_EREG', 77010 );
83define( 'PCLZIP_OPT_BY_PREG', 77011 );
84define( 'PCLZIP_OPT_COMMENT', 77012 );
85define( 'PCLZIP_OPT_ADD_COMMENT', 77013 );
86define( 'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
87define( 'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
88define( 'PCLZIP_OPT_REPLACE_NEWER', 77016 );
89define( 'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
90define( 'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
91define( 'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
92define( 'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
93define( 'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
94
95define( 'PCLZIP_ATT_FILE_NAME', 79001 );
96define( 'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
97define( 'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
98define( 'PCLZIP_ATT_FILE_MTIME', 79004 );
99define( 'PCLZIP_ATT_FILE_CONTENT', 79005 );
100define( 'PCLZIP_ATT_FILE_COMMENT', 79006 );
101
102define( 'PCLZIP_CB_PRE_EXTRACT', 78001 );
103define( 'PCLZIP_CB_POST_EXTRACT', 78002 );
104define( 'PCLZIP_CB_PRE_ADD', 78003 );
105define( 'PCLZIP_CB_POST_ADD', 78004 );
106/* For futur use
107define( 'PCLZIP_CB_PRE_LIST', 78005 );
108define( 'PCLZIP_CB_POST_LIST', 78006 );
109define( 'PCLZIP_CB_PRE_DELETE', 78007 );
110define( 'PCLZIP_CB_POST_DELETE', 78008 );
111*/
112
113class PclZip
114{
115  var $zipname = '';
116
117  var $zip_fd = 0;
118
119  var $error_code = 1;
120  var $error_string = '';
121 
122  var $magic_quotes_status;
123
124function PclZip($p_zipname)
125{
126
127  if (!function_exists('gzopen'))
128  {
129    die('Abort '.basename(__FILE__).' : Missing zlib extensions');
130  }
131
132  $this->zipname = $p_zipname;
133  $this->zip_fd = 0;
134  $this->magic_quotes_status = -1;
135
136  return;
137}
138
139function create($p_filelist)
140{
141  $v_result=1;
142
143  $this->privErrorReset();
144
145  $v_options = array();
146  $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
147
148  $v_size = func_num_args();
149
150  if ($v_size > 1) {
151    $v_arg_list = func_get_args();
152
153    array_shift($v_arg_list);
154    $v_size--;
155
156    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
157
158      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
159                                          array (PCLZIP_OPT_REMOVE_PATH => 'optional',
160                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
161                                                 PCLZIP_OPT_ADD_PATH => 'optional',
162                                                 PCLZIP_CB_PRE_ADD => 'optional',
163                                                 PCLZIP_CB_POST_ADD => 'optional',
164                                                 PCLZIP_OPT_NO_COMPRESSION => 'optional',
165                                                 PCLZIP_OPT_COMMENT => 'optional',
166                                                 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
167                                                 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
168                                                 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
169                                           ));
170      if ($v_result != 1) {
171        return 0;
172      }
173    }
174
175    else {
176
177      $v_options[PCLZIP_OPT_ADD_PATH] = $v_arg_list[0];
178
179      if ($v_size == 2) {
180        $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
181      }
182      else if ($v_size > 2) {
183        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
184                         "Invalid number / type of arguments");
185        return 0;
186      }
187    }
188  }
189 
190  $this->privOptionDefaultThreshold($v_options);
191
192  $v_string_list = array();
193  $v_att_list = array();
194  $v_filedescr_list = array();
195  $p_result_list = array();
196 
197  if (is_array($p_filelist)) {
198 
199    if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
200      $v_att_list = $p_filelist;
201    }
202   
203    else {
204      $v_string_list = $p_filelist;
205    }
206  }
207
208  else if (is_string($p_filelist)) {
209    $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
210  }
211
212  else {
213    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_filelist");
214    return 0;
215  }
216 
217  if (sizeof($v_string_list) != 0) {
218    foreach ($v_string_list as $v_string) {
219      if ($v_string != '') {
220        $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
221      }
222      else {
223      }
224    }
225  }
226 
227  $v_supported_attributes
228  = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
229           ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
230           ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
231           ,PCLZIP_ATT_FILE_MTIME => 'optional'
232           ,PCLZIP_ATT_FILE_CONTENT => 'optional'
233           ,PCLZIP_ATT_FILE_COMMENT => 'optional'
234          );
235  foreach ($v_att_list as $v_entry) {
236    $v_result = $this->privFileDescrParseAtt($v_entry,
237                                             $v_filedescr_list[],
238                                             $v_options,
239                                             $v_supported_attributes);
240    if ($v_result != 1) {
241      return 0;
242    }
243  }
244
245  $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
246  if ($v_result != 1) {
247    return 0;
248  }
249
250  $v_result = $this->privCreate($v_filedescr_list, $p_result_list, $v_options);
251  if ($v_result != 1) {
252    return 0;
253  }
254
255  return $p_result_list;
256}
257
258function add($p_filelist)
259{
260  $v_result=1;
261
262  $this->privErrorReset();
263
264  $v_options = array();
265  $v_options[PCLZIP_OPT_NO_COMPRESSION] = FALSE;
266
267  $v_size = func_num_args();
268
269  if ($v_size > 1) {
270    $v_arg_list = func_get_args();
271
272    array_shift($v_arg_list);
273    $v_size--;
274
275    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
276
277      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
278                                          array (PCLZIP_OPT_REMOVE_PATH => 'optional',
279                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
280                                                 PCLZIP_OPT_ADD_PATH => 'optional',
281                                                 PCLZIP_CB_PRE_ADD => 'optional',
282                                                 PCLZIP_CB_POST_ADD => 'optional',
283                                                 PCLZIP_OPT_NO_COMPRESSION => 'optional',
284                                                 PCLZIP_OPT_COMMENT => 'optional',
285                                                 PCLZIP_OPT_ADD_COMMENT => 'optional',
286                                                 PCLZIP_OPT_PREPEND_COMMENT => 'optional',
287                                                 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
288                                                 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
289                                                 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
290                         ));
291      if ($v_result != 1) {
292        return 0;
293      }
294    }
295
296    else {
297
298      $v_options[PCLZIP_OPT_ADD_PATH] = $v_add_path = $v_arg_list[0];
299
300      if ($v_size == 2) {
301        $v_options[PCLZIP_OPT_REMOVE_PATH] = $v_arg_list[1];
302      }
303      else if ($v_size > 2) {
304        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
305
306        return 0;
307      }
308    }
309  }
310
311  $this->privOptionDefaultThreshold($v_options);
312
313  $v_string_list = array();
314  $v_att_list = array();
315  $v_filedescr_list = array();
316  $p_result_list = array();
317 
318  if (is_array($p_filelist)) {
319 
320    if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
321      $v_att_list = $p_filelist;
322    }
323   
324    else {
325      $v_string_list = $p_filelist;
326    }
327  }
328
329  else if (is_string($p_filelist)) {
330    $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
331  }
332
333  else {
334    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type '".gettype($p_filelist)."' for p_filelist");
335    return 0;
336  }
337 
338  if (sizeof($v_string_list) != 0) {
339    foreach ($v_string_list as $v_string) {
340      $v_att_list[][PCLZIP_ATT_FILE_NAME] = $v_string;
341    }
342  }
343 
344  $v_supported_attributes
345  = array ( PCLZIP_ATT_FILE_NAME => 'mandatory'
346           ,PCLZIP_ATT_FILE_NEW_SHORT_NAME => 'optional'
347           ,PCLZIP_ATT_FILE_NEW_FULL_NAME => 'optional'
348           ,PCLZIP_ATT_FILE_MTIME => 'optional'
349           ,PCLZIP_ATT_FILE_CONTENT => 'optional'
350           ,PCLZIP_ATT_FILE_COMMENT => 'optional'
351          );
352  foreach ($v_att_list as $v_entry) {
353    $v_result = $this->privFileDescrParseAtt($v_entry,
354                                             $v_filedescr_list[],
355                                             $v_options,
356                                             $v_supported_attributes);
357    if ($v_result != 1) {
358      return 0;
359    }
360  }
361
362  $v_result = $this->privFileDescrExpand($v_filedescr_list, $v_options);
363  if ($v_result != 1) {
364    return 0;
365  }
366
367  $v_result = $this->privAdd($v_filedescr_list, $p_result_list, $v_options);
368  if ($v_result != 1) {
369    return 0;
370  }
371
372  return $p_result_list;
373}
374
375function listContent()
376{
377  $v_result=1;
378
379  $this->privErrorReset();
380
381  if (!$this->privCheckFormat()) {
382    return(0);
383  }
384
385  $p_list = array();
386  if (($v_result = $this->privList($p_list)) != 1)
387  {
388    unset($p_list);
389    return(0);
390  }
391
392  return $p_list;
393}
394
395function extract()
396{
397  $v_result=1;
398
399  $this->privErrorReset();
400
401  if (!$this->privCheckFormat()) {
402    return(0);
403  }
404
405  $v_options = array();
406  $v_path = '';
407  $v_remove_path = "";
408  $v_remove_all_path = false;
409
410  $v_size = func_num_args();
411
412  $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
413
414  if ($v_size > 0) {
415    $v_arg_list = func_get_args();
416
417    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
418
419      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
420                                          array (PCLZIP_OPT_PATH => 'optional',
421                                                 PCLZIP_OPT_REMOVE_PATH => 'optional',
422                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
423                                                 PCLZIP_OPT_ADD_PATH => 'optional',
424                                                 PCLZIP_CB_PRE_EXTRACT => 'optional',
425                                                 PCLZIP_CB_POST_EXTRACT => 'optional',
426                                                 PCLZIP_OPT_SET_CHMOD => 'optional',
427                                                 PCLZIP_OPT_BY_NAME => 'optional',
428                                                 PCLZIP_OPT_BY_EREG => 'optional',
429                                                 PCLZIP_OPT_BY_PREG => 'optional',
430                                                 PCLZIP_OPT_BY_INDEX => 'optional',
431                                                 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
432                                                 PCLZIP_OPT_EXTRACT_IN_OUTPUT => 'optional',
433                                                 PCLZIP_OPT_REPLACE_NEWER => 'optional'
434                                                 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
435                                                 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
436                                                 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
437                                                 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
438                                                 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
439                          ));
440      if ($v_result != 1) {
441        return 0;
442      }
443
444      if (isset($v_options[PCLZIP_OPT_PATH])) {
445        $v_path = $v_options[PCLZIP_OPT_PATH];
446      }
447      if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
448        $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
449      }
450      if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
451        $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
452      }
453      if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
454        if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
455          $v_path .= '/';
456        }
457        $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
458      }
459    }
460
461    else {
462
463      $v_path = $v_arg_list[0];
464
465      if ($v_size == 2) {
466        $v_remove_path = $v_arg_list[1];
467      }
468      else if ($v_size > 2) {
469        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
470
471        return 0;
472      }
473    }
474  }
475
476  $this->privOptionDefaultThreshold($v_options);
477
478
479  $p_list = array();
480  $v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path,
481                                     $v_remove_all_path, $v_options);
482  if ($v_result < 1) {
483    unset($p_list);
484    return(0);
485  }
486
487  return $p_list;
488}
489
490
491function extractByIndex($p_index)
492{
493  $v_result=1;
494
495  $this->privErrorReset();
496
497  if (!$this->privCheckFormat()) {
498    return(0);
499  }
500
501  $v_options = array();
502  $v_path = '';
503  $v_remove_path = "";
504  $v_remove_all_path = false;
505
506  $v_size = func_num_args();
507
508  $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
509
510  if ($v_size > 1) {
511    $v_arg_list = func_get_args();
512
513    array_shift($v_arg_list);
514    $v_size--;
515
516    if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
517
518      $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
519                                          array (PCLZIP_OPT_PATH => 'optional',
520                                                 PCLZIP_OPT_REMOVE_PATH => 'optional',
521                                                 PCLZIP_OPT_REMOVE_ALL_PATH => 'optional',
522                                                 PCLZIP_OPT_EXTRACT_AS_STRING => 'optional',
523                                                 PCLZIP_OPT_ADD_PATH => 'optional',
524                                                 PCLZIP_CB_PRE_EXTRACT => 'optional',
525                                                 PCLZIP_CB_POST_EXTRACT => 'optional',
526                                                 PCLZIP_OPT_SET_CHMOD => 'optional',
527                                                 PCLZIP_OPT_REPLACE_NEWER => 'optional'
528                                                 ,PCLZIP_OPT_STOP_ON_ERROR => 'optional'
529                                                 ,PCLZIP_OPT_EXTRACT_DIR_RESTRICTION => 'optional',
530                                                 PCLZIP_OPT_TEMP_FILE_THRESHOLD => 'optional',
531                                                 PCLZIP_OPT_TEMP_FILE_ON => 'optional',
532                                                 PCLZIP_OPT_TEMP_FILE_OFF => 'optional'
533                         ));
534      if ($v_result != 1) {
535        return 0;
536      }
537
538      if (isset($v_options[PCLZIP_OPT_PATH])) {
539        $v_path = $v_options[PCLZIP_OPT_PATH];
540      }
541      if (isset($v_options[PCLZIP_OPT_REMOVE_PATH])) {
542        $v_remove_path = $v_options[PCLZIP_OPT_REMOVE_PATH];
543      }
544      if (isset($v_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
545        $v_remove_all_path = $v_options[PCLZIP_OPT_REMOVE_ALL_PATH];
546      }
547      if (isset($v_options[PCLZIP_OPT_ADD_PATH])) {
548        if ((strlen($v_path) > 0) && (substr($v_path, -1) != '/')) {
549          $v_path .= '/';
550        }
551        $v_path .= $v_options[PCLZIP_OPT_ADD_PATH];
552      }
553      if (!isset($v_options[PCLZIP_OPT_EXTRACT_AS_STRING])) {
554        $v_options[PCLZIP_OPT_EXTRACT_AS_STRING] = FALSE;
555      }
556      else {
557      }
558    }
559
560    else {
561
562      $v_path = $v_arg_list[0];
563
564      if ($v_size == 2) {
565        $v_remove_path = $v_arg_list[1];
566      }
567      else if ($v_size > 2) {
568        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid number / type of arguments");
569
570        return 0;
571      }
572    }
573  }
574
575
576  $v_arg_trick = array (PCLZIP_OPT_BY_INDEX, $p_index);
577  $v_options_trick = array();
578  $v_result = $this->privParseOptions($v_arg_trick, sizeof($v_arg_trick), $v_options_trick,
579                                      array (PCLZIP_OPT_BY_INDEX => 'optional' ));
580  if ($v_result != 1) {
581      return 0;
582  }
583  $v_options[PCLZIP_OPT_BY_INDEX] = $v_options_trick[PCLZIP_OPT_BY_INDEX];
584
585  $this->privOptionDefaultThreshold($v_options);
586
587  if (($v_result = $this->privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
588      return(0);
589  }
590
591  return $p_list;
592}
593
594function delete()
595{
596  $v_result=1;
597
598  $this->privErrorReset();
599
600  if (!$this->privCheckFormat()) {
601    return(0);
602  }
603
604  $v_options = array();
605
606  $v_size = func_num_args();
607
608  if ($v_size > 0) {
609    $v_arg_list = func_get_args();
610
611    $v_result = $this->privParseOptions($v_arg_list, $v_size, $v_options,
612                                      array (PCLZIP_OPT_BY_NAME => 'optional',
613                                             PCLZIP_OPT_BY_EREG => 'optional',
614                                             PCLZIP_OPT_BY_PREG => 'optional',
615                                             PCLZIP_OPT_BY_INDEX => 'optional' ));
616    if ($v_result != 1) {
617        return 0;
618    }
619  }
620
621  $this->privDisableMagicQuotes();
622
623  $v_list = array();
624  if (($v_result = $this->privDeleteByRule($v_list, $v_options)) != 1) {
625    $this->privSwapBackMagicQuotes();
626    unset($v_list);
627    return(0);
628  }
629
630  $this->privSwapBackMagicQuotes();
631
632  return $v_list;
633}
634
635function deleteByIndex($p_index)
636{
637 
638  $p_list = $this->delete(PCLZIP_OPT_BY_INDEX, $p_index);
639
640  return $p_list;
641}
642
643function properties()
644{
645
646  $this->privErrorReset();
647
648  $this->privDisableMagicQuotes();
649
650  if (!$this->privCheckFormat()) {
651    $this->privSwapBackMagicQuotes();
652    return(0);
653  }
654
655  $v_prop = array();
656  $v_prop['comment'] = '';
657  $v_prop['nb'] = 0;
658  $v_prop['status'] = 'not_exist';
659
660  if (@is_file($this->zipname))
661  {
662    if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
663    {
664      $this->privSwapBackMagicQuotes();
665     
666      PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
667
668      return 0;
669    }
670
671    $v_central_dir = array();
672    if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
673    {
674      $this->privSwapBackMagicQuotes();
675      return 0;
676    }
677
678    $this->privCloseFd();
679
680    $v_prop['comment'] = $v_central_dir['comment'];
681    $v_prop['nb'] = $v_central_dir['entries'];
682    $v_prop['status'] = 'ok';
683  }
684
685  $this->privSwapBackMagicQuotes();
686
687  return $v_prop;
688}
689
690function duplicate($p_archive)
691{
692  $v_result = 1;
693
694  $this->privErrorReset();
695
696  if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip'))
697  {
698
699    $v_result = $this->privDuplicate($p_archive->zipname);
700  }
701
702  else if (is_string($p_archive))
703  {
704
705    if (!is_file($p_archive)) {
706      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'");
707      $v_result = PCLZIP_ERR_MISSING_FILE;
708    }
709    else {
710      $v_result = $this->privDuplicate($p_archive);
711    }
712  }
713
714  else
715  {
716    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
717    $v_result = PCLZIP_ERR_INVALID_PARAMETER;
718  }
719
720  return $v_result;
721}
722
723function merge($p_archive_to_add)
724{
725  $v_result = 1;
726
727  $this->privErrorReset();
728
729  if (!$this->privCheckFormat()) {
730    return(0);
731  }
732
733  if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip'))
734  {
735
736    $v_result = $this->privMerge($p_archive_to_add);
737  }
738
739  else if (is_string($p_archive_to_add))
740  {
741
742    $v_object_archive = new PclZip($p_archive_to_add);
743
744    $v_result = $this->privMerge($v_object_archive);
745  }
746
747  else
748  {
749    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add");
750    $v_result = PCLZIP_ERR_INVALID_PARAMETER;
751  }
752
753  return $v_result;
754}
755
756
757
758function errorCode()
759{
760  if (PCLZIP_ERROR_EXTERNAL == 1) {
761    return(PclErrorCode());
762  }
763  else {
764    return($this->error_code);
765  }
766}
767
768function errorName($p_with_code=false)
769{
770  $v_name = array ( PCLZIP_ERR_NO_ERROR => 'PCLZIP_ERR_NO_ERROR',
771                    PCLZIP_ERR_WRITE_OPEN_FAIL => 'PCLZIP_ERR_WRITE_OPEN_FAIL',
772                    PCLZIP_ERR_READ_OPEN_FAIL => 'PCLZIP_ERR_READ_OPEN_FAIL',
773                    PCLZIP_ERR_INVALID_PARAMETER => 'PCLZIP_ERR_INVALID_PARAMETER',
774                    PCLZIP_ERR_MISSING_FILE => 'PCLZIP_ERR_MISSING_FILE',
775                    PCLZIP_ERR_FILENAME_TOO_LONG => 'PCLZIP_ERR_FILENAME_TOO_LONG',
776                    PCLZIP_ERR_INVALID_ZIP => 'PCLZIP_ERR_INVALID_ZIP',
777                    PCLZIP_ERR_BAD_EXTRACTED_FILE => 'PCLZIP_ERR_BAD_EXTRACTED_FILE',
778                    PCLZIP_ERR_DIR_CREATE_FAIL => 'PCLZIP_ERR_DIR_CREATE_FAIL',
779                    PCLZIP_ERR_BAD_EXTENSION => 'PCLZIP_ERR_BAD_EXTENSION',
780                    PCLZIP_ERR_BAD_FORMAT => 'PCLZIP_ERR_BAD_FORMAT',
781                    PCLZIP_ERR_DELETE_FILE_FAIL => 'PCLZIP_ERR_DELETE_FILE_FAIL',
782                    PCLZIP_ERR_RENAME_FILE_FAIL => 'PCLZIP_ERR_RENAME_FILE_FAIL',
783                    PCLZIP_ERR_BAD_CHECKSUM => 'PCLZIP_ERR_BAD_CHECKSUM',
784                    PCLZIP_ERR_INVALID_ARCHIVE_ZIP => 'PCLZIP_ERR_INVALID_ARCHIVE_ZIP',
785                    PCLZIP_ERR_MISSING_OPTION_VALUE => 'PCLZIP_ERR_MISSING_OPTION_VALUE',
786                    PCLZIP_ERR_INVALID_OPTION_VALUE => 'PCLZIP_ERR_INVALID_OPTION_VALUE',
787                    PCLZIP_ERR_UNSUPPORTED_COMPRESSION => 'PCLZIP_ERR_UNSUPPORTED_COMPRESSION',
788                    PCLZIP_ERR_UNSUPPORTED_ENCRYPTION => 'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION'
789                    ,PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE => 'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE'
790                    ,PCLZIP_ERR_DIRECTORY_RESTRICTION => 'PCLZIP_ERR_DIRECTORY_RESTRICTION'
791                  );
792
793  if (isset($v_name[$this->error_code])) {
794    $v_value = $v_name[$this->error_code];
795  }
796  else {
797    $v_value = 'NoName';
798  }
799
800  if ($p_with_code) {
801    return($v_value.' ('.$this->error_code.')');
802  }
803  else {
804    return($v_value);
805  }
806}
807
808function errorInfo($p_full=false)
809{
810  if (PCLZIP_ERROR_EXTERNAL == 1) {
811    return(PclErrorString());
812  }
813  else {
814    if ($p_full) {
815      return($this->errorName(true)." : ".$this->error_string);
816    }
817    else {
818      return($this->error_string." [code ".$this->error_code."]");
819    }
820  }
821}
822
823
824
825
826
827function privCheckFormat($p_level=0)
828{
829  $v_result = true;
830
831  clearstatcache();
832
833  $this->privErrorReset();
834
835  if (!is_file($this->zipname)) {
836    PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'");
837    return(false);
838  }
839
840  if (!is_readable($this->zipname)) {
841    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'");
842    return(false);
843  }
844
845
846
847
848  return $v_result;
849}
850
851function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
852{
853  $v_result=1;
854 
855  $i=0;
856  while ($i<$p_size) {
857
858    if (!isset($v_requested_options[$p_options_list[$i]])) {
859      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method");
860
861      return PclZip::errorCode();
862    }
863
864    switch ($p_options_list[$i]) {
865      case PCLZIP_OPT_PATH :
866      case PCLZIP_OPT_REMOVE_PATH :
867      case PCLZIP_OPT_ADD_PATH :
868        if (($i+1) >= $p_size) {
869          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
870
871          return PclZip::errorCode();
872        }
873
874        $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
875        $i++;
876      break;
877
878      case PCLZIP_OPT_TEMP_FILE_THRESHOLD :
879        if (($i+1) >= $p_size) {
880          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
881          return PclZip::errorCode();
882        }
883       
884        if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
885          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
886          return PclZip::errorCode();
887        }
888       
889        $v_value = $p_options_list[$i+1];
890        if ((!is_integer($v_value)) || ($v_value<0)) {
891          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'");
892          return PclZip::errorCode();
893        }
894
895        $v_result_list[$p_options_list[$i]] = $v_value*1048576;
896        $i++;
897      break;
898
899      case PCLZIP_OPT_TEMP_FILE_ON :
900        if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) {
901          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'");
902          return PclZip::errorCode();
903        }
904       
905        $v_result_list[$p_options_list[$i]] = true;
906      break;
907
908      case PCLZIP_OPT_TEMP_FILE_OFF :
909        if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) {
910          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'");
911          return PclZip::errorCode();
912        }
913        if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
914          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'");
915          return PclZip::errorCode();
916        }
917       
918        $v_result_list[$p_options_list[$i]] = true;
919      break;
920
921      case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION :
922        if (($i+1) >= $p_size) {
923          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
924
925          return PclZip::errorCode();
926        }
927
928        if (   is_string($p_options_list[$i+1])
929            && ($p_options_list[$i+1] != '')) {
930          $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE);
931          $i++;
932        }
933        else {
934        }
935      break;
936
937      case PCLZIP_OPT_BY_NAME :
938        if (($i+1) >= $p_size) {
939          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
940
941          return PclZip::errorCode();
942        }
943
944        if (is_string($p_options_list[$i+1])) {
945            $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1];
946        }
947        else if (is_array($p_options_list[$i+1])) {
948            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
949        }
950        else {
951          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
952
953          return PclZip::errorCode();
954        }
955        $i++;
956      break;
957
958      case PCLZIP_OPT_BY_EREG :
959        $p_options_list[$i] = PCLZIP_OPT_BY_PREG;
960      case PCLZIP_OPT_BY_PREG :
961        if (($i+1) >= $p_size) {
962          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
963
964          return PclZip::errorCode();
965        }
966
967        if (is_string($p_options_list[$i+1])) {
968            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
969        }
970        else {
971          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
972
973          return PclZip::errorCode();
974        }
975        $i++;
976      break;
977
978      case PCLZIP_OPT_COMMENT :
979      case PCLZIP_OPT_ADD_COMMENT :
980      case PCLZIP_OPT_PREPEND_COMMENT :
981        if (($i+1) >= $p_size) {
982          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE,
983                         "Missing parameter value for option '"
984               .PclZipUtilOptionText($p_options_list[$i])
985               ."'");
986
987          return PclZip::errorCode();
988        }
989
990        if (is_string($p_options_list[$i+1])) {
991            $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
992        }
993        else {
994          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE,
995                         "Wrong parameter value for option '"
996               .PclZipUtilOptionText($p_options_list[$i])
997               ."'");
998
999          return PclZip::errorCode();
1000        }
1001        $i++;
1002      break;
1003
1004      case PCLZIP_OPT_BY_INDEX :
1005        if (($i+1) >= $p_size) {
1006          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1007
1008          return PclZip::errorCode();
1009        }
1010
1011        $v_work_list = array();
1012        if (is_string($p_options_list[$i+1])) {
1013
1014            $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', '');
1015
1016            $v_work_list = explode(",", $p_options_list[$i+1]);
1017        }
1018        else if (is_integer($p_options_list[$i+1])) {
1019            $v_work_list[0] = $p_options_list[$i+1].'-'.$p_options_list[$i+1];
1020        }
1021        else if (is_array($p_options_list[$i+1])) {
1022            $v_work_list = $p_options_list[$i+1];
1023        }
1024        else {
1025          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1026
1027          return PclZip::errorCode();
1028        }
1029       
1030        $v_sort_flag=false;
1031        $v_sort_value=0;
1032        for ($j=0; $j<sizeof($v_work_list); $j++) {
1033            $v_item_list = explode("-", $v_work_list[$j]);
1034            $v_size_item_list = sizeof($v_item_list);
1035           
1036           
1037            if ($v_size_item_list == 1) {
1038                $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1039                $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[0];
1040            }
1041            elseif ($v_size_item_list == 2) {
1042                $v_result_list[$p_options_list[$i]][$j]['start'] = $v_item_list[0];
1043                $v_result_list[$p_options_list[$i]][$j]['end'] = $v_item_list[1];
1044            }
1045            else {
1046                PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1047
1048                return PclZip::errorCode();
1049            }
1050
1051
1052            if ($v_result_list[$p_options_list[$i]][$j]['start'] < $v_sort_value) {
1053                $v_sort_flag=true;
1054
1055                PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1056
1057                return PclZip::errorCode();
1058            }
1059            $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start'];
1060        }
1061       
1062        if ($v_sort_flag) {
1063        }
1064
1065        $i++;
1066      break;
1067
1068      case PCLZIP_OPT_REMOVE_ALL_PATH :
1069      case PCLZIP_OPT_EXTRACT_AS_STRING :
1070      case PCLZIP_OPT_NO_COMPRESSION :
1071      case PCLZIP_OPT_EXTRACT_IN_OUTPUT :
1072      case PCLZIP_OPT_REPLACE_NEWER :
1073      case PCLZIP_OPT_STOP_ON_ERROR :
1074        $v_result_list[$p_options_list[$i]] = true;
1075      break;
1076
1077      case PCLZIP_OPT_SET_CHMOD :
1078        if (($i+1) >= $p_size) {
1079          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1080
1081          return PclZip::errorCode();
1082        }
1083
1084        $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1];
1085        $i++;
1086      break;
1087
1088      case PCLZIP_CB_PRE_EXTRACT :
1089      case PCLZIP_CB_POST_EXTRACT :
1090      case PCLZIP_CB_PRE_ADD :
1091      case PCLZIP_CB_POST_ADD :
1092      /* for futur use
1093      case PCLZIP_CB_PRE_DELETE :
1094      case PCLZIP_CB_POST_DELETE :
1095      case PCLZIP_CB_PRE_LIST :
1096      case PCLZIP_CB_POST_LIST :
1097      */
1098        if (($i+1) >= $p_size) {
1099          PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1100
1101          return PclZip::errorCode();
1102        }
1103
1104        $v_function_name = $p_options_list[$i+1];
1105
1106        if (!function_exists($v_function_name)) {
1107          PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'");
1108
1109          return PclZip::errorCode();
1110        }
1111
1112        $v_result_list[$p_options_list[$i]] = $v_function_name;
1113        $i++;
1114      break;
1115
1116      default :
1117        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1118                         "Unknown parameter '"
1119               .$p_options_list[$i]."'");
1120
1121        return PclZip::errorCode();
1122    }
1123
1124    $i++;
1125  }
1126
1127  if ($v_requested_options !== false) {
1128    for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1129      if ($v_requested_options[$key] == 'mandatory') {
1130        if (!isset($v_result_list[$key])) {
1131          PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1132
1133          return PclZip::errorCode();
1134        }
1135      }
1136    }
1137  }
1138 
1139  if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) {
1140   
1141  }
1142
1143  return $v_result;
1144}
1145
1146function privOptionDefaultThreshold(&$p_options)
1147{
1148  $v_result=1;
1149 
1150  if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1151      || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) {
1152    return $v_result;
1153  }
1154 
1155  $v_memory_limit = ini_get('memory_limit');
1156  $v_memory_limit = trim($v_memory_limit);
1157  $last = strtolower(substr($v_memory_limit, -1));
1158
1159  if($last == 'g')
1160      $v_memory_limit = $v_memory_limit*1073741824;
1161  if($last == 'm')
1162      $v_memory_limit = $v_memory_limit*1048576;
1163  if($last == 'k')
1164      $v_memory_limit = $v_memory_limit*1024;
1165         
1166  $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO);
1167 
1168
1169  if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) {
1170    unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]);
1171  }
1172       
1173  return $v_result;
1174}
1175
1176function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
1177{
1178  $v_result=1;
1179 
1180  foreach ($p_file_list as $v_key => $v_value) {
1181 
1182    if (!isset($v_requested_options[$v_key])) {
1183      PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file");
1184
1185      return PclZip::errorCode();
1186    }
1187
1188    switch ($v_key) {
1189      case PCLZIP_ATT_FILE_NAME :
1190        if (!is_string($v_value)) {
1191          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1192          return PclZip::errorCode();
1193        }
1194
1195        $p_filedescr['filename'] = PclZipUtilPathReduction($v_value);
1196       
1197        if ($p_filedescr['filename'] == '') {
1198          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'");
1199          return PclZip::errorCode();
1200        }
1201
1202      break;
1203
1204      case PCLZIP_ATT_FILE_NEW_SHORT_NAME :
1205        if (!is_string($v_value)) {
1206          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1207          return PclZip::errorCode();
1208        }
1209
1210        $p_filedescr['new_short_name'] = PclZipUtilPathReduction($v_value);
1211
1212        if ($p_filedescr['new_short_name'] == '') {
1213          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'");
1214          return PclZip::errorCode();
1215        }
1216      break;
1217
1218      case PCLZIP_ATT_FILE_NEW_FULL_NAME :
1219        if (!is_string($v_value)) {
1220          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1221          return PclZip::errorCode();
1222        }
1223
1224        $p_filedescr['new_full_name'] = PclZipUtilPathReduction($v_value);
1225
1226        if ($p_filedescr['new_full_name'] == '') {
1227          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'");
1228          return PclZip::errorCode();
1229        }
1230      break;
1231
1232      case PCLZIP_ATT_FILE_COMMENT :
1233        if (!is_string($v_value)) {
1234          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'");
1235          return PclZip::errorCode();
1236        }
1237
1238        $p_filedescr['comment'] = $v_value;
1239      break;
1240
1241      case PCLZIP_ATT_FILE_MTIME :
1242        if (!is_integer($v_value)) {
1243          PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'");
1244          return PclZip::errorCode();
1245        }
1246
1247        $p_filedescr['mtime'] = $v_value;
1248      break;
1249
1250      case PCLZIP_ATT_FILE_CONTENT :
1251        $p_filedescr['content'] = $v_value;
1252      break;
1253
1254      default :
1255        PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER,
1256                             "Unknown parameter '".$v_key."'");
1257
1258        return PclZip::errorCode();
1259    }
1260
1261    if ($v_requested_options !== false) {
1262      for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) {
1263        if ($v_requested_options[$key] == 'mandatory') {
1264          if (!isset($p_file_list[$key])) {
1265            PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")");
1266            return PclZip::errorCode();
1267          }
1268        }
1269      }
1270    }
1271 
1272  }
1273 
1274  return $v_result;
1275}
1276
1277function privFileDescrExpand(&$p_filedescr_list, &$p_options)
1278{
1279  $v_result=1;
1280 
1281  $v_result_list = array();
1282 
1283  for ($i=0; $i<sizeof($p_filedescr_list); $i++) {
1284   
1285    $v_descr = $p_filedescr_list[$i];
1286   
1287    $v_descr['filename'] = PclZipUtilTranslateWinPath($v_descr['filename'], false);
1288    $v_descr['filename'] = PclZipUtilPathReduction($v_descr['filename']);
1289   
1290    if (file_exists($v_descr['filename'])) {
1291      if (@is_file($v_descr['filename'])) {
1292        $v_descr['type'] = 'file';
1293      }
1294      else if (@is_dir($v_descr['filename'])) {
1295        $v_descr['type'] = 'folder';
1296      }
1297      else if (@is_link($v_descr['filename'])) {
1298        continue;
1299      }
1300      else {
1301        continue;
1302      }
1303    }
1304   
1305    else if (isset($v_descr['content'])) {
1306      $v_descr['type'] = 'virtual_file';
1307    }
1308   
1309    else {
1310      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist");
1311
1312      return PclZip::errorCode();
1313    }
1314   
1315    $this->privCalculateStoredFilename($v_descr, $p_options);
1316   
1317    $v_result_list[sizeof($v_result_list)] = $v_descr;
1318   
1319    if ($v_descr['type'] == 'folder') {
1320      $v_dirlist_descr = array();
1321      $v_dirlist_nb = 0;
1322      if ($v_folder_handler = @opendir($v_descr['filename'])) {
1323        while (($v_item_handler = @readdir($v_folder_handler)) !== false) {
1324
1325          if (($v_item_handler == '.') || ($v_item_handler == '..')) {
1326              continue;
1327          }
1328         
1329          $v_dirlist_descr[$v_dirlist_nb]['filename'] = $v_descr['filename'].'/'.$v_item_handler;
1330         
1331          if ($v_descr['stored_filename'] != $v_descr['filename']) {
1332            if ($v_descr['stored_filename'] != '') {
1333              $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_descr['stored_filename'].'/'.$v_item_handler;
1334            }
1335            else {
1336              $v_dirlist_descr[$v_dirlist_nb]['new_full_name'] = $v_item_handler;
1337            }
1338          }
1339   
1340          $v_dirlist_nb++;
1341        }
1342       
1343        @closedir($v_folder_handler);
1344      }
1345      else {
1346      }
1347     
1348      if ($v_dirlist_nb != 0) {
1349        if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) {
1350          return $v_result;
1351        }
1352       
1353        $v_result_list = array_merge($v_result_list, $v_dirlist_descr);
1354      }
1355      else {
1356      }
1357       
1358      unset($v_dirlist_descr);
1359    }
1360  }
1361 
1362  $p_filedescr_list = $v_result_list;
1363
1364  return $v_result;
1365}
1366
1367function privCreate($p_filedescr_list, &$p_result_list, &$p_options)
1368{
1369  $v_result=1;
1370  $v_list_detail = array();
1371 
1372  $this->privDisableMagicQuotes();
1373
1374  if (($v_result = $this->privOpenFd('wb')) != 1)
1375  {
1376    return $v_result;
1377  }
1378
1379  $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options);
1380
1381  $this->privCloseFd();
1382
1383  $this->privSwapBackMagicQuotes();
1384
1385  return $v_result;
1386}
1387
1388function privAdd($p_filedescr_list, &$p_result_list, &$p_options)
1389{
1390  $v_result=1;
1391  $v_list_detail = array();
1392
1393  if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0))
1394  {
1395
1396    $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options);
1397
1398    return $v_result;
1399  }
1400  $this->privDisableMagicQuotes();
1401
1402  if (($v_result=$this->privOpenFd('rb')) != 1)
1403  {
1404    $this->privSwapBackMagicQuotes();
1405
1406    return $v_result;
1407  }
1408
1409  $v_central_dir = array();
1410  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
1411  {
1412    $this->privCloseFd();
1413    $this->privSwapBackMagicQuotes();
1414    return $v_result;
1415  }
1416
1417  @rewind($this->zip_fd);
1418
1419  $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
1420
1421  if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
1422  {
1423    $this->privCloseFd();
1424    $this->privSwapBackMagicQuotes();
1425
1426    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
1427
1428    return PclZip::errorCode();
1429  }
1430
1431  $v_size = $v_central_dir['offset'];
1432  while ($v_size != 0)
1433  {
1434    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1435    $v_buffer = fread($this->zip_fd, $v_read_size);
1436    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
1437    $v_size -= $v_read_size;
1438  }
1439
1440  $v_swap = $this->zip_fd;
1441  $this->zip_fd = $v_zip_temp_fd;
1442  $v_zip_temp_fd = $v_swap;
1443
1444  $v_header_list = array();
1445  if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
1446  {
1447    fclose($v_zip_temp_fd);
1448    $this->privCloseFd();
1449    @unlink($v_zip_temp_name);
1450    $this->privSwapBackMagicQuotes();
1451
1452    return $v_result;
1453  }
1454
1455  $v_offset = @ftell($this->zip_fd);
1456
1457  $v_size = $v_central_dir['size'];
1458  while ($v_size != 0)
1459  {
1460    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1461    $v_buffer = @fread($v_zip_temp_fd, $v_read_size);
1462    @fwrite($this->zip_fd, $v_buffer, $v_read_size);
1463    $v_size -= $v_read_size;
1464  }
1465
1466  for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++)
1467  {
1468    if ($v_header_list[$i]['status'] == 'ok') {
1469      if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
1470        fclose($v_zip_temp_fd);
1471        $this->privCloseFd();
1472        @unlink($v_zip_temp_name);
1473        $this->privSwapBackMagicQuotes();
1474
1475        return $v_result;
1476      }
1477      $v_count++;
1478    }
1479
1480    $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
1481  }
1482
1483  $v_comment = $v_central_dir['comment'];
1484  if (isset($p_options[PCLZIP_OPT_COMMENT])) {
1485    $v_comment = $p_options[PCLZIP_OPT_COMMENT];
1486  }
1487  if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) {
1488    $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT];
1489  }
1490  if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) {
1491    $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment;
1492  }
1493
1494  $v_size = @ftell($this->zip_fd)-$v_offset;
1495
1496  if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries'], $v_size, $v_offset, $v_comment)) != 1)
1497  {
1498    unset($v_header_list);
1499    $this->privSwapBackMagicQuotes();
1500
1501    return $v_result;
1502  }
1503
1504  $v_swap = $this->zip_fd;
1505  $this->zip_fd = $v_zip_temp_fd;
1506  $v_zip_temp_fd = $v_swap;
1507
1508  $this->privCloseFd();
1509
1510  @fclose($v_zip_temp_fd);
1511
1512  $this->privSwapBackMagicQuotes();
1513
1514  @unlink($this->zipname);
1515
1516  PclZipUtilRename($v_zip_temp_name, $this->zipname);
1517
1518  return $v_result;
1519}
1520
1521function privOpenFd($p_mode)
1522{
1523  $v_result=1;
1524
1525  if ($this->zip_fd != 0)
1526  {
1527    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip file \''.$this->zipname.'\' already open');
1528
1529    return PclZip::errorCode();
1530  }
1531
1532  if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0)
1533  {
1534    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in '.$p_mode.' mode');
1535
1536    return PclZip::errorCode();
1537  }
1538
1539  return $v_result;
1540}
1541
1542function privCloseFd()
1543{
1544  $v_result=1;
1545
1546  if ($this->zip_fd != 0)
1547    @fclose($this->zip_fd);
1548  $this->zip_fd = 0;
1549
1550  return $v_result;
1551}
1552
1553function privAddList($p_filedescr_list, &$p_result_list, &$p_options)
1554{
1555  $v_result=1;
1556
1557  $v_header_list = array();
1558  if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1)
1559  {
1560    return $v_result;
1561  }
1562
1563  $v_offset = @ftell($this->zip_fd);
1564
1565  for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++)
1566  {
1567    if ($v_header_list[$i]['status'] == 'ok') {
1568      if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
1569        return $v_result;
1570      }
1571      $v_count++;
1572    }
1573
1574    $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
1575  }
1576
1577  $v_comment = '';
1578  if (isset($p_options[PCLZIP_OPT_COMMENT])) {
1579    $v_comment = $p_options[PCLZIP_OPT_COMMENT];
1580  }
1581
1582  $v_size = @ftell($this->zip_fd)-$v_offset;
1583
1584  if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1)
1585  {
1586    unset($v_header_list);
1587
1588    return $v_result;
1589  }
1590
1591  return $v_result;
1592}
1593
1594function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options)
1595{
1596  $v_result=1;
1597  $v_header = array();
1598
1599  $v_nb = sizeof($p_result_list);
1600
1601  for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) {
1602    $p_filedescr_list[$j]['filename']
1603    = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename'], false);
1604   
1605
1606    if ($p_filedescr_list[$j]['filename'] == "") {
1607      continue;
1608    }
1609
1610    if (   ($p_filedescr_list[$j]['type'] != 'virtual_file')
1611        && (!file_exists($p_filedescr_list[$j]['filename']))) {
1612      PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist");
1613      return PclZip::errorCode();
1614    }
1615
1616    if (   ($p_filedescr_list[$j]['type'] == 'file')
1617        || ($p_filedescr_list[$j]['type'] == 'virtual_file')
1618        || (   ($p_filedescr_list[$j]['type'] == 'folder')
1619            && (   !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])
1620                || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))
1621        ) {
1622
1623      $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header,
1624                                     $p_options);
1625      if ($v_result != 1) {
1626        return $v_result;
1627      }
1628
1629      $p_result_list[$v_nb++] = $v_header;
1630    }
1631  }
1632
1633  return $v_result;
1634}
1635
1636function privAddFile($p_filedescr, &$p_header, &$p_options)
1637{
1638  $v_result=1;
1639 
1640  $p_filename = $p_filedescr['filename'];
1641
1642  if ($p_filename == "") {
1643    PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)");
1644
1645    return PclZip::errorCode();
1646  }
1647
1648  /* TBC : Removed
1649  if (isset($p_filedescr['stored_filename'])) {
1650    $v_stored_filename = $p_filedescr['stored_filename'];
1651  }
1652  else {
1653    $v_stored_filename = $p_filedescr['stored_filename'];
1654  }
1655  */
1656
1657  clearstatcache();
1658  $p_header['version'] = 20;
1659  $p_header['version_extracted'] = 10;
1660  $p_header['flag'] = 0;
1661  $p_header['compression'] = 0;
1662  $p_header['crc'] = 0;
1663  $p_header['compressed_size'] = 0;
1664  $p_header['filename_len'] = strlen($p_filename);
1665  $p_header['extra_len'] = 0;
1666  $p_header['disk'] = 0;
1667  $p_header['internal'] = 0;
1668  $p_header['offset'] = 0;
1669  $p_header['filename'] = $p_filename;
1670  $p_header['stored_filename'] = $p_filedescr['stored_filename'];
1671  $p_header['extra'] = '';
1672  $p_header['status'] = 'ok';
1673  $p_header['index'] = -1;
1674
1675  if ($p_filedescr['type']=='file') {
1676    $p_header['external'] = 0x00000000;
1677    $p_header['size'] = filesize($p_filename);
1678  }
1679 
1680  else if ($p_filedescr['type']=='folder') {
1681    $p_header['external'] = 0x00000010;
1682    $p_header['mtime'] = filemtime($p_filename);
1683    $p_header['size'] = filesize($p_filename);
1684  }
1685 
1686  else if ($p_filedescr['type'] == 'virtual_file') {
1687    $p_header['external'] = 0x00000000;
1688    $p_header['size'] = strlen($p_filedescr['content']);
1689  }
1690 
1691
1692  if (isset($p_filedescr['mtime'])) {
1693    $p_header['mtime'] = $p_filedescr['mtime'];
1694  }
1695  else if ($p_filedescr['type'] == 'virtual_file') {
1696    $p_header['mtime'] = time();
1697  }
1698  else {
1699    $p_header['mtime'] = filemtime($p_filename);
1700  }
1701
1702  if (isset($p_filedescr['comment'])) {
1703    $p_header['comment_len'] = strlen($p_filedescr['comment']);
1704    $p_header['comment'] = $p_filedescr['comment'];
1705  }
1706  else {
1707    $p_header['comment_len'] = 0;
1708    $p_header['comment'] = '';
1709  }
1710
1711  if (isset($p_options[PCLZIP_CB_PRE_ADD])) {
1712
1713    $v_local_header = array();
1714    $this->privConvertHeader2FileInfo($p_header, $v_local_header);
1715
1716    eval('$v_result = '.$p_options[PCLZIP_CB_PRE_ADD].'(PCLZIP_CB_PRE_ADD, $v_local_header);');
1717    if ($v_result == 0) {
1718      $p_header['status'] = "skipped";
1719      $v_result = 1;
1720    }
1721
1722    if ($p_header['stored_filename'] != $v_local_header['stored_filename']) {
1723      $p_header['stored_filename'] = PclZipUtilPathReduction($v_local_header['stored_filename']);
1724    }
1725  }
1726
1727  if ($p_header['stored_filename'] == "") {
1728    $p_header['status'] = "filtered";
1729  }
1730 
1731  if (strlen($p_header['stored_filename']) > 0xFF) {
1732    $p_header['status'] = 'filename_too_long';
1733  }
1734
1735  if ($p_header['status'] == 'ok') {
1736
1737    if ($p_filedescr['type'] == 'file') {
1738      if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 
1739          && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
1740              || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
1741                  && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) {
1742        $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options);
1743        if ($v_result < PCLZIP_ERR_NO_ERROR) {
1744          return $v_result;
1745        }
1746      }
1747     
1748      else {
1749
1750      if (($v_file = @fopen($p_filename, "rb")) == 0) {
1751        PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
1752        return PclZip::errorCode();
1753      }
1754
1755      $v_content = @fread($v_file, $p_header['size']);
1756
1757      @fclose($v_file);
1758
1759      $p_header['crc'] = @crc32($v_content);
1760     
1761      if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
1762        $p_header['compressed_size'] = $p_header['size'];
1763        $p_header['compression'] = 0;
1764      }
1765     
1766      else {
1767        $v_content = @gzdeflate($v_content);
1768
1769        $p_header['compressed_size'] = strlen($v_content);
1770        $p_header['compression'] = 8;
1771      }
1772     
1773      if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
1774        @fclose($v_file);
1775        return $v_result;
1776      }
1777
1778      @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
1779
1780      }
1781
1782    }
1783
1784    else if ($p_filedescr['type'] == 'virtual_file') {
1785       
1786      $v_content = $p_filedescr['content'];
1787
1788      $p_header['crc'] = @crc32($v_content);
1789     
1790      if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) {
1791        $p_header['compressed_size'] = $p_header['size'];
1792        $p_header['compression'] = 0;
1793      }
1794     
1795      else {
1796        $v_content = @gzdeflate($v_content);
1797
1798        $p_header['compressed_size'] = strlen($v_content);
1799        $p_header['compression'] = 8;
1800      }
1801     
1802      if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
1803        @fclose($v_file);
1804        return $v_result;
1805      }
1806
1807      @fwrite($this->zip_fd, $v_content, $p_header['compressed_size']);
1808    }
1809
1810    else if ($p_filedescr['type'] == 'folder') {
1811      if (@substr($p_header['stored_filename'], -1) != '/') {
1812        $p_header['stored_filename'] .= '/';
1813      }
1814
1815      $p_header['size'] = 0;
1816
1817      if (($v_result = $this->privWriteFileHeader($p_header)) != 1)
1818      {
1819        return $v_result;
1820      }
1821    }
1822  }
1823
1824  if (isset($p_options[PCLZIP_CB_POST_ADD])) {
1825
1826    $v_local_header = array();
1827    $this->privConvertHeader2FileInfo($p_header, $v_local_header);
1828
1829    eval('$v_result = '.$p_options[PCLZIP_CB_POST_ADD].'(PCLZIP_CB_POST_ADD, $v_local_header);');
1830    if ($v_result == 0) {
1831      $v_result = 1;
1832    }
1833
1834  }
1835
1836  return $v_result;
1837}
1838
1839function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options)
1840{
1841  $v_result=PCLZIP_ERR_NO_ERROR;
1842 
1843  $p_filename = $p_filedescr['filename'];
1844
1845
1846  if (($v_file = @fopen($p_filename, "rb")) == 0) {
1847    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename' in binary read mode");
1848    return PclZip::errorCode();
1849  }
1850
1851  $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
1852  if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) {
1853    fclose($v_file);
1854    PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
1855    return PclZip::errorCode();
1856  }
1857
1858  $v_size = filesize($p_filename);
1859  while ($v_size != 0) {
1860    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1861    $v_buffer = @fread($v_file, $v_read_size);
1862    @gzputs($v_file_compressed, $v_buffer, $v_read_size);
1863    $v_size -= $v_read_size;
1864  }
1865
1866  @fclose($v_file);
1867  @gzclose($v_file_compressed);
1868
1869  if (filesize($v_gzip_temp_name) < 18) {
1870    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary file \''.$v_gzip_temp_name.'\' has invalid filesize - should be minimum 18 bytes');
1871    return PclZip::errorCode();
1872  }
1873
1874  if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) {
1875    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
1876    return PclZip::errorCode();
1877  }
1878
1879  $v_binary_data = @fread($v_file_compressed, 10);
1880  $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os', $v_binary_data);
1881
1882  $v_data_header['os'] = bin2hex($v_data_header['os']);
1883
1884  @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8);
1885  $v_binary_data = @fread($v_file_compressed, 8);
1886  $v_data_footer = unpack('Vcrc/Vcompressed_size', $v_binary_data);
1887
1888  $p_header['compression'] = ord($v_data_header['cm']);
1889  $p_header['crc'] = $v_data_footer['crc'];
1890  $p_header['compressed_size'] = filesize($v_gzip_temp_name)-18;
1891
1892  @fclose($v_file_compressed);
1893
1894  if (($v_result = $this->privWriteFileHeader($p_header)) != 1) {
1895    return $v_result;
1896  }
1897
1898  if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0)
1899  {
1900    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
1901    return PclZip::errorCode();
1902  }
1903
1904  fseek($v_file_compressed, 10);
1905  $v_size = $p_header['compressed_size'];
1906  while ($v_size != 0)
1907  {
1908    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
1909    $v_buffer = @fread($v_file_compressed, $v_read_size);
1910    @fwrite($this->zip_fd, $v_buffer, $v_read_size);
1911    $v_size -= $v_read_size;
1912  }
1913
1914  @fclose($v_file_compressed);
1915
1916  @unlink($v_gzip_temp_name);
1917 
1918  return $v_result;
1919}
1920
1921function privCalculateStoredFilename(&$p_filedescr, &$p_options)
1922{
1923  $v_result=1;
1924 
1925  $p_filename = $p_filedescr['filename'];
1926  if (isset($p_options[PCLZIP_OPT_ADD_PATH])) {
1927    $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH];
1928  }
1929  else {
1930    $p_add_dir = '';
1931  }
1932  if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) {
1933    $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH];
1934  }
1935  else {
1936    $p_remove_dir = '';
1937  }
1938  if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) {
1939    $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH];
1940  }
1941  else {
1942    $p_remove_all_dir = 0;
1943  }
1944
1945  if (isset($p_filedescr['new_full_name'])) {
1946    $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name']);
1947  }
1948 
1949  else {
1950
1951    if (isset($p_filedescr['new_short_name'])) {
1952      $v_path_info = pathinfo($p_filename);
1953      $v_dir = '';
1954      if ($v_path_info['dirname'] != '') {
1955        $v_dir = $v_path_info['dirname'].'/';
1956      }
1957      $v_stored_filename = $v_dir.$p_filedescr['new_short_name'];
1958    }
1959    else {
1960      $v_stored_filename = $p_filename;
1961    }
1962
1963    if ($p_remove_all_dir) {
1964      $v_stored_filename = basename($p_filename);
1965    }
1966    else if ($p_remove_dir != "") {
1967      if (substr($p_remove_dir, -1) != '/')
1968        $p_remove_dir .= "/";
1969
1970      if (   (substr($p_filename, 0, 2) == "./")
1971          || (substr($p_remove_dir, 0, 2) == "./")) {
1972         
1973        if (   (substr($p_filename, 0, 2) == "./")
1974            && (substr($p_remove_dir, 0, 2) != "./")) {
1975          $p_remove_dir = "./".$p_remove_dir;
1976        }
1977        if (   (substr($p_filename, 0, 2) != "./")
1978            && (substr($p_remove_dir, 0, 2) == "./")) {
1979          $p_remove_dir = substr($p_remove_dir, 2);
1980        }
1981      }
1982
1983      $v_compare = PclZipUtilPathInclusion($p_remove_dir,
1984                                           $v_stored_filename);
1985      if ($v_compare > 0) {
1986        if ($v_compare == 2) {
1987          $v_stored_filename = "";
1988        }
1989        else {
1990          $v_stored_filename = substr($v_stored_filename,
1991                                      strlen($p_remove_dir));
1992        }
1993      }
1994    }
1995   
1996    $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename);
1997   
1998    if ($p_add_dir != "") {
1999      if (substr($p_add_dir, -1) == "/")
2000        $v_stored_filename = $p_add_dir.$v_stored_filename;
2001      else
2002        $v_stored_filename = $p_add_dir."/".$v_stored_filename;
2003    }
2004  }
2005
2006  $v_stored_filename = PclZipUtilPathReduction($v_stored_filename);
2007  $p_filedescr['stored_filename'] = $v_stored_filename;
2008 
2009  return $v_result;
2010}
2011
2012function privWriteFileHeader(&$p_header)
2013{
2014  $v_result=1;
2015
2016  $p_header['offset'] = ftell($this->zip_fd);
2017
2018  $v_date = getdate($p_header['mtime']);
2019  $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2020  $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2021
2022  $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50,
2023                      $p_header['version_extracted'], $p_header['flag'],
2024                        $p_header['compression'], $v_mtime, $v_mdate,
2025                        $p_header['crc'], $p_header['compressed_size'],
2026            $p_header['size'],
2027                        strlen($p_header['stored_filename']),
2028            $p_header['extra_len']);
2029
2030  fputs($this->zip_fd, $v_binary_data, 30);
2031
2032  if (strlen($p_header['stored_filename']) != 0)
2033  {
2034    fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2035  }
2036  if ($p_header['extra_len'] != 0)
2037  {
2038    fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2039  }
2040
2041  return $v_result;
2042}
2043
2044function privWriteCentralFileHeader(&$p_header)
2045{
2046  $v_result=1;
2047
2048
2049  $v_date = getdate($p_header['mtime']);
2050  $v_mtime = ($v_date['hours']<<11) + ($v_date['minutes']<<5) + $v_date['seconds']/2;
2051  $v_mdate = (($v_date['year']-1980)<<9) + ($v_date['mon']<<5) + $v_date['mday'];
2052
2053
2054  $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50,
2055                      $p_header['version'], $p_header['version_extracted'],
2056                        $p_header['flag'], $p_header['compression'],
2057            $v_mtime, $v_mdate, $p_header['crc'],
2058                        $p_header['compressed_size'], $p_header['size'],
2059                        strlen($p_header['stored_filename']),
2060            $p_header['extra_len'], $p_header['comment_len'],
2061                        $p_header['disk'], $p_header['internal'],
2062            $p_header['external'], $p_header['offset']);
2063
2064  fputs($this->zip_fd, $v_binary_data, 46);
2065
2066  if (strlen($p_header['stored_filename']) != 0)
2067  {
2068    fputs($this->zip_fd, $p_header['stored_filename'], strlen($p_header['stored_filename']));
2069  }
2070  if ($p_header['extra_len'] != 0)
2071  {
2072    fputs($this->zip_fd, $p_header['extra'], $p_header['extra_len']);
2073  }
2074  if ($p_header['comment_len'] != 0)
2075  {
2076    fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len']);
2077  }
2078
2079  return $v_result;
2080}
2081
2082function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
2083{
2084  $v_result=1;
2085
2086  $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries,
2087                      $p_nb_entries, $p_size,
2088            $p_offset, strlen($p_comment));
2089
2090  fputs($this->zip_fd, $v_binary_data, 22);
2091
2092  if (strlen($p_comment) != 0)
2093  {
2094    fputs($this->zip_fd, $p_comment, strlen($p_comment));
2095  }
2096
2097  return $v_result;
2098}
2099
2100function privList(&$p_list)
2101{
2102  $v_result=1;
2103
2104  $this->privDisableMagicQuotes();
2105
2106  if (($this->zip_fd = @fopen($this->zipname, 'rb')) == 0)
2107  {
2108    $this->privSwapBackMagicQuotes();
2109   
2110    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive \''.$this->zipname.'\' in binary read mode');
2111
2112    return PclZip::errorCode();
2113  }
2114
2115  $v_central_dir = array();
2116  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2117  {
2118    $this->privSwapBackMagicQuotes();
2119    return $v_result;
2120  }
2121
2122  @rewind($this->zip_fd);
2123  if (@fseek($this->zip_fd, $v_central_dir['offset']))
2124  {
2125    $this->privSwapBackMagicQuotes();
2126
2127    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
2128
2129    return PclZip::errorCode();
2130  }
2131
2132  for ($i=0; $i<$v_central_dir['entries']; $i++)
2133  {
2134    if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
2135    {
2136      $this->privSwapBackMagicQuotes();
2137      return $v_result;
2138    }
2139    $v_header['index'] = $i;
2140
2141    $this->privConvertHeader2FileInfo($v_header, $p_list[$i]);
2142    unset($v_header);
2143  }
2144
2145  $this->privCloseFd();
2146
2147  $this->privSwapBackMagicQuotes();
2148
2149  return $v_result;
2150}
2151
2152function privConvertHeader2FileInfo($p_header, &$p_info)
2153{
2154  $v_result=1;
2155
2156  $v_temp_path = PclZipUtilPathReduction($p_header['filename']);
2157  $p_info['filename'] = $v_temp_path;
2158  $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename']);
2159  $p_info['stored_filename'] = $v_temp_path;
2160  $p_info['size'] = $p_header['size'];
2161  $p_info['compressed_size'] = $p_header['compressed_size'];
2162  $p_info['mtime'] = $p_header['mtime'];
2163  $p_info['comment'] = $p_header['comment'];
2164  $p_info['folder'] = (($p_header['external']&0x00000010)==0x00000010);
2165  $p_info['index'] = $p_header['index'];
2166  $p_info['status'] = $p_header['status'];
2167  $p_info['crc'] = $p_header['crc'];
2168
2169  return $v_result;
2170}
2171
2172function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
2173{
2174  $v_result=1;
2175
2176  $this->privDisableMagicQuotes();
2177
2178  if (   ($p_path == "")
2179    || (   (substr($p_path, 0, 1) != "/")
2180      && (substr($p_path, 0, 3) != "../")
2181    && (substr($p_path,1,2)!=":/")))
2182    $p_path = "./".$p_path;
2183
2184  if (($p_path != "./") && ($p_path != "/"))
2185  {
2186    while (substr($p_path, -1) == "/")
2187    {
2188      $p_path = substr($p_path, 0, strlen($p_path)-1);
2189    }
2190  }
2191
2192  if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/'))
2193  {
2194    $p_remove_path .= '/';
2195  }
2196  $p_remove_path_size = strlen($p_remove_path);
2197
2198  if (($v_result = $this->privOpenFd('rb')) != 1)
2199  {
2200    $this->privSwapBackMagicQuotes();
2201    return $v_result;
2202  }
2203
2204  $v_central_dir = array();
2205  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
2206  {
2207    $this->privCloseFd();
2208    $this->privSwapBackMagicQuotes();
2209
2210    return $v_result;
2211  }
2212
2213  $v_pos_entry = $v_central_dir['offset'];
2214
2215  $j_start = 0;
2216  for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
2217  {
2218
2219    @rewind($this->zip_fd);
2220    if (@fseek($this->zip_fd, $v_pos_entry))
2221    {
2222      $this->privCloseFd();
2223      $this->privSwapBackMagicQuotes();
2224
2225      PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
2226
2227      return PclZip::errorCode();
2228    }
2229
2230    $v_header = array();
2231    if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1)
2232    {
2233      $this->privCloseFd();
2234      $this->privSwapBackMagicQuotes();
2235
2236      return $v_result;
2237    }
2238
2239    $v_header['index'] = $i;
2240
2241    $v_pos_entry = ftell($this->zip_fd);
2242
2243    $v_extract = false;
2244
2245    if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
2246        && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
2247
2248        for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) {
2249
2250            if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
2251
2252                if (   (strlen($v_header['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
2253                    && (substr($v_header['stored_filename'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
2254                    $v_extract = true;
2255                }
2256            }
2257            elseif ($v_header['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
2258                $v_extract = true;
2259            }
2260        }
2261    }
2262
2263    else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
2264             && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
2265
2266        if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename'])) {
2267            $v_extract = true;
2268        }
2269    }
2270
2271    else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
2272             && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
2273       
2274        for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) {
2275
2276            if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
2277                $v_extract = true;
2278            }
2279            if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
2280                $j_start = $j+1;
2281            }
2282
2283            if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
2284                break;
2285            }
2286        }
2287    }
2288
2289    else {
2290        $v_extract = true;
2291    }
2292
2293  if (   ($v_extract)
2294      && (   ($v_header['compression'] != 8)
2295        && ($v_header['compression'] != 0))) {
2296        $v_header['status'] = 'unsupported_compression';
2297
2298        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
2299        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
2300
2301            $this->privSwapBackMagicQuotes();
2302           
2303            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION,
2304                           "Filename '".$v_header['stored_filename']."' is "
2305                       ."compressed by an unsupported compression "
2306                       ."method (".$v_header['compression'].") ");
2307
2308            return PclZip::errorCode();
2309    }
2310  }
2311 
2312  if (($v_extract) && (($v_header['flag'] & 1) == 1)) {
2313        $v_header['status'] = 'unsupported_encryption';
2314
2315        if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
2316        && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
2317
2318            $this->privSwapBackMagicQuotes();
2319
2320            PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION,
2321                           "Unsupported encryption for "
2322                       ." filename '".$v_header['stored_filename']
2323                 ."'");
2324
2325            return PclZip::errorCode();
2326    }
2327  }
2328
2329    if (($v_extract) && ($v_header['status'] != 'ok')) {
2330        $v_result = $this->privConvertHeader2FileInfo($v_header,
2331                                          $p_file_list[$v_nb_extracted++]);
2332        if ($v_result != 1) {
2333            $this->privCloseFd();
2334            $this->privSwapBackMagicQuotes();
2335            return $v_result;
2336        }
2337
2338        $v_extract = false;
2339    }
2340   
2341    if ($v_extract)
2342    {
2343
2344      @rewind($this->zip_fd);
2345      if (@fseek($this->zip_fd, $v_header['offset']))
2346      {
2347        $this->privCloseFd();
2348
2349        $this->privSwapBackMagicQuotes();
2350
2351        PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
2352
2353        return PclZip::errorCode();
2354      }
2355
2356      if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) {
2357
2358        $v_result1 = $this->privExtractFileAsString($v_header, $v_string);
2359        if ($v_result1 < 1) {
2360          $this->privCloseFd();
2361          $this->privSwapBackMagicQuotes();
2362          return $v_result1;
2363        }
2364
2365        if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1)
2366        {
2367          $this->privCloseFd();
2368          $this->privSwapBackMagicQuotes();
2369
2370          return $v_result;
2371        }
2372
2373        $p_file_list[$v_nb_extracted]['content'] = $v_string;
2374
2375        $v_nb_extracted++;
2376       
2377        if ($v_result1 == 2) {
2378          break;
2379        }
2380      }
2381      elseif (   (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT]))
2382          && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) {
2383        $v_result1 = $this->privExtractFileInOutput($v_header, $p_options);
2384        if ($v_result1 < 1) {
2385          $this->privCloseFd();
2386          $this->privSwapBackMagicQuotes();
2387          return $v_result1;
2388        }
2389
2390        if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) {
2391          $this->privCloseFd();
2392          $this->privSwapBackMagicQuotes();
2393          return $v_result;
2394        }
2395
2396        if ($v_result1 == 2) {
2397          break;
2398        }
2399      }
2400      else {
2401        $v_result1 = $this->privExtractFile($v_header,
2402                                        $p_path, $p_remove_path,
2403                      $p_remove_all_path,
2404                      $p_options);
2405        if ($v_result1 < 1) {
2406          $this->privCloseFd();
2407          $this->privSwapBackMagicQuotes();
2408          return $v_result1;
2409        }
2410
2411        if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1)
2412        {
2413          $this->privCloseFd();
2414          $this->privSwapBackMagicQuotes();
2415
2416          return $v_result;
2417        }
2418
2419        if ($v_result1 == 2) {
2420          break;
2421        }
2422      }
2423    }
2424  }
2425
2426  $this->privCloseFd();
2427  $this->privSwapBackMagicQuotes();
2428
2429  return $v_result;
2430}
2431
2432function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
2433{
2434  $v_result=1;
2435
2436  if (($v_result = $this->privReadFileHeader($v_header)) != 1)
2437  {
2438    return $v_result;
2439  }
2440
2441
2442  if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
2443  }
2444
2445  if ($p_remove_all_path == true) {
2446      if (($p_entry['external']&0x00000010)==0x00000010) {
2447
2448          $p_entry['status'] = "filtered";
2449
2450          return $v_result;
2451      }
2452
2453      $p_entry['filename'] = basename($p_entry['filename']);
2454  }
2455
2456  else if ($p_remove_path != "")
2457  {
2458    if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename']) == 2)
2459    {
2460
2461      $p_entry['status'] = "filtered";
2462
2463      return $v_result;
2464    }
2465
2466    $p_remove_path_size = strlen($p_remove_path);
2467    if (substr($p_entry['filename'], 0, $p_remove_path_size) == $p_remove_path)
2468    {
2469
2470      $p_entry['filename'] = substr($p_entry['filename'], $p_remove_path_size);
2471
2472    }
2473  }
2474
2475  if ($p_path != '') {
2476    $p_entry['filename'] = $p_path."/".$p_entry['filename'];
2477  }
2478 
2479  if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) {
2480    $v_inclusion
2481    = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION],
2482                              $p_entry['filename']); 
2483    if ($v_inclusion == 0) {
2484
2485      PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION,
2486                         "Filename '".$p_entry['filename']."' is "
2487               ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION");
2488
2489      return PclZip::errorCode();
2490    }
2491  }
2492
2493  if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
2494
2495    $v_local_header = array();
2496    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
2497
2498    eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
2499    if ($v_result == 0) {
2500      $p_entry['status'] = "skipped";
2501      $v_result = 1;
2502    }
2503   
2504    if ($v_result == 2) {
2505      $p_entry['status'] = "aborted";
2506      $v_result = PCLZIP_ERR_USER_ABORTED;
2507    }
2508
2509    $p_entry['filename'] = $v_local_header['filename'];
2510  }
2511
2512
2513  if ($p_entry['status'] == 'ok') {
2514
2515  if (file_exists($p_entry['filename']))
2516  {
2517
2518    if (is_dir($p_entry['filename']))
2519    {
2520
2521      $p_entry['status'] = "already_a_directory";
2522     
2523      if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
2524      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
2525
2526          PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY,
2527                         "Filename '".$p_entry['filename']."' is "
2528               ."already used by an existing directory");
2529
2530          return PclZip::errorCode();
2531      }
2532    }
2533    else if (!is_writeable($p_entry['filename']))
2534    {
2535
2536      $p_entry['status'] = "write_protected";
2537
2538      if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
2539      && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
2540
2541          PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
2542                         "Filename '".$p_entry['filename']."' exists "
2543               ."and is write protected");
2544
2545          return PclZip::errorCode();
2546      }
2547    }
2548
2549    else if (filemtime($p_entry['filename']) > $p_entry['mtime'])
2550    {
2551      if (   (isset($p_options[PCLZIP_OPT_REPLACE_NEWER]))
2552      && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) {
2553      }
2554      else {
2555          $p_entry['status'] = "newer_exist";
2556
2557          if (   (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR]))
2558          && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) {
2559
2560              PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL,
2561                 "Newer version of '".$p_entry['filename']."' exists "
2562            ."and option PCLZIP_OPT_REPLACE_NEWER is not selected");
2563
2564              return PclZip::errorCode();
2565        }
2566      }
2567    }
2568    else {
2569    }
2570  }
2571
2572  else {
2573    if ((($p_entry['external']&0x00000010)==0x00000010) || (substr($p_entry['filename'], -1) == '/'))
2574      $v_dir_to_check = $p_entry['filename'];
2575    else if (!strstr($p_entry['filename'], "/"))
2576      $v_dir_to_check = "";
2577    else
2578      $v_dir_to_check = dirname($p_entry['filename']);
2579
2580      if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external']&0x00000010)==0x00000010))) != 1) {
2581
2582        $p_entry['status'] = "path_creation_fail";
2583
2584        $v_result = 1;
2585      }
2586    }
2587  }
2588
2589  if ($p_entry['status'] == 'ok') {
2590
2591    if (!(($p_entry['external']&0x00000010)==0x00000010))
2592    {
2593      if ($p_entry['compression'] == 0) {
2594
2595        if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0)
2596        {
2597
2598          $p_entry['status'] = "write_error";
2599
2600          return $v_result;
2601        }
2602
2603
2604        $v_size = $p_entry['compressed_size'];
2605        while ($v_size != 0)
2606        {
2607          $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2608          $v_buffer = @fread($this->zip_fd, $v_read_size);
2609          /* Try to speed up the code
2610          $v_binary_data = pack('a'.$v_read_size, $v_buffer);
2611          @fwrite($v_dest_file, $v_binary_data, $v_read_size);
2612          */
2613          @fwrite($v_dest_file, $v_buffer, $v_read_size);           
2614          $v_size -= $v_read_size;
2615        }
2616
2617        fclose($v_dest_file);
2618
2619        touch($p_entry['filename'], $p_entry['mtime']);
2620       
2621
2622      }
2623      else {
2624        if (($p_entry['flag'] & 1) == 1) {
2625          PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \''.$p_entry['filename'].'\' is encrypted. Encrypted files are not supported.');
2626          return PclZip::errorCode();
2627        }
2628
2629
2630        if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 
2631            && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON])
2632                || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD])
2633                    && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size'])) ) ) {
2634          $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options);
2635          if ($v_result < PCLZIP_ERR_NO_ERROR) {
2636            return $v_result;
2637          }
2638        }
2639       
2640        else {
2641
2642       
2643          $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
2644         
2645          $v_file_content = @gzinflate($v_buffer);
2646          unset($v_buffer);
2647          if ($v_file_content === FALSE) {
2648
2649            $p_entry['status'] = "error";
2650           
2651            return $v_result;
2652          }
2653         
2654          if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
2655
2656            $p_entry['status'] = "write_error";
2657
2658            return $v_result;
2659          }
2660
2661          @fwrite($v_dest_file, $v_file_content, $p_entry['size']);
2662          unset($v_file_content);
2663
2664          @fclose($v_dest_file);
2665         
2666        }
2667
2668        @touch($p_entry['filename'], $p_entry['mtime']);
2669      }
2670
2671      if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) {
2672
2673        @chmod($p_entry['filename'], $p_options[PCLZIP_OPT_SET_CHMOD]);
2674      }
2675
2676    }
2677  }
2678
2679if ($p_entry['status'] == "aborted") {
2680    $p_entry['status'] = "skipped";
2681}
2682
2683  elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
2684
2685    $v_local_header = array();
2686    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
2687
2688    eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
2689
2690    if ($v_result == 2) {
2691      $v_result = PCLZIP_ERR_USER_ABORTED;
2692    }
2693  }
2694
2695  return $v_result;
2696}
2697
2698function privExtractFileUsingTempFile(&$p_entry, &$p_options)
2699{
2700  $v_result=1;
2701     
2702  $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.gz';
2703  if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) {
2704    fclose($v_file);
2705    PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary write mode');
2706    return PclZip::errorCode();
2707  }
2708
2709
2710  $v_binary_data = pack('va1a1Va1a1', 0x8b1f, Chr($p_entry['compression']), Chr(0x00), time(), Chr(0x00), Chr(3));
2711  @fwrite($v_dest_file, $v_binary_data, 10);
2712
2713  $v_size = $p_entry['compressed_size'];
2714  while ($v_size != 0)
2715  {
2716    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2717    $v_buffer = @fread($this->zip_fd, $v_read_size);
2718    @fwrite($v_dest_file, $v_buffer, $v_read_size);
2719    $v_size -= $v_read_size;
2720  }
2721
2722  $v_binary_data = pack('VV', $p_entry['crc'], $p_entry['size']);
2723  @fwrite($v_dest_file, $v_binary_data, 8);
2724
2725  @fclose($v_dest_file);
2726
2727  if (($v_dest_file = @fopen($p_entry['filename'], 'wb')) == 0) {
2728    $p_entry['status'] = "write_error";
2729    return $v_result;
2730  }
2731
2732  if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb')) == 0) {
2733    @fclose($v_dest_file);
2734    $p_entry['status'] = "read_error";
2735    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_gzip_temp_name.'\' in binary read mode');
2736    return PclZip::errorCode();
2737  }
2738
2739
2740  $v_size = $p_entry['size'];
2741  while ($v_size != 0) {
2742    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
2743    $v_buffer = @gzread($v_src_file, $v_read_size);
2744    @fwrite($v_dest_file, $v_buffer, $v_read_size);
2745    $v_size -= $v_read_size;
2746  }
2747  @fclose($v_dest_file);
2748  @gzclose($v_src_file);
2749
2750  @unlink($v_gzip_temp_name);
2751 
2752  return $v_result;
2753}
2754
2755function privExtractFileInOutput(&$p_entry, &$p_options)
2756{
2757  $v_result=1;
2758
2759  if (($v_result = $this->privReadFileHeader($v_header)) != 1) {
2760    return $v_result;
2761  }
2762
2763
2764  if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
2765  }
2766
2767  if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) {
2768
2769    $v_local_header = array();
2770    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
2771
2772    eval('$v_result = '.$p_options[PCLZIP_CB_PRE_EXTRACT].'(PCLZIP_CB_PRE_EXTRACT, $v_local_header);');
2773    if ($v_result == 0) {
2774      $p_entry['status'] = "skipped";
2775      $v_result = 1;
2776    }
2777
2778    if ($v_result == 2) {
2779      $p_entry['status'] = "aborted";
2780      $v_result = PCLZIP_ERR_USER_ABORTED;
2781    }
2782
2783    $p_entry['filename'] = $v_local_header['filename'];
2784  }
2785
2786
2787  if ($p_entry['status'] == 'ok') {
2788
2789    if (!(($p_entry['external']&0x00000010)==0x00000010)) {
2790      if ($p_entry['compressed_size'] == $p_entry['size']) {
2791
2792        $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
2793
2794        echo $v_buffer;
2795        unset($v_buffer);
2796      }
2797      else {
2798
2799        $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size']);
2800       
2801        $v_file_content = gzinflate($v_buffer);
2802        unset($v_buffer);
2803
2804        echo $v_file_content;
2805        unset($v_file_content);
2806      }
2807    }
2808  }
2809
2810if ($p_entry['status'] == "aborted") {
2811    $p_entry['status'] = "skipped";
2812}
2813
2814  elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) {
2815
2816    $v_local_header = array();
2817    $this->privConvertHeader2FileInfo($p_entry, $v_local_header);
2818
2819    eval('$v_result = '.$p_options[PCLZIP_CB_POST_EXTRACT].'(PCLZIP_CB_POST_EXTRACT, $v_local_header);');
2820
2821    if ($v_result == 2) {
2822      $v_result = PCLZIP_ERR_USER_ABORTED;
2823    }
2824  }
2825
2826  return $v_result;
2827}
2828
2829function privExtractFileAsString(&$p_entry, &$p_string)
2830{
2831  $v_result=1;
2832
2833  $v_header = array();
2834  if (($v_result = $this->privReadFileHeader($v_header)) != 1)
2835  {
2836    return $v_result;
2837  }
2838
2839
2840  if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) {
2841  }
2842
2843
2844  if (!(($p_entry['external']&0x00000010)==0x00000010))
2845  {
2846    if ($p_entry['compression'] == 0) {
2847
2848      $p_string = @fread($this->zip_fd, $p_entry['compressed_size']);
2849    }
2850    else {
2851
2852      $v_data = @fread($this->zip_fd, $p_entry['compressed_size']);
2853     
2854      if (($p_string = @gzinflate($v_data)) === FALSE) {
2855      }
2856    }
2857
2858  }
2859  else {
2860  }
2861
2862  return $v_result;
2863}
2864
2865function privReadFileHeader(&$p_header)
2866{
2867  $v_result=1;
2868
2869  $v_binary_data = @fread($this->zip_fd, 4);
2870  $v_data = unpack('Vid', $v_binary_data);
2871
2872  if ($v_data['id'] != 0x04034b50)
2873  {
2874
2875    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
2876
2877    return PclZip::errorCode();
2878  }
2879
2880  $v_binary_data = fread($this->zip_fd, 26);
2881
2882  if (strlen($v_binary_data) != 26)
2883  {
2884    $p_header['filename'] = "";
2885    $p_header['status'] = "invalid_header";
2886
2887    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
2888
2889    return PclZip::errorCode();
2890  }
2891
2892  $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len', $v_binary_data);
2893
2894  $p_header['filename'] = fread($this->zip_fd, $v_data['filename_len']);
2895
2896  if ($v_data['extra_len'] != 0) {
2897    $p_header['extra'] = fread($this->zip_fd, $v_data['extra_len']);
2898  }
2899  else {
2900    $p_header['extra'] = '';
2901  }
2902
2903  $p_header['version_extracted'] = $v_data['version'];
2904  $p_header['compression'] = $v_data['compression'];
2905  $p_header['size'] = $v_data['size'];
2906  $p_header['compressed_size'] = $v_data['compressed_size'];
2907  $p_header['crc'] = $v_data['crc'];
2908  $p_header['flag'] = $v_data['flag'];
2909  $p_header['filename_len'] = $v_data['filename_len'];
2910
2911  $p_header['mdate'] = $v_data['mdate'];
2912  $p_header['mtime'] = $v_data['mtime'];
2913  if ($p_header['mdate'] && $p_header['mtime'])
2914  {
2915    $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
2916    $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
2917    $v_seconde = ($p_header['mtime'] & 0x001F)*2;
2918
2919    $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
2920    $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
2921    $v_day = $p_header['mdate'] & 0x001F;
2922
2923    $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
2924
2925  }
2926  else
2927  {
2928    $p_header['mtime'] = time();
2929  }
2930
2931
2932  $p_header['stored_filename'] = $p_header['filename'];
2933
2934  $p_header['status'] = "ok";
2935
2936  return $v_result;
2937}
2938
2939function privReadCentralFileHeader(&$p_header)
2940{
2941  $v_result=1;
2942
2943  $v_binary_data = @fread($this->zip_fd, 4);
2944  $v_data = unpack('Vid', $v_binary_data);
2945
2946  if ($v_data['id'] != 0x02014b50)
2947  {
2948
2949    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure');
2950
2951    return PclZip::errorCode();
2952  }
2953
2954  $v_binary_data = fread($this->zip_fd, 42);
2955
2956  if (strlen($v_binary_data) != 42)
2957  {
2958    $p_header['filename'] = "";
2959    $p_header['status'] = "invalid_header";
2960
2961    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data));
2962
2963    return PclZip::errorCode();
2964  }
2965
2966  $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);
2967
2968  if ($p_header['filename_len'] != 0)
2969    $p_header['filename'] = fread($this->zip_fd, $p_header['filename_len']);
2970  else
2971    $p_header['filename'] = '';
2972
2973  if ($p_header['extra_len'] != 0)
2974    $p_header['extra'] = fread($this->zip_fd, $p_header['extra_len']);
2975  else
2976    $p_header['extra'] = '';
2977
2978  if ($p_header['comment_len'] != 0)
2979    $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len']);
2980  else
2981    $p_header['comment'] = '';
2982
2983
2984  if (1)
2985  {
2986    $v_hour = ($p_header['mtime'] & 0xF800) >> 11;
2987    $v_minute = ($p_header['mtime'] & 0x07E0) >> 5;
2988    $v_seconde = ($p_header['mtime'] & 0x001F)*2;
2989
2990    $v_year = (($p_header['mdate'] & 0xFE00) >> 9) + 1980;
2991    $v_month = ($p_header['mdate'] & 0x01E0) >> 5;
2992    $v_day = $p_header['mdate'] & 0x001F;
2993
2994    $p_header['mtime'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year);
2995
2996  }
2997  else
2998  {
2999    $p_header['mtime'] = time();
3000  }
3001
3002  $p_header['stored_filename'] = $p_header['filename'];
3003
3004  $p_header['status'] = 'ok';
3005
3006  if (substr($p_header['filename'], -1) == '/') {
3007    $p_header['external'] = 0x00000010;
3008  }
3009
3010
3011  return $v_result;
3012}
3013
3014function privCheckFileHeaders(&$p_local_header, &$p_central_header)
3015{
3016  $v_result=1;
3017
3018  if ($p_local_header['filename'] != $p_central_header['filename']) {
3019  }
3020  if ($p_local_header['version_extracted'] != $p_central_header['version_extracted']) {
3021  }
3022  if ($p_local_header['flag'] != $p_central_header['flag']) {
3023  }
3024  if ($p_local_header['compression'] != $p_central_header['compression']) {
3025  }
3026  if ($p_local_header['mtime'] != $p_central_header['mtime']) {
3027  }
3028  if ($p_local_header['filename_len'] != $p_central_header['filename_len']) {
3029  }
3030
3031  if (($p_local_header['flag'] & 8) == 8) {
3032        $p_local_header['size'] = $p_central_header['size'];
3033        $p_local_header['compressed_size'] = $p_central_header['compressed_size'];
3034        $p_local_header['crc'] = $p_central_header['crc'];
3035  }
3036
3037  return $v_result;
3038}
3039
3040function privReadEndCentralDir(&$p_central_dir)
3041{
3042  $v_result=1;
3043
3044  $v_size = filesize($this->zipname);
3045  @fseek($this->zip_fd, $v_size);
3046  if (@ftell($this->zip_fd) != $v_size)
3047  {
3048    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to go to the end of the archive \''.$this->zipname.'\'');
3049
3050    return PclZip::errorCode();
3051  }
3052
3053  $v_found = 0;
3054  if ($v_size > 26) {
3055    @fseek($this->zip_fd, $v_size-22);
3056    if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
3057    {
3058      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
3059
3060      return PclZip::errorCode();
3061    }
3062
3063    $v_binary_data = @fread($this->zip_fd, 4);
3064    $v_data = @unpack('Vid', $v_binary_data);
3065
3066    if ($v_data['id'] == 0x06054b50) {
3067      $v_found = 1;
3068    }
3069
3070    $v_pos = ftell($this->zip_fd);
3071  }
3072
3073  if (!$v_found) {
3074    if ($v_maximum_size > $v_size)
3075      $v_maximum_size = $v_size;
3076    @fseek($this->zip_fd, $v_size-$v_maximum_size);
3077    if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
3078    {
3079      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable to seek back to the middle of the archive \''.$this->zipname.'\'');
3080
3081      return PclZip::errorCode();
3082    }
3083
3084    $v_pos = ftell($this->zip_fd);
3085    $v_bytes = 0x00000000;
3086    while ($v_pos < $v_size)
3087    {
3088      $v_byte = @fread($this->zip_fd, 1);
3089
3090      $v_bytes = ($v_bytes << 8) | Ord($v_byte);
3091
3092      if ($v_bytes == 0x504b0506)
3093      {
3094        $v_pos++;
3095        break;
3096      }
3097
3098      $v_pos++;
3099    }
3100
3101    if ($v_pos == $v_size)
3102    {
3103
3104      PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Unable to find End of Central Dir Record signature");
3105
3106      return PclZip::errorCode();
3107    }
3108  }
3109
3110  $v_binary_data = fread($this->zip_fd, 18);
3111
3112  if (strlen($v_binary_data) != 18)
3113  {
3114
3115    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid End of Central Dir Record size : ".strlen($v_binary_data));
3116
3117    return PclZip::errorCode();
3118  }
3119
3120  $v_data = unpack('vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
3121
3122  if (($v_pos + $v_data['comment_size'] + 18) != $v_size) {
3123
3124  if (0) {
3125    PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT,
3126                       'The central dir is not at the end of the archive.'
3127             .' Some trailing bytes exists after the archive.');
3128
3129    return PclZip::errorCode();
3130  }
3131  }
3132
3133  if ($v_data['comment_size'] != 0) {
3134    $p_central_dir['comment'] = fread($this->zip_fd, $v_data['comment_size']);
3135  }
3136  else
3137    $p_central_dir['comment'] = '';
3138
3139  $p_central_dir['entries'] = $v_data['entries'];
3140  $p_central_dir['disk_entries'] = $v_data['disk_entries'];
3141  $p_central_dir['offset'] = $v_data['offset'];
3142  $p_central_dir['size'] = $v_data['size'];
3143  $p_central_dir['disk'] = $v_data['disk'];
3144  $p_central_dir['disk_start'] = $v_data['disk_start'];
3145
3146
3147  return $v_result;
3148}
3149
3150function privDeleteByRule(&$p_result_list, &$p_options)
3151{
3152  $v_result=1;
3153  $v_list_detail = array();
3154
3155  if (($v_result=$this->privOpenFd('rb')) != 1)
3156  {
3157    return $v_result;
3158  }
3159
3160  $v_central_dir = array();
3161  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3162  {
3163    $this->privCloseFd();
3164    return $v_result;
3165  }
3166
3167  @rewind($this->zip_fd);
3168
3169  $v_pos_entry = $v_central_dir['offset'];
3170  @rewind($this->zip_fd);
3171  if (@fseek($this->zip_fd, $v_pos_entry))
3172  {
3173    $this->privCloseFd();
3174
3175    PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3176
3177    return PclZip::errorCode();
3178  }
3179
3180  $v_header_list = array();
3181  $j_start = 0;
3182  for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries']; $i++)
3183  {
3184
3185    $v_header_list[$v_nb_extracted] = array();
3186    if (($v_result = $this->privReadCentralFileHeader($v_header_list[$v_nb_extracted])) != 1)
3187    {
3188      $this->privCloseFd();
3189
3190      return $v_result;
3191    }
3192
3193
3194    $v_header_list[$v_nb_extracted]['index'] = $i;
3195
3196    $v_found = false;
3197
3198    if (   (isset($p_options[PCLZIP_OPT_BY_NAME]))
3199        && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
3200
3201        for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_found); $j++) {
3202
3203            if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") {
3204
3205                if (   (strlen($v_header_list[$v_nb_extracted]['stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
3206                    && (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])) {
3207                    $v_found = true;
3208                }
3209                elseif (   (($v_header_list[$v_nb_extracted]['external']&0x00000010)==0x00000010) /* Indicates a folder */
3210                        && ($v_header_list[$v_nb_extracted]['stored_filename'].'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
3211                    $v_found = true;
3212                }
3213            }
3214            elseif ($v_header_list[$v_nb_extracted]['stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
3215                $v_found = true;
3216            }
3217        }
3218    }
3219
3220    else if (   (isset($p_options[PCLZIP_OPT_BY_PREG]))
3221             && ($p_options[PCLZIP_OPT_BY_PREG] != "")) {
3222
3223        if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted]['stored_filename'])) {
3224            $v_found = true;
3225        }
3226    }
3227
3228    else if (   (isset($p_options[PCLZIP_OPT_BY_INDEX]))
3229             && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
3230
3231        for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_found); $j++) {
3232
3233            if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end'])) {
3234                $v_found = true;
3235            }
3236            if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end']) {
3237                $j_start = $j+1;
3238            }
3239
3240            if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start']>$i) {
3241                break;
3242            }
3243        }
3244    }
3245    else {
3246      $v_found = true;
3247    }
3248
3249    if ($v_found)
3250    {
3251      unset($v_header_list[$v_nb_extracted]);
3252    }
3253    else
3254    {
3255      $v_nb_extracted++;
3256    }
3257  }
3258
3259  if ($v_nb_extracted > 0) {
3260
3261      $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
3262
3263      $v_temp_zip = new PclZip($v_zip_temp_name);
3264
3265      if (($v_result = $v_temp_zip->privOpenFd('wb')) != 1) {
3266          $this->privCloseFd();
3267
3268          return $v_result;
3269      }
3270
3271      for ($i=0; $i<sizeof($v_header_list); $i++) {
3272
3273          @rewind($this->zip_fd);
3274          if (@fseek($this->zip_fd,  $v_header_list[$i]['offset'])) {
3275              $this->privCloseFd();
3276              $v_temp_zip->privCloseFd();
3277              @unlink($v_zip_temp_name);
3278
3279              PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive size');
3280
3281              return PclZip::errorCode();
3282          }
3283
3284          $v_local_header = array();
3285          if (($v_result = $this->privReadFileHeader($v_local_header)) != 1) {
3286              $this->privCloseFd();
3287              $v_temp_zip->privCloseFd();
3288              @unlink($v_zip_temp_name);
3289
3290              return $v_result;
3291          }
3292         
3293          if ($this->privCheckFileHeaders($v_local_header,
3294                                    $v_header_list[$i]) != 1) {
3295          }
3296          unset($v_local_header);
3297
3298          if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
3299              $this->privCloseFd();
3300              $v_temp_zip->privCloseFd();
3301              @unlink($v_zip_temp_name);
3302
3303              return $v_result;
3304          }
3305
3306          if (($v_result = PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i]['compressed_size'])) != 1) {
3307              $this->privCloseFd();
3308              $v_temp_zip->privCloseFd();
3309              @unlink($v_zip_temp_name);
3310
3311              return $v_result;
3312          }
3313      }
3314
3315      $v_offset = @ftell($v_temp_zip->zip_fd);
3316
3317      for ($i=0; $i<sizeof($v_header_list); $i++) {
3318          if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
3319              $v_temp_zip->privCloseFd();
3320              $this->privCloseFd();
3321              @unlink($v_zip_temp_name);
3322
3323              return $v_result;
3324          }
3325
3326          $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
3327      }
3328
3329
3330      $v_comment = '';
3331      if (isset($p_options[PCLZIP_OPT_COMMENT])) {
3332        $v_comment = $p_options[PCLZIP_OPT_COMMENT];
3333      }
3334
3335      $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
3336
3337      if (($v_result = $v_temp_zip->privWriteCentralHeader(sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
3338          unset($v_header_list);
3339          $v_temp_zip->privCloseFd();
3340          $this->privCloseFd();
3341          @unlink($v_zip_temp_name);
3342
3343          return $v_result;
3344      }
3345
3346      $v_temp_zip->privCloseFd();
3347      $this->privCloseFd();
3348
3349      @unlink($this->zipname);
3350
3351      PclZipUtilRename($v_zip_temp_name, $this->zipname);
3352 
3353      unset($v_temp_zip);
3354  }
3355 
3356  else if ($v_central_dir['entries'] != 0) {
3357      $this->privCloseFd();
3358
3359      if (($v_result = $this->privOpenFd('wb')) != 1) {
3360        return $v_result;
3361      }
3362
3363      if (($v_result = $this->privWriteCentralHeader(0, 0, 0, '')) != 1) {
3364        return $v_result;
3365      }
3366
3367      $this->privCloseFd();
3368  }
3369
3370  return $v_result;
3371}
3372
3373function privDirCheck($p_dir, $p_is_dir=false)
3374{
3375  $v_result = 1;
3376
3377
3378  if (($p_is_dir) && (substr($p_dir, -1)=='/'))
3379  {
3380    $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
3381  }
3382
3383  if ((is_dir($p_dir)) || ($p_dir == ""))
3384  {
3385    return 1;
3386  }
3387
3388  $p_parent_dir = dirname($p_dir);
3389
3390  if ($p_parent_dir != $p_dir)
3391  {
3392    if ($p_parent_dir != "")
3393    {
3394      if (($v_result = $this->privDirCheck($p_parent_dir)) != 1)
3395      {
3396        return $v_result;
3397      }
3398    }
3399  }
3400
3401  if (!@mkdir($p_dir, 0777))
3402  {
3403    PclZip::privErrorLog(PCLZIP_ERR_DIR_CREATE_FAIL, "Unable to create directory '$p_dir'");
3404
3405    return PclZip::errorCode();
3406  }
3407
3408  return $v_result;
3409}
3410
3411function privMerge(&$p_archive_to_add)
3412{
3413  $v_result=1;
3414
3415  if (!is_file($p_archive_to_add->zipname))
3416  {
3417
3418    $v_result = 1;
3419
3420    return $v_result;
3421  }
3422
3423  if (!is_file($this->zipname))
3424  {
3425
3426    $v_result = $this->privDuplicate($p_archive_to_add->zipname);
3427
3428    return $v_result;
3429  }
3430
3431  if (($v_result=$this->privOpenFd('rb')) != 1)
3432  {
3433    return $v_result;
3434  }
3435
3436  $v_central_dir = array();
3437  if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1)
3438  {
3439    $this->privCloseFd();
3440    return $v_result;
3441  }
3442
3443  @rewind($this->zip_fd);
3444
3445  if (($v_result=$p_archive_to_add->privOpenFd('rb')) != 1)
3446  {
3447    $this->privCloseFd();
3448
3449    return $v_result;
3450  }
3451
3452  $v_central_dir_to_add = array();
3453  if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
3454  {
3455    $this->privCloseFd();
3456    $p_archive_to_add->privCloseFd();
3457
3458    return $v_result;
3459  }
3460
3461  @rewind($p_archive_to_add->zip_fd);
3462
3463  $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-').'.tmp';
3464
3465  if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb')) == 0)
3466  {
3467    $this->privCloseFd();
3468    $p_archive_to_add->privCloseFd();
3469
3470    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open temporary file \''.$v_zip_temp_name.'\' in binary write mode');
3471
3472    return PclZip::errorCode();
3473  }
3474
3475  $v_size = $v_central_dir['offset'];
3476  while ($v_size != 0)
3477  {
3478    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3479    $v_buffer = fread($this->zip_fd, $v_read_size);
3480    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3481    $v_size -= $v_read_size;
3482  }
3483
3484  $v_size = $v_central_dir_to_add['offset'];
3485  while ($v_size != 0)
3486  {
3487    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3488    $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size);
3489    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3490    $v_size -= $v_read_size;
3491  }
3492
3493  $v_offset = @ftell($v_zip_temp_fd);
3494
3495  $v_size = $v_central_dir['size'];
3496  while ($v_size != 0)
3497  {
3498    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3499    $v_buffer = @fread($this->zip_fd, $v_read_size);
3500    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3501    $v_size -= $v_read_size;
3502  }
3503
3504  $v_size = $v_central_dir_to_add['size'];
3505  while ($v_size != 0)
3506  {
3507    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3508    $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size);
3509    @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size);
3510    $v_size -= $v_read_size;
3511  }
3512
3513  $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment'];
3514
3515  $v_size = @ftell($v_zip_temp_fd)-$v_offset;
3516
3517  $v_swap = $this->zip_fd;
3518  $this->zip_fd = $v_zip_temp_fd;
3519  $v_zip_temp_fd = $v_swap;
3520
3521  if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries']+$v_central_dir_to_add['entries'], $v_size, $v_offset, $v_comment)) != 1)
3522  {
3523    $this->privCloseFd();
3524    $p_archive_to_add->privCloseFd();
3525    @fclose($v_zip_temp_fd);
3526    $this->zip_fd = null;
3527
3528    unset($v_header_list);
3529
3530    return $v_result;
3531  }
3532
3533  $v_swap = $this->zip_fd;
3534  $this->zip_fd = $v_zip_temp_fd;
3535  $v_zip_temp_fd = $v_swap;
3536
3537  $this->privCloseFd();
3538  $p_archive_to_add->privCloseFd();
3539
3540  @fclose($v_zip_temp_fd);
3541
3542  @unlink($this->zipname);
3543
3544  PclZipUtilRename($v_zip_temp_name, $this->zipname);
3545
3546  return $v_result;
3547}
3548
3549function privDuplicate($p_archive_filename)
3550{
3551  $v_result=1;
3552
3553  if (!is_file($p_archive_filename))
3554  {
3555
3556    $v_result = 1;
3557
3558    return $v_result;
3559  }
3560
3561  if (($v_result=$this->privOpenFd('wb')) != 1)
3562  {
3563    return $v_result;
3564  }
3565
3566  if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb')) == 0)
3567  {
3568    $this->privCloseFd();
3569
3570    PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable to open archive file \''.$p_archive_filename.'\' in binary write mode');
3571
3572    return PclZip::errorCode();
3573  }
3574
3575  $v_size = filesize($p_archive_filename);
3576  while ($v_size != 0)
3577  {
3578    $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE);
3579    $v_buffer = fread($v_zip_temp_fd, $v_read_size);
3580    @fwrite($this->zip_fd, $v_buffer, $v_read_size);
3581    $v_size -= $v_read_size;
3582  }
3583
3584  $this->privCloseFd();
3585
3586  @fclose($v_zip_temp_fd);
3587
3588  return $v_result;
3589}
3590
3591function privErrorLog($p_error_code=0, $p_error_string='')
3592{
3593  if (PCLZIP_ERROR_EXTERNAL == 1) {
3594    PclError($p_error_code, $p_error_string);
3595  }
3596  else {
3597    $this->error_code = $p_error_code;
3598    $this->error_string = $p_error_string;
3599  }
3600}
3601
3602function privErrorReset()
3603{
3604  if (PCLZIP_ERROR_EXTERNAL == 1) {
3605    PclErrorReset();
3606  }
3607  else {
3608    $this->error_code = 0;
3609    $this->error_string = '';
3610  }
3611}
3612
3613function privDisableMagicQuotes()
3614{
3615  $v_result=1;
3616
3617  if (   (!function_exists("get_magic_quotes_runtime"))
3618    || (!function_exists("set_magic_quotes_runtime"))) {
3619    return $v_result;
3620}
3621
3622  if ($this->magic_quotes_status != -1) {
3623    return $v_result;
3624}
3625
3626$this->magic_quotes_status = @get_magic_quotes_runtime();
3627
3628if ($this->magic_quotes_status == 1) {
3629  @set_magic_quotes_runtime(0);
3630}
3631
3632  return $v_result;
3633}
3634
3635function privSwapBackMagicQuotes()
3636{
3637  $v_result=1;
3638
3639  if (   (!function_exists("get_magic_quotes_runtime"))
3640    || (!function_exists("set_magic_quotes_runtime"))) {
3641    return $v_result;
3642}
3643
3644  if ($this->magic_quotes_status != -1) {
3645    return $v_result;
3646}
3647
3648if ($this->magic_quotes_status == 1) {
3649    @set_magic_quotes_runtime($this->magic_quotes_status);
3650}
3651
3652  return $v_result;
3653}
3654
3655}
3656
3657function PclZipUtilPathReduction($p_dir)
3658{
3659  $v_result = "";
3660
3661  if ($p_dir != "") {
3662    $v_list = explode("/", $p_dir);
3663
3664    $v_skip = 0;
3665    for ($i=sizeof($v_list)-1; $i>=0; $i--) {
3666      if ($v_list[$i] == ".") {
3667      }
3668      else if ($v_list[$i] == "..") {
3669    $v_skip++;
3670      }
3671      else if ($v_list[$i] == "") {
3672    if ($i == 0) {
3673          $v_result = "/".$v_result;
3674      if ($v_skip > 0) {
3675          $v_result = $p_dir;
3676              $v_skip = 0;
3677      }
3678    }
3679    else if ($i == (sizeof($v_list)-1)) {
3680          $v_result = $v_list[$i];
3681    }
3682    else {
3683    }
3684      }
3685      else {
3686    if ($v_skip > 0) {
3687      $v_skip--;
3688    }
3689    else {
3690          $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:"");
3691    }
3692      }
3693    }
3694   
3695    if ($v_skip > 0) {
3696      while ($v_skip > 0) {
3697          $v_result = '../'.$v_result;
3698          $v_skip--;
3699      }
3700    }
3701  }
3702
3703  return $v_result;
3704}
3705
3706function PclZipUtilPathInclusion($p_dir, $p_path)
3707{
3708  $v_result = 1;
3709 
3710  if (   ($p_dir == '.')
3711      || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) == './'))) {
3712    $p_dir = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_dir, 1);
3713  }
3714  if (   ($p_path == '.')
3715      || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) == './'))) {
3716    $p_path = PclZipUtilTranslateWinPath(getcwd(), FALSE).'/'.substr($p_path, 1);
3717  }
3718
3719  $v_list_dir = explode("/", $p_dir);
3720  $v_list_dir_size = sizeof($v_list_dir);
3721  $v_list_path = explode("/", $p_path);
3722  $v_list_path_size = sizeof($v_list_path);
3723
3724  $i = 0;
3725  $j = 0;
3726  while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
3727
3728    if ($v_list_dir[$i] == '') {
3729      $i++;
3730      continue;
3731    }
3732    if ($v_list_path[$j] == '') {
3733      $j++;
3734      continue;
3735    }
3736
3737    if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] != '') && ( $v_list_path[$j] != ''))  {
3738      $v_result = 0;
3739    }
3740
3741    $i++;
3742    $j++;
3743  }
3744
3745  if ($v_result) {
3746    while (($j < $v_list_path_size) && ($v_list_path[$j] == '')) $j++;
3747    while (($i < $v_list_dir_size) && ($v_list_dir[$i] == '')) $i++;
3748
3749    if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
3750      $v_result = 2;
3751    }
3752    else if ($i < $v_list_dir_size) {
3753      $v_result = 0;
3754    }
3755  }
3756
3757  return $v_result;
3758}
3759
3760function PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
3761{
3762  $v_result = 1;
3763
3764  if ($p_mode==0)
3765  {
3766    while ($p_size != 0)
3767    {
3768      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
3769      $v_buffer = @fread($p_src, $v_read_size);
3770      @fwrite($p_dest, $v_buffer, $v_read_size);
3771      $p_size -= $v_read_size;
3772    }
3773  }
3774  else if ($p_mode==1)
3775  {
3776    while ($p_size != 0)
3777    {
3778      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
3779      $v_buffer = @gzread($p_src, $v_read_size);
3780      @fwrite($p_dest, $v_buffer, $v_read_size);
3781      $p_size -= $v_read_size;
3782    }
3783  }
3784  else if ($p_mode==2)
3785  {
3786    while ($p_size != 0)
3787    {
3788      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
3789      $v_buffer = @fread($p_src, $v_read_size);
3790      @gzwrite($p_dest, $v_buffer, $v_read_size);
3791      $p_size -= $v_read_size;
3792    }
3793  }
3794  else if ($p_mode==3)
3795  {
3796    while ($p_size != 0)
3797    {
3798      $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
3799      $v_buffer = @gzread($p_src, $v_read_size);
3800      @gzwrite($p_dest, $v_buffer, $v_read_size);
3801      $p_size -= $v_read_size;
3802    }
3803  }
3804
3805  return $v_result;
3806}
3807
3808function PclZipUtilRename($p_src, $p_dest)
3809{
3810  $v_result = 1;
3811
3812  if (!@rename($p_src, $p_dest)) {
3813
3814    if (!@copy($p_src, $p_dest)) {
3815      $v_result = 0;
3816    }
3817    else if (!@unlink($p_src)) {
3818      $v_result = 0;
3819    }
3820  }
3821
3822  return $v_result;
3823}
3824
3825function PclZipUtilOptionText($p_option)
3826{
3827 
3828  $v_list = get_defined_constants();
3829  for (reset($v_list); $v_key = key($v_list); next($v_list)) {
3830    $v_prefix = substr($v_key, 0, 10);
3831    if ((   ($v_prefix == 'PCLZIP_OPT')
3832         || ($v_prefix == 'PCLZIP_CB_')
3833         || ($v_prefix == 'PCLZIP_ATT'))
3834        && ($v_list[$v_key] == $p_option)) {
3835      return $v_key;
3836    }
3837  }
3838 
3839  $v_result = 'Unknown';
3840
3841  return $v_result;
3842}
3843
3844function PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
3845{
3846  if (stristr(php_uname(), 'windows')) {
3847    if (($p_remove_disk_letter) && (($v_position = strpos($p_path, ':')) != false)) {
3848        $p_path = substr($p_path, $v_position+1);
3849    }
3850    if ((strpos($p_path, '\\') > 0) || (substr($p_path, 0,1) == '\\')) {
3851        $p_path = strtr($p_path, '\\', '/');
3852    }
3853  }
3854  return $p_path;
3855}
3856?>
Note: See TracBrowser for help on using the repository browser.