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