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