source: branches/2.0/admin/include/pclzip.lib.php @ 3822

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

Update pclzip to 2.8.1 (PHP 5.3 compatibility)

  • Property svn:eol-style set to LF
  • Property svn:keywords set to Author Date Id Revision
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.