29 if (!
defined(
'PCLZIP_READ_BLOCK_SIZE')) {
30 define(
'PCLZIP_READ_BLOCK_SIZE', 2048 );
43 if (!
defined(
'PCLZIP_SEPARATOR')) {
44 define(
'PCLZIP_SEPARATOR',
',' );
52 if (!
defined(
'PCLZIP_ERROR_EXTERNAL')) {
53 define(
'PCLZIP_ERROR_EXTERNAL', 0 );
65 if (!
defined(
'PCLZIP_TEMPORARY_DIR')) {
66 define(
'PCLZIP_TEMPORARY_DIR',
'' );
77 if (!
defined(
'PCLZIP_TEMPORARY_FILE_RATIO')) {
78 define(
'PCLZIP_TEMPORARY_FILE_RATIO', 0.47 );
103 define(
'PCLZIP_ERR_USER_ABORTED', 2 );
104 define(
'PCLZIP_ERR_NO_ERROR', 0 );
105 define(
'PCLZIP_ERR_WRITE_OPEN_FAIL', -1 );
106 define(
'PCLZIP_ERR_READ_OPEN_FAIL', -2 );
107 define(
'PCLZIP_ERR_INVALID_PARAMETER', -3 );
108 define(
'PCLZIP_ERR_MISSING_FILE', -4 );
109 define(
'PCLZIP_ERR_FILENAME_TOO_LONG', -5 );
110 define(
'PCLZIP_ERR_INVALID_ZIP', -6 );
111 define(
'PCLZIP_ERR_BAD_EXTRACTED_FILE', -7 );
112 define(
'PCLZIP_ERR_DIR_CREATE_FAIL', -8 );
113 define(
'PCLZIP_ERR_BAD_EXTENSION', -9 );
114 define(
'PCLZIP_ERR_BAD_FORMAT', -10 );
115 define(
'PCLZIP_ERR_DELETE_FILE_FAIL', -11 );
116 define(
'PCLZIP_ERR_RENAME_FILE_FAIL', -12 );
117 define(
'PCLZIP_ERR_BAD_CHECKSUM', -13 );
118 define(
'PCLZIP_ERR_INVALID_ARCHIVE_ZIP', -14 );
119 define(
'PCLZIP_ERR_MISSING_OPTION_VALUE', -15 );
120 define(
'PCLZIP_ERR_INVALID_OPTION_VALUE', -16 );
121 define(
'PCLZIP_ERR_ALREADY_A_DIRECTORY', -17 );
122 define(
'PCLZIP_ERR_UNSUPPORTED_COMPRESSION', -18 );
123 define(
'PCLZIP_ERR_UNSUPPORTED_ENCRYPTION', -19 );
124 define(
'PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE', -20 );
125 define(
'PCLZIP_ERR_DIRECTORY_RESTRICTION', -21 );
128 define(
'PCLZIP_OPT_PATH', 77001 );
129 define(
'PCLZIP_OPT_ADD_PATH', 77002 );
130 define(
'PCLZIP_OPT_REMOVE_PATH', 77003 );
131 define(
'PCLZIP_OPT_REMOVE_ALL_PATH', 77004 );
132 define(
'PCLZIP_OPT_SET_CHMOD', 77005 );
133 define(
'PCLZIP_OPT_EXTRACT_AS_STRING', 77006 );
134 define(
'PCLZIP_OPT_NO_COMPRESSION', 77007 );
135 define(
'PCLZIP_OPT_BY_NAME', 77008 );
136 define(
'PCLZIP_OPT_BY_INDEX', 77009 );
137 define(
'PCLZIP_OPT_BY_EREG', 77010 );
138 define(
'PCLZIP_OPT_BY_PREG', 77011 );
139 define(
'PCLZIP_OPT_COMMENT', 77012 );
140 define(
'PCLZIP_OPT_ADD_COMMENT', 77013 );
141 define(
'PCLZIP_OPT_PREPEND_COMMENT', 77014 );
142 define(
'PCLZIP_OPT_EXTRACT_IN_OUTPUT', 77015 );
143 define(
'PCLZIP_OPT_REPLACE_NEWER', 77016 );
144 define(
'PCLZIP_OPT_STOP_ON_ERROR', 77017 );
148 define(
'PCLZIP_OPT_EXTRACT_DIR_RESTRICTION', 77019 );
149 define(
'PCLZIP_OPT_TEMP_FILE_THRESHOLD', 77020 );
150 define(
'PCLZIP_OPT_ADD_TEMP_FILE_THRESHOLD', 77020 );
151 define(
'PCLZIP_OPT_TEMP_FILE_ON', 77021 );
152 define(
'PCLZIP_OPT_ADD_TEMP_FILE_ON', 77021 );
153 define(
'PCLZIP_OPT_TEMP_FILE_OFF', 77022 );
154 define(
'PCLZIP_OPT_ADD_TEMP_FILE_OFF', 77022 );
157 define(
'PCLZIP_ATT_FILE_NAME', 79001 );
158 define(
'PCLZIP_ATT_FILE_NEW_SHORT_NAME', 79002 );
159 define(
'PCLZIP_ATT_FILE_NEW_FULL_NAME', 79003 );
160 define(
'PCLZIP_ATT_FILE_MTIME', 79004 );
161 define(
'PCLZIP_ATT_FILE_CONTENT', 79005 );
162 define(
'PCLZIP_ATT_FILE_COMMENT', 79006 );
165 define(
'PCLZIP_CB_PRE_EXTRACT', 78001 );
166 define(
'PCLZIP_CB_POST_EXTRACT', 78002 );
167 define(
'PCLZIP_CB_PRE_ADD', 78003 );
168 define(
'PCLZIP_CB_POST_ADD', 78004 );
219 if (!function_exists(
'gzopen'))
221 die(
'Abort '.basename(__FILE__).
' : Missing zlib extensions');
225 $this->zipname = $p_zipname;
227 $this->magic_quotes_status = -1;
279 $v_options =
array();
283 $v_size = func_num_args();
288 $v_arg_list = func_get_args();
291 array_shift($v_arg_list);
295 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
311 if ($v_result != 1) {
328 else if ($v_size > 2) {
330 "Invalid number / type of arguments");
340 $v_string_list =
array();
341 $v_att_list =
array();
342 $v_filedescr_list =
array();
343 $p_result_list =
array();
346 if (is_array($p_filelist)) {
350 if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
351 $v_att_list = $p_filelist;
356 $v_string_list = $p_filelist;
361 else if (is_string($p_filelist)) {
363 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
373 if (
sizeof($v_string_list) != 0) {
374 foreach ($v_string_list as $v_string) {
375 if ($v_string !=
'') {
384 $v_supported_attributes
392 foreach ($v_att_list as $v_entry) {
396 $v_supported_attributes);
397 if ($v_result != 1) {
404 if ($v_result != 1) {
409 $v_result = $this->
privCreate($v_filedescr_list, $p_result_list, $v_options);
410 if ($v_result != 1) {
415 return $p_result_list;
462 $v_options =
array();
466 $v_size = func_num_args();
471 $v_arg_list = func_get_args();
474 array_shift($v_arg_list);
478 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
496 if ($v_result != 1) {
513 else if ($v_size > 2) {
527 $v_string_list =
array();
528 $v_att_list =
array();
529 $v_filedescr_list =
array();
530 $p_result_list =
array();
533 if (is_array($p_filelist)) {
537 if (isset($p_filelist[0]) && is_array($p_filelist[0])) {
538 $v_att_list = $p_filelist;
543 $v_string_list = $p_filelist;
548 else if (is_string($p_filelist)) {
550 $v_string_list = explode(PCLZIP_SEPARATOR, $p_filelist);
560 if (
sizeof($v_string_list) != 0) {
561 foreach ($v_string_list as $v_string) {
567 $v_supported_attributes
575 foreach ($v_att_list as $v_entry) {
579 $v_supported_attributes);
580 if ($v_result != 1) {
587 if ($v_result != 1) {
592 $v_result = $this->
privAdd($v_filedescr_list, $p_result_list, $v_options);
593 if ($v_result != 1) {
598 return $p_result_list;
657 if (($v_result = $this->
privList($p_list)) != 1)
713 $v_options =
array();
717 $v_remove_all_path =
false;
720 $v_size = func_num_args();
728 $v_arg_list = func_get_args();
731 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
755 if ($v_result != 1) {
771 if ((strlen($v_path) > 0) && (substr($v_path, -1) !=
'/')) {
784 $v_path = $v_arg_list[0];
788 $v_remove_path = $v_arg_list[1];
790 else if ($v_size > 2) {
808 $v_remove_all_path, $v_options);
870 $v_options =
array();
874 $v_remove_all_path =
false;
877 $v_size = func_num_args();
885 $v_arg_list = func_get_args();
888 array_shift($v_arg_list);
892 if ((is_integer($v_arg_list[0])) && ($v_arg_list[0] > 77000)) {
911 if ($v_result != 1) {
927 if ((strlen($v_path) > 0) && (substr($v_path, -1) !=
'/')) {
945 $v_path = $v_arg_list[0];
949 $v_remove_path = $v_arg_list[1];
951 else if ($v_size > 2) {
967 $v_options_trick =
array();
968 $v_result = $this->
privParseOptions($v_arg_trick,
sizeof($v_arg_trick), $v_options_trick,
970 if ($v_result != 1) {
979 if (($v_result = $this->
privExtractByRule($p_list, $v_path, $v_remove_path, $v_remove_all_path, $v_options)) < 1) {
1019 $v_options =
array();
1022 $v_size = func_num_args();
1027 $v_arg_list = func_get_args();
1035 if ($v_result != 1) {
1106 $v_prop[
'comment'] =
'';
1108 $v_prop[
'status'] =
'not_exist';
1111 if (@is_file($this->zipname))
1114 if (($this->zip_fd = @fopen($this->zipname,
'rb')) == 0)
1125 // ----- Read the central directory informations 1126 $v_central_dir = array(); 1127 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 1129 $this->privSwapBackMagicQuotes(); 1133 // ----- Close the zip file 1134 $this->privCloseFd(); 1136 // ----- Set the user attributes 1138 $v_prop['nb
'] = $v_central_dir['entries
']; 1139 $v_prop['status
'] = 'ok
'; 1142 // ----- Magic quotes trick 1143 $this->privSwapBackMagicQuotes(); 1148 // -------------------------------------------------------------------------------- 1150 // -------------------------------------------------------------------------------- 1151 // Function : duplicate() 1153 // This method creates an archive by copying the content of an other one. If 1154 // the archive already exist, it is replaced by the new one without any warning. 1156 // $p_archive : The filename of a valid archive, or 1157 // a valid PclZip object. 1160 // 0 or a negative value on error (error code). 1161 // -------------------------------------------------------------------------------- 1162 function duplicate($p_archive) 1166 // ----- Reset the error handler 1167 $this->privErrorReset(); 1169 // ----- Look if the $p_archive is a PclZip object 1170 if ((is_object($p_archive)) && (get_class($p_archive) == 'pclzip
')) 1173 // ----- Duplicate the archive 1174 $v_result = $this->privDuplicate($p_archive->zipname); 1177 // ----- Look if the $p_archive is a string (so a filename) 1178 else if (is_string($p_archive)) 1181 // ----- Check that $p_archive is a valid zip file 1182 // TBC : Should also check the archive format 1183 if (!is_file($p_archive)) { 1185 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "No file with filename '".$p_archive."'"); 1186 $v_result = PCLZIP_ERR_MISSING_FILE; 1189 // ----- Duplicate the archive 1190 $v_result = $this->privDuplicate($p_archive); 1194 // ----- Invalid variable 1198 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 1199 $v_result = PCLZIP_ERR_INVALID_PARAMETER; 1205 // -------------------------------------------------------------------------------- 1207 // -------------------------------------------------------------------------------- 1208 // Function : merge() 1210 // This method merge the $p_archive_to_add archive at the end of the current 1212 // If the archive ($this) does not exist, the merge becomes a duplicate. 1213 // If the $p_archive_to_add archive does not exist, the merge is a success. 1215 // $p_archive_to_add : It can be directly the filename of a valid zip archive, 1216 // or a PclZip object archive. 1219 // 0 or negative values on error (see below). 1220 // -------------------------------------------------------------------------------- 1221 function merge($p_archive_to_add) 1225 // ----- Reset the error handler 1226 $this->privErrorReset(); 1228 // ----- Check archive 1229 if (!$this->privCheckFormat()) { 1233 // ----- Look if the $p_archive_to_add is a PclZip object 1234 if ((is_object($p_archive_to_add)) && (get_class($p_archive_to_add) == 'pclzip
')) 1237 // ----- Merge the archive 1238 $v_result = $this->privMerge($p_archive_to_add); 1241 // ----- Look if the $p_archive_to_add is a string (so a filename) 1242 else if (is_string($p_archive_to_add)) 1245 // ----- Create a temporary archive 1246 $v_object_archive = new PclZip($p_archive_to_add); 1248 // ----- Merge the archive 1249 $v_result = $this->privMerge($v_object_archive); 1252 // ----- Invalid variable 1256 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid variable type p_archive_to_add"); 1257 $v_result = PCLZIP_ERR_INVALID_PARAMETER; 1263 // -------------------------------------------------------------------------------- 1267 // -------------------------------------------------------------------------------- 1268 // Function : errorCode() 1271 // -------------------------------------------------------------------------------- 1272 function errorCode() 1274 if (PCLZIP_ERROR_EXTERNAL == 1) { 1275 return(PclErrorCode()); 1278 return($this->error_code); 1281 // -------------------------------------------------------------------------------- 1283 // -------------------------------------------------------------------------------- 1284 // Function : errorName() 1287 // -------------------------------------------------------------------------------- 1288 function errorName($p_with_code=false) 1313 if (isset($v_name[$this->error_code])) { 1314 $v_value = $v_name[$this->error_code]; 1317 $v_value = 'NoName
'; 1321 return($v_value.' (
'.$this->error_code.')
'); 1327 // -------------------------------------------------------------------------------- 1329 // -------------------------------------------------------------------------------- 1330 // Function : errorInfo() 1333 // -------------------------------------------------------------------------------- 1334 function errorInfo($p_full=false) 1336 if (PCLZIP_ERROR_EXTERNAL == 1) { 1337 return(PclErrorString()); 1341 return($this->errorName(true)." : ".$this->error_string); 1344 return($this->error_string." [code ".$this->error_code."]"); 1348 // -------------------------------------------------------------------------------- 1351 // -------------------------------------------------------------------------------- 1352 // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** 1354 // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** 1355 // -------------------------------------------------------------------------------- 1359 // -------------------------------------------------------------------------------- 1360 // Function : privCheckFormat() 1362 // This method check that the archive exists and is a valid zip archive. 1363 // Several level of check exists. (futur) 1365 // $p_level : Level of check. Default 0. 1366 // 0 : Check the first bytes (magic codes) (default value)) 1367 // 1 : 0 + Check the central directory (futur) 1368 // 2 : 1 + Check each file header (futur) 1371 // false on error, the error code is set. 1372 // -------------------------------------------------------------------------------- 1373 function privCheckFormat($p_level=0) 1377 // ----- Reset the file system cache 1380 // ----- Reset the error handler 1381 $this->privErrorReset(); 1383 // ----- Look if the file exits 1384 if (!is_file($this->zipname)) { 1386 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "Missing archive file '".$this->zipname."'"); 1390 // ----- Check that the file is readeable 1391 if (!is_readable($this->zipname)) { 1393 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to read archive '".$this->zipname."'"); 1397 // ----- Check the magic code 1400 // ----- Check the central header 1403 // ----- Check each file header 1409 // -------------------------------------------------------------------------------- 1411 // -------------------------------------------------------------------------------- 1412 // Function : privParseOptions() 1414 // This internal methods reads the variable list of arguments ($p_options_list, 1415 // $p_size) and generate an array with the options and values ($v_result_list). 1416 // $v_requested_options contains the options that can be present and those that 1418 // $v_requested_options is an array, with the option value as key, and 'optional
', 1419 // or 'mandatory
' as value. 1425 // -------------------------------------------------------------------------------- 1426 function privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false) 1430 // ----- Read the options 1432 while ($i<$p_size) { 1434 // ----- Check if the option is supported 1435 if (!isset($v_requested_options[$p_options_list[$i]])) { 1437 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid optional parameter '".$p_options_list[$i]."' for this method"); 1440 return PclZip::errorCode(); 1443 // ----- Look for next option 1444 switch ($p_options_list[$i]) { 1445 // ----- Look for options that request a path value 1446 case PCLZIP_OPT_PATH : 1447 case PCLZIP_OPT_REMOVE_PATH : 1448 case PCLZIP_OPT_ADD_PATH : 1449 // ----- Check the number of parameters 1450 if (($i+1) >= $p_size) { 1452 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1455 return PclZip::errorCode(); 1458 // ----- Get the value 1459 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 1463 case PCLZIP_OPT_TEMP_FILE_THRESHOLD : 1464 // ----- Check the number of parameters 1465 if (($i+1) >= $p_size) { 1466 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1467 return PclZip::errorCode(); 1470 // ----- Check for incompatible options 1471 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 1472 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 1473 return PclZip::errorCode(); 1476 // ----- Check the value 1477 $v_value = $p_options_list[$i+1]; 1478 if ((!is_integer($v_value)) || ($v_value<0)) { 1479 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Integer expected for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1480 return PclZip::errorCode(); 1483 // ----- Get the value (and convert it in bytes) 1484 $v_result_list[$p_options_list[$i]] = $v_value*1048576; 1488 case PCLZIP_OPT_TEMP_FILE_ON : 1489 // ----- Check for incompatible options 1490 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_OFF])) { 1491 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_OFF'"); 1492 return PclZip::errorCode(); 1495 $v_result_list[$p_options_list[$i]] = true; 1498 case PCLZIP_OPT_TEMP_FILE_OFF : 1499 // ----- Check for incompatible options 1500 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_ON])) { 1501 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_ON'"); 1502 return PclZip::errorCode(); 1504 // ----- Check for incompatible options 1505 if (isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 1506 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Option '".PclZipUtilOptionText($p_options_list[$i])."' can not be used with option 'PCLZIP_OPT_TEMP_FILE_THRESHOLD'"); 1507 return PclZip::errorCode(); 1510 $v_result_list[$p_options_list[$i]] = true; 1513 case PCLZIP_OPT_EXTRACT_DIR_RESTRICTION : 1514 // ----- Check the number of parameters 1515 if (($i+1) >= $p_size) { 1517 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1520 return PclZip::errorCode(); 1523 // ----- Get the value 1524 if ( is_string($p_options_list[$i+1]) 1525 && ($p_options_list[$i+1] != '')) { 1526 $v_result_list[$p_options_list[$i]] = PclZipUtilTranslateWinPath($p_options_list[$i+1], FALSE); 1533 // ----- Look for options that request an array of string for value 1534 case PCLZIP_OPT_BY_NAME : 1535 // ----- Check the number of parameters 1536 if (($i+1) >= $p_size) { 1538 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1541 return PclZip::errorCode(); 1544 // ----- Get the value 1545 if (is_string($p_options_list[$i+1])) { 1546 $v_result_list[$p_options_list[$i]][0] = $p_options_list[$i+1]; 1548 else if (is_array($p_options_list[$i+1])) { 1549 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1553 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1556 return PclZip::errorCode(); 1561 // ----- Look for options that request an EREG or PREG expression 1562 case PCLZIP_OPT_BY_EREG : 1563 // ereg() is deprecated starting with PHP 5.3. Move PCLZIP_OPT_BY_EREG 1564 // to PCLZIP_OPT_BY_PREG 1565 $p_options_list[$i] = PCLZIP_OPT_BY_PREG; 1566 case PCLZIP_OPT_BY_PREG : 1567 //case PCLZIP_OPT_CRYPT : 1568 // ----- Check the number of parameters 1569 if (($i+1) >= $p_size) { 1571 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1574 return PclZip::errorCode(); 1577 // ----- Get the value 1578 if (is_string($p_options_list[$i+1])) { 1579 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1583 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Wrong parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1586 return PclZip::errorCode(); 1591 // ----- Look for options that takes a string 1592 case PCLZIP_OPT_COMMENT : 1593 case PCLZIP_OPT_ADD_COMMENT : 1594 case PCLZIP_OPT_PREPEND_COMMENT : 1595 // ----- Check the number of parameters 1596 if (($i+1) >= $p_size) { 1598 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, 1599 "Missing parameter value for option '" 1600 .PclZipUtilOptionText($p_options_list[$i]) 1604 return PclZip::errorCode(); 1607 // ----- Get the value 1608 if (is_string($p_options_list[$i+1])) { 1609 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1613 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, 1614 "Wrong parameter value for option '" 1615 .PclZipUtilOptionText($p_options_list[$i]) 1619 return PclZip::errorCode(); 1624 // ----- Look for options that request an array of index 1625 case PCLZIP_OPT_BY_INDEX : 1626 // ----- Check the number of parameters 1627 if (($i+1) >= $p_size) { 1629 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1632 return PclZip::errorCode(); 1635 // ----- Get the value 1636 $v_work_list = array(); 1637 if (is_string($p_options_list[$i+1])) { 1639 // ----- Remove spaces 1640 $p_options_list[$i+1] = strtr($p_options_list[$i+1], ' ', ''); 1642 // ----- Parse items 1643 $v_work_list = explode(",", $p_options_list[$i+1]); 1645 else if (is_integer($p_options_list[$i+1])) { 1646 $v_work_list[0] = $p_options_list[$i+1].'-
'.$p_options_list[$i+1]; 1648 else if (is_array($p_options_list[$i+1])) { 1649 $v_work_list = $p_options_list[$i+1]; 1653 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Value must be integer, string or array for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1656 return PclZip::errorCode(); 1659 // ----- Reduce the index list 1660 // each index item in the list must be a couple with a start and 1661 // an end value : [0,3], [5-5], [8-10], ... 1662 // ----- Check the format of each item 1665 for ($j=0; $j<sizeof($v_work_list); $j++) { 1666 // ----- Explode the item 1667 $v_item_list = explode("-", $v_work_list[$j]); 1668 $v_size_item_list = sizeof($v_item_list); 1670 // ----- TBC : Here we might check that each item is a 1673 // ----- Look for single value 1674 if ($v_size_item_list == 1) { 1675 // ----- Set the option value 1676 $v_result_list[$p_options_list[$i]][$j]['start
'] = $v_item_list[0]; 1677 $v_result_list[$p_options_list[$i]][$j]['end
'] = $v_item_list[0]; 1679 elseif ($v_size_item_list == 2) { 1680 // ----- Set the option value 1681 $v_result_list[$p_options_list[$i]][$j]['start
'] = $v_item_list[0]; 1682 $v_result_list[$p_options_list[$i]][$j]['end
'] = $v_item_list[1]; 1686 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Too many values in index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1689 return PclZip::errorCode(); 1693 // ----- Look for list sort 1694 if ($v_result_list[$p_options_list[$i]][$j]['start
'] < $v_sort_value) { 1697 // ----- TBC : An automatic sort should be writen ... 1699 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Invalid order of index range for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1702 return PclZip::errorCode(); 1704 $v_sort_value = $v_result_list[$p_options_list[$i]][$j]['start
']; 1707 // ----- Sort the items 1709 // TBC : To Be Completed 1712 // ----- Next option 1716 // ----- Look for options that request no value 1717 case PCLZIP_OPT_REMOVE_ALL_PATH : 1718 case PCLZIP_OPT_EXTRACT_AS_STRING : 1719 case PCLZIP_OPT_NO_COMPRESSION : 1720 case PCLZIP_OPT_EXTRACT_IN_OUTPUT : 1721 case PCLZIP_OPT_REPLACE_NEWER : 1722 case PCLZIP_OPT_STOP_ON_ERROR : 1723 $v_result_list[$p_options_list[$i]] = true; 1726 // ----- Look for options that request an octal value 1727 case PCLZIP_OPT_SET_CHMOD : 1728 // ----- Check the number of parameters 1729 if (($i+1) >= $p_size) { 1731 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1734 return PclZip::errorCode(); 1737 // ----- Get the value 1738 $v_result_list[$p_options_list[$i]] = $p_options_list[$i+1]; 1742 // ----- Look for options that request a call-back 1743 case PCLZIP_CB_PRE_EXTRACT : 1744 case PCLZIP_CB_POST_EXTRACT : 1745 case PCLZIP_CB_PRE_ADD : 1746 case PCLZIP_CB_POST_ADD : 1748 case PCLZIP_CB_PRE_DELETE : 1749 case PCLZIP_CB_POST_DELETE : 1750 case PCLZIP_CB_PRE_LIST : 1751 case PCLZIP_CB_POST_LIST : 1753 // ----- Check the number of parameters 1754 if (($i+1) >= $p_size) { 1756 PclZip::privErrorLog(PCLZIP_ERR_MISSING_OPTION_VALUE, "Missing parameter value for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1759 return PclZip::errorCode(); 1762 // ----- Get the value 1763 $v_function_name = $p_options_list[$i+1]; 1765 // ----- Check that the value is a valid existing function 1766 if (!function_exists($v_function_name)) { 1768 PclZip::privErrorLog(PCLZIP_ERR_INVALID_OPTION_VALUE, "Function '".$v_function_name."()
' is not an existing function for option '".PclZipUtilOptionText($p_options_list[$i])."'"); 1771 return PclZip::errorCode(); 1774 // ----- Set the attribute 1775 $v_result_list[$p_options_list[$i]] = $v_function_name; 1781 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, 1782 "Unknown parameter '" 1783 .$p_options_list[$i]."'"); 1786 return PclZip::errorCode(); 1789 // ----- Next options 1793 // ----- Look for mandatory options 1794 if ($v_requested_options !== false) { 1795 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 1796 // ----- Look for mandatory option 1797 if ($v_requested_options[$key] == 'mandatory
') { 1798 // ----- Look if present 1799 if (!isset($v_result_list[$key])) { 1801 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 1804 return PclZip::errorCode(); 1810 // ----- Look for default values 1811 if (!isset($v_result_list[PCLZIP_OPT_TEMP_FILE_THRESHOLD])) { 1818 // -------------------------------------------------------------------------------- 1820 // -------------------------------------------------------------------------------- 1821 // Function : privOptionDefaultThreshold() 1825 // -------------------------------------------------------------------------------- 1826 function privOptionDefaultThreshold(&$p_options) 1830 if (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 1831 || isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) { 1835 // ----- Get 'memory_limit
' configuration value 1836 $v_memory_limit = ini_get('memory_limit
'); 1837 $v_memory_limit = trim($v_memory_limit); 1838 $last = strtolower(substr($v_memory_limit, -1)); 1841 //$v_memory_limit = $v_memory_limit*1024*1024*1024; 1842 $v_memory_limit = $v_memory_limit*1073741824; 1844 //$v_memory_limit = $v_memory_limit*1024*1024; 1845 $v_memory_limit = $v_memory_limit*1048576; 1847 $v_memory_limit = $v_memory_limit*1024; 1849 $p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] = floor($v_memory_limit*PCLZIP_TEMPORARY_FILE_RATIO); 1852 // ----- Sanity check : No threshold if value lower than 1M 1853 if ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] < 1048576) { 1854 unset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]); 1860 // -------------------------------------------------------------------------------- 1862 // -------------------------------------------------------------------------------- 1863 // Function : privFileDescrParseAtt() 1869 // -------------------------------------------------------------------------------- 1870 function privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false) 1874 // ----- For each file in the list check the attributes 1875 foreach ($p_file_list as $v_key => $v_value) { 1877 // ----- Check if the option is supported 1878 if (!isset($v_requested_options[$v_key])) { 1880 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file attribute '".$v_key."' for this file"); 1883 return PclZip::errorCode(); 1886 // ----- Look for attribute 1888 case PCLZIP_ATT_FILE_NAME : 1889 if (!is_string($v_value)) { 1890 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1891 return PclZip::errorCode(); 1894 $p_filedescr['filename
'] = PclZipUtilPathReduction($v_value); 1896 if ($p_filedescr['filename
'] == '') { 1897 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty filename for attribute '".PclZipUtilOptionText($v_key)."'"); 1898 return PclZip::errorCode(); 1903 case PCLZIP_ATT_FILE_NEW_SHORT_NAME : 1904 if (!is_string($v_value)) { 1905 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1906 return PclZip::errorCode(); 1909 $p_filedescr['new_short_name
'] = PclZipUtilPathReduction($v_value); 1911 if ($p_filedescr['new_short_name
'] == '') { 1912 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty short filename for attribute '".PclZipUtilOptionText($v_key)."'"); 1913 return PclZip::errorCode(); 1917 case PCLZIP_ATT_FILE_NEW_FULL_NAME : 1918 if (!is_string($v_value)) { 1919 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1920 return PclZip::errorCode(); 1923 $p_filedescr['new_full_name
'] = PclZipUtilPathReduction($v_value); 1925 if ($p_filedescr['new_full_name
'] == '') { 1926 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid empty full filename for attribute '".PclZipUtilOptionText($v_key)."'"); 1927 return PclZip::errorCode(); 1931 // ----- Look for options that takes a string 1932 case PCLZIP_ATT_FILE_COMMENT : 1933 if (!is_string($v_value)) { 1934 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". String expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1935 return PclZip::errorCode(); 1938 $p_filedescr['comment'] = $v_value; 1941 case PCLZIP_ATT_FILE_MTIME : 1942 if (!is_integer($v_value)) { 1943 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE, "Invalid type ".gettype($v_value).". Integer expected for attribute '".PclZipUtilOptionText($v_key)."'"); 1944 return PclZip::errorCode(); 1947 $p_filedescr['mtime
'] = $v_value; 1950 case PCLZIP_ATT_FILE_CONTENT : 1951 $p_filedescr['content
'] = $v_value; 1956 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, 1957 "Unknown parameter '".$v_key."'"); 1960 return PclZip::errorCode(); 1963 // ----- Look for mandatory options 1964 if ($v_requested_options !== false) { 1965 for ($key=reset($v_requested_options); $key=key($v_requested_options); $key=next($v_requested_options)) { 1966 // ----- Look for mandatory option 1967 if ($v_requested_options[$key] == 'mandatory
') { 1968 // ----- Look if present 1969 if (!isset($p_file_list[$key])) { 1970 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Missing mandatory parameter ".PclZipUtilOptionText($key)."(".$key.")"); 1971 return PclZip::errorCode(); 1983 // -------------------------------------------------------------------------------- 1985 // -------------------------------------------------------------------------------- 1986 // Function : privFileDescrExpand() 1988 // This method look for each item of the list to see if its a file, a folder 1989 // or a string to be added as file. For any other type of files (link, other) 1990 // just ignore the item. 1991 // Then prepare the information that will be stored for that file. 1992 // When its a folder, expand the folder with all the files that are in that 1993 // folder (recursively). 1998 // -------------------------------------------------------------------------------- 1999 function privFileDescrExpand(&$p_filedescr_list, &$p_options) 2003 // ----- Create a result list 2004 $v_result_list = array(); 2006 // ----- Look each entry 2007 for ($i=0; $i<sizeof($p_filedescr_list); $i++) { 2009 // ----- Get filedescr 2010 $v_descr = $p_filedescr_list[$i]; 2012 // ----- Reduce the filename 2013 $v_descr['filename
'] = PclZipUtilTranslateWinPath($v_descr['filename
'], false); 2014 $v_descr['filename
'] = PclZipUtilPathReduction($v_descr['filename
']); 2016 // ----- Look for real file or folder 2017 if (file_exists($v_descr['filename
'])) { 2018 if (@is_file($v_descr['filename
'])) { 2019 $v_descr['type
'] = 'file'; 2021 else if (@is_dir($v_descr['filename
'])) { 2022 $v_descr['type
'] = 'folder
'; 2024 else if (@is_link($v_descr['filename
'])) { 2034 // ----- Look for string added as file 2035 else if (isset($v_descr['content
'])) { 2036 $v_descr['type
'] = 'virtual_file
'; 2039 // ----- Missing file 2042 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$v_descr['filename']."' does not exist"); 2045 return PclZip::errorCode(); 2048 // ----- Calculate the stored filename 2049 $this->privCalculateStoredFilename($v_descr, $p_options); 2051 // ----- Add the descriptor in result list 2052 $v_result_list[sizeof($v_result_list)] = $v_descr; 2054 // ----- Look for folder 2055 if ($v_descr['type
'] == 'folder
') { 2056 // ----- List of items in folder 2057 $v_dirlist_descr = array(); 2059 if ($v_folder_handler = @opendir($v_descr['filename
'])) { 2060 while (($v_item_handler = @readdir($v_folder_handler)) !== false) { 2062 // ----- Skip '.
' and '..
' 2063 if (($v_item_handler == '.
') || ($v_item_handler == '..
')) { 2067 // ----- Compose the full filename 2068 $v_dirlist_descr[$v_dirlist_nb]['filename
'] = $v_descr['filename
'].'/
'.$v_item_handler; 2070 // ----- Look for different stored filename 2071 // Because the name of the folder was changed, the name of the 2072 // files/sub-folders also change 2073 if (($v_descr['stored_filename
'] != $v_descr['filename
']) 2074 && (!isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]))) { 2075 if ($v_descr['stored_filename
'] != '') { 2076 $v_dirlist_descr[$v_dirlist_nb]['new_full_name
'] = $v_descr['stored_filename
'].'/
'.$v_item_handler; 2079 $v_dirlist_descr[$v_dirlist_nb]['new_full_name
'] = $v_item_handler; 2086 @closedir($v_folder_handler); 2089 // TBC : unable to open folder in read mode 2092 // ----- Expand each element of the list 2093 if ($v_dirlist_nb != 0) { 2095 if (($v_result = $this->privFileDescrExpand($v_dirlist_descr, $p_options)) != 1) { 2099 // ----- Concat the resulting list 2100 $v_result_list = array_merge($v_result_list, $v_dirlist_descr); 2105 // ----- Free local array 2106 unset($v_dirlist_descr); 2110 // ----- Get the result list 2111 $p_filedescr_list = $v_result_list; 2116 // -------------------------------------------------------------------------------- 2118 // -------------------------------------------------------------------------------- 2119 // Function : privCreate() 2123 // -------------------------------------------------------------------------------- 2124 function privCreate($p_filedescr_list, &$p_result_list, &$p_options) 2127 $v_list_detail = array(); 2129 // ----- Magic quotes trick 2130 $this->privDisableMagicQuotes(); 2132 // ----- Open the file in write mode 2133 if (($v_result = $this->privOpenFd('wb
')) != 1) 2139 // ----- Add the list of files 2140 $v_result = $this->privAddList($p_filedescr_list, $p_result_list, $p_options); 2143 $this->privCloseFd(); 2145 // ----- Magic quotes trick 2146 $this->privSwapBackMagicQuotes(); 2151 // -------------------------------------------------------------------------------- 2153 // -------------------------------------------------------------------------------- 2154 // Function : privAdd() 2158 // -------------------------------------------------------------------------------- 2159 function privAdd($p_filedescr_list, &$p_result_list, &$p_options) 2162 $v_list_detail = array(); 2164 // ----- Look if the archive exists or is empty 2165 if ((!is_file($this->zipname)) || (filesize($this->zipname) == 0)) 2168 // ----- Do a create 2169 $v_result = $this->privCreate($p_filedescr_list, $p_result_list, $p_options); 2174 // ----- Magic quotes trick 2175 $this->privDisableMagicQuotes(); 2177 // ----- Open the zip file 2178 if (($v_result=$this->privOpenFd('rb
')) != 1) 2180 // ----- Magic quotes trick 2181 $this->privSwapBackMagicQuotes(); 2187 // ----- Read the central directory informations 2188 $v_central_dir = array(); 2189 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 2191 $this->privCloseFd(); 2192 $this->privSwapBackMagicQuotes(); 2196 // ----- Go to beginning of File 2197 @rewind($this->zip_fd); 2199 // ----- Creates a temporay file 2200 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-
').'.tmp
'; 2202 // ----- Open the temporary file in write mode 2203 if (($v_zip_temp_fd = @fopen($v_zip_temp_name, 'wb
')) == 0) 2205 $this->privCloseFd(); 2206 $this->privSwapBackMagicQuotes(); 2208 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open temporary
file \
''.$v_zip_temp_name.
'\' in binary write mode
'); 2211 return PclZip::errorCode(); 2214 // ----- Copy the files from the archive to the temporary file 2215 // TBC : Here I should better append the file and go back to erase the central dir 2216 $v_size = $v_central_dir['offset
']; 2217 while ($v_size != 0) 2219 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 2220 $v_buffer = fread($this->zip_fd, $v_read_size); 2221 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 2222 $v_size -= $v_read_size; 2225 // ----- Swap the file descriptor 2226 // Here is a trick : I swap the temporary fd with the zip fd, in order to use 2227 // the following methods on the temporary fil and not the real archive 2228 $v_swap = $this->zip_fd; 2229 $this->zip_fd = $v_zip_temp_fd; 2230 $v_zip_temp_fd = $v_swap; 2232 // ----- Add the files 2233 $v_header_list = array(); 2234 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 2236 fclose($v_zip_temp_fd); 2237 $this->privCloseFd(); 2238 @unlink($v_zip_temp_name); 2239 $this->privSwapBackMagicQuotes(); 2245 // ----- Store the offset of the central dir 2246 $v_offset = @ftell($this->zip_fd); 2248 // ----- Copy the block of file headers from the old archive 2249 $v_size = $v_central_dir['size']; 2250 while ($v_size != 0) 2252 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 2253 $v_buffer = @fread($v_zip_temp_fd, $v_read_size); 2254 @fwrite($this->zip_fd, $v_buffer, $v_read_size); 2255 $v_size -= $v_read_size; 2258 // ----- Create the Central Dir files header 2259 for ($i=0, $v_count=0; $i<sizeof($v_header_list); $i++) 2261 // ----- Create the file header 2262 if ($v_header_list[$i]['status
'] == 'ok
') { 2263 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 2264 fclose($v_zip_temp_fd); 2265 $this->privCloseFd(); 2266 @unlink($v_zip_temp_name); 2267 $this->privSwapBackMagicQuotes(); 2275 // ----- Transform the header to a 'usable
' info 2276 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 2279 // ----- Zip file comment 2280 $v_comment = $v_central_dir['comment']; 2281 if (isset($p_options[PCLZIP_OPT_COMMENT])) { 2282 $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 2284 if (isset($p_options[PCLZIP_OPT_ADD_COMMENT])) { 2285 $v_comment = $v_comment.$p_options[PCLZIP_OPT_ADD_COMMENT]; 2287 if (isset($p_options[PCLZIP_OPT_PREPEND_COMMENT])) { 2288 $v_comment = $p_options[PCLZIP_OPT_PREPEND_COMMENT].$v_comment; 2291 // ----- Calculate the size of the central header 2292 $v_size = @ftell($this->zip_fd)-$v_offset; 2294 // ----- Create the central dir footer 2295 if (($v_result = $this->privWriteCentralHeader($v_count+$v_central_dir['entries
'], $v_size, $v_offset, $v_comment)) != 1) 2297 // ----- Reset the file list 2298 unset($v_header_list); 2299 $this->privSwapBackMagicQuotes(); 2305 // ----- Swap back the file descriptor 2306 $v_swap = $this->zip_fd; 2307 $this->zip_fd = $v_zip_temp_fd; 2308 $v_zip_temp_fd = $v_swap; 2311 $this->privCloseFd(); 2313 // ----- Close the temporary file 2314 @fclose($v_zip_temp_fd); 2316 // ----- Magic quotes trick 2317 $this->privSwapBackMagicQuotes(); 2319 // ----- Delete the zip file 2320 // TBC : I should test the result ... 2321 @unlink($this->zipname); 2323 // ----- Rename the temporary file 2324 // TBC : I should test the result ... 2325 //@rename($v_zip_temp_name, $this->zipname); 2326 PclZipUtilRename($v_zip_temp_name, $this->zipname); 2331 // -------------------------------------------------------------------------------- 2333 // -------------------------------------------------------------------------------- 2334 // Function : privOpenFd() 2337 // -------------------------------------------------------------------------------- 2338 function privOpenFd($p_mode) 2342 // ----- Look if already open 2343 if ($this->zip_fd != 0) 2346 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Zip
file \
''.$this->zipname.
'\' already open
'); 2349 return PclZip::errorCode(); 2352 // ----- Open the zip file 2353 if (($this->zip_fd = @fopen($this->zipname, $p_mode)) == 0) 2356 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open archive \
''.$this->zipname.
'\' in '.$p_mode.' mode
'); 2359 return PclZip::errorCode(); 2365 // -------------------------------------------------------------------------------- 2367 // -------------------------------------------------------------------------------- 2368 // Function : privCloseFd() 2371 // -------------------------------------------------------------------------------- 2372 function privCloseFd() 2376 if ($this->zip_fd != 0) 2377 @fclose($this->zip_fd); 2383 // -------------------------------------------------------------------------------- 2385 // -------------------------------------------------------------------------------- 2386 // Function : privAddList() 2388 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is 2389 // different from the real path of the file. This is usefull if you want to have PclTar 2390 // running in any directory, and memorize relative path from an other directory. 2392 // $p_list : An array containing the file or directory names to add in the tar 2393 // $p_result_list : list of added files with their properties (specially the status field) 2394 // $p_add_dir : Path to add in the filename path archived 2395 // $p_remove_dir : Path to remove in the filename path archived 2397 // -------------------------------------------------------------------------------- 2398 // function privAddList($p_list, &$p_result_list, $p_add_dir, $p_remove_dir, $p_remove_all_dir, &$p_options) 2399 function privAddList($p_filedescr_list, &$p_result_list, &$p_options) 2403 // ----- Add the files 2404 $v_header_list = array(); 2405 if (($v_result = $this->privAddFileList($p_filedescr_list, $v_header_list, $p_options)) != 1) 2411 // ----- Store the offset of the central dir 2412 $v_offset = @ftell($this->zip_fd); 2414 // ----- Create the Central Dir files header 2415 for ($i=0,$v_count=0; $i<sizeof($v_header_list); $i++) 2417 // ----- Create the file header 2418 if ($v_header_list[$i]['status
'] == 'ok
') { 2419 if (($v_result = $this->privWriteCentralFileHeader($v_header_list[$i])) != 1) { 2426 // ----- Transform the header to a 'usable
' info 2427 $this->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]); 2430 // ----- Zip file comment 2432 if (isset($p_options[PCLZIP_OPT_COMMENT])) { 2433 $v_comment = $p_options[PCLZIP_OPT_COMMENT]; 2436 // ----- Calculate the size of the central header 2437 $v_size = @ftell($this->zip_fd)-$v_offset; 2439 // ----- Create the central dir footer 2440 if (($v_result = $this->privWriteCentralHeader($v_count, $v_size, $v_offset, $v_comment)) != 1) 2442 // ----- Reset the file list 2443 unset($v_header_list); 2452 // -------------------------------------------------------------------------------- 2454 // -------------------------------------------------------------------------------- 2455 // Function : privAddFileList() 2458 // $p_filedescr_list : An array containing the file description 2459 // or directory names to add in the zip 2460 // $p_result_list : list of added files with their properties (specially the status field) 2462 // -------------------------------------------------------------------------------- 2463 function privAddFileList($p_filedescr_list, &$p_result_list, &$p_options) 2466 $v_header = array(); 2468 // ----- Recuperate the current number of elt in list 2469 $v_nb = sizeof($p_result_list); 2471 // ----- Loop on the files 2472 for ($j=0; ($j<sizeof($p_filedescr_list)) && ($v_result==1); $j++) { 2473 // ----- Format the filename 2474 $p_filedescr_list[$j]['filename
'] 2475 = PclZipUtilTranslateWinPath($p_filedescr_list[$j]['filename
'], false); 2478 // ----- Skip empty file names 2479 // TBC : Can this be possible ? not checked in DescrParseAtt ? 2480 if ($p_filedescr_list[$j]['filename
'] == "") { 2484 // ----- Check the filename 2485 if ( ($p_filedescr_list[$j]['type
'] != 'virtual_file
') 2486 && (!file_exists($p_filedescr_list[$j]['filename
']))) { 2487 PclZip::privErrorLog(PCLZIP_ERR_MISSING_FILE, "File '".$p_filedescr_list[$j]['filename']."' does not exist"); 2488 return PclZip::errorCode(); 2491 // ----- Look if it is a file or a dir with no all path remove option 2492 // or a dir with all its path removed 2493 // if ( (is_file($p_filedescr_list[$j]['filename
'])) 2494 // || ( is_dir($p_filedescr_list[$j]['filename
']) 2495 if ( ($p_filedescr_list[$j]['type
'] == 'file') 2496 || ($p_filedescr_list[$j]['type
'] == 'virtual_file
') 2497 || ( ($p_filedescr_list[$j]['type
'] == 'folder
') 2498 && ( !isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH]) 2499 || !$p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) 2502 // ----- Add the file 2503 $v_result = $this->privAddFile($p_filedescr_list[$j], $v_header, 2505 if ($v_result != 1) { 2509 // ----- Store the file infos 2510 $p_result_list[$v_nb++] = $v_header; 2517 // -------------------------------------------------------------------------------- 2519 // -------------------------------------------------------------------------------- 2520 // Function : privAddFile() 2524 // -------------------------------------------------------------------------------- 2525 function privAddFile($p_filedescr, &$p_header, &$p_options) 2529 // ----- Working variable 2530 $p_filename = $p_filedescr['filename
']; 2532 // TBC : Already done in the fileAtt check ... ? 2533 if ($p_filename == "") { 2535 PclZip::privErrorLog(PCLZIP_ERR_INVALID_PARAMETER, "Invalid file list parameter (invalid or empty list)"); 2538 return PclZip::errorCode(); 2541 // ----- Look for a stored different filename 2543 if (isset($p_filedescr['stored_filename
'])) { 2544 $v_stored_filename = $p_filedescr['stored_filename
']; 2547 $v_stored_filename = $p_filedescr['stored_filename
']; 2551 // ----- Set the file properties 2553 $p_header['version
'] = 20; 2554 $p_header['version_extracted
'] = 10; 2555 $p_header['flag
'] = 0; 2556 $p_header['compression
'] = 0; 2557 $p_header['crc
'] = 0; 2558 $p_header['compressed_size
'] = 0; 2559 $p_header['filename_len
'] = strlen($p_filename); 2560 $p_header['extra_len
'] = 0; 2561 $p_header['disk
'] = 0; 2562 $p_header['internal'] = 0; 2563 $p_header['offset
'] = 0; 2564 $p_header['filename
'] = $p_filename; 2565 // TBC : Removed $p_header['stored_filename
'] = $v_stored_filename; 2566 $p_header['stored_filename
'] = $p_filedescr['stored_filename
']; 2567 $p_header['extra
'] = ''; 2568 $p_header['status
'] = 'ok
'; 2569 $p_header['index
'] = -1; 2571 // ----- Look for regular file 2572 if ($p_filedescr['type
']=='file') { 2573 $p_header['external
'] = 0x00000000; 2574 $p_header['size'] = filesize($p_filename); 2577 // ----- Look for regular folder 2578 else if ($p_filedescr['type
']=='folder
') { 2579 $p_header['external
'] = 0x00000010; 2580 $p_header['mtime
'] = filemtime($p_filename); 2581 $p_header['size'] = filesize($p_filename); 2584 // ----- Look for virtual file 2585 else if ($p_filedescr['type
'] == 'virtual_file
') { 2586 $p_header['external
'] = 0x00000000; 2587 $p_header['size'] = strlen($p_filedescr['content
']); 2591 // ----- Look for filetime 2592 if (isset($p_filedescr['mtime
'])) { 2593 $p_header['mtime
'] = $p_filedescr['mtime
']; 2595 else if ($p_filedescr['type
'] == 'virtual_file
') { 2596 $p_header['mtime
'] = time(); 2599 $p_header['mtime
'] = filemtime($p_filename); 2602 // ------ Look for file comment 2603 if (isset($p_filedescr['comment'])) { 2604 $p_header['comment_len
'] = strlen($p_filedescr['comment']); 2608 $p_header['comment_len
'] = 0; 2612 // ----- Look for pre-add callback 2613 if (isset($p_options[PCLZIP_CB_PRE_ADD])) { 2615 // ----- Generate a local information 2616 $v_local_header = array(); 2617 $this->privConvertHeader2FileInfo($p_header, $v_local_header); 2619 // ----- Call the callback 2620 // Here I do not use call_user_func() because I need to send a reference to the 2622 // eval('$v_result =
'.$p_options[PCLZIP_CB_PRE_ADD].'(
PCLZIP_CB_PRE_ADD, $v_local_header);
'); 2623 $v_result = $p_options[PCLZIP_CB_PRE_ADD](PCLZIP_CB_PRE_ADD, $v_local_header); 2624 if ($v_result == 0) { 2625 // ----- Change the file status 2626 $p_header['status
'] = "skipped"; 2630 // ----- Update the informations 2631 // Only some fields can be modified 2632 if ($p_header['stored_filename
'] != $v_local_header['stored_filename
']) { 2633 $p_header['stored_filename
'] = PclZipUtilPathReduction($v_local_header['stored_filename
']); 2637 // ----- Look for empty stored filename 2638 if ($p_header['stored_filename
'] == "") { 2639 $p_header['status
'] = "filtered"; 2642 // ----- Check the path length 2643 if (strlen($p_header['stored_filename
']) > 0xFF) { 2644 $p_header['status
'] = 'filename_too_long
'; 2647 // ----- Look if no error, or file not skipped 2648 if ($p_header['status
'] == 'ok
') { 2650 // ----- Look for a file 2651 if ($p_filedescr['type
'] == 'file') { 2652 // ----- Look for using temporary file to zip 2653 if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 2654 && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) 2655 || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 2656 && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_header['size'])) ) ) { 2657 $v_result = $this->privAddFileUsingTempFile($p_filedescr, $p_header, $p_options); 2658 if ($v_result < PCLZIP_ERR_NO_ERROR) { 2663 // ----- Use "in memory" zip algo 2666 // ----- Open the source file 2667 if (($v_file = @fopen($p_filename, "rb")) == 0) { 2668 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename
' in binary read mode"); 2669 return PclZip::errorCode(); 2672 // ----- Read the file content 2673 $v_content = @fread($v_file, $p_header['size']); 2675 // ----- Close the file 2678 // ----- Calculate the CRC 2679 $p_header['crc
'] = @crc32($v_content); 2681 // ----- Look for no compression 2682 if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { 2683 // ----- Set header parameters 2684 $p_header['compressed_size
'] = $p_header['size']; 2685 $p_header['compression
'] = 0; 2688 // ----- Look for normal compression 2690 // ----- Compress the content 2691 $v_content = @gzdeflate($v_content); 2693 // ----- Set header parameters 2694 $p_header['compressed_size
'] = strlen($v_content); 2695 $p_header['compression
'] = 8; 2698 // ----- Call the header generation 2699 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { 2704 // ----- Write the compressed (or not) content 2705 @fwrite($this->zip_fd, $v_content, $p_header['compressed_size
']); 2711 // ----- Look for a virtual file (a file from string) 2712 else if ($p_filedescr['type
'] == 'virtual_file
') { 2714 $v_content = $p_filedescr['content
']; 2716 // ----- Calculate the CRC 2717 $p_header['crc
'] = @crc32($v_content); 2719 // ----- Look for no compression 2720 if ($p_options[PCLZIP_OPT_NO_COMPRESSION]) { 2721 // ----- Set header parameters 2722 $p_header['compressed_size
'] = $p_header['size']; 2723 $p_header['compression
'] = 0; 2726 // ----- Look for normal compression 2728 // ----- Compress the content 2729 $v_content = @gzdeflate($v_content); 2731 // ----- Set header parameters 2732 $p_header['compressed_size
'] = strlen($v_content); 2733 $p_header['compression
'] = 8; 2736 // ----- Call the header generation 2737 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { 2742 // ----- Write the compressed (or not) content 2743 @fwrite($this->zip_fd, $v_content, $p_header['compressed_size
']); 2746 // ----- Look for a directory 2747 else if ($p_filedescr['type
'] == 'folder
') { 2748 // ----- Look for directory last '/
' 2749 if (@substr($p_header['stored_filename
'], -1) != '/
') { 2750 $p_header['stored_filename
'] .= '/
'; 2753 // ----- Set the file properties 2754 $p_header['size'] = 0; 2755 //$p_header['external
'] = 0x41FF0010; // Value for a folder : to be checked 2756 $p_header['external
'] = 0x00000010; // Value for a folder : to be checked 2758 // ----- Call the header generation 2759 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) 2766 // ----- Look for post-add callback 2767 if (isset($p_options[PCLZIP_CB_POST_ADD])) { 2769 // ----- Generate a local information 2770 $v_local_header = array(); 2771 $this->privConvertHeader2FileInfo($p_header, $v_local_header); 2773 // ----- Call the callback 2774 // Here I do not use call_user_func() because I need to send a reference to the 2776 // eval('$v_result =
'.$p_options[PCLZIP_CB_POST_ADD].'(
PCLZIP_CB_POST_ADD, $v_local_header);
'); 2777 $v_result = $p_options[PCLZIP_CB_POST_ADD](PCLZIP_CB_POST_ADD, $v_local_header); 2778 if ($v_result == 0) { 2783 // ----- Update the informations 2784 // Nothing can be modified 2790 // -------------------------------------------------------------------------------- 2792 // -------------------------------------------------------------------------------- 2793 // Function : privAddFileUsingTempFile() 2797 // -------------------------------------------------------------------------------- 2798 function privAddFileUsingTempFile($p_filedescr, &$p_header, &$p_options) 2800 $v_result=PCLZIP_ERR_NO_ERROR; 2802 // ----- Working variable 2803 $p_filename = $p_filedescr['filename
']; 2806 // ----- Open the source file 2807 if (($v_file = @fopen($p_filename, "rb")) == 0) { 2808 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, "Unable to open file '$p_filename
' in binary read mode"); 2809 return PclZip::errorCode(); 2812 // ----- Creates a compressed temporary file 2813 $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-
').'.gz
'; 2814 if (($v_file_compressed = @gzopen($v_gzip_temp_name, "wb")) == 0) { 2816 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable
to open temporary
file \
''.$v_gzip_temp_name.
'\' in binary write mode
'); 2817 return PclZip::errorCode(); 2820 // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 2821 $v_size = filesize($p_filename); 2822 while ($v_size != 0) { 2823 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 2824 $v_buffer = @fread($v_file, $v_read_size); 2825 //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 2826 @gzputs($v_file_compressed, $v_buffer, $v_read_size); 2827 $v_size -= $v_read_size; 2830 // ----- Close the file 2832 @gzclose($v_file_compressed); 2834 // ----- Check the minimum file size 2835 if (filesize($v_gzip_temp_name) < 18) { 2836 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'gzip temporary
file \
''.$v_gzip_temp_name.
'\' has invalid filesize - should be minimum 18 bytes
'); 2837 return PclZip::errorCode(); 2840 // ----- Extract the compressed attributes 2841 if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) { 2842 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open temporary
file \
''.$v_gzip_temp_name.
'\' in binary read mode
'); 2843 return PclZip::errorCode(); 2846 // ----- Read the gzip file header 2847 $v_binary_data = @fread($v_file_compressed, 10); 2848 $v_data_header = unpack('a1id1/a1id2/a1cm/a1flag/Vmtime/a1xfl/a1os
', $v_binary_data); 2850 // ----- Check some parameters 2851 $v_data_header['os
'] = bin2hex($v_data_header['os
']); 2853 // ----- Read the gzip file footer 2854 @fseek($v_file_compressed, filesize($v_gzip_temp_name)-8); 2855 $v_binary_data = @fread($v_file_compressed, 8); 2856 $v_data_footer = unpack('Vcrc/Vcompressed_size
', $v_binary_data); 2858 // ----- Set the attributes 2859 $p_header['compression
'] = ord($v_data_header['cm
']); 2860 //$p_header['mtime
'] = $v_data_header['mtime
']; 2861 $p_header['crc
'] = $v_data_footer['crc
']; 2862 $p_header['compressed_size
'] = filesize($v_gzip_temp_name)-18; 2864 // ----- Close the file 2865 @fclose($v_file_compressed); 2867 // ----- Call the header generation 2868 if (($v_result = $this->privWriteFileHeader($p_header)) != 1) { 2872 // ----- Add the compressed data 2873 if (($v_file_compressed = @fopen($v_gzip_temp_name, "rb")) == 0) 2875 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open temporary
file \
''.$v_gzip_temp_name.
'\' in binary read mode
'); 2876 return PclZip::errorCode(); 2879 // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 2880 fseek($v_file_compressed, 10); 2881 $v_size = $p_header['compressed_size
']; 2882 while ($v_size != 0) 2884 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 2885 $v_buffer = @fread($v_file_compressed, $v_read_size); 2886 //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 2887 @fwrite($this->zip_fd, $v_buffer, $v_read_size); 2888 $v_size -= $v_read_size; 2891 // ----- Close the file 2892 @fclose($v_file_compressed); 2894 // ----- Unlink the temporary file 2895 @unlink($v_gzip_temp_name); 2900 // -------------------------------------------------------------------------------- 2902 // -------------------------------------------------------------------------------- 2903 // Function : privCalculateStoredFilename() 2905 // Based on file descriptor properties and global options, this method 2906 // calculate the filename that will be stored in the archive. 2909 // -------------------------------------------------------------------------------- 2910 function privCalculateStoredFilename(&$p_filedescr, &$p_options) 2914 // ----- Working variables 2915 $p_filename = $p_filedescr['filename
']; 2916 if (isset($p_options[PCLZIP_OPT_ADD_PATH])) { 2917 $p_add_dir = $p_options[PCLZIP_OPT_ADD_PATH]; 2922 if (isset($p_options[PCLZIP_OPT_REMOVE_PATH])) { 2923 $p_remove_dir = $p_options[PCLZIP_OPT_REMOVE_PATH]; 2928 if (isset($p_options[PCLZIP_OPT_REMOVE_ALL_PATH])) { 2929 $p_remove_all_dir = $p_options[PCLZIP_OPT_REMOVE_ALL_PATH]; 2932 $p_remove_all_dir = 0; 2936 // ----- Look for full name change 2937 if (isset($p_filedescr['new_full_name
'])) { 2938 // ----- Remove drive letter if any 2939 $v_stored_filename = PclZipUtilTranslateWinPath($p_filedescr['new_full_name
']); 2942 // ----- Look for path and/or short name change 2945 // ----- Look for short name change 2946 // Its when we cahnge just the filename but not the path 2947 if (isset($p_filedescr['new_short_name
'])) { 2948 $v_path_info = pathinfo($p_filename); 2950 if ($v_path_info['dirname
'] != '') { 2951 $v_dir = $v_path_info['dirname
'].'/
'; 2953 $v_stored_filename = $v_dir.$p_filedescr['new_short_name
']; 2956 // ----- Calculate the stored filename 2957 $v_stored_filename = $p_filename; 2960 // ----- Look for all path to remove 2961 if ($p_remove_all_dir) { 2962 $v_stored_filename = basename($p_filename); 2964 // ----- Look for partial path remove 2965 else if ($p_remove_dir != "") { 2966 if (substr($p_remove_dir, -1) != '/
') 2967 $p_remove_dir .= "/"; 2969 if ( (substr($p_filename, 0, 2) == "./") 2970 || (substr($p_remove_dir, 0, 2) == "./")) { 2972 if ( (substr($p_filename, 0, 2) == "./") 2973 && (substr($p_remove_dir, 0, 2) != "./")) { 2974 $p_remove_dir = "./".$p_remove_dir; 2976 if ( (substr($p_filename, 0, 2) != "./") 2977 && (substr($p_remove_dir, 0, 2) == "./")) { 2978 $p_remove_dir = substr($p_remove_dir, 2); 2982 $v_compare = PclZipUtilPathInclusion($p_remove_dir, 2983 $v_stored_filename); 2984 if ($v_compare > 0) { 2985 if ($v_compare == 2) { 2986 $v_stored_filename = ""; 2989 $v_stored_filename = substr($v_stored_filename, 2990 strlen($p_remove_dir)); 2995 // ----- Remove drive letter if any 2996 $v_stored_filename = PclZipUtilTranslateWinPath($v_stored_filename); 2998 // ----- Look for path to add 2999 if ($p_add_dir != "") { 3000 if (substr($p_add_dir, -1) == "/") 3001 $v_stored_filename = $p_add_dir.$v_stored_filename; 3003 $v_stored_filename = $p_add_dir."/".$v_stored_filename; 3007 // ----- Filename (reduce the path of stored name) 3008 $v_stored_filename = PclZipUtilPathReduction($v_stored_filename); 3009 $p_filedescr['stored_filename
'] = $v_stored_filename; 3014 // -------------------------------------------------------------------------------- 3016 // -------------------------------------------------------------------------------- 3017 // Function : privWriteFileHeader() 3021 // -------------------------------------------------------------------------------- 3022 function privWriteFileHeader(&$p_header) 3026 // ----- Store the offset position of the file 3027 $p_header['offset
'] = ftell($this->zip_fd); 3029 // ----- Transform UNIX mtime to DOS format mdate/mtime 3030 $v_date = getdate($p_header['mtime
']); 3031 $v_mtime = ($v_date['hours
']<<11) + ($v_date['minutes
']<<5) + $v_date['seconds']/2; 3032 $v_mdate = (($v_date['year
']-1980)<<9) + ($v_date['mon
']<<5) + $v_date['mday
']; 3034 // ----- Packed data 3035 $v_binary_data = pack("VvvvvvVVVvv", 0x04034b50, 3036 $p_header['version_extracted
'], $p_header['flag
'], 3037 $p_header['compression
'], $v_mtime, $v_mdate, 3038 $p_header['crc
'], $p_header['compressed_size
'], 3040 strlen($p_header['stored_filename
']), 3041 $p_header['extra_len
']); 3043 // ----- Write the first 148 bytes of the header in the archive 3044 fputs($this->zip_fd, $v_binary_data, 30); 3046 // ----- Write the variable fields 3047 if (strlen($p_header['stored_filename
']) != 0) 3049 fputs($this->zip_fd, $p_header['stored_filename
'], strlen($p_header['stored_filename
'])); 3051 if ($p_header['extra_len
'] != 0) 3053 fputs($this->zip_fd, $p_header['extra
'], $p_header['extra_len
']); 3059 // -------------------------------------------------------------------------------- 3061 // -------------------------------------------------------------------------------- 3062 // Function : privWriteCentralFileHeader() 3066 // -------------------------------------------------------------------------------- 3067 function privWriteCentralFileHeader(&$p_header) 3072 //for(reset($p_header); $key = key($p_header); next($p_header)) { 3075 // ----- Transform UNIX mtime to DOS format mdate/mtime 3076 $v_date = getdate($p_header['mtime
']); 3077 $v_mtime = ($v_date['hours
']<<11) + ($v_date['minutes
']<<5) + $v_date['seconds']/2; 3078 $v_mdate = (($v_date['year
']-1980)<<9) + ($v_date['mon
']<<5) + $v_date['mday
']; 3081 // ----- Packed data 3082 $v_binary_data = pack("VvvvvvvVVVvvvvvVV", 0x02014b50, 3083 $p_header['version
'], $p_header['version_extracted
'], 3084 $p_header['flag
'], $p_header['compression
'], 3085 $v_mtime, $v_mdate, $p_header['crc
'], 3086 $p_header['compressed_size
'], $p_header['size'], 3087 strlen($p_header['stored_filename
']), 3088 $p_header['extra_len
'], $p_header['comment_len
'], 3089 $p_header['disk
'], $p_header['internal'], 3090 $p_header['external
'], $p_header['offset
']); 3092 // ----- Write the 42 bytes of the header in the zip file 3093 fputs($this->zip_fd, $v_binary_data, 46); 3095 // ----- Write the variable fields 3096 if (strlen($p_header['stored_filename
']) != 0) 3098 fputs($this->zip_fd, $p_header['stored_filename
'], strlen($p_header['stored_filename
'])); 3100 if ($p_header['extra_len
'] != 0) 3102 fputs($this->zip_fd, $p_header['extra
'], $p_header['extra_len
']); 3104 if ($p_header['comment_len
'] != 0) 3106 fputs($this->zip_fd, $p_header['comment'], $p_header['comment_len
']); 3112 // -------------------------------------------------------------------------------- 3114 // -------------------------------------------------------------------------------- 3115 // Function : privWriteCentralHeader() 3119 // -------------------------------------------------------------------------------- 3120 function privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment) 3124 // ----- Packed data 3125 $v_binary_data = pack("VvvvvVVv", 0x06054b50, 0, 0, $p_nb_entries, 3126 $p_nb_entries, $p_size, 3127 $p_offset, strlen($p_comment)); 3129 // ----- Write the 22 bytes of the header in the zip file 3130 fputs($this->zip_fd, $v_binary_data, 22); 3132 // ----- Write the variable fields 3133 if (strlen($p_comment) != 0) 3135 fputs($this->zip_fd, $p_comment, strlen($p_comment)); 3141 // -------------------------------------------------------------------------------- 3143 // -------------------------------------------------------------------------------- 3144 // Function : privList() 3148 // -------------------------------------------------------------------------------- 3149 function privList(&$p_list) 3153 // ----- Magic quotes trick 3154 $this->privDisableMagicQuotes(); 3156 // ----- Open the zip file 3157 if (($this->zip_fd = @fopen($this->zipname, 'rb
')) == 0) 3159 // ----- Magic quotes trick 3160 $this->privSwapBackMagicQuotes(); 3163 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open archive \
''.$this->zipname.
'\' in binary read mode
'); 3166 return PclZip::errorCode(); 3169 // ----- Read the central directory informations 3170 $v_central_dir = array(); 3171 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 3173 $this->privSwapBackMagicQuotes(); 3177 // ----- Go to beginning of Central Dir 3178 @rewind($this->zip_fd); 3179 if (@fseek($this->zip_fd, $v_central_dir['offset
'])) 3181 $this->privSwapBackMagicQuotes(); 3184 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive
size'); 3187 return PclZip::errorCode(); 3190 // ----- Read each entry 3191 for ($i=0; $i<$v_central_dir['entries
']; $i++) 3193 // ----- Read the file header 3194 if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) 3196 $this->privSwapBackMagicQuotes(); 3199 $v_header['index
'] = $i; 3201 // ----- Get the only interesting attributes 3202 $this->privConvertHeader2FileInfo($v_header, $p_list[$i]); 3206 // ----- Close the zip file 3207 $this->privCloseFd(); 3209 // ----- Magic quotes trick 3210 $this->privSwapBackMagicQuotes(); 3215 // -------------------------------------------------------------------------------- 3217 // -------------------------------------------------------------------------------- 3218 // Function : privConvertHeader2FileInfo() 3220 // This function takes the file informations from the central directory 3221 // entries and extract the interesting parameters that will be given back. 3222 // The resulting file infos are set in the array $p_info 3223 // $p_info['filename
'] : Filename with full path. Given by user (add), 3224 // extracted in the filesystem (extract). 3225 // $p_info['stored_filename
'] : Stored filename in the archive. 3226 // $p_info['size'] = Size of the file. 3227 // $p_info['compressed_size
'] = Compressed size of the file. 3228 // $p_info['mtime
'] = Last modification date of the file. 3229 // $p_info['comment'] = Comment associated with the file. 3230 // $p_info['folder
'] = true/false : indicates if the entry is a folder or not. 3231 // $p_info['status
'] = status of the action on the file. 3232 // $p_info['crc
'] = CRC of the file content. 3235 // -------------------------------------------------------------------------------- 3236 function privConvertHeader2FileInfo($p_header, &$p_info) 3240 // ----- Get the interesting attributes 3241 $v_temp_path = PclZipUtilPathReduction($p_header['filename
']); 3242 $p_info['filename
'] = $v_temp_path; 3243 $v_temp_path = PclZipUtilPathReduction($p_header['stored_filename
']); 3244 $p_info['stored_filename
'] = $v_temp_path; 3245 $p_info['size'] = $p_header['size']; 3246 $p_info['compressed_size
'] = $p_header['compressed_size
']; 3247 $p_info['mtime
'] = $p_header['mtime
']; 3249 $p_info['folder
'] = (($p_header['external
']&0x00000010)==0x00000010); 3250 $p_info['index
'] = $p_header['index
']; 3251 $p_info['status
'] = $p_header['status
']; 3252 $p_info['crc
'] = $p_header['crc
']; 3257 // -------------------------------------------------------------------------------- 3259 // -------------------------------------------------------------------------------- 3260 // Function : privExtractByRule() 3262 // Extract a file or directory depending of rules (by index, by name, ...) 3264 // $p_file_list : An array where will be placed the properties of each 3266 // $p_path : Path to add while writing the extracted files 3267 // $p_remove_path : Path to remove (from the file memorized path) while writing the 3268 // extracted files. If the path does not match the file path, 3269 // the file is extracted with its memorized path. 3270 // $p_remove_path does not apply to 'list
' mode. 3271 // $p_path and $p_remove_path are commulative. 3273 // 1 on success,0 or less on error (see error code list) 3274 // -------------------------------------------------------------------------------- 3275 function privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) 3279 // ----- Magic quotes trick 3280 $this->privDisableMagicQuotes(); 3282 // ----- Check the path 3283 if ( ($p_path == "") 3284 || ( (substr($p_path, 0, 1) != "/") 3285 && (substr($p_path, 0, 3) != "../") 3286 && (substr($p_path,1,2)!=":/"))) 3287 $p_path = "./".$p_path; 3289 // ----- Reduce the path last (and duplicated) '/
' 3290 if (($p_path != "./") && ($p_path != "/")) 3292 // ----- Look for the path end '/
' 3293 while (substr($p_path, -1) == "/") 3295 $p_path = substr($p_path, 0, strlen($p_path)-1); 3299 // ----- Look for path to remove format (should end by /) 3300 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/
')) 3302 $p_remove_path .= '/
'; 3304 $p_remove_path_size = strlen($p_remove_path); 3306 // ----- Open the zip file 3307 if (($v_result = $this->privOpenFd('rb
')) != 1) 3309 $this->privSwapBackMagicQuotes(); 3313 // ----- Read the central directory informations 3314 $v_central_dir = array(); 3315 if (($v_result = $this->privReadEndCentralDir($v_central_dir)) != 1) 3317 // ----- Close the zip file 3318 $this->privCloseFd(); 3319 $this->privSwapBackMagicQuotes(); 3324 // ----- Start at beginning of Central Dir 3325 $v_pos_entry = $v_central_dir['offset
']; 3327 // ----- Read each entry 3329 for ($i=0, $v_nb_extracted=0; $i<$v_central_dir['entries
']; $i++) 3332 // ----- Read next Central dir entry 3333 @rewind($this->zip_fd); 3334 if (@fseek($this->zip_fd, $v_pos_entry)) 3336 // ----- Close the zip file 3337 $this->privCloseFd(); 3338 $this->privSwapBackMagicQuotes(); 3341 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive
size'); 3344 return PclZip::errorCode(); 3347 // ----- Read the file header 3348 $v_header = array(); 3349 if (($v_result = $this->privReadCentralFileHeader($v_header)) != 1) 3351 // ----- Close the zip file 3352 $this->privCloseFd(); 3353 $this->privSwapBackMagicQuotes(); 3358 // ----- Store the index 3359 $v_header['index
'] = $i; 3361 // ----- Store the file position 3362 $v_pos_entry = ftell($this->zip_fd); 3364 // ----- Look for the specific extract rules 3367 // ----- Look for extract by name rule 3368 if ( (isset($p_options[PCLZIP_OPT_BY_NAME])) 3369 && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) { 3371 // ----- Look if the filename is in the list 3372 for ($j=0; ($j<sizeof($p_options[PCLZIP_OPT_BY_NAME])) && (!$v_extract); $j++) { 3374 // ----- Look for a directory 3375 if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) == "/") { 3377 // ----- Look if the directory is in the filename path 3378 if ( (strlen($v_header['stored_filename
']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) 3379 && (substr($v_header['stored_filename
'], 0, strlen($p_options[PCLZIP_OPT_BY_NAME][$j])) == $p_options[PCLZIP_OPT_BY_NAME][$j])) { 3383 // ----- Look for a filename 3384 elseif ($v_header['stored_filename
'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) { 3390 // ----- Look for extract by ereg rule 3391 // ereg() is deprecated with PHP 5.3 3393 else if ( (isset($p_options[PCLZIP_OPT_BY_EREG])) 3394 && ($p_options[PCLZIP_OPT_BY_EREG] != "")) { 3396 if (ereg($p_options[PCLZIP_OPT_BY_EREG], $v_header['stored_filename
'])) { 3402 // ----- Look for extract by preg rule 3403 else if ( (isset($p_options[PCLZIP_OPT_BY_PREG])) 3404 && ($p_options[PCLZIP_OPT_BY_PREG] != "")) { 3406 if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header['stored_filename
'])) { 3411 // ----- Look for extract by index rule 3412 else if ( (isset($p_options[PCLZIP_OPT_BY_INDEX])) 3413 && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) { 3415 // ----- Look if the index is in the list 3416 for ($j=$j_start; ($j<sizeof($p_options[PCLZIP_OPT_BY_INDEX])) && (!$v_extract); $j++) { 3418 if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['start
']) && ($i<=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end
'])) { 3421 if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j]['end
']) { 3425 if ($p_options[PCLZIP_OPT_BY_INDEX][$j]['start
']>$i) { 3431 // ----- Look for no rule, which means extract all the archive 3436 // ----- Check compression method 3438 && ( ($v_header['compression
'] != 8) 3439 && ($v_header['compression
'] != 0))) { 3440 $v_header['status
'] = 'unsupported_compression
'; 3442 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 3443 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 3444 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 3446 $this->privSwapBackMagicQuotes(); 3448 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_COMPRESSION, 3449 "Filename '".$v_header['stored_filename']."' is " 3450 ."compressed by an unsupported compression " 3451 ."method (".$v_header['compression
'].") "); 3453 return PclZip::errorCode(); 3457 // ----- Check encrypted files 3458 if (($v_extract) && (($v_header['flag
'] & 1) == 1)) { 3459 $v_header['status
'] = 'unsupported_encryption
'; 3461 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 3462 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 3463 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 3465 $this->privSwapBackMagicQuotes(); 3467 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 3468 "Unsupported encryption for " 3469 ." filename '".$v_header['stored_filename'] 3472 return PclZip::errorCode(); 3476 // ----- Look for real extraction 3477 if (($v_extract) && ($v_header['status
'] != 'ok
')) { 3478 $v_result = $this->privConvertHeader2FileInfo($v_header, 3479 $p_file_list[$v_nb_extracted++]); 3480 if ($v_result != 1) { 3481 $this->privCloseFd(); 3482 $this->privSwapBackMagicQuotes(); 3489 // ----- Look for real extraction 3493 // ----- Go to the file position 3494 @rewind($this->zip_fd); 3495 if (@fseek($this->zip_fd, $v_header['offset
'])) 3497 // ----- Close the zip file 3498 $this->privCloseFd(); 3500 $this->privSwapBackMagicQuotes(); 3503 PclZip::privErrorLog(PCLZIP_ERR_INVALID_ARCHIVE_ZIP, 'Invalid archive
size'); 3506 return PclZip::errorCode(); 3509 // ----- Look for extraction as string 3510 if ($p_options[PCLZIP_OPT_EXTRACT_AS_STRING]) { 3514 // ----- Extracting the file 3515 $v_result1 = $this->privExtractFileAsString($v_header, $v_string, $p_options); 3516 if ($v_result1 < 1) { 3517 $this->privCloseFd(); 3518 $this->privSwapBackMagicQuotes(); 3522 // ----- Get the only interesting attributes 3523 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted])) != 1) 3525 // ----- Close the zip file 3526 $this->privCloseFd(); 3527 $this->privSwapBackMagicQuotes(); 3532 // ----- Set the file content 3533 $p_file_list[$v_nb_extracted]['content
'] = $v_string; 3535 // ----- Next extracted file 3538 // ----- Look for user callback abort 3539 if ($v_result1 == 2) { 3543 // ----- Look for extraction in standard output 3544 elseif ( (isset($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) 3545 && ($p_options[PCLZIP_OPT_EXTRACT_IN_OUTPUT])) { 3546 // ----- Extracting the file in standard output 3547 $v_result1 = $this->privExtractFileInOutput($v_header, $p_options); 3548 if ($v_result1 < 1) { 3549 $this->privCloseFd(); 3550 $this->privSwapBackMagicQuotes(); 3554 // ----- Get the only interesting attributes 3555 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) { 3556 $this->privCloseFd(); 3557 $this->privSwapBackMagicQuotes(); 3561 // ----- Look for user callback abort 3562 if ($v_result1 == 2) { 3566 // ----- Look for normal extraction 3568 // ----- Extracting the file 3569 $v_result1 = $this->privExtractFile($v_header, 3570 $p_path, $p_remove_path, 3573 if ($v_result1 < 1) { 3574 $this->privCloseFd(); 3575 $this->privSwapBackMagicQuotes(); 3579 // ----- Get the only interesting attributes 3580 if (($v_result = $this->privConvertHeader2FileInfo($v_header, $p_file_list[$v_nb_extracted++])) != 1) 3582 // ----- Close the zip file 3583 $this->privCloseFd(); 3584 $this->privSwapBackMagicQuotes(); 3589 // ----- Look for user callback abort 3590 if ($v_result1 == 2) { 3597 // ----- Close the zip file 3598 $this->privCloseFd(); 3599 $this->privSwapBackMagicQuotes(); 3604 // -------------------------------------------------------------------------------- 3606 // -------------------------------------------------------------------------------- 3607 // Function : privExtractFile() 3613 // PCLZIP_ERR_USER_ABORTED(2) : User ask for extraction stop in callback 3614 // -------------------------------------------------------------------------------- 3615 function privExtractFile(&$p_entry, $p_path, $p_remove_path, $p_remove_all_path, &$p_options) 3619 // ----- Read the file header 3620 if (($v_result = $this->privReadFileHeader($v_header)) != 1) 3627 // ----- Check that the file header is coherent with $p_entry info 3628 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { 3632 // ----- Look for all path to remove 3633 if ($p_remove_all_path == true) { 3634 // ----- Look for folder entry that not need to be extracted 3635 if (($p_entry['external
']&0x00000010)==0x00000010) { 3637 $p_entry['status
'] = "filtered"; 3642 // ----- Get the basename of the path 3643 $p_entry['filename
'] = basename($p_entry['filename
']); 3646 // ----- Look for path to remove 3647 else if ($p_remove_path != "") 3649 if (PclZipUtilPathInclusion($p_remove_path, $p_entry['filename
']) == 2) 3652 // ----- Change the file status 3653 $p_entry['status
'] = "filtered"; 3659 $p_remove_path_size = strlen($p_remove_path); 3660 if (substr($p_entry['filename
'], 0, $p_remove_path_size) == $p_remove_path) 3663 // ----- Remove the path 3664 $p_entry['filename
'] = substr($p_entry['filename
'], $p_remove_path_size); 3669 // ----- Add the path 3670 if ($p_path != '') { 3671 $p_entry['filename
'] = $p_path."/".$p_entry['filename
']; 3674 // ----- Check a base_dir_restriction 3675 if (isset($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION])) { 3677 = PclZipUtilPathInclusion($p_options[PCLZIP_OPT_EXTRACT_DIR_RESTRICTION], 3678 $p_entry['filename
']); 3679 if ($v_inclusion == 0) { 3681 PclZip::privErrorLog(PCLZIP_ERR_DIRECTORY_RESTRICTION, 3682 "Filename '".$p_entry['filename']."' is " 3683 ."outside PCLZIP_OPT_EXTRACT_DIR_RESTRICTION"); 3685 return PclZip::errorCode(); 3689 // ----- Look for pre-extract callback 3690 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { 3692 // ----- Generate a local information 3693 $v_local_header = array(); 3694 $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 3696 // ----- Call the callback 3697 // Here I do not use call_user_func() because I need to send a reference to the 3699 // eval('$v_result =
'.$p_options[PCLZIP_CB_PRE_EXTRACT].'(
PCLZIP_CB_PRE_EXTRACT, $v_local_header);
'); 3700 $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); 3701 if ($v_result == 0) { 3702 // ----- Change the file status 3703 $p_entry['status
'] = "skipped"; 3707 // ----- Look for abort result 3708 if ($v_result == 2) { 3709 // ----- This status is internal and will be changed in 'skipped
' 3710 $p_entry['status
'] = "aborted"; 3711 $v_result = PCLZIP_ERR_USER_ABORTED; 3714 // ----- Update the informations 3715 // Only some fields can be modified 3716 $p_entry['filename
'] = $v_local_header['filename
']; 3720 // ----- Look if extraction should be done 3721 if ($p_entry['status
'] == 'ok
') { 3723 // ----- Look for specific actions while the file exist 3724 if (file_exists($p_entry['filename
'])) 3727 // ----- Look if file is a directory 3728 if (is_dir($p_entry['filename
'])) 3731 // ----- Change the file status 3732 $p_entry['status
'] = "already_a_directory"; 3734 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 3735 // For historical reason first PclZip implementation does not stop 3736 // when this kind of error occurs. 3737 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 3738 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 3740 PclZip::privErrorLog(PCLZIP_ERR_ALREADY_A_DIRECTORY, 3741 "Filename '".$p_entry['filename']."' is " 3742 ."already used by an existing directory"); 3744 return PclZip::errorCode(); 3747 // ----- Look if file is write protected 3748 else if (!is_writeable($p_entry['filename
'])) 3751 // ----- Change the file status 3752 $p_entry['status
'] = "write_protected"; 3754 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 3755 // For historical reason first PclZip implementation does not stop 3756 // when this kind of error occurs. 3757 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 3758 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 3760 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 3761 "Filename '".$p_entry['filename']."' exists " 3762 ."and is write protected"); 3764 return PclZip::errorCode(); 3768 // ----- Look if the extracted file is older 3769 else if (filemtime($p_entry['filename
']) > $p_entry['mtime
']) 3771 // ----- Change the file status 3772 if ( (isset($p_options[PCLZIP_OPT_REPLACE_NEWER])) 3773 && ($p_options[PCLZIP_OPT_REPLACE_NEWER]===true)) { 3776 $p_entry['status
'] = "newer_exist"; 3778 // ----- Look for PCLZIP_OPT_STOP_ON_ERROR 3779 // For historical reason first PclZip implementation does not stop 3780 // when this kind of error occurs. 3781 if ( (isset($p_options[PCLZIP_OPT_STOP_ON_ERROR])) 3782 && ($p_options[PCLZIP_OPT_STOP_ON_ERROR]===true)) { 3784 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 3785 "Newer version of '".$p_entry['filename']."' exists " 3786 ."and option PCLZIP_OPT_REPLACE_NEWER is not selected"); 3788 return PclZip::errorCode(); 3796 // ----- Check the directory availability and create it if necessary 3798 if ((($p_entry['external
']&0x00000010)==0x00000010) || (substr($p_entry['filename
'], -1) == '/
')) 3799 $v_dir_to_check = $p_entry['filename
']; 3800 else if (!strstr($p_entry['filename
'], "/")) 3801 $v_dir_to_check = ""; 3803 $v_dir_to_check = dirname($p_entry['filename
']); 3805 if (($v_result = $this->privDirCheck($v_dir_to_check, (($p_entry['external
']&0x00000010)==0x00000010))) != 1) { 3807 // ----- Change the file status 3808 $p_entry['status
'] = "path_creation_fail"; 3817 // ----- Look if extraction should be done 3818 if ($p_entry['status
'] == 'ok
') { 3820 // ----- Do the extraction (if not a folder) 3821 if (!(($p_entry['external
']&0x00000010)==0x00000010)) 3823 // ----- Look for not compressed file 3824 if ($p_entry['compression
'] == 0) { 3826 // ----- Opening destination file 3827 if (($v_dest_file = @fopen($p_entry['filename
'], 'wb
')) == 0) 3830 // ----- Change the file status 3831 $p_entry['status
'] = "write_error"; 3838 // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 3839 $v_size = $p_entry['compressed_size
']; 3840 while ($v_size != 0) 3842 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 3843 $v_buffer = @fread($this->zip_fd, $v_read_size); 3844 /* Try to speed up the code 3845 $v_binary_data = pack('a'.$v_read_size, $v_buffer); 3846 @fwrite($v_dest_file, $v_binary_data, $v_read_size); 3848 @fwrite($v_dest_file, $v_buffer, $v_read_size); 3849 $v_size -= $v_read_size; 3852 // ----- Closing the destination file 3853 fclose($v_dest_file); 3855 // ----- Change the file mtime 3856 touch($p_entry['filename
'], $p_entry['mtime
']); 3862 // Need to be finished 3863 if (($p_entry['flag
'] & 1) == 1) { 3864 PclZip::privErrorLog(PCLZIP_ERR_UNSUPPORTED_ENCRYPTION, 'File \
''.$p_entry[
'filename'].
'\' is encrypted. Encrypted
files are not supported.
'); 3865 return PclZip::errorCode(); 3869 // ----- Look for using temporary file to unzip 3870 if ( (!isset($p_options[PCLZIP_OPT_TEMP_FILE_OFF])) 3871 && (isset($p_options[PCLZIP_OPT_TEMP_FILE_ON]) 3872 || (isset($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD]) 3873 && ($p_options[PCLZIP_OPT_TEMP_FILE_THRESHOLD] <= $p_entry['size
'])) ) ) { 3874 $v_result = $this->privExtractFileUsingTempFile($p_entry, $p_options); 3875 if ($v_result < PCLZIP_ERR_NO_ERROR) { 3880 // ----- Look for extract in memory 3884 // ----- Read the compressed file in a buffer (one shot) 3885 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size
']); 3887 // ----- Decompress the file 3888 $v_file_content = @gzinflate($v_buffer); 3890 if ($v_file_content === FALSE) { 3892 // ----- Change the file status 3894 $p_entry['status
'] = "error"; 3899 // ----- Opening destination file 3900 if (($v_dest_file = @fopen($p_entry['filename
'], 'wb
')) == 0) { 3902 // ----- Change the file status 3903 $p_entry['status
'] = "write_error"; 3908 // ----- Write the uncompressed data 3909 @fwrite($v_dest_file, $v_file_content, $p_entry['size']); 3910 unset($v_file_content); 3912 // ----- Closing the destination file 3913 @fclose($v_dest_file); 3917 // ----- Change the file mtime 3918 @touch($p_entry['filename
'], $p_entry['mtime
']); 3921 // ----- Look for chmod option 3922 if (isset($p_options[PCLZIP_OPT_SET_CHMOD])) { 3924 // ----- Change the mode of the file 3925 @chmod($p_entry['filename
'], $p_options[PCLZIP_OPT_SET_CHMOD]); 3931 // ----- Change abort status 3932 if ($p_entry['status
'] == "aborted") { 3933 $p_entry['status
'] = "skipped"; 3936 // ----- Look for post-extract callback 3937 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { 3939 // ----- Generate a local information 3940 $v_local_header = array(); 3941 $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 3943 // ----- Call the callback 3944 // Here I do not use call_user_func() because I need to send a reference to the 3947 $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); 3949 // ----- Look for abort result 3950 if ($v_result == 2) { 3951 $v_result = PCLZIP_ERR_USER_ABORTED; 3958 // -------------------------------------------------------------------------------- 3960 // -------------------------------------------------------------------------------- 3961 // Function : privExtractFileUsingTempFile() 3965 // -------------------------------------------------------------------------------- 3966 function privExtractFileUsingTempFile(&$p_entry, &$p_options) 3970 // ----- Creates a temporary file 3971 $v_gzip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid('pclzip-
').'.gz
'; 3972 if (($v_dest_file = @fopen($v_gzip_temp_name, "wb")) == 0) { 3974 PclZip::privErrorLog(PCLZIP_ERR_WRITE_OPEN_FAIL, 'Unable
to open temporary
file \
''.$v_gzip_temp_name.
'\' in binary write mode
'); 3975 return PclZip::errorCode(); 3979 // ----- Write gz file format header 3980 $v_binary_data = pack('va1a1Va1a1
', 0x8b1f, Chr($p_entry['compression
']), Chr(0x00), time(), Chr(0x00), Chr(3)); 3981 @fwrite($v_dest_file, $v_binary_data, 10); 3983 // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 3984 $v_size = $p_entry['compressed_size
']; 3985 while ($v_size != 0) 3987 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 3988 $v_buffer = @fread($this->zip_fd, $v_read_size); 3989 //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 3990 @fwrite($v_dest_file, $v_buffer, $v_read_size); 3991 $v_size -= $v_read_size; 3994 // ----- Write gz file format footer 3995 $v_binary_data = pack('VV
', $p_entry['crc
'], $p_entry['size']); 3996 @fwrite($v_dest_file, $v_binary_data, 8); 3998 // ----- Close the temporary file 3999 @fclose($v_dest_file); 4001 // ----- Opening destination file 4002 if (($v_dest_file = @fopen($p_entry['filename
'], 'wb
')) == 0) { 4003 $p_entry['status
'] = "write_error"; 4007 // ----- Open the temporary gz file 4008 if (($v_src_file = @gzopen($v_gzip_temp_name, 'rb
')) == 0) { 4009 @fclose($v_dest_file); 4010 $p_entry['status
'] = "read_error"; 4011 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open temporary
file \
''.$v_gzip_temp_name.
'\' in binary read mode
'); 4012 return PclZip::errorCode(); 4016 // ----- Read the file by PCLZIP_READ_BLOCK_SIZE octets blocks 4017 $v_size = $p_entry['size']; 4018 while ($v_size != 0) { 4019 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 4020 $v_buffer = @gzread($v_src_file, $v_read_size); 4021 //$v_binary_data = pack('a'.$v_read_size, $v_buffer); 4022 @fwrite($v_dest_file, $v_buffer, $v_read_size); 4023 $v_size -= $v_read_size; 4025 @fclose($v_dest_file); 4026 @gzclose($v_src_file); 4028 // ----- Delete the temporary file 4029 @unlink($v_gzip_temp_name); 4034 // -------------------------------------------------------------------------------- 4036 // -------------------------------------------------------------------------------- 4037 // Function : privExtractFileInOutput() 4041 // -------------------------------------------------------------------------------- 4042 function privExtractFileInOutput(&$p_entry, &$p_options) 4046 // ----- Read the file header 4047 if (($v_result = $this->privReadFileHeader($v_header)) != 1) { 4052 // ----- Check that the file header is coherent with $p_entry info 4053 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { 4057 // ----- Look for pre-extract callback 4058 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { 4060 // ----- Generate a local information 4061 $v_local_header = array(); 4062 $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 4064 // ----- Call the callback 4065 // Here I do not use call_user_func() because I need to send a reference to the 4067 // eval('$v_result =
'.$p_options[PCLZIP_CB_PRE_EXTRACT].'(
PCLZIP_CB_PRE_EXTRACT, $v_local_header);
'); 4068 $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); 4069 if ($v_result == 0) { 4070 // ----- Change the file status 4071 $p_entry['status
'] = "skipped"; 4075 // ----- Look for abort result 4076 if ($v_result == 2) { 4077 // ----- This status is internal and will be changed in 'skipped
' 4078 $p_entry['status
'] = "aborted"; 4079 $v_result = PCLZIP_ERR_USER_ABORTED; 4082 // ----- Update the informations 4083 // Only some fields can be modified 4084 $p_entry['filename
'] = $v_local_header['filename
']; 4089 // ----- Look if extraction should be done 4090 if ($p_entry['status
'] == 'ok
') { 4092 // ----- Do the extraction (if not a folder) 4093 if (!(($p_entry['external
']&0x00000010)==0x00000010)) { 4094 // ----- Look for not compressed file 4095 if ($p_entry['compressed_size
'] == $p_entry['size']) { 4097 // ----- Read the file in a buffer (one shot) 4098 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size
']); 4100 // ----- Send the file to the output 4106 // ----- Read the compressed file in a buffer (one shot) 4107 $v_buffer = @fread($this->zip_fd, $p_entry['compressed_size
']); 4109 // ----- Decompress the file 4110 $v_file_content = gzinflate($v_buffer); 4113 // ----- Send the file to the output 4114 echo $v_file_content; 4115 unset($v_file_content); 4120 // ----- Change abort status 4121 if ($p_entry['status
'] == "aborted") { 4122 $p_entry['status
'] = "skipped"; 4125 // ----- Look for post-extract callback 4126 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { 4128 // ----- Generate a local information 4129 $v_local_header = array(); 4130 $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 4132 // ----- Call the callback 4133 // Here I do not use call_user_func() because I need to send a reference to the 4136 $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); 4138 // ----- Look for abort result 4139 if ($v_result == 2) { 4140 $v_result = PCLZIP_ERR_USER_ABORTED; 4146 // -------------------------------------------------------------------------------- 4148 // -------------------------------------------------------------------------------- 4149 // Function : privExtractFileAsString() 4153 // -------------------------------------------------------------------------------- 4154 function privExtractFileAsString(&$p_entry, &$p_string, &$p_options) 4158 // ----- Read the file header 4159 $v_header = array(); 4160 if (($v_result = $this->privReadFileHeader($v_header)) != 1) 4167 // ----- Check that the file header is coherent with $p_entry info 4168 if ($this->privCheckFileHeaders($v_header, $p_entry) != 1) { 4172 // ----- Look for pre-extract callback 4173 if (isset($p_options[PCLZIP_CB_PRE_EXTRACT])) { 4175 // ----- Generate a local information 4176 $v_local_header = array(); 4177 $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 4179 // ----- Call the callback 4180 // Here I do not use call_user_func() because I need to send a reference to the 4182 // eval('$v_result =
'.$p_options[PCLZIP_CB_PRE_EXTRACT].'(
PCLZIP_CB_PRE_EXTRACT, $v_local_header);
'); 4183 $v_result = $p_options[PCLZIP_CB_PRE_EXTRACT](PCLZIP_CB_PRE_EXTRACT, $v_local_header); 4184 if ($v_result == 0) { 4185 // ----- Change the file status 4186 $p_entry['status
'] = "skipped"; 4190 // ----- Look for abort result 4191 if ($v_result == 2) { 4192 // ----- This status is internal and will be changed in 'skipped
' 4193 $p_entry['status
'] = "aborted"; 4194 $v_result = PCLZIP_ERR_USER_ABORTED; 4197 // ----- Update the informations 4198 // Only some fields can be modified 4199 $p_entry['filename
'] = $v_local_header['filename
']; 4203 // ----- Look if extraction should be done 4204 if ($p_entry['status
'] == 'ok
') { 4206 // ----- Do the extraction (if not a folder) 4207 if (!(($p_entry['external
']&0x00000010)==0x00000010)) { 4208 // ----- Look for not compressed file 4209 // if ($p_entry['compressed_size
'] == $p_entry['size']) 4210 if ($p_entry['compression
'] == 0) { 4212 // ----- Reading the file 4213 $p_string = @fread($this->zip_fd, $p_entry['compressed_size
']); 4217 // ----- Reading the file 4218 $v_data = @fread($this->zip_fd, $p_entry['compressed_size
']); 4220 // ----- Decompress the file 4221 if (($p_string = @gzinflate($v_data)) === FALSE) { 4229 // TBC : error : can not extract a folder in a string 4234 // ----- Change abort status 4235 if ($p_entry['status
'] == "aborted") { 4236 $p_entry['status
'] = "skipped"; 4239 // ----- Look for post-extract callback 4240 elseif (isset($p_options[PCLZIP_CB_POST_EXTRACT])) { 4242 // ----- Generate a local information 4243 $v_local_header = array(); 4244 $this->privConvertHeader2FileInfo($p_entry, $v_local_header); 4246 // ----- Swap the content to header 4247 $v_local_header['content
'] = $p_string; 4250 // ----- Call the callback 4251 // Here I do not use call_user_func() because I need to send a reference to the 4254 $v_result = $p_options[PCLZIP_CB_POST_EXTRACT](PCLZIP_CB_POST_EXTRACT, $v_local_header); 4256 // ----- Swap back the content to header 4257 $p_string = $v_local_header['content
']; 4258 unset($v_local_header['content
']); 4260 // ----- Look for abort result 4261 if ($v_result == 2) { 4262 $v_result = PCLZIP_ERR_USER_ABORTED; 4269 // -------------------------------------------------------------------------------- 4271 // -------------------------------------------------------------------------------- 4272 // Function : privReadFileHeader() 4276 // -------------------------------------------------------------------------------- 4277 function privReadFileHeader(&$p_header) 4281 // ----- Read the 4 bytes signature 4282 $v_binary_data = @fread($this->zip_fd, 4); 4283 $v_data = unpack('Vid
', $v_binary_data); 4285 // ----- Check signature 4286 if ($v_data['id'] != 0x04034b50) 4290 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure
'); 4293 return PclZip::errorCode(); 4296 // ----- Read the first 42 bytes of the header 4297 $v_binary_data = fread($this->zip_fd, 26); 4299 // ----- Look for invalid block size 4300 if (strlen($v_binary_data) != 26) 4302 $p_header['filename
'] = ""; 4303 $p_header['status
'] = "invalid_header"; 4306 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); 4309 return PclZip::errorCode(); 4312 // ----- Extract the values 4313 $v_data = unpack('vversion/vflag/vcompression/vmtime/vmdate/Vcrc/Vcompressed_size/Vsize/vfilename_len/vextra_len
', $v_binary_data); 4315 // ----- Get filename 4316 $p_header['filename
'] = fread($this->zip_fd, $v_data['filename_len
']); 4318 // ----- Get extra_fields 4319 if ($v_data['extra_len
'] != 0) { 4320 $p_header['extra
'] = fread($this->zip_fd, $v_data['extra_len
']); 4323 $p_header['extra
'] = ''; 4326 // ----- Extract properties 4327 $p_header['version_extracted
'] = $v_data['version
']; 4328 $p_header['compression
'] = $v_data['compression
']; 4329 $p_header['size'] = $v_data['size']; 4330 $p_header['compressed_size
'] = $v_data['compressed_size
']; 4331 $p_header['crc
'] = $v_data['crc
']; 4332 $p_header['flag
'] = $v_data['flag
']; 4333 $p_header['filename_len
'] = $v_data['filename_len
']; 4335 // ----- Recuperate date in UNIX format 4336 $p_header['mdate
'] = $v_data['mdate
']; 4337 $p_header['mtime
'] = $v_data['mtime
']; 4338 if ($p_header['mdate
'] && $p_header['mtime
']) 4340 // ----- Extract time 4341 $v_hour = ($p_header['mtime
'] & 0xF800) >> 11; 4342 $v_minute = ($p_header['mtime
'] & 0x07E0) >> 5; 4343 $v_seconde = ($p_header['mtime
'] & 0x001F)*2; 4345 // ----- Extract date 4346 $v_year = (($p_header['mdate
'] & 0xFE00) >> 9) + 1980; 4347 $v_month = ($p_header['mdate
'] & 0x01E0) >> 5; 4348 $v_day = $p_header['mdate
'] & 0x001F; 4350 // ----- Get UNIX date format 4351 $p_header['mtime
'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); 4356 $p_header['mtime
'] = time(); 4360 //for(reset($v_data); $key = key($v_data); next($v_data)) { 4363 // ----- Set the stored filename 4364 $p_header['stored_filename
'] = $p_header['filename
']; 4366 // ----- Set the status field 4367 $p_header['status
'] = "ok"; 4372 // -------------------------------------------------------------------------------- 4374 // -------------------------------------------------------------------------------- 4375 // Function : privReadCentralFileHeader() 4379 // -------------------------------------------------------------------------------- 4380 function privReadCentralFileHeader(&$p_header) 4384 // ----- Read the 4 bytes signature 4385 $v_binary_data = @fread($this->zip_fd, 4); 4386 $v_data = unpack('Vid
', $v_binary_data); 4388 // ----- Check signature 4389 if ($v_data['id'] != 0x02014b50) 4393 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Invalid archive structure
'); 4396 return PclZip::errorCode(); 4399 // ----- Read the first 42 bytes of the header 4400 $v_binary_data = fread($this->zip_fd, 42); 4402 // ----- Look for invalid block size 4403 if (strlen($v_binary_data) != 42) 4405 $p_header['filename
'] = ""; 4406 $p_header['status
'] = "invalid_header"; 4409 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, "Invalid block size : ".strlen($v_binary_data)); 4412 return PclZip::errorCode(); 4415 // ----- Extract the values 4416 $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); 4418 // ----- Get filename 4419 if ($p_header['filename_len
'] != 0) 4420 $p_header['filename
'] = fread($this->zip_fd, $p_header['filename_len
']); 4422 $p_header['filename
'] = ''; 4425 if ($p_header['extra_len
'] != 0) 4426 $p_header['extra
'] = fread($this->zip_fd, $p_header['extra_len
']); 4428 $p_header['extra
'] = ''; 4430 // ----- Get comment 4431 if ($p_header['comment_len
'] != 0) 4432 $p_header['comment'] = fread($this->zip_fd, $p_header['comment_len
']); 4436 // ----- Extract properties 4438 // ----- Recuperate date in UNIX format 4439 //if ($p_header['mdate
'] && $p_header['mtime
']) 4440 // TBC : bug : this was ignoring time with 0/0/0 4443 // ----- Extract time 4444 $v_hour = ($p_header['mtime
'] & 0xF800) >> 11; 4445 $v_minute = ($p_header['mtime
'] & 0x07E0) >> 5; 4446 $v_seconde = ($p_header['mtime
'] & 0x001F)*2; 4448 // ----- Extract date 4449 $v_year = (($p_header['mdate
'] & 0xFE00) >> 9) + 1980; 4450 $v_month = ($p_header['mdate
'] & 0x01E0) >> 5; 4451 $v_day = $p_header['mdate
'] & 0x001F; 4453 // ----- Get UNIX date format 4454 $p_header['mtime
'] = @mktime($v_hour, $v_minute, $v_seconde, $v_month, $v_day, $v_year); 4459 $p_header['mtime
'] = time(); 4462 // ----- Set the stored filename 4463 $p_header['stored_filename
'] = $p_header['filename
']; 4465 // ----- Set default status to ok 4466 $p_header['status
'] = 'ok
'; 4468 // ----- Look if it is a directory 4469 if (substr($p_header['filename
'], -1) == '/
') { 4470 //$p_header['external
'] = 0x41FF0010; 4471 $p_header['external
'] = 0x00000010; 4478 // -------------------------------------------------------------------------------- 4480 // -------------------------------------------------------------------------------- 4481 // Function : privCheckFileHeaders() 4487 // -------------------------------------------------------------------------------- 4488 function privCheckFileHeaders(&$p_local_header, &$p_central_header) 4492 // ----- Check the static values 4494 if ($p_local_header['filename
'] != $p_central_header['filename
']) { 4496 if ($p_local_header['version_extracted
'] != $p_central_header['version_extracted
']) { 4498 if ($p_local_header['flag
'] != $p_central_header['flag
']) { 4500 if ($p_local_header['compression
'] != $p_central_header['compression
']) { 4502 if ($p_local_header['mtime
'] != $p_central_header['mtime
']) { 4504 if ($p_local_header['filename_len
'] != $p_central_header['filename_len
']) { 4507 // ----- Look for flag bit 3 4508 if (($p_local_header['flag
'] & 8) == 8) { 4509 $p_local_header['size'] = $p_central_header['size']; 4510 $p_local_header['compressed_size
'] = $p_central_header['compressed_size
']; 4511 $p_local_header['crc
'] = $p_central_header['crc
']; 4517 // -------------------------------------------------------------------------------- 4519 // -------------------------------------------------------------------------------- 4520 // Function : privReadEndCentralDir() 4524 // -------------------------------------------------------------------------------- 4525 function privReadEndCentralDir(&$p_central_dir) 4529 // ----- Go to the end of the zip file 4530 $v_size = filesize($this->zipname); 4531 @fseek($this->zip_fd, $v_size); 4532 if (@ftell($this->zip_fd) != $v_size) 4535 PclZip::privErrorLog(PCLZIP_ERR_BAD_FORMAT, 'Unable
to go
to the end
of the archive \
''.$this->zipname.
'\'');
4545 @fseek($this->zip_fd, $v_size-22);
4546 if (($v_pos = @ftell($this->zip_fd)) != ($v_size-22))
4556 $v_binary_data = @fread($this->zip_fd, 4);
4557 $v_data = @unpack(
'Vid', $v_binary_data);
4560 if ($v_data[
'id'] == 0x06054b50) {
4564 $v_pos = ftell($this->zip_fd);
4569 $v_maximum_size = 65557;
4570 if ($v_maximum_size > $v_size)
4571 $v_maximum_size = $v_size;
4572 @fseek($this->zip_fd, $v_size-$v_maximum_size);
4573 if (@ftell($this->zip_fd) != ($v_size-$v_maximum_size))
4583 $v_pos = ftell($this->zip_fd);
4584 $v_bytes = 0x00000000;
4585 while ($v_pos < $v_size)
4588 $v_byte = @fread($this->zip_fd, 1);
4594 $v_bytes = ( ($v_bytes & 0xFFFFFF) << 8) | Ord($v_byte);
4597 if ($v_bytes == 0x504b0506)
4607 if ($v_pos == $v_size)
4619 $v_binary_data = fread($this->zip_fd, 18);
4622 if (strlen($v_binary_data) != 18)
4633 $v_data = unpack(
'vdisk/vdisk_start/vdisk_entries/ventries/Vsize/Voffset/vcomment_size', $v_binary_data);
4636 if (($v_pos + $v_data[
'comment_size'] + 18) != $v_size) {
4645 'The central dir is not at the end of the archive.' 4646 .
' Some trailing bytes exists after the archive.');
4654 if ($v_data[
'comment_size'] != 0) {
4655 $p_central_dir[
'comment'] = fread($this->zip_fd, $v_data[
'comment_size']);
4658 $p_central_dir[
'comment'] =
'';
4660 $p_central_dir[
'entries'] = $v_data[
'entries'];
4661 $p_central_dir[
'disk_entries'] = $v_data[
'disk_entries'];
4662 $p_central_dir[
'offset'] = $v_data[
'offset'];
4663 $p_central_dir[
'size'] = $v_data[
'size'];
4664 $p_central_dir[
'disk'] = $v_data[
'disk'];
4665 $p_central_dir[
'disk_start'] = $v_data[
'disk_start'];
4685 $v_list_detail =
array();
4688 if (($v_result=$this->
privOpenFd(
'rb')) != 1)
4695 $v_central_dir =
array();
4703 @rewind($this->zip_fd);
4707 $v_pos_entry = $v_central_dir[
'offset'];
4708 @rewind($this->zip_fd);
4709 if (@fseek($this->zip_fd, $v_pos_entry))
4722 $v_header_list =
array();
4724 for ($i=0, $v_nb_extracted=0; $i<$v_central_dir[
'entries']; $i++)
4728 $v_header_list[$v_nb_extracted] =
array();
4739 $v_header_list[$v_nb_extracted][
'index'] = $i;
4746 && ($p_options[PCLZIP_OPT_BY_NAME] != 0)) {
4752 if (substr($p_options[PCLZIP_OPT_BY_NAME][$j], -1) ==
"/") {
4755 if ( (strlen($v_header_list[$v_nb_extracted][
'stored_filename']) > strlen($p_options[PCLZIP_OPT_BY_NAME][$j]))
4756 && (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])) {
4759 elseif ( (($v_header_list[$v_nb_extracted][
'external']&0x00000010)==0x00000010)
4760 && ($v_header_list[$v_nb_extracted][
'stored_filename'].
'/' == $p_options[PCLZIP_OPT_BY_NAME][$j])) {
4765 elseif ($v_header_list[$v_nb_extracted][
'stored_filename'] == $p_options[PCLZIP_OPT_BY_NAME][$j]) {
4785 && ($p_options[PCLZIP_OPT_BY_PREG] !=
"")) {
4787 if (preg_match($p_options[PCLZIP_OPT_BY_PREG], $v_header_list[$v_nb_extracted][
'stored_filename'])) {
4794 && ($p_options[PCLZIP_OPT_BY_INDEX] != 0)) {
4799 if (($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j][
'start']) && ($i<=$p_options[
PCLZIP_OPT_BY_INDEX][$j][
'end'])) {
4802 if ($i>=$p_options[PCLZIP_OPT_BY_INDEX][$j][
'end']) {
4806 if ($p_options[PCLZIP_OPT_BY_INDEX][$j][
'start']>$i) {
4818 unset($v_header_list[$v_nb_extracted]);
4827 if ($v_nb_extracted > 0) {
4830 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid(
'pclzip-').
'.tmp';
4833 $v_temp_zip =
new PclZip($v_zip_temp_name);
4836 if (($v_result = $v_temp_zip->privOpenFd(
'wb')) != 1) {
4844 for ($i=0; $i<
sizeof($v_header_list); $i++) {
4847 @rewind($this->zip_fd);
4848 if (@fseek($this->zip_fd, $v_header_list[$i][
'offset'])) {
4851 $v_temp_zip->privCloseFd();
4852 @unlink($v_zip_temp_name);
4862 $v_local_header =
array();
4866 $v_temp_zip->privCloseFd();
4867 @unlink($v_zip_temp_name);
4875 $v_header_list[$i]) != 1) {
4878 unset($v_local_header);
4881 if (($v_result = $v_temp_zip->privWriteFileHeader($v_header_list[$i])) != 1) {
4884 $v_temp_zip->privCloseFd();
4885 @unlink($v_zip_temp_name);
4892 if (($v_result =
PclZipUtilCopyBlock($this->zip_fd, $v_temp_zip->zip_fd, $v_header_list[$i][
'compressed_size'])) != 1) {
4895 $v_temp_zip->privCloseFd();
4896 @unlink($v_zip_temp_name);
4904 $v_offset = @ftell($v_temp_zip->zip_fd);
4907 for ($i=0; $i<
sizeof($v_header_list); $i++) {
4909 if (($v_result = $v_temp_zip->privWriteCentralFileHeader($v_header_list[$i])) != 1) {
4910 $v_temp_zip->privCloseFd();
4912 @unlink($v_zip_temp_name);
4919 $v_temp_zip->privConvertHeader2FileInfo($v_header_list[$i], $p_result_list[$i]);
4930 $v_size = @ftell($v_temp_zip->zip_fd)-$v_offset;
4933 if (($v_result = $v_temp_zip->privWriteCentralHeader(
sizeof($v_header_list), $v_size, $v_offset, $v_comment)) != 1) {
4935 unset($v_header_list);
4936 $v_temp_zip->privCloseFd();
4938 @unlink($v_zip_temp_name);
4945 $v_temp_zip->privCloseFd();
4950 @unlink($this->zipname);
4962 else if ($v_central_dir[
'entries'] != 0) {
4965 if (($v_result = $this->
privOpenFd(
'wb')) != 1) {
4998 if (($p_is_dir) && (substr($p_dir, -1)==
'/'))
5000 $p_dir = substr($p_dir, 0, strlen($p_dir)-1);
5004 if ((is_dir($p_dir)) || ($p_dir ==
""))
5010 $p_parent_dir = dirname($p_dir);
5013 if ($p_parent_dir != $p_dir)
5016 if ($p_parent_dir !=
"")
5018 if (($v_result = $this->
privDirCheck($p_parent_dir)) != 1)
5026 if (!@mkdir($p_dir, 0777))
5052 if (!is_file($p_archive_to_add->zipname))
5063 if (!is_file($this->zipname))
5067 $v_result = $this->
privDuplicate($p_archive_to_add->zipname);
5074 if (($v_result=$this->
privOpenFd(
'rb')) != 1)
5081 $v_central_dir =
array();
5089 @rewind($this->zip_fd);
5092 if (($v_result=$p_archive_to_add->privOpenFd(
'rb')) != 1)
5101 $v_central_dir_to_add =
array();
5102 if (($v_result = $p_archive_to_add->privReadEndCentralDir($v_central_dir_to_add)) != 1)
5105 $p_archive_to_add->privCloseFd();
5111 @rewind($p_archive_to_add->zip_fd);
5114 $v_zip_temp_name = PCLZIP_TEMPORARY_DIR.uniqid(
'pclzip-').
'.tmp';
5117 if (($v_zip_temp_fd = @fopen($v_zip_temp_name,
'wb')) == 0)
5120 $p_archive_to_add->privCloseFd();
5125 return PclZip::errorCode(); 5128 // ----- Copy the files from the archive to the temporary file 5129 // TBC : Here I should better append the file and go back to erase the central dir 5130 $v_size = $v_central_dir['offset
']; 5131 while ($v_size != 0) 5133 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 5134 $v_buffer = fread($this->zip_fd, $v_read_size); 5135 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 5136 $v_size -= $v_read_size; 5139 // ----- Copy the files from the archive_to_add into the temporary file 5140 $v_size = $v_central_dir_to_add['offset
']; 5141 while ($v_size != 0) 5143 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 5144 $v_buffer = fread($p_archive_to_add->zip_fd, $v_read_size); 5145 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 5146 $v_size -= $v_read_size; 5149 // ----- Store the offset of the central dir 5150 $v_offset = @ftell($v_zip_temp_fd); 5152 // ----- Copy the block of file headers from the old archive 5153 $v_size = $v_central_dir['size']; 5154 while ($v_size != 0) 5156 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 5157 $v_buffer = @fread($this->zip_fd, $v_read_size); 5158 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 5159 $v_size -= $v_read_size; 5162 // ----- Copy the block of file headers from the archive_to_add 5163 $v_size = $v_central_dir_to_add['size']; 5164 while ($v_size != 0) 5166 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 5167 $v_buffer = @fread($p_archive_to_add->zip_fd, $v_read_size); 5168 @fwrite($v_zip_temp_fd, $v_buffer, $v_read_size); 5169 $v_size -= $v_read_size; 5172 // ----- Merge the file comments 5173 $v_comment = $v_central_dir['comment'].' '.$v_central_dir_to_add['comment']; 5175 // ----- Calculate the size of the (new) central header 5176 $v_size = @ftell($v_zip_temp_fd)-$v_offset; 5178 // ----- Swap the file descriptor 5179 // Here is a trick : I swap the temporary fd with the zip fd, in order to use 5180 // the following methods on the temporary fil and not the real archive fd 5181 $v_swap = $this->zip_fd; 5182 $this->zip_fd = $v_zip_temp_fd; 5183 $v_zip_temp_fd = $v_swap; 5185 // ----- Create the central dir footer 5186 if (($v_result = $this->privWriteCentralHeader($v_central_dir['entries
']+$v_central_dir_to_add['entries
'], $v_size, $v_offset, $v_comment)) != 1) 5188 $this->privCloseFd(); 5189 $p_archive_to_add->privCloseFd(); 5190 @fclose($v_zip_temp_fd); 5191 $this->zip_fd = null; 5193 // ----- Reset the file list 5194 unset($v_header_list); 5200 // ----- Swap back the file descriptor 5201 $v_swap = $this->zip_fd; 5202 $this->zip_fd = $v_zip_temp_fd; 5203 $v_zip_temp_fd = $v_swap; 5206 $this->privCloseFd(); 5207 $p_archive_to_add->privCloseFd(); 5209 // ----- Close the temporary file 5210 @fclose($v_zip_temp_fd); 5212 // ----- Delete the zip file 5213 // TBC : I should test the result ... 5214 @unlink($this->zipname); 5216 // ----- Rename the temporary file 5217 // TBC : I should test the result ... 5218 //@rename($v_zip_temp_name, $this->zipname); 5219 PclZipUtilRename($v_zip_temp_name, $this->zipname); 5224 // -------------------------------------------------------------------------------- 5226 // -------------------------------------------------------------------------------- 5227 // Function : privDuplicate() 5231 // -------------------------------------------------------------------------------- 5232 function privDuplicate($p_archive_filename) 5236 // ----- Look if the $p_archive_filename exists 5237 if (!is_file($p_archive_filename)) 5240 // ----- Nothing to duplicate, so duplicate is a success. 5247 // ----- Open the zip file 5248 if (($v_result=$this->privOpenFd('wb
')) != 1) 5254 // ----- Open the temporary file in write mode 5255 if (($v_zip_temp_fd = @fopen($p_archive_filename, 'rb
')) == 0) 5257 $this->privCloseFd(); 5259 PclZip::privErrorLog(PCLZIP_ERR_READ_OPEN_FAIL, 'Unable
to open archive
file \
''.$p_archive_filename.
'\' in binary write mode
'); 5262 return PclZip::errorCode(); 5265 // ----- Copy the files from the archive to the temporary file 5266 // TBC : Here I should better append the file and go back to erase the central dir 5267 $v_size = filesize($p_archive_filename); 5268 while ($v_size != 0) 5270 $v_read_size = ($v_size < PCLZIP_READ_BLOCK_SIZE ? $v_size : PCLZIP_READ_BLOCK_SIZE); 5271 $v_buffer = fread($v_zip_temp_fd, $v_read_size); 5272 @fwrite($this->zip_fd, $v_buffer, $v_read_size); 5273 $v_size -= $v_read_size; 5277 $this->privCloseFd(); 5279 // ----- Close the temporary file 5280 @fclose($v_zip_temp_fd); 5285 // -------------------------------------------------------------------------------- 5287 // -------------------------------------------------------------------------------- 5288 // Function : privErrorLog() 5291 // -------------------------------------------------------------------------------- 5292 function privErrorLog($p_error_code=0, $p_error_string='') 5294 if (PCLZIP_ERROR_EXTERNAL == 1) { 5295 PclError($p_error_code, $p_error_string); 5298 $this->error_code = $p_error_code; 5299 $this->error_string = $p_error_string; 5302 // -------------------------------------------------------------------------------- 5304 // -------------------------------------------------------------------------------- 5305 // Function : privErrorReset() 5308 // -------------------------------------------------------------------------------- 5309 function privErrorReset() 5311 if (PCLZIP_ERROR_EXTERNAL == 1) { 5315 $this->error_code = 0; 5316 $this->error_string = ''; 5319 // -------------------------------------------------------------------------------- 5321 // -------------------------------------------------------------------------------- 5322 // Function : privDisableMagicQuotes() 5326 // -------------------------------------------------------------------------------- 5327 function privDisableMagicQuotes() 5331 // ----- Look if function exists 5332 if ( (!function_exists("get_magic_quotes_runtime")) 5333 || (!function_exists("set_magic_quotes_runtime"))) { 5337 // ----- Look if already done 5338 if ($this->magic_quotes_status != -1) { 5342 // ----- Get and memorize the magic_quote value 5343 $this->magic_quotes_status = @get_magic_quotes_runtime(); 5345 // ----- Disable magic_quotes 5346 if ($this->magic_quotes_status == 1) { 5347 @set_magic_quotes_runtime(0); 5353 // -------------------------------------------------------------------------------- 5355 // -------------------------------------------------------------------------------- 5356 // Function : privSwapBackMagicQuotes() 5360 // -------------------------------------------------------------------------------- 5361 function privSwapBackMagicQuotes() 5365 // ----- Look if function exists 5366 if ( (!function_exists("get_magic_quotes_runtime")) 5367 || (!function_exists("set_magic_quotes_runtime"))) { 5371 // ----- Look if something to do 5372 if ($this->magic_quotes_status != -1) { 5376 // ----- Swap back magic_quotes 5377 if ($this->magic_quotes_status == 1) { 5378 @set_magic_quotes_runtime($this->magic_quotes_status); 5384 // -------------------------------------------------------------------------------- 5388 // -------------------------------------------------------------------------------- 5390 // -------------------------------------------------------------------------------- 5391 // Function : PclZipUtilPathReduction() 5395 // -------------------------------------------------------------------------------- 5396 function PclZipUtilPathReduction($p_dir) 5400 // ----- Look for not empty path 5402 // ----- Explode path by directory names 5403 $v_list = explode("/", $p_dir); 5405 // ----- Study directories from last to first 5407 for ($i=sizeof($v_list)-1; $i>=0; $i--) { 5408 // ----- Look for current path 5409 if ($v_list[$i] == ".") { 5410 // ----- Ignore this directory 5411 // Should be the first $i=0, but no check is done 5413 else if ($v_list[$i] == "..") { 5416 else if ($v_list[$i] == "") { 5417 // ----- First '/
' i.e. root slash 5419 $v_result = "/".$v_result; 5421 // ----- It is an invalid path, so the path is not modified 5427 // ----- Last '/
' i.e. indicates a directory 5428 else if ($i == (sizeof($v_list)-1)) { 5429 $v_result = $v_list[$i]; 5431 // ----- Double '/
' inside the path 5433 // ----- Ignore only the double ' 5443 $v_result = $v_list[$i].($i!=(
sizeof($v_list)-1)?
"/".$v_result:
"");
5450 while ($v_skip > 0) {
5451 $v_result =
'../'.$v_result;
5482 if ( ($p_dir ==
'.')
5483 || ((strlen($p_dir) >=2) && (substr($p_dir, 0, 2) ==
'./'))) {
5486 if ( ($p_path ==
'.')
5487 || ((strlen($p_path) >=2) && (substr($p_path, 0, 2) ==
'./'))) {
5492 $v_list_dir = explode(
"/", $p_dir);
5493 $v_list_dir_size =
sizeof($v_list_dir);
5494 $v_list_path = explode(
"/", $p_path);
5495 $v_list_path_size =
sizeof($v_list_path);
5500 while (($i < $v_list_dir_size) && ($j < $v_list_path_size) && ($v_result)) {
5503 if ($v_list_dir[$i] ==
'') {
5507 if ($v_list_path[$j] ==
'') {
5513 if (($v_list_dir[$i] != $v_list_path[$j]) && ($v_list_dir[$i] !=
'') && ( $v_list_path[$j] !=
'')) {
5525 while (($j < $v_list_path_size) && ($v_list_path[$j] ==
'')) $j++;
5526 while (($i < $v_list_dir_size) && ($v_list_dir[$i] ==
'')) $i++;
5528 if (($i >= $v_list_dir_size) && ($j >= $v_list_path_size)) {
5532 else if ($i < $v_list_dir_size) {
5560 while ($p_size != 0)
5562 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5563 $v_buffer = @fread($p_src, $v_read_size);
5564 @fwrite($p_dest, $v_buffer, $v_read_size);
5565 $p_size -= $v_read_size;
5568 else if ($p_mode==1)
5570 while ($p_size != 0)
5572 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5573 $v_buffer = @gzread($p_src, $v_read_size);
5574 @fwrite($p_dest, $v_buffer, $v_read_size);
5575 $p_size -= $v_read_size;
5578 else if ($p_mode==2)
5580 while ($p_size != 0)
5582 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5583 $v_buffer = @fread($p_src, $v_read_size);
5584 @gzwrite($p_dest, $v_buffer, $v_read_size);
5585 $p_size -= $v_read_size;
5588 else if ($p_mode==3)
5590 while ($p_size != 0)
5592 $v_read_size = ($p_size < PCLZIP_READ_BLOCK_SIZE ? $p_size : PCLZIP_READ_BLOCK_SIZE);
5593 $v_buffer = @gzread($p_src, $v_read_size);
5594 @gzwrite($p_dest, $v_buffer, $v_read_size);
5595 $p_size -= $v_read_size;
5621 if (!@rename($p_src, $p_dest)) {
5624 if (!@copy($p_src, $p_dest)) {
5627 else if (!@unlink($p_src)) {
5649 $v_list = get_defined_constants();
5650 for (reset($v_list); $v_key = key($v_list); next($v_list)) {
5651 $v_prefix = substr($v_key, 0, 10);
5652 if (( ($v_prefix ==
'PCLZIP_OPT')
5653 || ($v_prefix ==
'PCLZIP_CB_')
5654 || ($v_prefix ==
'PCLZIP_ATT'))
5655 && ($v_list[$v_key] == $p_option)) {
5660 $v_result =
'Unknown';
5679 if (stristr(php_uname(),
'windows')) {
5681 if (($p_remove_disk_letter) && (($v_position = strpos($p_path,
':')) !=
false)) {
5682 $p_path = substr($p_path, $v_position+1);
5685 if ((strpos($p_path,
'\\') > 0) || (substr($p_path, 0,1) ==
'\\')) {
5686 $p_path = strtr($p_path,
'\\',
'/');
const PCLZIP_ERR_BAD_CHECKSUM
const PCLZIP_OPT_SET_CHMOD
const PCLZIP_OPT_EXTRACT_AS_STRING
privDeleteByRule(&$p_result_list, &$p_options)
PclZipUtilTranslateWinPath($p_path, $p_remove_disk_letter=true)
const PCLZIP_OPT_TEMP_FILE_THRESHOLD
const PCLZIP_ERR_RENAME_FILE_FAIL
const PCLZIP_ATT_FILE_MTIME
privReadCentralFileHeader(&$p_header)
privCheckFormat($p_level=0)
PclZipUtilCopyBlock($p_src, $p_dest, $p_size, $p_mode=0)
const PCLZIP_ERR_INVALID_PARAMETER
const PCLZIP_ERR_UNSUPPORTED_ENCRYPTION
const PCLZIP_OPT_ADD_COMMENT
privReadEndCentralDir(&$p_central_dir)
const PCLZIP_ATT_FILE_NEW_FULL_NAME
const PCLZIP_ERR_UNSUPPORTED_COMPRESSION
const PCLZIP_ATT_FILE_COMMENT
const PCLZIP_OPT_TEMP_FILE_ON
const PCLZIP_ERR_WRITE_OPEN_FAIL
privMerge(&$p_archive_to_add)
const PCLZIP_ERR_BAD_EXTRACTED_FILE
const PCLZIP_ERR_MISSING_FILE
const PCLZIP_OPT_PREPEND_COMMENT
const PCLZIP_ERR_INVALID_ATTRIBUTE_VALUE
const PCLZIP_ERR_INVALID_OPTION_VALUE
const PCLZIP_ATT_FILE_NAME
const PCLZIP_ERR_NO_ERROR
const PCLZIP_OPT_REMOVE_ALL_PATH
privExtractByRule(&$p_file_list, $p_path, $p_remove_path, $p_remove_all_path, &$p_options)
const PCLZIP_ERR_READ_OPEN_FAIL
privAdd($p_filedescr_list, &$p_result_list, &$p_options)
privSwapBackMagicQuotes()
privFileDescrExpand(&$p_filedescr_list, &$p_options)
const PCLZIP_OPT_REPLACE_NEWER
privCheckFileHeaders(&$p_local_header, &$p_central_header)
PclZipUtilOptionText($p_option)
const PCLZIP_OPT_NO_COMPRESSION
const PCLZIP_ERR_DIR_CREATE_FAIL
Reload workbook from saved file
const PCLZIP_OPT_EXTRACT_DIR_RESTRICTION
const PCLZIP_ATT_FILE_NEW_SHORT_NAME
const PCLZIP_ERR_FILENAME_TOO_LONG
const PCLZIP_ERR_DIRECTORY_RESTRICTION
PclZipUtilRename($p_src, $p_dest)
Create styles array
The data for the language used.
if(!defined('PCLZIP_READ_BLOCK_SIZE')) if(!defined('PCLZIP_SEPARATOR')) if(!defined('PCLZIP_ERROR_EXTERNAL')) if(!defined('PCLZIP_TEMPORARY_DIR')) if(!defined('PCLZIP_TEMPORARY_FILE_RATIO')) $g_pclzip_version
const PCLZIP_OPT_STOP_ON_ERROR
const PCLZIP_ERR_DELETE_FILE_FAIL
const PCLZIP_CB_PRE_EXTRACT
const PCLZIP_OPT_ADD_PATH
privDirCheck($p_dir, $p_is_dir=false)
const PCLZIP_ERR_BAD_EXTENSION
privParseOptions(&$p_options_list, $p_size, &$v_result_list, $v_requested_options=false)
privWriteCentralHeader($p_nb_entries, $p_size, $p_offset, $p_comment)
const PCLZIP_ERR_MISSING_OPTION_VALUE
privDuplicate($p_archive_filename)
privOptionDefaultThreshold(&$p_options)
const PCLZIP_OPT_BY_INDEX
const PCLZIP_ERR_INVALID_ARCHIVE_ZIP
const PCLZIP_ERR_BAD_FORMAT
privReadFileHeader(&$p_header)
const PCLZIP_ATT_FILE_CONTENT
privFileDescrParseAtt(&$p_file_list, &$p_filedescr, $v_options, $v_requested_options=false)
privCreate($p_filedescr_list, &$p_result_list, &$p_options)
const PCLZIP_OPT_REMOVE_PATH
const PCLZIP_OPT_EXTRACT_IN_OUTPUT
defined( 'APPLICATION_ENV')||define( 'APPLICATION_ENV'
privErrorLog($p_error_code=0, $p_error_string='')
PclZipUtilPathInclusion($p_dir, $p_path)
const PCLZIP_CB_POST_EXTRACT
sprintf('%.4f', $callTime) seconds
const PCLZIP_ERR_INVALID_ZIP
const PCLZIP_OPT_TEMP_FILE_OFF