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