| [ Index ] |
|
Code source de Joomla 1.0.13 |
1 <?php 2 /** 3 * @version $Id: pcltar.lib.php 49 2005-09-15 02:55:27Z rhuk $ 4 * @package Joomla 5 */ 6 7 // no direct access 8 defined( '_VALID_MOS' ) or die( 'Restricted access' ); 9 10 // -------------------------------------------------------------------------------- 11 // PhpConcept Library - Tar Module 1.3 12 // -------------------------------------------------------------------------------- 13 // License GNU/GPL - Vincent Blavet - August 2001 14 // http://www.phpconcept.net 15 // -------------------------------------------------------------------------------- 16 // 17 // Presentation : 18 // PclTar is a library that allow you to create a GNU TAR + GNU ZIP archive, 19 // to add files or directories, to extract all the archive or a part of it. 20 // So far tests show that the files generated by PclTar are readable by 21 // gzip tools and WinZip application. 22 // 23 // Description : 24 // See readme.txt (English & Fran�ais) and http://www.phpconcept.net 25 // 26 // Warning : 27 // This library and the associated files are non commercial, non professional 28 // work. 29 // It should not have unexpected results. However if any damage is caused by 30 // this software the author can not be responsible. 31 // The use of this software is at the risk of the user. 32 // 33 // -------------------------------------------------------------------------------- 34 35 // ----- Look for double include 36 if (!defined("PCL_TAR")) 37 { 38 define( "PCL_TAR", 1 ); 39 40 // ----- Configuration variable 41 // Theses values may be changed by the user of PclTar library 42 if (!isset($g_pcltar_lib_dir)) 43 $g_pcltar_lib_dir = "lib"; 44 45 // ----- Error codes 46 // -1 : Unable to open file in binary write mode 47 // -2 : Unable to open file in binary read mode 48 // -3 : Invalid parameters 49 // -4 : File does not exist 50 // -5 : Filename is too long (max. 99) 51 // -6 : Not a valid tar file 52 // -7 : Invalid extracted file size 53 // -8 : Unable to create directory 54 // -9 : Invalid archive extension 55 // -10 : Invalid archive format 56 // -11 : Unable to delete file (unlink) 57 // -12 : Unable to rename file (rename) 58 // -13 : Invalid header checksum 59 60 61 // -------------------------------------------------------------------------------- 62 // ***** UNDER THIS LINE NOTHING NEEDS TO BE MODIFIED ***** 63 // -------------------------------------------------------------------------------- 64 65 // ----- Global variables 66 $g_pcltar_version = "1.3"; 67 68 // ----- Extract extension type (.php3/.php/...) 69 // $g_pcltar_extension = substr(strrchr(basename($PATH_TRANSLATED), '.'), 1); 70 $g_pcltar_extension = substr(strrchr(basename(@$_SERVER["PATH_TRANSLATED"]), '.'), 1); 71 72 // ----- Include other libraries 73 // This library should be called by each script before the include of PhpZip 74 // Library in order to limit the potential 'lib' directory path problem. 75 76 if (!defined("PCLERROR_LIB")) 77 { 78 include($g_pcltar_lib_dir."/pclerror.lib.".$g_pcltar_extension); 79 } 80 if (!defined("PCLTRACE_LIB")) 81 { 82 include($g_pcltar_lib_dir."/pcltrace.lib.".$g_pcltar_extension); 83 } 84 85 // -------------------------------------------------------------------------------- 86 // Function : PclTarCreate() 87 // Description : 88 // Creates a new archive with name $p_tarname containing the files and/or 89 // directories indicated in $p_list. If the tar filename extension is 90 // ".tar", the file will not be compressed. If it is ".tar.gz" or ".tgz" 91 // it will be a gzip compressed tar archive. 92 // If you want to use an other extension, you must indicate the mode in 93 // $p_mode ("tar" or "tgz"). 94 // $p_add_dir and $p_remove_dir give you the ability to store a path 95 // which is not the real path of the files. 96 // Parameters : 97 // $p_tarname : Name of an existing tar file 98 // $p_filelist : An array containing file or directory names, or 99 // a string containing one filename or directory name, or 100 // a string containing a list of filenames and/or directory 101 // names separated by spaces. 102 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive, 103 // if $p_mode is not specified, it will be determined by the extension. 104 // $p_add_dir : Path to add in the filename path archived 105 // $p_remove_dir : Path to remove in the filename path archived 106 // Return Values : 107 // 1 on success, or an error code (see table at the beginning). 108 // -------------------------------------------------------------------------------- 109 function PclTarCreate($p_tarname, $p_filelist="", $p_mode="", $p_add_dir="", $p_remove_dir="") 110 { 111 TrFctStart(__FILE__, __LINE__, "PclTarCreate", "tar=$p_tarname, file='$p_filelist', mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'"); 112 $v_result=1; 113 114 // ----- Look for default mode 115 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 116 { 117 // ----- Extract the tar format from the extension 118 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 119 { 120 // ----- Return 121 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 122 return PclErrorCode(); 123 } 124 125 // ----- Trace 126 TrFctMessage(__FILE__, __LINE__, 1, "Auto mode selected : found $p_mode"); 127 } 128 129 // ----- Look if the $p_filelist is really an array 130 if (is_array($p_filelist)) 131 { 132 // ----- Call the create fct 133 $v_result = PclTarHandleCreate($p_tarname, $p_filelist, $p_mode, $p_add_dir, $p_remove_dir); 134 } 135 136 // ----- Look if the $p_filelist is a string 137 else if (is_string($p_filelist)) 138 { 139 // ----- Create a list with the elements from the string 140 $v_list = explode(" ", $p_filelist); 141 142 // ----- Call the create fct 143 $v_result = PclTarHandleCreate($p_tarname, $v_list, $p_mode, $p_add_dir, $p_remove_dir); 144 } 145 146 // ----- Invalid variable 147 else 148 { 149 // ----- Error log 150 PclErrorLog(-3, "Invalid variable type p_filelist"); 151 $v_result = -3; 152 } 153 154 // ----- Return 155 TrFctEnd(__FILE__, __LINE__, $v_result); 156 return $v_result; 157 } 158 // -------------------------------------------------------------------------------- 159 160 // -------------------------------------------------------------------------------- 161 // Function : PclTarAdd() 162 // Description : 163 // PLEASE DO NOT USE ANY MORE THIS FUNCTION. Use PclTarAddList(). 164 // 165 // This function is maintained only for compatibility reason 166 // 167 // Parameters : 168 // $p_tarname : Name of an existing tar file 169 // $p_filelist : An array containing file or directory names, or 170 // a string containing one filename or directory name, or 171 // a string containing a list of filenames and/or directory 172 // names separated by spaces. 173 // Return Values : 174 // 1 on success, 175 // Or an error code (see list on top). 176 // -------------------------------------------------------------------------------- 177 function PclTarAdd($p_tarname, $p_filelist) 178 { 179 TrFctStart(__FILE__, __LINE__, "PclTarAdd", "tar=$p_tarname, file=$p_filelist"); 180 $v_result=1; 181 $v_list_detail = array(); 182 183 // ----- Extract the tar format from the extension 184 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 185 { 186 // ----- Return 187 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 188 return PclErrorCode(); 189 } 190 191 // ----- Look if the $p_filelist is really an array 192 if (is_array($p_filelist)) 193 { 194 // ----- Call the add fct 195 $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $v_list_detail, "", ""); 196 } 197 198 // ----- Look if the $p_filelist is a string 199 else if (is_string($p_filelist)) 200 { 201 // ----- Create a list with the elements from the string 202 $v_list = explode(" ", $p_filelist); 203 204 // ----- Call the add fct 205 $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $v_list_detail, "", ""); 206 } 207 208 // ----- Invalid variable 209 else 210 { 211 // ----- Error log 212 PclErrorLog(-3, "Invalid variable type p_filelist"); 213 $v_result = -3; 214 } 215 216 // ----- Cleaning 217 unset($v_list_detail); 218 219 // ----- Return 220 TrFctEnd(__FILE__, __LINE__, $v_result); 221 return $v_result; 222 } 223 // -------------------------------------------------------------------------------- 224 225 // -------------------------------------------------------------------------------- 226 // Function : PclTarAddList() 227 // Description : 228 // Add a list of files or directories ($p_filelist) in the tar archive $p_tarname. 229 // The list can be an array of file/directory names or a string with names 230 // separated by one space. 231 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is 232 // different from the real path of the file. This is usefull if you want to have PclTar 233 // running in any directory, and memorize relative path from an other directory. 234 // If $p_mode is not set it will be automatically computed from the $p_tarname 235 // extension (.tar, .tar.gz or .tgz). 236 // Parameters : 237 // $p_tarname : Name of an existing tar file 238 // $p_filelist : An array containing file or directory names, or 239 // a string containing one filename or directory name, or 240 // a string containing a list of filenames and/or directory 241 // names separated by spaces. 242 // $p_add_dir : Path to add in the filename path archived 243 // $p_remove_dir : Path to remove in the filename path archived 244 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 245 // Return Values : 246 // 1 on success, 247 // Or an error code (see list on top). 248 // -------------------------------------------------------------------------------- 249 function PclTarAddList($p_tarname, $p_filelist, $p_add_dir="", $p_remove_dir="", $p_mode="") 250 { 251 TrFctStart(__FILE__, __LINE__, "PclTarAddList", "tar=$p_tarname, file=$p_filelist, p_add_dir='$p_add_dir', p_remove_dir='$p_remove_dir', mode=$p_mode"); 252 $v_result=1; 253 $p_list_detail = array(); 254 255 // ----- Extract the tar format from the extension 256 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 257 { 258 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 259 { 260 // ----- Return 261 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 262 return PclErrorCode(); 263 } 264 } 265 266 // ----- Look if the $p_filelist is really an array 267 if (is_array($p_filelist)) 268 { 269 // ----- Call the add fct 270 $v_result = PclTarHandleAppend($p_tarname, $p_filelist, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir); 271 } 272 273 // ----- Look if the $p_filelist is a string 274 else if (is_string($p_filelist)) 275 { 276 // ----- Create a list with the elements from the string 277 $v_list = explode(" ", $p_filelist); 278 279 // ----- Call the add fct 280 $v_result = PclTarHandleAppend($p_tarname, $v_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir); 281 } 282 283 // ----- Invalid variable 284 else 285 { 286 // ----- Error log 287 PclErrorLog(-3, "Invalid variable type p_filelist"); 288 $v_result = -3; 289 } 290 291 // ----- Return 292 if ($v_result != 1) 293 { 294 TrFctEnd(__FILE__, __LINE__, 0); 295 return 0; 296 } 297 TrFctEnd(__FILE__, __LINE__, $p_list_detail); 298 return $p_list_detail; 299 } 300 // -------------------------------------------------------------------------------- 301 302 // -------------------------------------------------------------------------------- 303 // Function : PclTarList() 304 // Description : 305 // Gives the list of all the files present in the tar archive $p_tarname. 306 // The list is the function result, it will be 0 on error. 307 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the 308 // function will determine the type of the archive. 309 // Parameters : 310 // $p_tarname : Name of an existing tar file 311 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 312 // Return Values : 313 // 0 on error (Use PclErrorCode() and PclErrorString() for more info) 314 // or 315 // An array containing file properties. Each file properties is an array of 316 // properties. 317 // The properties (array field names) are : 318 // filename, size, mode, uid, gid, mtime, typeflag, status 319 // Exemple : $v_list = PclTarList("my.tar"); 320 // for ($i=0; $i<sizeof($v_list); $i++) 321 // echo "Filename :'".$v_list[$i][filename]."'<br>"; 322 // -------------------------------------------------------------------------------- 323 function PclTarList($p_tarname, $p_mode="") 324 { 325 TrFctStart(__FILE__, __LINE__, "PclTarList", "tar=$p_tarname, mode='$p_mode'"); 326 $v_result=1; 327 328 // ----- Extract the tar format from the extension 329 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 330 { 331 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 332 { 333 // ----- Return 334 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 335 return 0; 336 } 337 } 338 339 // ----- Call the extracting fct 340 $p_list = array(); 341 if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "list", "", $p_mode, "")) != 1) 342 { 343 unset($p_list); 344 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 345 return(0); 346 } 347 348 // ----- Return 349 TrFctEnd(__FILE__, __LINE__, $p_list); 350 return $p_list; 351 } 352 // -------------------------------------------------------------------------------- 353 354 // -------------------------------------------------------------------------------- 355 // Function : PclTarExtract() 356 // Description : 357 // Extract all the files present in the archive $p_tarname, in the directory 358 // $p_path. The relative path of the archived files are keep and become 359 // relative to $p_path. 360 // If a file with the same name already exists it will be replaced. 361 // If the path to the file does not exist, it will be created. 362 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the 363 // function will determine the type of the archive. 364 // Parameters : 365 // $p_tarname : Name of an existing tar file. 366 // $p_path : Path where the files will be extracted. The files will use 367 // their memorized path from $p_path. 368 // If $p_path is "", files will be extracted in "./". 369 // $p_remove_path : Path to remove (from the file memorized path) while writing the 370 // extracted files. If the path does not match the file path, 371 // the file is extracted with its memorized path. 372 // $p_path and $p_remove_path are commulative. 373 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 374 // Return Values : 375 // Same as PclTarList() 376 // -------------------------------------------------------------------------------- 377 function PclTarExtract($p_tarname, $p_path="./", $p_remove_path="", $p_mode="") 378 { 379 TrFctStart(__FILE__, __LINE__, "PclTarExtract", "tar='$p_tarname', path='$p_path', remove_path='$p_remove_path', mode='$p_mode'"); 380 $v_result=1; 381 382 // ----- Extract the tar format from the extension 383 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 384 { 385 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 386 { 387 // ----- Return 388 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 389 return 0; 390 } 391 } 392 393 // ----- Call the extracting fct 394 if (($v_result = PclTarHandleExtract($p_tarname, 0, $p_list, "complete", $p_path, $p_mode, $p_remove_path)) != 1) 395 { 396 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 397 return(0); 398 } 399 400 // ----- Return 401 TrFctEnd(__FILE__, __LINE__, $p_list); 402 return $p_list; 403 } 404 // -------------------------------------------------------------------------------- 405 406 // -------------------------------------------------------------------------------- 407 // Function : PclTarExtractList() 408 // Description : 409 // Extract the files present in the archive $p_tarname and specified in 410 // $p_filelist, in the directory 411 // $p_path. The relative path of the archived files are keep and become 412 // relative to $p_path. 413 // If a directory is sp�cified in the list, all the files from this directory 414 // will be extracted. 415 // If a file with the same name already exists it will be replaced. 416 // If the path to the file does not exist, it will be created. 417 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the 418 // function will determine the type of the archive. 419 // Parameters : 420 // $p_tarname : Name of an existing tar file 421 // $p_filelist : An array containing file or directory names, or 422 // a string containing one filename or directory name, or 423 // a string containing a list of filenames and/or directory 424 // names separated by spaces. 425 // $p_path : Path where the files will be extracted. The files will use 426 // their memorized path from $p_path. 427 // If $p_path is "", files will be extracted in "./". 428 // $p_remove_path : Path to remove (from the file memorized path) while writing the 429 // extracted files. If the path does not match the file path, 430 // the file is extracted with its memorized path. 431 // $p_path and $p_remove_path are commulative. 432 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 433 // Return Values : 434 // Same as PclTarList() 435 // -------------------------------------------------------------------------------- 436 function PclTarExtractList($p_tarname, $p_filelist, $p_path="./", $p_remove_path="", $p_mode="") 437 { 438 TrFctStart(__FILE__, __LINE__, "PclTarExtractList", "tar=$p_tarname, list, path=$p_path, remove_path='$p_remove_path', mode='$p_mode'"); 439 $v_result=1; 440 441 // ----- Extract the tar format from the extension 442 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 443 { 444 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 445 { 446 // ----- Return 447 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 448 return 0; 449 } 450 } 451 452 // ----- Look if the $p_filelist is really an array 453 if (is_array($p_filelist)) 454 { 455 // ----- Call the extracting fct 456 if (($v_result = PclTarHandleExtract($p_tarname, $p_filelist, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1) 457 { 458 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 459 return(0); 460 } 461 } 462 463 // ----- Look if the $p_filelist is a string 464 else if (is_string($p_filelist)) 465 { 466 // ----- Create a list with the elements from the string 467 $v_list = explode(" ", $p_filelist); 468 469 // ----- Call the extracting fct 470 if (($v_result = PclTarHandleExtract($p_tarname, $v_list, $p_list, "partial", $p_path, $v_tar_mode, $p_remove_path)) != 1) 471 { 472 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 473 return(0); 474 } 475 } 476 477 // ----- Invalid variable 478 else 479 { 480 // ----- Error log 481 PclErrorLog(-3, "Invalid variable type p_filelist"); 482 483 // ----- Return 484 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 485 return 0; 486 } 487 488 // ----- Return 489 TrFctEnd(__FILE__, __LINE__, $p_list); 490 return $p_list; 491 } 492 // -------------------------------------------------------------------------------- 493 494 // -------------------------------------------------------------------------------- 495 // Function : PclTarExtractIndex() 496 // Description : 497 // Extract the files present in the archive $p_tarname and specified at 498 // the indexes in $p_index, in the directory 499 // $p_path. The relative path of the archived files are keep and become 500 // relative to $p_path. 501 // If a directory is specified in the list, the directory only is created. All 502 // the file stored in this archive for this directory 503 // are not extracted. 504 // If a file with the same name already exists it will be replaced. 505 // If the path to the file does not exist, it will be created. 506 // Depending on the $p_tarname extension (.tar, .tar.gz or .tgz) the 507 // function will determine the type of the archive. 508 // Parameters : 509 // $p_tarname : Name of an existing tar file 510 // $p_index : A single index (integer) or a string of indexes of files to 511 // extract. The form of the string is "0,4-6,8-12" with only numbers 512 // and '-' for range or ',' to separate ranges. No spaces or ';' 513 // are allowed. 514 // $p_path : Path where the files will be extracted. The files will use 515 // their memorized path from $p_path. 516 // If $p_path is "", files will be extracted in "./". 517 // $p_remove_path : Path to remove (from the file memorized path) while writing the 518 // extracted files. If the path does not match the file path, 519 // the file is extracted with its memorized path. 520 // $p_path and $p_remove_path are commulative. 521 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 522 // Return Values : 523 // Same as PclTarList() 524 // -------------------------------------------------------------------------------- 525 function PclTarExtractIndex($p_tarname, $p_index, $p_path="./", $p_remove_path="", $p_mode="") 526 { 527 TrFctStart(__FILE__, __LINE__, "PclTarExtractIndex", "tar=$p_tarname, index='$p_index', path=$p_path, remove_path='$p_remove_path', mode='$p_mode'"); 528 $v_result=1; 529 530 // ----- Extract the tar format from the extension 531 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 532 { 533 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 534 { 535 // ----- Return 536 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 537 return 0; 538 } 539 } 540 541 // ----- Look if the $p_index is really an integer 542 if (is_integer($p_index)) 543 { 544 // ----- Call the extracting fct 545 if (($v_result = PclTarHandleExtractByIndexList($p_tarname, "$p_index", $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1) 546 { 547 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 548 return(0); 549 } 550 } 551 552 // ----- Look if the $p_filelist is a string 553 else if (is_string($p_index)) 554 { 555 // ----- Call the extracting fct 556 if (($v_result = PclTarHandleExtractByIndexList($p_tarname, $p_index, $p_list, $p_path, $p_remove_path, $v_tar_mode)) != 1) 557 { 558 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 559 return(0); 560 } 561 } 562 563 // ----- Invalid variable 564 else 565 { 566 // ----- Error log 567 PclErrorLog(-3, "Invalid variable type $p_index"); 568 569 // ----- Return 570 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 571 return 0; 572 } 573 574 // ----- Return 575 TrFctEnd(__FILE__, __LINE__, $p_list); 576 return $p_list; 577 } 578 // -------------------------------------------------------------------------------- 579 580 // -------------------------------------------------------------------------------- 581 // Function : PclTarDelete() 582 // Description : 583 // This function deletes from the archive $p_tarname the files which are listed 584 // in $p_filelist. $p_filelist can be a string with file names separated by 585 // spaces, or an array containing the file names. 586 // Parameters : 587 // $p_tarname : Name of an existing tar file 588 // $p_filelist : An array or a string containing file names to remove from the 589 // archive. 590 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 591 // Return Values : 592 // List of the files which are kept in the archive (same format as PclTarList()) 593 // -------------------------------------------------------------------------------- 594 function PclTarDelete($p_tarname, $p_filelist, $p_mode="") 595 { 596 TrFctStart(__FILE__, __LINE__, "PclTarDelete", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'"); 597 $v_result=1; 598 599 // ----- Extract the tar format from the extension 600 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 601 { 602 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 603 { 604 // ----- Return 605 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 606 return 0; 607 } 608 } 609 610 // ----- Look if the $p_filelist is really an array 611 if (is_array($p_filelist)) 612 { 613 // ----- Call the extracting fct 614 if (($v_result = PclTarHandleDelete($p_tarname, $p_filelist, $p_list, $p_mode)) != 1) 615 { 616 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 617 return(0); 618 } 619 } 620 621 // ----- Look if the $p_filelist is a string 622 else if (is_string($p_filelist)) 623 { 624 // ----- Create a list with the elements from the string 625 $v_list = explode(" ", $p_filelist); 626 627 // ----- Call the extracting fct 628 if (($v_result = PclTarHandleDelete($p_tarname, $v_list, $p_list, $p_mode)) != 1) 629 { 630 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 631 return(0); 632 } 633 } 634 635 // ----- Invalid variable 636 else 637 { 638 // ----- Error log 639 PclErrorLog(-3, "Invalid variable type p_filelist"); 640 641 // ----- Return 642 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 643 return 0; 644 } 645 646 // ----- Return 647 TrFctEnd(__FILE__, __LINE__, $p_list); 648 return $p_list; 649 } 650 // -------------------------------------------------------------------------------- 651 652 // -------------------------------------------------------------------------------- 653 // Function : PclTarUpdate() 654 // Description : 655 // This function updates the files in $p_filelist which are already in the 656 // $p_tarname archive with an older last modified date. If the file does not 657 // exist, it is added at the end of the archive. 658 // Parameters : 659 // $p_tarname : Name of an existing tar file 660 // $p_filelist : An array or a string containing file names to update from the 661 // archive. 662 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 663 // Return Values : 664 // List of the files contained in the archive. The field status contains 665 // "updated", "not_updated", "added" or "ok" for the files not concerned. 666 // -------------------------------------------------------------------------------- 667 function PclTarUpdate($p_tarname, $p_filelist, $p_mode="", $p_add_dir="", $p_remove_dir="") 668 { 669 TrFctStart(__FILE__, __LINE__, "PclTarUpdate", "tar='$p_tarname', list='$p_filelist', mode='$p_mode'"); 670 $v_result=1; 671 672 // ----- Extract the tar format from the extension 673 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 674 { 675 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 676 { 677 // ----- Return 678 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 679 return 0; 680 } 681 } 682 683 // ----- Look if the $p_filelist is really an array 684 if (is_array($p_filelist)) 685 { 686 // ----- Call the extracting fct 687 if (($v_result = PclTarHandleUpdate($p_tarname, $p_filelist, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1) 688 { 689 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 690 return(0); 691 } 692 } 693 694 // ----- Look if the $p_filelist is a string 695 else if (is_string($p_filelist)) 696 { 697 // ----- Create a list with the elements from the string 698 $v_list = explode(" ", $p_filelist); 699 700 // ----- Call the extracting fct 701 if (($v_result = PclTarHandleUpdate($p_tarname, $v_list, $p_list, $p_mode, $p_add_dir, $p_remove_dir)) != 1) 702 { 703 TrFctEnd(__FILE__, __LINE__, 0, PclErrorString()); 704 return(0); 705 } 706 } 707 708 // ----- Invalid variable 709 else 710 { 711 // ----- Error log 712 PclErrorLog(-3, "Invalid variable type p_filelist"); 713 714 // ----- Return 715 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 716 return 0; 717 } 718 719 // ----- Return 720 TrFctEnd(__FILE__, __LINE__, $p_list); 721 return $p_list; 722 } 723 // -------------------------------------------------------------------------------- 724 725 726 // -------------------------------------------------------------------------------- 727 // Function : PclTarMerge() 728 // Description : 729 // This function add the content of $p_tarname_add at the end of $p_tarname. 730 // Parameters : 731 // $p_tarname : Name of an existing tar file 732 // $p_tarname_add : Name of an existing tar file taht will be added at the end 733 // of $p_tarname. 734 // $p_mode : 'tar' or 'tgz', if not set, will be determined by $p_tarname extension 735 // $p_mode_add : 'tar' or 'tgz', if not set, will be determined by $p_tarname_add 736 // extension 737 // Return Values : 738 // List of the files contained in the archive. The field status contains 739 // "updated", "not_updated", "added" or "ok" for the files not concerned. 740 // -------------------------------------------------------------------------------- 741 function PclTarMerge($p_tarname, $p_tarname_add, $p_mode="", $p_mode_add="") 742 { 743 TrFctStart(__FILE__, __LINE__, "PclTarMerge", "tar='$p_tarname', tar_add='$p_tarname_add', mode='$p_mode', mode_add='$p_mode_add'"); 744 $v_result=1; 745 746 // ----- Check the parameters 747 if (($p_tarname == "") || ($p_tarname_add == "")) 748 { 749 // ----- Error log 750 PclErrorLog(-3, "Invalid empty archive name"); 751 752 // ----- Return 753 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 754 return PclErrorCode(); 755 } 756 757 // ----- Extract the tar format from the extension 758 if (($p_mode == "") || (($p_mode!="tar") && ($p_mode!="tgz"))) 759 { 760 if (($p_mode = PclTarHandleExtension($p_tarname)) == "") 761 { 762 // ----- Return 763 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 764 return 0; 765 } 766 } 767 if (($p_mode_add == "") || (($p_mode_add!="tar") && ($p_mode_add!="tgz"))) 768 { 769 if (($p_mode_add = PclTarHandleExtension($p_tarname_add)) == "") 770 { 771 // ----- Return 772 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 773 return 0; 774 } 775 } 776 777 // ----- Clear filecache 778 clearstatcache(); 779 780 // ----- Check the file size 781 if ((!is_file($p_tarname)) || 782 (((($v_size = filesize($p_tarname)) % 512) != 0) && ($p_mode=="tar"))) 783 { 784 // ----- Error log 785 if (!is_file($p_tarname)) 786 PclErrorLog(-4, "Archive '$p_tarname' does not exist"); 787 else 788 PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)"); 789 790 // ----- Return 791 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 792 return PclErrorCode(); 793 } 794 if ((!is_file($p_tarname_add)) || 795 (((($v_size_add = filesize($p_tarname_add)) % 512) != 0) && ($p_mode_add=="tar"))) 796 { 797 // ----- Error log 798 if (!is_file($p_tarname_add)) 799 PclErrorLog(-4, "Archive '$p_tarname_add' does not exist"); 800 else 801 PclErrorLog(-6, "Archive '$p_tarname_add' has invalid size ".filesize($p_tarname_add)."(not a 512 block multiple)"); 802 803 // ----- Return 804 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 805 return PclErrorCode(); 806 } 807 808 // ----- Look for compressed archive 809 if ($p_mode == "tgz") 810 { 811 // ----- Open the file in read mode 812 if (($p_tar = @gzopen($p_tarname, "rb")) == 0) 813 { 814 // ----- Error log 815 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); 816 817 // ----- Return 818 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 819 return PclErrorCode(); 820 } 821 822 // ----- Open a temporary file in write mode 823 $v_temp_tarname = uniqid("pcltar-").".tmp"; 824 TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); 825 if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0) 826 { 827 // ----- Close tar file 828 gzclose($p_tar); 829 830 // ----- Error log 831 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); 832 833 // ----- Return 834 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 835 return PclErrorCode(); 836 } 837 838 // ----- Read the first 512 bytes block 839 $v_buffer = gzread($p_tar, 512); 840 841 // ----- Read the following blocks but not the last one 842 if (!gzeof($p_tar)) 843 { 844 TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file"); 845 $i=1; 846 847 // ----- Read new 512 block and write the already read 848 do{ 849 // ----- Write the already read block 850 $v_binary_data = pack("a512", "$v_buffer"); 851 gzputs($v_temp_tar, $v_binary_data); 852 853 $i++; 854 TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i"); 855 856 // ----- Read next block 857 $v_buffer = gzread($p_tar, 512); 858 859 } while (!gzeof($p_tar)); 860 861 TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks"); 862 } 863 } 864 865 // ----- Look for uncompressed tar file 866 else if ($p_mode=="tar") 867 { 868 // ----- Open the tar file 869 if (($p_tar = fopen($p_tarname, "r+b")) == 0) 870 { 871 // ----- Error log 872 PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode"); 873 874 // ----- Return 875 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 876 return PclErrorCode(); 877 } 878 879 // ----- Go to the beginning of last block 880 TrFctMessage(__FILE__, __LINE__, 4, "Position before :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 881 fseek($p_tar, $v_size-512); 882 TrFctMessage(__FILE__, __LINE__, 4, "Position after :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 883 } 884 885 // ----- Look for unknown type 886 else 887 { 888 // ----- Error log 889 PclErrorLog(-3, "Invalid tar mode $p_mode"); 890 891 // ----- Return 892 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 893 return PclErrorCode(); 894 } 895 896 // ----- Look for type of archive to add 897 if ($p_mode_add == "tgz") 898 { 899 TrFctMessage(__FILE__, __LINE__, 4, "Opening file $p_tarname_add"); 900 901 // ----- Open the file in read mode 902 if (($p_tar_add = @gzopen($p_tarname_add, "rb")) == 0) 903 { 904 // ----- Error log 905 PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode"); 906 907 // ----- Return 908 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 909 return PclErrorCode(); 910 } 911 912 // ----- Read the first 512 bytes block 913 $v_buffer = gzread($p_tar_add, 512); 914 915 // ----- Read the following blocks but not the last one 916 if (!gzeof($p_tar_add)) 917 { 918 TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file"); 919 $i=1; 920 921 // ----- Read new 512 block and write the already read 922 do{ 923 // ----- Write the already read block 924 $v_binary_data = pack("a512", "$v_buffer"); 925 if ($p_mode=="tar") 926 fputs($p_tar, $v_binary_data); 927 else 928 gzputs($v_temp_tar, $v_binary_data); 929 930 $i++; 931 TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i"); 932 933 // ----- Read next block 934 $v_buffer = gzread($p_tar_add, 512); 935 936 } while (!gzeof($p_tar_add)); 937 938 TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks"); 939 } 940 941 // ----- Close the files 942 gzclose($p_tar_add); 943 } 944 945 // ----- Look for uncompressed tar file 946 else if ($p_mode=="tar") 947 { 948 // ----- Open the file in read mode 949 if (($p_tar_add = @fopen($p_tarname_add, "rb")) == 0) 950 { 951 // ----- Error log 952 PclErrorLog(-2, "Unable to open file '$p_tarname_add' in binary read mode"); 953 954 // ----- Return 955 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 956 return PclErrorCode(); 957 } 958 959 // ----- Read the first 512 bytes block 960 $v_buffer = fread($p_tar_add, 512); 961 962 // ----- Read the following blocks but not the last one 963 if (!feof($p_tar_add)) 964 { 965 TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file"); 966 $i=1; 967 968 // ----- Read new 512 block and write the already read 969 do{ 970 // ----- Write the already read block 971 $v_binary_data = pack("a512", "$v_buffer"); 972 if ($p_mode=="tar") 973 fputs($p_tar, $v_binary_data); 974 else 975 gzputs($v_temp_tar, $v_binary_data); 976 977 $i++; 978 TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i"); 979 980 // ----- Read next block 981 $v_buffer = fread($p_tar_add, 512); 982 983 } while (!feof($p_tar_add)); 984 985 TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks"); 986 } 987 988 // ----- Close the files 989 fclose($p_tar_add); 990 } 991 992 // ----- Call the footer of the tar archive 993 $v_result = PclTarHandleFooter($p_tar, $p_mode); 994 995 // ----- Look for closing compressed archive 996 if ($p_mode == "tgz") 997 { 998 // ----- Close the files 999 gzclose($p_tar); 1000 gzclose($v_temp_tar); 1001 1002 // ----- Unlink tar file 1003 if (!@unlink($p_tarname)) 1004 { 1005 // ----- Error log 1006 PclErrorLog(-11, "Error while deleting archive name $p_tarname"); 1007 } 1008 1009 // ----- Rename tar file 1010 if (!@rename($v_temp_tarname, $p_tarname)) 1011 { 1012 // ----- Error log 1013 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname"); 1014 1015 // ----- Return 1016 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1017 return PclErrorCode(); 1018 } 1019 1020 // ----- Return 1021 TrFctEnd(__FILE__, __LINE__, $v_result); 1022 return $v_result; 1023 } 1024 1025 // ----- Look for closing uncompressed tar file 1026 else if ($p_mode=="tar") 1027 { 1028 // ----- Close the tarfile 1029 fclose($p_tar); 1030 } 1031 1032 // ----- Return 1033 TrFctEnd(__FILE__, __LINE__, $v_result); 1034 return $v_result; 1035 } 1036 // -------------------------------------------------------------------------------- 1037 1038 1039 // -------------------------------------------------------------------------------- 1040 // ***** UNDER THIS LINE ARE DEFINED PRIVATE INTERNAL FUNCTIONS ***** 1041 // ***** ***** 1042 // ***** THESES FUNCTIONS MUST NOT BE USED DIRECTLY ***** 1043 // -------------------------------------------------------------------------------- 1044 1045 1046 1047 // -------------------------------------------------------------------------------- 1048 // Function : PclTarHandleCreate() 1049 // Description : 1050 // Parameters : 1051 // $p_tarname : Name of the tar file 1052 // $p_list : An array containing the file or directory names to add in the tar 1053 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive 1054 // Return Values : 1055 // -------------------------------------------------------------------------------- 1056 function PclTarHandleCreate($p_tarname, $p_list, $p_mode, $p_add_dir="", $p_remove_dir="") 1057 { 1058 TrFctStart(__FILE__, __LINE__, "PclTarHandleCreate", "tar=$p_tarname, list, mode=$p_mode, add_dir='$p_add_dir', remove_dir='$p_remove_dir'"); 1059 $v_result=1; 1060 $v_list_detail = array(); 1061 1062 // ----- Check the parameters 1063 if (($p_tarname == "") || (($p_mode != "tar") && ($p_mode != "tgz"))) 1064 { 1065 // ----- Error log 1066 if ($p_tarname == "") 1067 PclErrorLog(-3, "Invalid empty archive name"); 1068 else 1069 PclErrorLog(-3, "Unknown mode '$p_mode'"); 1070 1071 // ----- Return 1072 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1073 return PclErrorCode(); 1074 } 1075 1076 // ----- Look for tar file 1077 if ($p_mode == "tar") 1078 { 1079 // ----- Open the tar file 1080 if (($p_tar = fopen($p_tarname, "wb")) == 0) 1081 { 1082 // ----- Error log 1083 PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode"); 1084 1085 // ----- Return 1086 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1087 return PclErrorCode(); 1088 } 1089 1090 // ----- Call the adding fct inside the tar 1091 if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1) 1092 { 1093 // ----- Call the footer of the tar archive 1094 $v_result = PclTarHandleFooter($p_tar, $p_mode); 1095 } 1096 1097 // ----- Close the tarfile 1098 fclose($p_tar); 1099 } 1100 // ----- Look for tgz file 1101 else 1102 { 1103 // ----- Open the tar file 1104 if (($p_tar = @gzopen($p_tarname, "wb")) == 0) 1105 { 1106 // ----- Error log 1107 PclErrorLog(-1, "Unable to open file [$p_tarname] in binary write mode"); 1108 1109 // ----- Return 1110 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1111 return PclErrorCode(); 1112 } 1113 1114 // ----- Call the adding fct inside the tar 1115 if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $v_list_detail, $p_add_dir, $p_remove_dir)) == 1) 1116 { 1117 // ----- Call the footer of the tar archive 1118 $v_result = PclTarHandleFooter($p_tar, $p_mode); 1119 } 1120 1121 // ----- Close the tarfile 1122 gzclose($p_tar); 1123 } 1124 1125 // ----- Return 1126 TrFctEnd(__FILE__, __LINE__, $v_result); 1127 return $v_result; 1128 } 1129 // -------------------------------------------------------------------------------- 1130 1131 // -------------------------------------------------------------------------------- 1132 // Function : PclTarHandleAppend() 1133 // Description : 1134 // Parameters : 1135 // $p_tarname : Name of the tar file 1136 // $p_list : An array containing the file or directory names to add in the tar 1137 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive 1138 // Return Values : 1139 // -------------------------------------------------------------------------------- 1140 function PclTarHandleAppend($p_tarname, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir) 1141 { 1142 TrFctStart(__FILE__, __LINE__, "PclTarHandleAppend", "tar=$p_tarname, list, mode=$p_mode"); 1143 $v_result=1; 1144 1145 // ----- Check the parameters 1146 if ($p_tarname == "") 1147 { 1148 // ----- Error log 1149 PclErrorLog(-3, "Invalid empty archive name"); 1150 1151 // ----- Return 1152 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1153 return PclErrorCode(); 1154 } 1155 1156 clearstatcache(); 1157 1158 // ----- Check the file size 1159 if ((!is_file($p_tarname)) || 1160 (((($v_size = filesize($p_tarname)) % 512) != 0) && ($p_mode=="tar"))) 1161 { 1162 // ----- Error log 1163 if (!is_file($p_tarname)) 1164 PclErrorLog(-4, "Archive '$p_tarname' does not exist"); 1165 else 1166 PclErrorLog(-6, "Archive '$p_tarname' has invalid size ".filesize($p_tarname)."(not a 512 block multiple)"); 1167 1168 // ----- Return 1169 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1170 return PclErrorCode(); 1171 } 1172 1173 // ----- Look for compressed archive 1174 if ($p_mode == "tgz") 1175 { 1176 // ----- Open the file in read mode 1177 if (($p_tar = @gzopen($p_tarname, "rb")) == 0) 1178 { 1179 // ----- Error log 1180 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); 1181 1182 // ----- Return 1183 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1184 return PclErrorCode(); 1185 } 1186 1187 // ----- Open a temporary file in write mode 1188 $v_temp_tarname = uniqid("pcltar-").".tmp"; 1189 TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); 1190 if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0) 1191 { 1192 // ----- Close tar file 1193 gzclose($p_tar); 1194 1195 // ----- Error log 1196 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); 1197 1198 // ----- Return 1199 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1200 return PclErrorCode(); 1201 } 1202 1203 // ----- Read the first 512 bytes block 1204 $v_buffer = gzread($p_tar, 512); 1205 1206 // ----- Read the following blocks but not the last one 1207 if (!gzeof($p_tar)) 1208 { 1209 TrFctMessage(__FILE__, __LINE__, 3, "More than one 512 block file"); 1210 $i=1; 1211 1212 // ----- Read new 512 block and write the already read 1213 do{ 1214 // ----- Write the already read block 1215 $v_binary_data = pack("a512", "$v_buffer"); 1216 gzputs($v_temp_tar, $v_binary_data); 1217 1218 $i++; 1219 TrFctMessage(__FILE__, __LINE__, 3, "Reading block $i"); 1220 1221 // ----- Read next block 1222 $v_buffer = gzread($p_tar, 512); 1223 1224 } while (!gzeof($p_tar)); 1225 1226 TrFctMessage(__FILE__, __LINE__, 3, "$i 512 bytes blocks"); 1227 } 1228 1229 // ----- Call the adding fct inside the tar 1230 if (($v_result = PclTarHandleAddList($v_temp_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1) 1231 { 1232 // ----- Call the footer of the tar archive 1233 $v_result = PclTarHandleFooter($v_temp_tar, $p_mode); 1234 } 1235 1236 // ----- Close the files 1237 gzclose($p_tar); 1238 gzclose($v_temp_tar); 1239 1240 // ----- Unlink tar file 1241 if (!@unlink($p_tarname)) 1242 { 1243 // ----- Error log 1244 PclErrorLog(-11, "Error while deleting archive name $p_tarname"); 1245 } 1246 1247 // ----- Rename tar file 1248 if (!@rename($v_temp_tarname, $p_tarname)) 1249 { 1250 // ----- Error log 1251 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname"); 1252 1253 // ----- Return 1254 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1255 return PclErrorCode(); 1256 } 1257 1258 // ----- Return 1259 TrFctEnd(__FILE__, __LINE__, $v_result); 1260 return $v_result; 1261 } 1262 1263 // ----- Look for uncompressed tar file 1264 else if ($p_mode=="tar") 1265 { 1266 // ----- Open the tar file 1267 if (($p_tar = fopen($p_tarname, "r+b")) == 0) 1268 { 1269 // ----- Error log 1270 PclErrorLog(-1, "Unable to open file '$p_tarname' in binary write mode"); 1271 1272 // ----- Return 1273 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1274 return PclErrorCode(); 1275 } 1276 1277 // ----- Go to the beginning of last block 1278 TrFctMessage(__FILE__, __LINE__, 4, "Position before :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1279 fseek($p_tar, $v_size-512); 1280 TrFctMessage(__FILE__, __LINE__, 4, "Position after :".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1281 1282 // ----- Call the adding fct inside the tar 1283 if (($v_result = PclTarHandleAddList($p_tar, $p_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir)) == 1) 1284 { 1285 // ----- Call the footer of the tar archive 1286 $v_result = PclTarHandleFooter($p_tar, $p_mode); 1287 } 1288 1289 // ----- Close the tarfile 1290 fclose($p_tar); 1291 } 1292 1293 // ----- Look for unknown type 1294 else 1295 { 1296 // ----- Error log 1297 PclErrorLog(-3, "Invalid tar mode $p_mode"); 1298 1299 // ----- Return 1300 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1301 return PclErrorCode(); 1302 } 1303 1304 // ----- Return 1305 TrFctEnd(__FILE__, __LINE__, $v_result); 1306 return $v_result; 1307 } 1308 // -------------------------------------------------------------------------------- 1309 1310 // -------------------------------------------------------------------------------- 1311 // Function : PclTarHandleAddList() 1312 // Description : 1313 // $p_add_dir and $p_remove_dir will give the ability to memorize a path which is 1314 // different from the real path of the file. This is usefull if you want to have PclTar 1315 // running in any directory, and memorize relative path from an other directory. 1316 // Parameters : 1317 // $p_tar : File descriptor of the tar archive 1318 // $p_list : An array containing the file or directory names to add in the tar 1319 // $p_mode : "tar" for normal tar archive, "tgz" for gzipped tar archive 1320 // $p_list_detail : list of added files with their properties (specially the status field) 1321 // $p_add_dir : Path to add in the filename path archived 1322 // $p_remove_dir : Path to remove in the filename path archived 1323 // Return Values : 1324 // -------------------------------------------------------------------------------- 1325 function PclTarHandleAddList($p_tar, $p_list, $p_mode, &$p_list_detail, $p_add_dir, $p_remove_dir) 1326 { 1327 TrFctStart(__FILE__, __LINE__, "PclTarHandleAddList", "tar='$p_tar', list, mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'"); 1328 $v_result=1; 1329 $v_header = array(); 1330 1331 // ----- Recuperate the current number of elt in list 1332 $v_nb = sizeof($p_list_detail); 1333 1334 // ----- Check the parameters 1335 if ($p_tar == 0) 1336 { 1337 // ----- Error log 1338 PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__); 1339 1340 // ----- Return 1341 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1342 return PclErrorCode(); 1343 } 1344 1345 // ----- Check the arguments 1346 if (sizeof($p_list) == 0) 1347 { 1348 // ----- Error log 1349 PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)"); 1350 1351 // ----- Return 1352 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1353 return PclErrorCode(); 1354 } 1355 1356 // ----- Loop on the files 1357 for ($j=0; ($j<count($p_list)) && ($v_result==1); $j++) 1358 { 1359 // ----- Recuperate the filename 1360 $p_filename = $p_list[$j]; 1361 1362 TrFctMessage(__FILE__, __LINE__, 2, "Looking for file [$p_filename]"); 1363 1364 // ----- Skip empty file names 1365 if ($p_filename == "") 1366 { 1367 TrFctMessage(__FILE__, __LINE__, 2, "Skip empty filename"); 1368 continue; 1369 } 1370 1371 // ----- Check the filename 1372 if (!file_exists($p_filename)) 1373 { 1374 // ----- Error log 1375 TrFctMessage(__FILE__, __LINE__, 2, "File '$p_filename' does not exists"); 1376 PclErrorLog(-4, "File '$p_filename' does not exists"); 1377 1378 // ----- Return 1379 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1380 return PclErrorCode(); 1381 } 1382 1383 // ----- Check the path length 1384 if (strlen($p_filename) > 99) 1385 { 1386 // ----- Error log 1387 PclErrorLog(-5, "File name is too long (max. 99) : '$p_filename'"); 1388 1389 // ----- Return 1390 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1391 return PclErrorCode(); 1392 } 1393 1394 TrFctMessage(__FILE__, __LINE__, 4, "File position before header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1395 1396 // ----- Add the file 1397 if (($v_result = PclTarHandleAddFile($p_tar, $p_filename, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1) 1398 { 1399 // ----- Return status 1400 TrFctEnd(__FILE__, __LINE__, $v_result); 1401 return $v_result; 1402 } 1403 1404 // ----- Store the file infos 1405 $p_list_detail[$v_nb++] = $v_header; 1406 1407 // ----- Look for directory 1408 if (is_dir($p_filename)) 1409 { 1410 TrFctMessage(__FILE__, __LINE__, 2, "$p_filename is a directory"); 1411 1412 // ----- Look for path 1413 if ($p_filename != ".") 1414 $v_path = $p_filename."/"; 1415 else 1416 $v_path = ""; 1417 1418 // ----- Read the directory for files and sub-directories 1419 $p_hdir = opendir($p_filename); 1420 $p_hitem = readdir($p_hdir); // '.' directory 1421 $p_hitem = readdir($p_hdir); // '..' directory 1422 while ($p_hitem = readdir($p_hdir)) 1423 { 1424 // ----- Look for a file 1425 if (is_file($v_path.$p_hitem)) 1426 { 1427 TrFctMessage(__FILE__, __LINE__, 4, "Add the file '".$v_path.$p_hitem."'"); 1428 1429 // ----- Add the file 1430 if (($v_result = PclTarHandleAddFile($p_tar, $v_path.$p_hitem, $p_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1) 1431 { 1432 // ----- Return status 1433 TrFctEnd(__FILE__, __LINE__, $v_result); 1434 return $v_result; 1435 } 1436 1437 // ----- Store the file infos 1438 $p_list_detail[$v_nb++] = $v_header; 1439 } 1440 1441 // ----- Recursive call to PclTarHandleAddFile() 1442 else 1443 { 1444 TrFctMessage(__FILE__, __LINE__, 4, "'".$v_path.$p_hitem."' is a directory"); 1445 1446 // ----- Need an array as parameter 1447 $p_temp_list[0] = $v_path.$p_hitem; 1448 $v_result = PclTarHandleAddList($p_tar, $p_temp_list, $p_mode, $p_list_detail, $p_add_dir, $p_remove_dir); 1449 } 1450 } 1451 1452 // ----- Free memory for the recursive loop 1453 unset($p_temp_list); 1454 unset($p_hdir); 1455 unset($p_hitem); 1456 } 1457 else 1458 { 1459 TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1460 } 1461 } 1462 1463 // ----- Return 1464 TrFctEnd(__FILE__, __LINE__, $v_result); 1465 return $v_result; 1466 } 1467 // -------------------------------------------------------------------------------- 1468 1469 // -------------------------------------------------------------------------------- 1470 // Function : PclTarHandleAddFile() 1471 // Description : 1472 // Parameters : 1473 // Return Values : 1474 // -------------------------------------------------------------------------------- 1475 function PclTarHandleAddFile($p_tar, $p_filename, $p_mode, &$p_header, $p_add_dir, $p_remove_dir) 1476 { 1477 TrFctStart(__FILE__, __LINE__, "PclTarHandleAddFile", "tar='$p_tar', filename='$p_filename', p_mode='$p_mode', add_dir='$p_add_dir', remove_dir='$p_remove_dir'"); 1478 $v_result=1; 1479 1480 // ----- Check the parameters 1481 if ($p_tar == 0) 1482 { 1483 // ----- Error log 1484 PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__); 1485 1486 // ----- Return 1487 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1488 return PclErrorCode(); 1489 } 1490 1491 // ----- Skip empty file names 1492 if ($p_filename == "") 1493 { 1494 // ----- Error log 1495 PclErrorLog(-3, "Invalid file list parameter (invalid or empty list)"); 1496 1497 // ----- Return 1498 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1499 return PclErrorCode(); 1500 } 1501 1502 // ----- Calculate the stored filename 1503 $v_stored_filename = $p_filename; 1504 if ($p_remove_dir != "") 1505 { 1506 if (substr($p_remove_dir, -1) != '/') 1507 $p_remove_dir .= "/"; 1508 1509 if ((substr($p_filename, 0, 2) == "./") || (substr($p_remove_dir, 0, 2) == "./")) 1510 { 1511 if ((substr($p_filename, 0, 2) == "./") && (substr($p_remove_dir, 0, 2) != "./")) 1512 $p_remove_dir = "./".$p_remove_dir; 1513 if ((substr($p_filename, 0, 2) != "./") && (substr($p_remove_dir, 0, 2) == "./")) 1514 $p_remove_dir = substr($p_remove_dir, 2); 1515 } 1516 1517 if (substr($p_filename, 0, strlen($p_remove_dir)) == $p_remove_dir) 1518 { 1519 $v_stored_filename = substr($p_filename, strlen($p_remove_dir)); 1520 TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_filename' = '$v_stored_filename'"); 1521 } 1522 } 1523 if ($p_add_dir != "") 1524 { 1525 if (substr($p_add_dir, -1) == "/") 1526 $v_stored_filename = $p_add_dir.$v_stored_filename; 1527 else 1528 $v_stored_filename = $p_add_dir."/".$v_stored_filename; 1529 TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_filename' = '$v_stored_filename'"); 1530 } 1531 1532 // ----- Check the path length 1533 if (strlen($v_stored_filename) > 99) 1534 { 1535 // ----- Error log 1536 PclErrorLog(-5, "Stored file name is too long (max. 99) : '$v_stored_filename'"); 1537 1538 // ----- Return 1539 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1540 return PclErrorCode(); 1541 } 1542 1543 // ----- Look for a file 1544 if (is_file($p_filename)) 1545 { 1546 // ----- Open the source file 1547 if (($v_file = fopen($p_filename, "rb")) == 0) 1548 { 1549 // ----- Error log 1550 PclErrorLog(-2, "Unable to open file '$p_filename' in binary read mode"); 1551 1552 // ----- Return 1553 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1554 return PclErrorCode(); 1555 } 1556 1557 // ----- Call the header generation 1558 if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1) 1559 { 1560 // ----- Return status 1561 TrFctEnd(__FILE__, __LINE__, $v_result); 1562 return $v_result; 1563 } 1564 1565 TrFctMessage(__FILE__, __LINE__, 4, "File position after header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1566 1567 // ----- Read the file by 512 octets blocks 1568 $i=0; 1569 while (($v_buffer = fread($v_file, 512)) != "") 1570 { 1571 $v_binary_data = pack("a512", "$v_buffer"); 1572 if ($p_mode == "tar") 1573 fputs($p_tar, $v_binary_data); 1574 else 1575 gzputs($p_tar, $v_binary_data); 1576 $i++; 1577 } 1578 TrFctMessage(__FILE__, __LINE__, 2, "$i 512 bytes blocks"); 1579 1580 // ----- Close the file 1581 fclose($v_file); 1582 1583 TrFctMessage(__FILE__, __LINE__, 4, "File position after blocks =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1584 } 1585 1586 // ----- Look for a directory 1587 else 1588 { 1589 // ----- Call the header generation 1590 if (($v_result = PclTarHandleHeader($p_tar, $p_filename, $p_mode, $p_header, $v_stored_filename)) != 1) 1591 { 1592 // ----- Return status 1593 TrFctEnd(__FILE__, __LINE__, $v_result); 1594 return $v_result; 1595 } 1596 1597 TrFctMessage(__FILE__, __LINE__, 4, "File position after header =".($p_mode=="tar"?ftell($p_tar):gztell($p_tar))); 1598 } 1599 1600 // ----- Return 1601 TrFctEnd(__FILE__, __LINE__, $v_result); 1602 return $v_result; 1603 } 1604 // -------------------------------------------------------------------------------- 1605 1606 // -------------------------------------------------------------------------------- 1607 // Function : PclTarHandleHeader() 1608 // Description : 1609 // This function creates in the TAR $p_tar, the TAR header for the file 1610 // $p_filename. 1611 // 1612 // 1. The informations needed to compose the header are recuperated and formatted 1613 // 2. Two binary strings are composed for the first part of the header, before 1614 // and after checksum field. 1615 // 3. The checksum is calculated from the two binary strings 1616 // 4. The header is write in the tar file (first binary string, binary string 1617 // for checksum and last binary string). 1618 // Parameters : 1619 // $p_tar : a valid file descriptor, opened in write mode, 1620 // $p_filename : The name of the file the header is for, 1621 // $p_mode : The mode of the archive ("tar" or "tgz"). 1622 // $p_header : A pointer to a array where will be set the file properties 1623 // Return Values : 1624 // -------------------------------------------------------------------------------- 1625 function PclTarHandleHeader($p_tar, $p_filename, $p_mode, &$p_header, $p_stored_filename) 1626 { 1627 TrFctStart(__FILE__, __LINE__, "PclTarHandleHeader", "tar=$p_tar, file='$p_filename', mode='$p_mode', stored_filename='$p_stored_filename'"); 1628 $v_result=1; 1629 1630 // ----- Check the parameters 1631 if (($p_tar == 0) || ($p_filename == "")) 1632 { 1633 // ----- Error log 1634 PclErrorLog(-3, "Invalid file descriptor in file ".__FILE__.", line ".__LINE__); 1635 1636 // ----- Return 1637 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1638 return PclErrorCode(); 1639 } 1640 1641 // ----- Filename (reduce the path of stored name) 1642 if ($p_stored_filename == "") 1643 $p_stored_filename = $p_filename; 1644 $v_reduce_filename = PclTarHandlePathReduction($p_stored_filename); 1645 TrFctMessage(__FILE__, __LINE__, 2, "Filename (reduced) '$v_reduce_filename', strlen ".strlen($v_reduce_filename)); 1646 1647 // ----- Get file info 1648 $v_info = stat($p_filename); 1649 $v_uid = sprintf("%6s ", DecOct($v_info[4])); 1650 $v_gid = sprintf("%6s ", DecOct($v_info[5])); 1651 TrFctMessage(__FILE__, __LINE__, 3, "uid=$v_uid, gid=$v_gid"); 1652 $v_perms = sprintf("%6s ", DecOct(fileperms($p_filename))); 1653 TrFctMessage(__FILE__, __LINE__, 3, "file permissions $v_perms"); 1654 1655 // ----- File mtime 1656 $v_mtime_data = filemtime($p_filename); 1657 TrFctMessage(__FILE__, __LINE__, 2, "File mtime : $v_mtime_data"); 1658 $v_mtime = sprintf("%11s", DecOct($v_mtime_data)); 1659 1660 // ----- File typeflag 1661 // '0' or '\0' is the code for regular file 1662 // '5' is directory 1663 if (is_dir($p_filename)) 1664 { 1665 $v_typeflag = "5"; 1666 $v_size = 0; 1667 } 1668 else 1669 { 1670 $v_typeflag = ""; 1671 1672 // ----- Get the file size 1673 clearstatcache(); 1674 $v_size = filesize($p_filename); 1675 } 1676 1677 TrFctMessage(__FILE__, __LINE__, 2, "File size : $v_size"); 1678 $v_size = sprintf("%11s ", DecOct($v_size)); 1679 1680 TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_typeflag"); 1681 1682 // ----- Linkname 1683 $v_linkname = ""; 1684 1685 // ----- Magic 1686 $v_magic = ""; 1687 1688 // ----- Version 1689 $v_version = ""; 1690 1691 // ----- uname 1692 $v_uname = ""; 1693 1694 // ----- gname 1695 $v_gname = ""; 1696 1697 // ----- devmajor 1698 $v_devmajor = ""; 1699 1700 // ----- devminor 1701 $v_devminor = ""; 1702 1703 // ----- prefix 1704 $v_prefix = ""; 1705 1706 // ----- Compose the binary string of the header in two parts arround the checksum position 1707 $v_binary_data_first = pack("a100a8a8a8a12A12", $v_reduce_filename, $v_perms, $v_uid, $v_gid, $v_size, $v_mtime); 1708 $v_binary_data_last = pack("a1a100a6a2a32a32a8a8a155a12", $v_typeflag, $v_linkname, $v_magic, $v_version, $v_uname, $v_gname, $v_devmajor, $v_devminor, $v_prefix, ""); 1709 1710 // ----- Calculate the checksum 1711 $v_checksum = 0; 1712 // ..... First part of the header 1713 for ($i=0; $i<148; $i++) 1714 { 1715 $v_checksum += ord(substr($v_binary_data_first,$i,1)); 1716 } 1717 // ..... Ignore the checksum value and replace it by ' ' (space) 1718 for ($i=148; $i<156; $i++) 1719 { 1720 $v_checksum += ord(' '); 1721 } 1722 // ..... Last part of the header 1723 for ($i=156, $j=0; $i<512; $i++, $j++) 1724 { 1725 $v_checksum += ord(substr($v_binary_data_last,$j,1)); 1726 } 1727 TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum"); 1728 1729 // ----- Write the first 148 bytes of the header in the archive 1730 if ($p_mode == "tar") 1731 fputs($p_tar, $v_binary_data_first, 148); 1732 else 1733 gzputs($p_tar, $v_binary_data_first, 148); 1734 1735 // ----- Write the calculated checksum 1736 $v_checksum = sprintf("%6s ", DecOct($v_checksum)); 1737 $v_binary_data = pack("a8", $v_checksum); 1738 if ($p_mode == "tar") 1739 fputs($p_tar, $v_binary_data, 8); 1740 else 1741 gzputs($p_tar, $v_binary_data, 8); 1742 1743 // ----- Write the last 356 bytes of the header in the archive 1744 if ($p_mode == "tar") 1745 fputs($p_tar, $v_binary_data_last, 356); 1746 else 1747 gzputs($p_tar, $v_binary_data_last, 356); 1748 1749 // ----- Set the properties in the header "structure" 1750 $p_header[filename] = $v_reduce_filename; 1751 $p_header[mode] = $v_perms; 1752 $p_header[uid] = $v_uid; 1753 $p_header[gid] = $v_gid; 1754 $p_header[size] = $v_size; 1755 $p_header[mtime] = $v_mtime; 1756 $p_header[typeflag] = $v_typeflag; 1757 $p_header[status] = "added"; 1758 1759 // ----- Return 1760 TrFctEnd(__FILE__, __LINE__, $v_result); 1761 return $v_result; 1762 } 1763 // -------------------------------------------------------------------------------- 1764 1765 // -------------------------------------------------------------------------------- 1766 // Function : PclTarHandleFooter() 1767 // Description : 1768 // Parameters : 1769 // Return Values : 1770 // -------------------------------------------------------------------------------- 1771 function PclTarHandleFooter($p_tar, $p_mode) 1772 { 1773 TrFctStart(__FILE__, __LINE__, "PclTarHandleFooter", "tar='$p_tar', p_mode=$p_mode"); 1774 $v_result=1; 1775 1776 // ----- Write the last 0 filled block for end of archive 1777 $v_binary_data = pack("a512", ""); 1778 if ($p_mode == "tar") 1779 fputs($p_tar, $v_binary_data); 1780 else 1781 gzputs($p_tar, $v_binary_data); 1782 1783 // ----- Return 1784 TrFctEnd(__FILE__, __LINE__, $v_result); 1785 return $v_result; 1786 } 1787 // -------------------------------------------------------------------------------- 1788 1789 // -------------------------------------------------------------------------------- 1790 // Function : PclTarHandleExtract() 1791 // Description : 1792 // Parameters : 1793 // $p_tarname : Filename of the tar (or tgz) archive 1794 // $p_file_list : An array which contains the list of files to extract, this 1795 // array may be empty when $p_mode is 'complete' 1796 // $p_list_detail : An array where will be placed the properties of each extracted/listed file 1797 // $p_mode : 'complete' will extract all files from the archive, 1798 // 'partial' will look for files in $p_file_list 1799 // 'list' will only list the files from the archive without any extract 1800 // $p_path : Path to add while writing the extracted files 1801 // $p_tar_mode : 'tar' for GNU TAR archive, 'tgz' for compressed archive 1802 // $p_remove_path : Path to remove (from the file memorized path) while writing the 1803 // extracted files. If the path does not match the file path, 1804 // the file is extracted with its memorized path. 1805 // $p_remove_path does not apply to 'list' mode. 1806 // $p_path and $p_remove_path are commulative. 1807 // Return Values : 1808 // -------------------------------------------------------------------------------- 1809 function PclTarHandleExtract($p_tarname, $p_file_list, &$p_list_detail, $p_mode, $p_path, $p_tar_mode, $p_remove_path) 1810 { 1811 TrFctStart(__FILE__, __LINE__, "PclTarHandleExtract", "archive='$p_tarname', list, mode=$p_mode, path=$p_path, tar_mode=$p_tar_mode, remove_path='$p_remove_path'"); 1812 $v_result=1; 1813 $v_nb = 0; 1814 $v_extract_all = TRUE; 1815 $v_listing = FALSE; 1816 1817 // ----- Check the path 1818 /* 1819 if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../"))) 1820 $p_path = "./".$p_path; 1821 */ 1822 1823 $isWin = (substr(PHP_OS, 0, 3) == 'WIN'); 1824 1825 if(!$isWin) 1826 { 1827 if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../"))) 1828 $p_path = "./".$p_path; 1829 } 1830 // ----- Look for path to remove format (should end by /) 1831 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) 1832 { 1833 $p_remove_path .= '/'; 1834 } 1835 $p_remove_path_size = strlen($p_remove_path); 1836 1837 // ----- Study the mode 1838 switch ($p_mode) { 1839 case "complete" : 1840 // ----- Flag extract of all files 1841 $v_extract_all = TRUE; 1842 $v_listing = FALSE; 1843 break; 1844 case "partial" : 1845 // ----- Flag extract of specific files 1846 $v_extract_all = FALSE; 1847 $v_listing = FALSE; 1848 break; 1849 case "list" : 1850 // ----- Flag list of all files 1851 $v_extract_all = FALSE; 1852 $v_listing = TRUE; 1853 break; 1854 default : 1855 // ----- Error log 1856 PclErrorLog(-3, "Invalid extract mode ($p_mode)"); 1857 1858 // ----- Return 1859 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1860 return PclErrorCode(); 1861 } 1862 1863 // ----- Open the tar file 1864 if ($p_tar_mode == "tar") 1865 { 1866 TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); 1867 $v_tar = fopen($p_tarname, "rb"); 1868 } 1869 else 1870 { 1871 TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); 1872 $v_tar = @gzopen($p_tarname, "rb"); 1873 } 1874 1875 // ----- Check that the archive is open 1876 if ($v_tar == 0) 1877 { 1878 // ----- Error log 1879 PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode"); 1880 1881 // ----- Return 1882 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 1883 return PclErrorCode(); 1884 } 1885 1886 // ----- Read the blocks 1887 While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))) 1888 { 1889 TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); 1890 1891 // ----- Clear cache of file infos 1892 clearstatcache(); 1893 1894 // ----- Reset extract tag 1895 $v_extract_file = FALSE; 1896 $v_extraction_stopped = 0; 1897 1898 // ----- Read the 512 bytes header 1899 if ($p_tar_mode == "tar") 1900 $v_binary_data = fread($v_tar, 512); 1901 else 1902 $v_binary_data = gzread($v_tar, 512); 1903 1904 // ----- Read the header properties 1905 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1) 1906 { 1907 // ----- Close the archive file 1908 if ($p_tar_mode == "tar") 1909 fclose($v_tar); 1910 else 1911 gzclose($v_tar); 1912 1913 // ----- Return 1914 TrFctEnd(__FILE__, __LINE__, $v_result); 1915 return $v_result; 1916 } 1917 1918 // ----- Look for empty blocks to skip 1919 if ($v_header["filename"] == "") 1920 { 1921 TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?"); 1922 continue; 1923 } 1924 1925 TrFctMessage(__FILE__, __LINE__, 2, "Found file '" . $v_header["filename"] . "', size '$v_header[size]'"); 1926 1927 // ----- Look for partial extract 1928 if ((!$v_extract_all) && (is_array($p_file_list))) 1929 { 1930 TrFctMessage(__FILE__, __LINE__, 2, "Look if the file '$v_header[filename]' need to be extracted"); 1931 1932 // ----- By default no unzip if the file is not found 1933 $v_extract_file = FALSE; 1934 1935 // ----- Look into the file list 1936 for ($i=0; $i<sizeof($p_file_list); $i++) 1937 { 1938 TrFctMessage(__FILE__, __LINE__, 2, "Compare archived file '$v_header[filename]' from asked list file '".$p_file_list[$i]."'"); 1939 1940 // ----- Look if it is a directory 1941 if (substr($p_file_list[$i], -1) == "/") 1942 { 1943 TrFctMessage(__FILE__, __LINE__, 3, "Compare file '$v_header[filename]' with directory '$p_file_list[$i]'"); 1944 1945 // ----- Look if the directory is in the filename path 1946 if ((strlen($v_header["filename"]) > strlen($p_file_list[$i])) && (substr($v_header["filename"], 0, strlen($p_file_list[$i])) == $p_file_list[$i])) 1947 { 1948 // ----- The file is in the directory, so extract it 1949 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in directory '$p_file_list[$i]' : extract it"); 1950 $v_extract_file = TRUE; 1951 1952 // ----- End of loop 1953 break; 1954 } 1955 } 1956 1957 // ----- It is a file, so compare the file names 1958 else if ($p_file_list[$i] == $v_header["filename"]) 1959 { 1960 // ----- File found 1961 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should be extracted"); 1962 $v_extract_file = TRUE; 1963 1964 // ----- End of loop 1965 break; 1966 } 1967 } 1968 1969 // ----- Trace 1970 if (!$v_extract_file) 1971 { 1972 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' should not be extracted"); 1973 } 1974 } 1975 else 1976 { 1977 // ----- All files need to be extracted 1978 $v_extract_file = TRUE; 1979 } 1980 1981 // ----- Look if this file need to be extracted 1982 if (($v_extract_file) && (!$v_listing)) 1983 { 1984 // ----- Look for path to remove 1985 if (($p_remove_path != "") 1986 && (substr($v_header["filename"], 0, $p_remove_path_size) == $p_remove_path)) 1987 { 1988 TrFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'"); 1989 // ----- Remove the path 1990 $v_header["filename"] = substr($v_header["filename"], $p_remove_path_size); 1991 TrFctMessage(__FILE__, __LINE__, 3, "Reslting file is '$v_header[filename]'"); 1992 } 1993 1994 // ----- Add the path to the file 1995 if (($p_path != "./") && ($p_path != "/")) 1996 { 1997 // ----- Look for the path end '/' 1998 while (substr($p_path, -1) == "/") 1999 { 2000 TrFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'"); 2001 $p_path = substr($p_path, 0, strlen($p_path)-1); 2002 TrFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]"); 2003 } 2004 2005 // ----- Add the path 2006 if (substr($v_header["filename"], 0, 1) == "/") 2007 $v_header["filename"] = $p_path.$v_header["filename"]; 2008 else 2009 $v_header["filename"] = $p_path."/".$v_header["filename"]; 2010 } 2011 2012 // ----- Trace 2013 TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'"); 2014 2015 // ----- Check that the file does not exists 2016 if (file_exists($v_header["filename"])) 2017 { 2018 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists"); 2019 2020 // ----- Look if file is a directory 2021 if (is_dir($v_header["filename"])) 2022 { 2023 TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory"); 2024 2025 // ----- Change the file status 2026 $v_header["status"] = "already_a_directory"; 2027 2028 // ----- Skip the extract 2029 $v_extraction_stopped = 1; 2030 $v_extract_file = 0; 2031 } 2032 // ----- Look if file is write protected 2033 else if (!is_writeable($v_header["filename"])) 2034 { 2035 TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected"); 2036 2037 // ----- Change the file status 2038 $v_header["status"] = "write_protected"; 2039 2040 // ----- Skip the extract 2041 $v_extraction_stopped = 1; 2042 $v_extract_file = 0; 2043 } 2044 // ----- Look if the extracted file is older 2045 else if (filemtime($v_header["filename"]) > $v_header["mtime"]) 2046 { 2047 TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is newer (".date("l dS of F Y h:i:s A", filemtime($v_header[filename])).") than the extracted file (".date("l dS of F Y h:i:s A", $v_header[mtime]).")"); 2048 2049 // ----- Change the file status 2050 $v_header["status"] = "newer_exist"; 2051 2052 // ----- Skip the extract 2053 $v_extraction_stopped = 1; 2054 $v_extract_file = 0; 2055 } 2056 } 2057 2058 // ----- Check the directory availability and create it if necessary 2059 else 2060 { 2061 if ($v_header["typeflag"]=="5") 2062 $v_dir_to_check = $v_header["filename"]; 2063 else if (!strstr($v_header["filename"], "/")) 2064 $v_dir_to_check = ""; 2065 else 2066 $v_dir_to_check = dirname($v_header["filename"]); 2067 2068 if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1) 2069 { 2070 TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'"); 2071 2072 // ----- Change the file status 2073 $v_header["status"] = "path_creation_fail"; 2074 2075 // ----- Skip the extract 2076 $v_extraction_stopped = 1; 2077 $v_extract_file = 0; 2078 } 2079 } 2080 2081 // ----- Do the extraction 2082 if (($v_extract_file) && ($v_header["typeflag"]!="5")) 2083 { 2084 // ----- Open the destination file in write mode 2085 if (($v_dest_file = @fopen($v_header["filename"], "wb")) == 0) 2086 { 2087 TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode"); 2088 2089 // ----- Change the file status 2090 $v_header["status"] = "write_error"; 2091 2092 // ----- Jump to next file 2093 TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); 2094 if ($p_tar_mode == "tar") 2095 fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512)); 2096 else 2097 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512)); 2098 } 2099 else 2100 { 2101 TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'"); 2102 2103 // ----- Read data 2104 $n = floor($v_header["size"]/512); 2105 for ($i=0; $i<$n; $i++) 2106 { 2107 TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1)); 2108 if ($p_tar_mode == "tar") 2109 $v_content = fread($v_tar, 512); 2110 else 2111 $v_content = gzread($v_tar, 512); 2112 fwrite($v_dest_file, $v_content, 512); 2113 } 2114 if (($v_header["size"] % 512) != 0) 2115 { 2116 TrFctMessage(__FILE__, __LINE__, 3, "Read last ".($v_header["size"] % 512)." bytes in a 512 block"); 2117 if ($p_tar_mode == "tar") 2118 $v_content = fread($v_tar, 512); 2119 else 2120 $v_content = gzread($v_tar, 512); 2121 fwrite($v_dest_file, $v_content, ($v_header["size"] % 512)); 2122 } 2123 2124 // ----- Close the destination file 2125 fclose($v_dest_file); 2126 2127 // ----- Change the file mode, mtime 2128 touch($v_header["filename"], $v_header["mtime"]); 2129 //chmod($v_header[filename], DecOct($v_header[mode])); 2130 } 2131 2132 // ----- Check the file size 2133 clearstatcache(); 2134 if (filesize($v_header["filename"]) != $v_header["size"]) 2135 { 2136 // ----- Close the archive file 2137 if ($p_tar_mode == "tar") 2138 fclose($v_tar); 2139 else 2140 gzclose($v_tar); 2141 2142 // ----- Error log 2143 PclErrorLog(-7, "Extracted file '$v_header[filename]' does not have the correct file size '".filesize($v_filename)."' ('$v_header[size]' expected). Archive may be corrupted."); 2144 2145 // ----- Return 2146 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2147 return PclErrorCode(); 2148 } 2149 2150 // ----- Trace 2151 TrFctMessage(__FILE__, __LINE__, 2, "Extraction done"); 2152 } 2153 2154 else 2155 { 2156 TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped."); 2157 2158 // ----- Jump to next file 2159 TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); 2160 if ($p_tar_mode == "tar") 2161 fseek($v_tar, ftell($v_tar)+(ceil(($v_header["size"]/512))*512)); 2162 else 2163 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header["size"]/512))*512)); 2164 } 2165 } 2166 2167 // ----- Look for file that is not to be unzipped 2168 else 2169 { 2170 // ----- Trace 2171 TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'"); 2172 TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]"); 2173 2174 // ----- Jump to next file 2175 if ($p_tar_mode == "tar") 2176 fseek($v_tar, ($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))+(ceil(($v_header[size]/512))*512)); 2177 else 2178 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512)); 2179 2180 TrFctMessage(__FILE__, __LINE__, 4, "Position apr�s jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]"); 2181 } 2182 2183 if ($p_tar_mode == "tar") 2184 $v_end_of_file = feof($v_tar); 2185 else 2186 $v_end_of_file = gzeof($v_tar); 2187 2188 // ----- File name and properties are logged if listing mode or file is extracted 2189 if ($v_listing || $v_extract_file || $v_extraction_stopped) 2190 { 2191 TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); 2192 2193 // ----- Log extracted files 2194 if (($v_file_dir = dirname($v_header["filename"])) == $v_header["filename"]) 2195 $v_file_dir = ""; 2196 if ((substr($v_header["filename"], 0, 1) == "/") && ($v_file_dir == "")) 2197 $v_file_dir = "/"; 2198 2199 // ----- Add the array describing the file into the list 2200 $p_list_detail[$v_nb] = $v_header; 2201 2202 // ----- Increment 2203 $v_nb++; 2204 } 2205 } 2206 2207 // ----- Close the tarfile 2208 if ($p_tar_mode == "tar") 2209 fclose($v_tar); 2210 else 2211 gzclose($v_tar); 2212 2213 // ----- Return 2214 TrFctEnd(__FILE__, __LINE__, $v_result); 2215 return $v_result; 2216 } 2217 // -------------------------------------------------------------------------------- 2218 2219 // -------------------------------------------------------------------------------- 2220 // Function : PclTarHandleExtractByIndexList() 2221 // Description : 2222 // Extract the files which are at the indexes specified. If the 'file' at the 2223 // index is a directory, the directory only is created, not all the files stored 2224 // for that directory. 2225 // Parameters : 2226 // $p_index_string : String of indexes of files to extract. The form of the 2227 // string is "0,4-6,8-12" with only numbers and '-' for 2228 // for range, and ',' to separate ranges. No spaces or ';' 2229 // are allowed. 2230 // Return Values : 2231 // -------------------------------------------------------------------------------- 2232 function PclTarHandleExtractByIndexList($p_tarname, $p_index_string, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode) 2233 { 2234 TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractByIndexList", "archive='$p_tarname', index_string='$p_index_string', list, path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode"); 2235 $v_result=1; 2236 $v_nb = 0; 2237 2238 // ----- TBC : I should check the string by a regexp 2239 2240 // ----- Check the path 2241 if (($p_path == "") || ((substr($p_path, 0, 1) != "/") && (substr($p_path, 0, 3) != "../") && (substr($p_path, 0, 2) != "./"))) 2242 $p_path = "./".$p_path; 2243 2244 // ----- Look for path to remove format (should end by /) 2245 if (($p_remove_path != "") && (substr($p_remove_path, -1) != '/')) 2246 { 2247 $p_remove_path .= '/'; 2248 } 2249 $p_remove_path_size = strlen($p_remove_path); 2250 2251 // ----- Open the tar file 2252 if ($p_tar_mode == "tar") 2253 { 2254 TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); 2255 $v_tar = @fopen($p_tarname, "rb"); 2256 } 2257 else 2258 { 2259 TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); 2260 $v_tar = @gzopen($p_tarname, "rb"); 2261 } 2262 2263 // ----- Check that the archive is open 2264 if ($v_tar == 0) 2265 { 2266 // ----- Error log 2267 PclErrorLog(-2, "Unable to open archive '$p_tarname' in binary read mode"); 2268 2269 // ----- Return 2270 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2271 return PclErrorCode(); 2272 } 2273 2274 // ----- Manipulate the index list 2275 $v_list = explode(",", $p_index_string); 2276 sort($v_list); 2277 2278 // ----- Loop on the index list 2279 $v_index=0; 2280 for ($i=0; ($i<sizeof($v_list)) && ($v_result); $i++) 2281 { 2282 TrFctMessage(__FILE__, __LINE__, 3, "Looking for index part '$v_list[$i]'"); 2283 2284 // ----- Extract range 2285 $v_index_list = explode("-", $v_list[$i]); 2286 $v_size_index_list = sizeof($v_index_list); 2287 if ($v_size_index_list == 1) 2288 { 2289 TrFctMessage(__FILE__, __LINE__, 3, "Only one index '$v_index_list[0]'"); 2290 2291 // ----- Do the extraction 2292 $v_result = PclTarHandleExtractByIndex($v_tar, $v_index, $v_index_list[0], $v_index_list[0], $p_list_detail, $p_path, $p_remove_path, $p_tar_mode); 2293 } 2294 else if ($v_size_index_list == 2) 2295 { 2296 TrFctMessage(__FILE__, __LINE__, 3, "Two indexes '$v_index_list[0]' and '$v_index_list[1]'"); 2297 2298 // ----- Do the extraction 2299 $v_result = PclTarHandleExtractByIndex($v_tar, $v_index, $v_index_list[0], $v_index_list[1], $p_list_detail, $p_path, $p_remove_path, $p_tar_mode); 2300 } 2301 } 2302 2303 // ----- Close the tarfile 2304 if ($p_tar_mode == "tar") 2305 fclose($v_tar); 2306 else 2307 gzclose($v_tar); 2308 2309 // ----- Return 2310 TrFctEnd(__FILE__, __LINE__, $v_result); 2311 return $v_result; 2312 } 2313 // -------------------------------------------------------------------------------- 2314 2315 // -------------------------------------------------------------------------------- 2316 // Function : PclTarHandleExtractByIndex() 2317 // Description : 2318 // Parameters : 2319 // Return Values : 2320 // -------------------------------------------------------------------------------- 2321 function PclTarHandleExtractByIndex($p_tar, &$p_index_current, $p_index_start, $p_index_stop, &$p_list_detail, $p_path, $p_remove_path, $p_tar_mode) 2322 { 2323 TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractByIndex", "archive_descr='$p_tar', index_current=$p_index_current, index_start='$p_index_start', index_stop='$p_index_stop', list, path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode"); 2324 $v_result=1; 2325 $v_nb = 0; 2326 2327 // TBC : I should replace all $v_tar by $p_tar in this function .... 2328 $v_tar = $p_tar; 2329 2330 // ----- Look the number of elements already in $p_list_detail 2331 $v_nb = sizeof($p_list_detail); 2332 2333 // ----- Read the blocks 2334 While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))) 2335 { 2336 TrFctMessage(__FILE__, __LINE__, 3, "Looking for next file ..."); 2337 TrFctMessage(__FILE__, __LINE__, 3, "Index current=$p_index_current, range=[$p_index_start, $p_index_stop])"); 2338 2339 if ($p_index_current > $p_index_stop) 2340 { 2341 TrFctMessage(__FILE__, __LINE__, 2, "Stop extraction, past stop index"); 2342 break; 2343 } 2344 2345 // ----- Clear cache of file infos 2346 clearstatcache(); 2347 2348 // ----- Reset extract tag 2349 $v_extract_file = FALSE; 2350 $v_extraction_stopped = 0; 2351 2352 // ----- Read the 512 bytes header 2353 if ($p_tar_mode == "tar") 2354 $v_binary_data = fread($v_tar, 512); 2355 else 2356 $v_binary_data = gzread($v_tar, 512); 2357 2358 // ----- Read the header properties 2359 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1) 2360 { 2361 // ----- Return 2362 TrFctEnd(__FILE__, __LINE__, $v_result); 2363 return $v_result; 2364 } 2365 2366 // ----- Look for empty blocks to skip 2367 if ($v_header[filename] == "") 2368 { 2369 TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?"); 2370 continue; 2371 } 2372 2373 TrFctMessage(__FILE__, __LINE__, 2, "Found file '$v_header[filename]', size '$v_header[size]'"); 2374 2375 // ----- Look if file is in the range to be extracted 2376 if (($p_index_current >= $p_index_start) && ($p_index_current <= $p_index_stop)) 2377 { 2378 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is in the range to be extracted"); 2379 $v_extract_file = TRUE; 2380 } 2381 else 2382 { 2383 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' is out of the range"); 2384 $v_extract_file = FALSE; 2385 } 2386 2387 // ----- Look if this file need to be extracted 2388 if ($v_extract_file) 2389 { 2390 if (($v_result = PclTarHandleExtractFile($v_tar, $v_header, $p_path, $p_remove_path, $p_tar_mode)) != 1) 2391 { 2392 // ----- Return 2393 TrFctEnd(__FILE__, __LINE__, $v_result); 2394 return $v_result; 2395 } 2396 } 2397 2398 // ----- Look for file that is not to be extracted 2399 else 2400 { 2401 // ----- Trace 2402 TrFctMessage(__FILE__, __LINE__, 2, "Jump file '$v_header[filename]'"); 2403 TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]"); 2404 2405 // ----- Jump to next file 2406 if ($p_tar_mode == "tar") 2407 fseek($v_tar, ($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))+(ceil(($v_header[size]/512))*512)); 2408 else 2409 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512)); 2410 2411 TrFctMessage(__FILE__, __LINE__, 4, "Position apr�s jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]"); 2412 } 2413 2414 if ($p_tar_mode == "tar") 2415 $v_end_of_file = feof($v_tar); 2416 else 2417 $v_end_of_file = gzeof($v_tar); 2418 2419 // ----- File name and properties are logged if listing mode or file is extracted 2420 if ($v_extract_file) 2421 { 2422 TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); 2423 2424 // ----- Log extracted files 2425 if (($v_file_dir = dirname($v_header[filename])) == $v_header[filename]) 2426 $v_file_dir = ""; 2427 if ((substr($v_header[filename], 0, 1) == "/") && ($v_file_dir == "")) 2428 $v_file_dir = "/"; 2429 2430 // ----- Add the array describing the file into the list 2431 $p_list_detail[$v_nb] = $v_header; 2432 2433 // ----- Increment 2434 $v_nb++; 2435 } 2436 2437 // ----- Increment the current file index 2438 $p_index_current++; 2439 } 2440 2441 // ----- Return 2442 TrFctEnd(__FILE__, __LINE__, $v_result); 2443 return $v_result; 2444 } 2445 // -------------------------------------------------------------------------------- 2446 2447 // -------------------------------------------------------------------------------- 2448 // Function : PclTarHandleExtractFile() 2449 // Description : 2450 // Parameters : 2451 // Return Values : 2452 // -------------------------------------------------------------------------------- 2453 function PclTarHandleExtractFile($p_tar, &$v_header, $p_path, $p_remove_path, $p_tar_mode) 2454 { 2455 TrFctStart(__FILE__, __LINE__, "PclTarHandleExtractFile", "archive_descr='$p_tar', path=$p_path, remove_path='$p_remove_path', tar_mode=$p_tar_mode"); 2456 $v_result=1; 2457 2458 // TBC : I should replace all $v_tar by $p_tar in this function .... 2459 $v_tar = $p_tar; 2460 $v_extract_file = 1; 2461 2462 $p_remove_path_size = strlen($p_remove_path); 2463 2464 // ----- Look for path to remove 2465 if (($p_remove_path != "") 2466 && (substr($v_header[filename], 0, $p_remove_path_size) == $p_remove_path)) 2467 { 2468 TrFctMessage(__FILE__, __LINE__, 3, "Found path '$p_remove_path' to remove in file '$v_header[filename]'"); 2469 // ----- Remove the path 2470 $v_header[filename] = substr($v_header[filename], $p_remove_path_size); 2471 TrFctMessage(__FILE__, __LINE__, 3, "Resulting file is '$v_header[filename]'"); 2472 } 2473 2474 // ----- Add the path to the file 2475 if (($p_path != "./") && ($p_path != "/")) 2476 { 2477 // ----- Look for the path end '/' 2478 while (substr($p_path, -1) == "/") 2479 { 2480 TrFctMessage(__FILE__, __LINE__, 3, "Destination path [$p_path] ends by '/'"); 2481 $p_path = substr($p_path, 0, strlen($p_path)-1); 2482 TrFctMessage(__FILE__, __LINE__, 3, "Modified to [$p_path]"); 2483 } 2484 2485 // ----- Add the path 2486 if (substr($v_header[filename], 0, 1) == "/") 2487 $v_header[filename] = $p_path.$v_header[filename]; 2488 else 2489 $v_header[filename] = $p_path."/".$v_header[filename]; 2490 } 2491 2492 // ----- Trace 2493 TrFctMessage(__FILE__, __LINE__, 2, "Extracting file (with path) '$v_header[filename]', size '$v_header[size]'"); 2494 2495 // ----- Check that the file does not exists 2496 if (file_exists($v_header[filename])) 2497 { 2498 TrFctMessage(__FILE__, __LINE__, 2, "File '$v_header[filename]' already exists"); 2499 2500 // ----- Look if file is a directory 2501 if (is_dir($v_header[filename])) 2502 { 2503 TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is a directory"); 2504 2505 // ----- Change the file status 2506 $v_header[status] = "already_a_directory"; 2507 2508 // ----- Skip the extract 2509 $v_extraction_stopped = 1; 2510 $v_extract_file = 0; 2511 } 2512 // ----- Look if file is write protected 2513 else if (!is_writeable($v_header[filename])) 2514 { 2515 TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is write protected"); 2516 2517 // ----- Change the file status 2518 $v_header[status] = "write_protected"; 2519 2520 // ----- Skip the extract 2521 $v_extraction_stopped = 1; 2522 $v_extract_file = 0; 2523 } 2524 // ----- Look if the extracted file is older 2525 else if (filemtime($v_header[filename]) > $v_header[mtime]) 2526 { 2527 TrFctMessage(__FILE__, __LINE__, 2, "Existing file '$v_header[filename]' is newer (".date("l dS of F Y h:i:s A", filemtime($v_header[filename])).") than the extracted file (".date("l dS of F Y h:i:s A", $v_header[mtime]).")"); 2528 2529 // ----- Change the file status 2530 $v_header[status] = "newer_exist"; 2531 2532 // ----- Skip the extract 2533 $v_extraction_stopped = 1; 2534 $v_extract_file = 0; 2535 } 2536 } 2537 2538 // ----- Check the directory availability and create it if necessary 2539 else 2540 { 2541 if ($v_header[typeflag]=="5") 2542 $v_dir_to_check = $v_header[filename]; 2543 else if (!strstr($v_header[filename], "/")) 2544 $v_dir_to_check = ""; 2545 else 2546 $v_dir_to_check = dirname($v_header[filename]); 2547 2548 if (($v_result = PclTarHandlerDirCheck($v_dir_to_check)) != 1) 2549 { 2550 TrFctMessage(__FILE__, __LINE__, 2, "Unable to create path for '$v_header[filename]'"); 2551 2552 // ----- Change the file status 2553 $v_header[status] = "path_creation_fail"; 2554 2555 // ----- Skip the extract 2556 $v_extraction_stopped = 1; 2557 $v_extract_file = 0; 2558 } 2559 } 2560 2561 // ----- Do the real bytes extraction (if not a directory) 2562 if (($v_extract_file) && ($v_header[typeflag]!="5")) 2563 { 2564 // ----- Open the destination file in write mode 2565 if (($v_dest_file = @fopen($v_header[filename], "wb")) == 0) 2566 { 2567 TrFctMessage(__FILE__, __LINE__, 2, "Error while opening '$v_header[filename]' in write binary mode"); 2568 2569 // ----- Change the file status 2570 $v_header[status] = "write_error"; 2571 2572 // ----- Jump to next file 2573 TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); 2574 if ($p_tar_mode == "tar") 2575 fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512)); 2576 else 2577 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512)); 2578 } 2579 else 2580 { 2581 TrFctMessage(__FILE__, __LINE__, 2, "Start extraction of '$v_header[filename]'"); 2582 2583 // ----- Read data 2584 $n = floor($v_header[size]/512); 2585 for ($i=0; $i<$n; $i++) 2586 { 2587 TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1)); 2588 if ($p_tar_mode == "tar") 2589 $v_content = fread($v_tar, 512); 2590 else 2591 $v_content = gzread($v_tar, 512); 2592 fwrite($v_dest_file, $v_content, 512); 2593 } 2594 if (($v_header[size] % 512) != 0) 2595 { 2596 TrFctMessage(__FILE__, __LINE__, 3, "Read last ".($v_header[size] % 512)." bytes in a 512 block"); 2597 if ($p_tar_mode == "tar") 2598 $v_content = fread($v_tar, 512); 2599 else 2600 $v_content = gzread($v_tar, 512); 2601 fwrite($v_dest_file, $v_content, ($v_header[size] % 512)); 2602 } 2603 2604 // ----- Close the destination file 2605 fclose($v_dest_file); 2606 2607 // ----- Change the file mode, mtime 2608 touch($v_header[filename], $v_header[mtime]); 2609 //chmod($v_header[filename], DecOct($v_header[mode])); 2610 } 2611 2612 // ----- Check the file size 2613 clearstatcache(); 2614 if (filesize($v_header[filename]) != $v_header[size]) 2615 { 2616 // ----- Error log 2617 PclErrorLog(-7, "Extracted file '$v_header[filename]' does not have the correct file size '".filesize($v_filename)."' ('$v_header[size]' expected). Archive may be corrupted."); 2618 2619 // ----- Return 2620 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2621 return PclErrorCode(); 2622 } 2623 2624 // ----- Trace 2625 TrFctMessage(__FILE__, __LINE__, 2, "Extraction done"); 2626 } 2627 else 2628 { 2629 TrFctMessage(__FILE__, __LINE__, 2, "Extraction of file '$v_header[filename]' skipped."); 2630 2631 // ----- Jump to next file 2632 TrFctMessage(__FILE__, __LINE__, 2, "Jump to next file"); 2633 if ($p_tar_mode == "tar") 2634 fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512)); 2635 else 2636 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512)); 2637 } 2638 2639 // ----- Return 2640 TrFctEnd(__FILE__, __LINE__, $v_result); 2641 return $v_result; 2642 } 2643 // -------------------------------------------------------------------------------- 2644 2645 // -------------------------------------------------------------------------------- 2646 // Function : PclTarHandleDelete() 2647 // Description : 2648 // Parameters : 2649 // Return Values : 2650 // -------------------------------------------------------------------------------- 2651 function PclTarHandleDelete($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode) 2652 { 2653 TrFctStart(__FILE__, __LINE__, "PclTarHandleDelete", "archive='$p_tarname', list, tar_mode=$p_tar_mode"); 2654 $v_result=1; 2655 $v_nb=0; 2656 2657 // ----- Look for regular tar file 2658 if ($p_tar_mode == "tar") 2659 { 2660 // ----- Open file 2661 TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); 2662 if (($v_tar = @fopen($p_tarname, "rb")) == 0) 2663 { 2664 // ----- Error log 2665 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); 2666 2667 // ----- Return 2668 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2669 return PclErrorCode(); 2670 } 2671 2672 // ----- Open a temporary file in write mode 2673 $v_temp_tarname = uniqid("pcltar-").".tmp"; 2674 TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); 2675 if (($v_temp_tar = @fopen($v_temp_tarname, "wb")) == 0) 2676 { 2677 // ----- Close tar file 2678 fclose($v_tar); 2679 2680 // ----- Error log 2681 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); 2682 2683 // ----- Return 2684 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2685 return PclErrorCode(); 2686 } 2687 } 2688 2689 // ----- Look for compressed tar file 2690 else 2691 { 2692 // ----- Open the file in read mode 2693 TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); 2694 if (($v_tar = @gzopen($p_tarname, "rb")) == 0) 2695 { 2696 // ----- Error log 2697 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); 2698 2699 // ----- Return 2700 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2701 return PclErrorCode(); 2702 } 2703 2704 // ----- Open a temporary file in write mode 2705 $v_temp_tarname = uniqid("pcltar-").".tmp"; 2706 TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); 2707 if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0) 2708 { 2709 // ----- Close tar file 2710 gzclose($v_tar); 2711 2712 // ----- Error log 2713 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); 2714 2715 // ----- Return 2716 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2717 return PclErrorCode(); 2718 } 2719 } 2720 2721 // ----- Read the blocks 2722 While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))) 2723 { 2724 TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); 2725 2726 // ----- Clear cache of file infos 2727 clearstatcache(); 2728 2729 // ----- Reset delete tag 2730 $v_delete_file = FALSE; 2731 2732 // ----- Read the first 512 block header 2733 if ($p_tar_mode == "tar") 2734 $v_binary_data = fread($v_tar, 512); 2735 else 2736 $v_binary_data = gzread($v_tar, 512); 2737 2738 // ----- Read the header properties 2739 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1) 2740 { 2741 // ----- Close the archive file 2742 if ($p_tar_mode == "tar") 2743 { 2744 fclose($v_tar); 2745 fclose($v_temp_tar); 2746 } 2747 else 2748 { 2749 gzclose($v_tar); 2750 gzclose($v_temp_tar); 2751 } 2752 @unlink($v_temp_tarname); 2753 2754 // ----- Return 2755 TrFctEnd(__FILE__, __LINE__, $v_result); 2756 return $v_result; 2757 } 2758 2759 // ----- Look for empty blocks to skip 2760 if ($v_header[filename] == "") 2761 { 2762 TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?"); 2763 continue; 2764 } 2765 2766 TrFctMessage(__FILE__, __LINE__, 2, "Found file '$v_header[filename]', size '$v_header[size]'"); 2767 2768 // ----- Look for filenames to delete 2769 for ($i=0, $v_delete_file=FALSE; ($i<sizeof($p_file_list)) && (!$v_delete_file); $i++) 2770 { 2771 // ----- Compare the file names 2772 // if ($p_file_list[$i] == $v_header[filename]) 2773 if (($v_len = strcmp($p_file_list[$i], $v_header[filename])) <= 0) 2774 { 2775 if ($v_len==0) 2776 { 2777 TrFctMessage(__FILE__, __LINE__, 3, "Found that '$v_header[filename]' need to be deleted"); 2778 $v_delete_file = TRUE; 2779 } 2780 else 2781 { 2782 TrFctMessage(__FILE__, __LINE__, 3, "Look if '$v_header[filename]' is a file in $p_file_list[$i]"); 2783 if (substr($v_header[filename], strlen($p_file_list[$i]), 1) == "/") 2784 { 2785 TrFctMessage(__FILE__, __LINE__, 3, "'$v_header[filename]' is a file in $p_file_list[$i]"); 2786 $v_delete_file = TRUE; 2787 } 2788 } 2789 } 2790 } 2791 2792 // ----- Copy files that do not need to be deleted 2793 if (!$v_delete_file) 2794 { 2795 TrFctMessage(__FILE__, __LINE__, 2, "Keep file '$v_header[filename]'"); 2796 2797 // ----- Write the file header 2798 if ($p_tar_mode == "tar") 2799 { 2800 fputs($v_temp_tar, $v_binary_data, 512); 2801 } 2802 else 2803 { 2804 gzputs($v_temp_tar, $v_binary_data, 512); 2805 } 2806 2807 // ----- Write the file data 2808 $n = ceil($v_header[size]/512); 2809 for ($i=0; $i<$n; $i++) 2810 { 2811 TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($i+1)); 2812 if ($p_tar_mode == "tar") 2813 { 2814 $v_content = fread($v_tar, 512); 2815 fwrite($v_temp_tar, $v_content, 512); 2816 } 2817 else 2818 { 2819 $v_content = gzread($v_tar, 512); 2820 gzwrite($v_temp_tar, $v_content, 512); 2821 } 2822 } 2823 2824 // ----- File name and properties are logged if listing mode or file is extracted 2825 TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); 2826 2827 // ----- Add the array describing the file into the list 2828 $p_list_detail[$v_nb] = $v_header; 2829 $p_list_detail[$v_nb][status] = "ok"; 2830 2831 // ----- Increment 2832 $v_nb++; 2833 } 2834 2835 // ----- Look for file that is to be deleted 2836 else 2837 { 2838 // ----- Trace 2839 TrFctMessage(__FILE__, __LINE__, 2, "Start deletion of '$v_header[filename]'"); 2840 TrFctMessage(__FILE__, __LINE__, 4, "Position avant jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]"); 2841 2842 // ----- Jump to next file 2843 if ($p_tar_mode == "tar") 2844 fseek($v_tar, ftell($v_tar)+(ceil(($v_header[size]/512))*512)); 2845 else 2846 gzseek($v_tar, gztell($v_tar)+(ceil(($v_header[size]/512))*512)); 2847 2848 TrFctMessage(__FILE__, __LINE__, 4, "Position apr�s jump [".($p_tar_mode=="tar"?ftell($v_tar):gztell($v_tar))."]"); 2849 } 2850 2851 // ----- Look for end of file 2852 if ($p_tar_mode == "tar") 2853 $v_end_of_file = feof($v_tar); 2854 else 2855 $v_end_of_file = gzeof($v_tar); 2856 } 2857 2858 // ----- Write the last empty buffer 2859 PclTarHandleFooter($v_temp_tar, $p_tar_mode); 2860 2861 // ----- Close the tarfile 2862 if ($p_tar_mode == "tar") 2863 { 2864 fclose($v_tar); 2865 fclose($v_temp_tar); 2866 } 2867 else 2868 { 2869 gzclose($v_tar); 2870 gzclose($v_temp_tar); 2871 } 2872 2873 // ----- Unlink tar file 2874 if (!@unlink($p_tarname)) 2875 { 2876 // ----- Error log 2877 PclErrorLog(-11, "Error while deleting archive name $p_tarname"); 2878 } 2879 2880 2881 // ----- Rename tar file 2882 if (!@rename($v_temp_tarname, $p_tarname)) 2883 { 2884 // ----- Error log 2885 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname"); 2886 2887 // ----- Return 2888 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2889 return PclErrorCode(); 2890 } 2891 2892 // ----- Return 2893 TrFctEnd(__FILE__, __LINE__, $v_result); 2894 return $v_result; 2895 } 2896 // -------------------------------------------------------------------------------- 2897 2898 // -------------------------------------------------------------------------------- 2899 // Function : PclTarHandleUpdate() 2900 // Description : 2901 // Parameters : 2902 // Return Values : 2903 // -------------------------------------------------------------------------------- 2904 function PclTarHandleUpdate($p_tarname, $p_file_list, &$p_list_detail, $p_tar_mode, $p_add_dir, $p_remove_dir) 2905 { 2906 TrFctStart(__FILE__, __LINE__, "PclTarHandleUpdate", "archive='$p_tarname', list, tar_mode=$p_tar_mode"); 2907 $v_result=1; 2908 $v_nb=0; 2909 $v_found_list = array(); 2910 2911 // ----- Look for regular tar file 2912 if ($p_tar_mode == "tar") 2913 { 2914 // ----- Open file 2915 TrFctMessage(__FILE__, __LINE__, 3, "Open file in binary read mode"); 2916 if (($v_tar = @fopen($p_tarname, "rb")) == 0) 2917 { 2918 // ----- Error log 2919 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); 2920 2921 // ----- Return 2922 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2923 return PclErrorCode(); 2924 } 2925 2926 // ----- Open a temporary file in write mode 2927 $v_temp_tarname = uniqid("pcltar-").".tmp"; 2928 TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); 2929 if (($v_temp_tar = @fopen($v_temp_tarname, "wb")) == 0) 2930 { 2931 // ----- Close tar file 2932 fclose($v_tar); 2933 2934 // ----- Error log 2935 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); 2936 2937 // ----- Return 2938 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2939 return PclErrorCode(); 2940 } 2941 } 2942 2943 // ----- Look for compressed tar file 2944 else 2945 { 2946 // ----- Open the file in read mode 2947 TrFctMessage(__FILE__, __LINE__, 3, "Open file in gzip binary read mode"); 2948 if (($v_tar = @gzopen($p_tarname, "rb")) == 0) 2949 { 2950 // ----- Error log 2951 PclErrorLog(-2, "Unable to open file '$p_tarname' in binary read mode"); 2952 2953 // ----- Return 2954 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2955 return PclErrorCode(); 2956 } 2957 2958 // ----- Open a temporary file in write mode 2959 $v_temp_tarname = uniqid("pcltar-").".tmp"; 2960 TrFctMessage(__FILE__, __LINE__, 2, "Creating temporary archive file $v_temp_tarname"); 2961 if (($v_temp_tar = @gzopen($v_temp_tarname, "wb")) == 0) 2962 { 2963 // ----- Close tar file 2964 gzclose($v_tar); 2965 2966 // ----- Error log 2967 PclErrorLog(-1, "Unable to open file '$v_temp_tarname' in binary write mode"); 2968 2969 // ----- Return 2970 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 2971 return PclErrorCode(); 2972 } 2973 } 2974 2975 // ----- Prepare the list of files 2976 for ($i=0; $i<sizeof($p_file_list); $i++) 2977 { 2978 // ----- Reset the found list 2979 $v_found_list[$i] = 0; 2980 2981 // ----- Calculate the stored filename 2982 $v_stored_list[$i] = $p_file_list[$i]; 2983 if ($p_remove_dir != "") 2984 { 2985 if (substr($p_file_list[$i], -1) != '/') 2986 $p_remove_dir .= "/"; 2987 2988 if (substr($p_file_list[$i], 0, strlen($p_remove_dir)) == $p_remove_dir) 2989 { 2990 $v_stored_list[$i] = substr($p_file_list[$i], strlen($p_remove_dir)); 2991 TrFctMessage(__FILE__, __LINE__, 3, "Remove path '$p_remove_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'"); 2992 } 2993 } 2994 if ($p_add_dir != "") 2995 { 2996 if (substr($p_add_dir, -1) == "/") 2997 $v_stored_list[$i] = $p_add_dir.$v_stored_list[$i]; 2998 else 2999 $v_stored_list[$i] = $p_add_dir."/".$v_stored_list[$i]; 3000 TrFctMessage(__FILE__, __LINE__, 3, "Add path '$p_add_dir' in file '$p_file_list[$i]' = '$v_stored_list[$i]'"); 3001 } 3002 $v_stored_list[$i] = PclTarHandlePathReduction($v_stored_list[$i]); 3003 TrFctMessage(__FILE__, __LINE__, 3, "After reduction '$v_stored_list[$i]'"); 3004 } 3005 3006 3007 // ----- Update file cache 3008 clearstatcache(); 3009 3010 // ----- Read the blocks 3011 While (!($v_end_of_file = ($p_tar_mode == "tar"?feof($v_tar):gzeof($v_tar)))) 3012 { 3013 TrFctMessage(__FILE__, __LINE__, 3, "Looking for next header ..."); 3014 3015 // ----- Clear cache of file infos 3016 clearstatcache(); 3017 3018 // ----- Reset current found filename 3019 $v_current_filename = ""; 3020 3021 // ----- Reset delete tag 3022 $v_delete_file = FALSE; 3023 3024 // ----- Read the first 512 block header 3025 if ($p_tar_mode == "tar") 3026 $v_binary_data = fread($v_tar, 512); 3027 else 3028 $v_binary_data = gzread($v_tar, 512); 3029 3030 // ----- Read the header properties 3031 if (($v_result = PclTarHandleReadHeader($v_binary_data, $v_header)) != 1) 3032 { 3033 // ----- Close the archive file 3034 if ($p_tar_mode == "tar") 3035 { 3036 fclose($v_tar); 3037 fclose($v_temp_tar); 3038 } 3039 else 3040 { 3041 gzclose($v_tar); 3042 gzclose($v_temp_tar); 3043 } 3044 @unlink($v_temp_tarname); 3045 3046 // ----- Return 3047 TrFctEnd(__FILE__, __LINE__, $v_result); 3048 return $v_result; 3049 } 3050 3051 // ----- Look for empty blocks to skip 3052 if ($v_header[filename] == "") 3053 { 3054 TrFctMessage(__FILE__, __LINE__, 2, "Empty block found. End of archive ?"); 3055 continue; 3056 } 3057 3058 TrFctMessage(__FILE__, __LINE__, 2, "Found file '$v_header[filename]', size '$v_header[size]'"); 3059 3060 // ----- Look for filenames to update 3061 for ($i=0, $v_update_file=FALSE, $v_found_file=FALSE; ($i<sizeof($v_stored_list)) && (!$v_update_file); $i++) 3062 { 3063 TrFctMessage(__FILE__, __LINE__, 4, "Compare with file '$v_stored_list[$i]'"); 3064 3065 // ----- Compare the file names 3066 if ($v_stored_list[$i] == $v_header[filename]) 3067 { 3068 TrFctMessage(__FILE__, __LINE__, 3, "File '$v_stored_list[$i]' is present in archive"); 3069 TrFctMessage(__FILE__, __LINE__, 3, "File '$v_stored_list[$i]' mtime=".filemtime($p_file_list[$i])." ".date("l dS of F Y h:i:s A", filemtime($p_file_list[$i]))); 3070 TrFctMessage(__FILE__, __LINE__, 3, "Archived mtime=".$v_header[mtime]." ".date("l dS of F Y h:i:s A", $v_header[mtime])); 3071 3072 // ----- Store found informations 3073 $v_found_file = TRUE; 3074 $v_current_filename = $p_file_list[$i]; 3075 3076 // ----- Look if the file need to be updated 3077 if (filemtime($p_file_list[$i]) > $v_header[mtime]) 3078 { 3079 TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' need to be updated"); 3080 $v_update_file = TRUE; 3081 } 3082 else 3083 { 3084 TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' does not need to be updated"); 3085 $v_update_file = FALSE; 3086 } 3087 3088 // ----- Flag the name in order not to add the file at the end 3089 $v_found_list[$i] = 1; 3090 } 3091 else 3092 { 3093 TrFctMessage(__FILE__, __LINE__, 4, "File '$p_file_list[$i]' is not '$v_header[filename]'"); 3094 } 3095 } 3096 3097 // ----- Copy files that do not need to be updated 3098 if (!$v_update_file) 3099 { 3100 TrFctMessage(__FILE__, __LINE__, 2, "Keep file '$v_header[filename]'"); 3101 3102 // ----- Write the file header 3103 if ($p_tar_mode == "tar") 3104 { 3105 fputs($v_temp_tar, $v_binary_data, 512); 3106 } 3107 else 3108 { 3109 gzputs($v_temp_tar, $v_binary_data, 512); 3110 } 3111 3112 // ----- Write the file data 3113 $n = ceil($v_header[size]/512); 3114 for ($j=0; $j<$n; $j++) 3115 { 3116 TrFctMessage(__FILE__, __LINE__, 3, "Read complete 512 bytes block number ".($j+1)); 3117 if ($p_tar_mode == "tar") 3118 { 3119 $v_content = fread($v_tar, 512); 3120 fwrite($v_temp_tar, $v_content, 512); 3121 } 3122 else 3123 { 3124 $v_content = gzread($v_tar, 512); 3125 gzwrite($v_temp_tar, $v_content, 512); 3126 } 3127 } 3128 3129 // ----- File name and properties are logged if listing mode or file is extracted 3130 TrFctMessage(__FILE__, __LINE__, 2, "Memorize info about file '$v_header[filename]'"); 3131 3132 // ----- Add the array describing the file into the list 3133 $p_list_detail[$v_nb] = $v_header; 3134 $p_list_detail[$v_nb][status] = ($v_found_file?"not_updated":"ok"); 3135 3136 // ----- Increment 3137 $v_nb++; 3138 } 3139 3140 // ----- Look for file that need to be updated 3141 else 3142 { 3143 // ----- Trace 3144 TrFctMessage(__FILE__, __LINE__, 2, "Start update of file '$v_current_filename'"); 3145 3146 // ----- Store the old file size 3147 $v_old_size = $v_header[size]; 3148 3149 // ----- Add the file 3150 if (($v_result = PclTarHandleAddFile($v_temp_tar, $v_current_filename, $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1) 3151 { 3152 // ----- Close the tarfile 3153 if ($p_tar_mode == "tar") 3154 { 3155 fclose($v_tar); 3156 fclose($v_temp_tar); 3157 } 3158 else 3159 { 3160 gzclose($v_tar); 3161 gzclose($v_temp_tar); 3162 } 3163 @unlink($p_temp_tarname); 3164 3165 // ----- Return status 3166 TrFctEnd(__FILE__, __LINE__, $v_result); 3167 return $v_result; 3168 } 3169 3170 // ----- Trace 3171 TrFctMessage(__FILE__, __LINE__, 2, "Skip old file '$v_header[filename]'"); 3172 3173 // ----- Jump to next file 3174 if ($p_tar_mode == "tar") 3175 fseek($v_tar, ftell($v_tar)+(ceil(($v_old_size/512))*512)); 3176 else 3177 gzseek($v_tar, gztell($v_tar)+(ceil(($v_old_size/512))*512)); 3178 3179 // ----- Add the array describing the file into the list 3180 $p_list_detail[$v_nb] = $v_header; 3181 $p_list_detail[$v_nb][status] = "updated"; 3182 3183 // ----- Increment 3184 $v_nb++; 3185 } 3186 3187 // ----- Look for end of file 3188 if ($p_tar_mode == "tar") 3189 $v_end_of_file = feof($v_tar); 3190 else 3191 $v_end_of_file = gzeof($v_tar); 3192 } 3193 3194 // ----- Look for files that does not exists in the archive and need to be added 3195 for ($i=0; $i<sizeof($p_file_list); $i++) 3196 { 3197 // ----- Look if file not found in the archive 3198 if (!$v_found_list[$i]) 3199 { 3200 TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' need to be added"); 3201 3202 // ----- Add the file 3203 if (($v_result = PclTarHandleAddFile($v_temp_tar, $p_file_list[$i], $p_tar_mode, $v_header, $p_add_dir, $p_remove_dir)) != 1) 3204 { 3205 // ----- Close the tarfile 3206 if ($p_tar_mode == "tar") 3207 { 3208 fclose($v_tar); 3209 fclose($v_temp_tar); 3210 } 3211 else 3212 { 3213 gzclose($v_tar); 3214 gzclose($v_temp_tar); 3215 } 3216 @unlink($p_temp_tarname); 3217 3218 // ----- Return status 3219 TrFctEnd(__FILE__, __LINE__, $v_result); 3220 return $v_result; 3221 } 3222 3223 // ----- Add the array describing the file into the list 3224 $p_list_detail[$v_nb] = $v_header; 3225 $p_list_detail[$v_nb][status] = "added"; 3226 3227 // ----- Increment 3228 $v_nb++; 3229 } 3230 else 3231 { 3232 TrFctMessage(__FILE__, __LINE__, 3, "File '$p_file_list[$i]' was already updated if needed"); 3233 } 3234 } 3235 3236 // ----- Write the last empty buffer 3237 PclTarHandleFooter($v_temp_tar, $p_tar_mode); 3238 3239 // ----- Close the tarfile 3240 if ($p_tar_mode == "tar") 3241 { 3242 fclose($v_tar); 3243 fclose($v_temp_tar); 3244 } 3245 else 3246 { 3247 gzclose($v_tar); 3248 gzclose($v_temp_tar); 3249 } 3250 3251 // ----- Unlink tar file 3252 if (!@unlink($p_tarname)) 3253 { 3254 // ----- Error log 3255 PclErrorLog(-11, "Error while deleting archive name $p_tarname"); 3256 } 3257 3258 3259 // ----- Rename tar file 3260 if (!@rename($v_temp_tarname, $p_tarname)) 3261 { 3262 // ----- Error log 3263 PclErrorLog(-12, "Error while renaming temporary file $v_temp_tarname to archive name $p_tarname"); 3264 3265 // ----- Return 3266 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 3267 return PclErrorCode(); 3268 } 3269 3270 // ----- Return 3271 TrFctEnd(__FILE__, __LINE__, $v_result); 3272 return $v_result; 3273 } 3274 // -------------------------------------------------------------------------------- 3275 3276 // -------------------------------------------------------------------------------- 3277 // Function : PclTarHandleReadHeader() 3278 // Description : 3279 // Parameters : 3280 // Return Values : 3281 // -------------------------------------------------------------------------------- 3282 function PclTarHandleReadHeader($v_binary_data, &$v_header) 3283 { 3284 TrFctStart(__FILE__, __LINE__, "PclTarHandleReadHeader", ""); 3285 $v_result=1; 3286 3287 // ----- Read the 512 bytes header 3288 /* 3289 if ($p_tar_mode == "tar") 3290 $v_binary_data = fread($p_tar, 512); 3291 else 3292 $v_binary_data = gzread($p_tar, 512); 3293 */ 3294 3295 // ----- Look for no more block 3296 if (strlen($v_binary_data)==0) 3297 { 3298 $v_header[filename] = ""; 3299 $v_header[status] = "empty"; 3300 3301 // ----- Return 3302 TrFctEnd(__FILE__, __LINE__, $v_result, "End of archive found"); 3303 return $v_result; 3304 } 3305 3306 // ----- Look for invalid block size 3307 if (strlen($v_binary_data) != 512) 3308 { 3309 $v_header[filename] = ""; 3310 $v_header[status] = "invalid_header"; 3311 TrFctMessage(__FILE__, __LINE__, 2, "Invalid block size : ".strlen($v_binary_data)); 3312 3313 // ----- Error log 3314 PclErrorLog(-10, "Invalid block size : ".strlen($v_binary_data)); 3315 3316 // ----- Return 3317 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 3318 return PclErrorCode(); 3319 } 3320 3321 // ----- Calculate the checksum 3322 $v_checksum = 0; 3323 // ..... First part of the header 3324 for ($i=0; $i<148; $i++) 3325 { 3326 $v_checksum+=ord(substr($v_binary_data,$i,1)); 3327 } 3328 // ..... Ignore the checksum value and replace it by ' ' (space) 3329 for ($i=148; $i<156; $i++) 3330 { 3331 $v_checksum += ord(' '); 3332 } 3333 // ..... Last part of the header 3334 for ($i=156; $i<512; $i++) 3335 { 3336 $v_checksum+=ord(substr($v_binary_data,$i,1)); 3337 } 3338 TrFctMessage(__FILE__, __LINE__, 3, "Calculated checksum : $v_checksum"); 3339 3340 // ----- Extract the values 3341 TrFctMessage(__FILE__, __LINE__, 2, "Header : '$v_binary_data'"); 3342 $v_data = unpack("a100filename/a8mode/a8uid/a8gid/a12size/a12mtime/a8checksum/a1typeflag/a100link/a6magic/a2version/a32uname/a32gname/a8devmajor/a8devminor", $v_binary_data); 3343 3344 // ----- Extract the checksum for check 3345 $v_header["checksum"] = OctDec(trim($v_data["checksum"])); 3346 TrFctMessage(__FILE__, __LINE__, 3, "File checksum : $v_header[checksum]"); 3347 if ($v_header["checksum"] != $v_checksum) 3348 { 3349 TrFctMessage(__FILE__, __LINE__, 2, "File checksum is invalid : $v_checksum calculated, $v_header[checksum] expected"); 3350 3351 $v_header["filename"] = ""; 3352 $v_header["status"] = "invalid_header"; 3353 3354 // ----- Look for last block (empty block) 3355 if (($v_checksum == 256) && ($v_header["checksum"] == 0)) 3356 { 3357 $v_header["status"] = "empty"; 3358 // ----- Return 3359 TrFctEnd(__FILE__, __LINE__, $v_result, "End of archive found"); 3360 return $v_result; 3361 } 3362 3363 // ----- Error log 3364 PclErrorLog(-13, "Invalid checksum : $v_checksum calculated, " . $v_header["checksum"] . " expected"); 3365 3366 // ----- Return 3367 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 3368 return PclErrorCode(); 3369 } 3370 TrFctMessage(__FILE__, __LINE__, 2, "File checksum is valid ($v_checksum)"); 3371 3372 // ----- Extract the properties 3373 $v_header["filename"] = trim($v_data["filename"]); 3374 TrFctMessage(__FILE__, __LINE__, 2, "Name : '$v_header[filename]'"); 3375 $v_header["mode"] = OctDec(trim($v_data["mode"])); 3376 TrFctMessage(__FILE__, __LINE__, 2, "Mode : '".DecOct($v_header["mode"])."'"); 3377 $v_header["uid"] = OctDec(trim($v_data["uid"])); 3378 TrFctMessage(__FILE__, __LINE__, 2, "Uid : '$v_header[uid]'"); 3379 $v_header["gid"] = OctDec(trim($v_data["gid"])); 3380 TrFctMessage(__FILE__, __LINE__, 2, "Gid : '$v_header[gid]'"); 3381 $v_header["size"] = OctDec(trim($v_data["size"])); 3382 TrFctMessage(__FILE__, __LINE__, 2, "Size : '$v_header[size]'"); 3383 $v_header["mtime"] = OctDec(trim($v_data["mtime"])); 3384 TrFctMessage(__FILE__, __LINE__, 2, "Date : ".date("l dS of F Y h:i:s A", $v_header["mtime"])); 3385 if (($v_header["typeflag"] = $v_data["typeflag"]) == "5") 3386 { 3387 $v_header["size"] = 0; 3388 TrFctMessage(__FILE__, __LINE__, 2, "Size (folder) : '$v_header[size]'"); 3389 } 3390 TrFctMessage(__FILE__, __LINE__, 2, "File typeflag : $v_header[typeflag]"); 3391 /* ----- All these fields are removed form the header because they do not carry interesting info 3392 $v_header[link] = trim($v_data[link]); 3393 TrFctMessage(__FILE__, __LINE__, 2, "Linkname : $v_header[linkname]"); 3394 $v_header[magic] = trim($v_data[magic]); 3395 TrFctMessage(__FILE__, __LINE__, 2, "Magic : $v_header[magic]"); 3396 $v_header[version] = trim($v_data[version]); 3397 TrFctMessage(__FILE__, __LINE__, 2, "Version : $v_header[version]"); 3398 $v_header[uname] = trim($v_data[uname]); 3399 TrFctMessage(__FILE__, __LINE__, 2, "Uname : $v_header[uname]"); 3400 $v_header[gname] = trim($v_data[gname]); 3401 TrFctMessage(__FILE__, __LINE__, 2, "Gname : $v_header[gname]"); 3402 $v_header[devmajor] = trim($v_data[devmajor]); 3403 TrFctMessage(__FILE__, __LINE__, 2, "Devmajor : $v_header[devmajor]"); 3404 $v_header[devminor] = trim($v_data[devminor]); 3405 TrFctMessage(__FILE__, __LINE__, 2, "Devminor : $v_header[devminor]"); 3406 */ 3407 3408 // ----- Set the status field 3409 $v_header["status"] = "ok"; 3410 3411 // ----- Return 3412 TrFctEnd(__FILE__, __LINE__, $v_result); 3413 return $v_result; 3414 } 3415 // -------------------------------------------------------------------------------- 3416 3417 // -------------------------------------------------------------------------------- 3418 // Function : PclTarHandlerDirCheck() 3419 // Description : 3420 // Check if a directory exists, if not it creates it and all the parents directory 3421 // which may be useful. 3422 // Parameters : 3423 // $p_dir : Directory path to check (without / at the end). 3424 // Return Values : 3425 // 1 : OK 3426 // -1 : Unable to create directory 3427 // -------------------------------------------------------------------------------- 3428 function PclTarHandlerDirCheck($p_dir) 3429 { 3430 $v_result = 1; 3431 3432 TrFctStart(__FILE__, __LINE__, "PclTarHandlerDirCheck", "$p_dir"); 3433 3434 // ----- Check the directory availability 3435 if ((is_dir($p_dir)) || ($p_dir == "")) 3436 { 3437 TrFctEnd(__FILE__, __LINE__, "'$p_dir' is a directory"); 3438 return 1; 3439 } 3440 3441 // ----- Look for file alone 3442 /* 3443 if (!strstr("$p_dir", "/")) 3444 { 3445 TrFctEnd(__FILE__, __LINE__, "'$p_dir' is a file with no directory"); 3446 return 1; 3447 } 3448 */ 3449 3450 // ----- Extract parent directory 3451 $p_parent_dir = dirname($p_dir); 3452 TrFctMessage(__FILE__, __LINE__, 3, "Parent directory is '$p_parent_dir'"); 3453 3454 // ----- Just a check 3455 if ($p_parent_dir != $p_dir) 3456 { 3457 // ----- Look for parent directory 3458 if ($p_parent_dir != "") 3459 { 3460 if (($v_result = PclTarHandlerDirCheck($p_parent_dir)) != 1) 3461 { 3462 TrFctEnd(__FILE__, __LINE__, $v_result); 3463 return $v_result; 3464 } 3465 } 3466 } 3467 3468 // ----- Create the directory 3469 TrFctMessage(__FILE__, __LINE__, 3, "Create directory '$p_dir'"); 3470 if (!@mkdir($p_dir, 0777)) 3471 { 3472 // ----- Error log 3473 PclErrorLog(-8, "Unable to create directory '$p_dir'"); 3474 3475 // ----- Return 3476 TrFctEnd(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 3477 return PclErrorCode(); 3478 } 3479 3480 // ----- Return 3481 TrFctEnd(__FILE__, __LINE__, $v_result, "Directory '$p_dir' created"); 3482 return $v_result; 3483 } 3484 // -------------------------------------------------------------------------------- 3485 3486 // -------------------------------------------------------------------------------- 3487 // Function : PclTarHandleExtension() 3488 // Description : 3489 // Parameters : 3490 // Return Values : 3491 // -------------------------------------------------------------------------------- 3492 function PclTarHandleExtension($p_tarname) 3493 { 3494 TrFctStart(__FILE__, __LINE__, "PclTarHandleExtension", "tar=$p_tarname"); 3495 3496 // ----- Look for file extension 3497 if ((substr($p_tarname, -7) == ".tar.gz") || (substr($p_tarname, -4) == ".tgz")) 3498 { 3499 TrFctMessage(__FILE__, __LINE__, 2, "Archive is a gzip tar"); 3500 $v_tar_mode = "tgz"; 3501 } 3502 else if (substr($p_tarname, -4) == ".tar") 3503 { 3504 TrFctMessage(__FILE__, __LINE__, 2, "Archive is a tar"); 3505 $v_tar_mode = "tar"; 3506 } 3507 else 3508 { 3509 // ----- Error log 3510 PclErrorLog(-9, "Invalid archive extension"); 3511 3512 TrFctMessage(__FILE__, __LINE__, PclErrorCode(), PclErrorString()); 3513 3514 $v_tar_mode = ""; 3515 } 3516 3517 // ----- Return 3518 TrFctEnd(__FILE__, __LINE__, $v_tar_mode); 3519 return $v_tar_mode; 3520 } 3521 // -------------------------------------------------------------------------------- 3522 3523 3524 // -------------------------------------------------------------------------------- 3525 // Function : PclTarHandlePathReduction() 3526 // Description : 3527 // Parameters : 3528 // Return Values : 3529 // -------------------------------------------------------------------------------- 3530 function PclTarHandlePathReduction($p_dir) 3531 { 3532 TrFctStart(__FILE__, __LINE__, "PclTarHandlePathReduction", "dir='$p_dir'"); 3533 $v_result = ""; 3534 3535 // ----- Look for not empty path 3536 if ($p_dir != "") 3537 { 3538 // ----- Explode path by directory names 3539 $v_list = explode("/", $p_dir); 3540 3541 // ----- Study directories from last to first 3542 for ($i=sizeof($v_list)-1; $i>=0; $i--) 3543 { 3544 // ----- Look for current path 3545 if ($v_list[$i] == ".") 3546 { 3547 // ----- Ignore this directory 3548 // Should be the first $i=0, but no check is done 3549 } 3550 else if ($v_list[$i] == "..") 3551 { 3552 // ----- Ignore it and ignore the $i-1 3553 $i--; 3554 } 3555 else if (($v_list[$i] == "") && ($i!=(sizeof($v_list)-1)) && ($i!=0)) 3556 { 3557 // ----- Ignore only the double '//' in path, 3558 // but not the first and last '/' 3559 } 3560 else 3561 { 3562 $v_result = $v_list[$i].($i!=(sizeof($v_list)-1)?"/".$v_result:""); 3563 } 3564 } 3565 } 3566 3567 // ----- Return 3568 TrFctEnd(__FILE__, __LINE__, $v_result); 3569 return $v_result; 3570 } 3571 // -------------------------------------------------------------------------------- 3572 3573 3574 // ----- End of double include look 3575 } 3576 ?>
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Wed Nov 21 14:43:32 2007 | par Balluche grâce à PHPXref 0.7 |
|