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